控制Prolog变量值选择 [英] Controlling Prolog variable value selection

查看:137
本文介绍了控制Prolog变量值选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个先前的问题的启发,我尝试实施这会列举出布尔表达式的可能性.但是,我在选择变量时遇到了麻烦.这是我预期的结果:

Inspired by an earlier question I tried to implement something that would enumerate the possibilities for a boolean expression. However, I'm having trouble with variable choice. Here's my intended outcome:

?- eval(X^Y, R).
R = 0^0;
R = 0^1;
R = 1^0;
R = 1^1;
no.

这是我的代码:

:- op(200, yfx, ^).

split(V, R) :- var(V), R = 0.
split(V, R) :- var(V), R = 1.
split(X ^ Y, XP ^ YP) :- split(X, XP), split(Y, YP).

即使在这种简单情况下,这也无法满足我的要求:

This already doesn't do what I want even for this simple case:

?- split(Y, R).
R = 0 ;
R = 1 ;
Y = _G269^_G270,
R = 0^0 ;
Y = _G269^_G270,
R = 0^1 ;
Y = _G269^ (_G275^_G276),
R = 0^ (0^0) ;
Y = _G269^ (_G275^_G276),
R = 0^ (0^1) ;
Y = _G269^ (_G275^ (_G281^_G282)),
R = 0^ (0^ (0^0)) .

所以,我可以看到这里的问题是,在通过split(Y, YP)的途中,Prolog已经用尽了前两个子句,因此它再次出现在split(X^Y, ...)中,将我的Y,本质上.我只是不确定我需要做什么来封闭该路径,除非一开始我的结构是^/2.

So, I can see what the problem is here, which is that on the way through split(Y, YP) Prolog has exhausted the first two clauses, so it winds up in split(X^Y, ...) again, unifying my Y with X'^Y', essentially. I am just not sure what I need to do to close off that path except at the outset where I have the structure ^/2.

我也希望它可以用于嵌套结构,所以我不能只消除分支的递归处理.

I'd also like this to work with nested structures, so I can't just eliminate the recursive processing of the branches.

修改:无操作符

如果op/3困扰您,请考虑以下公式:

If the op/3 is bothering you, consider this formulation:

eval(and(X,Y), R).
R = and(0,0);
R = and(0,1);
R = and(1,0);
R = and(1,1);
no.

在这种情况下,这就是代码:

This would be the code in that case:

split(V, R) :- var(V), R = 0.
split(V, R) :- var(V), R = 1.
split(and(X,Y), and(XP,YP)) :- split(X, XP), split(Y, YP).

请记住,我仍然希望它可以与and(and(X,Y),and(Y,Z))等递归公式一起使用.

Bear in mind I'd still like it to work with recursive formulations like and(and(X,Y),and(Y,Z)) etc.

推荐答案

主要问题:默认表示形式

在这种情况下,核心问题是用于表示布尔表达式的默认表示.

默认"是指您无法通过模式匹配清楚地区分案例:在您的案例中,变量V可能表示

By "defaulty" I mean that you cannot clearly distinguish the cases by pattern matching: In your case, a variable V may denote either

  • 命题常量01
  • 之一
  • A^B形式的复合表达式.
  • one of the propositional constants 0 and 1, or
  • a compound expression of the form A^B.

由于此缺点,您不能在程序中干净地表达变量X仅代表两个命题常量之一"形式的约束.

Due to this shortcoming, you cannot cleanly express a constraint of the form "the variable X stands only for one of the two propositional constants" within your program.

声明性的出路是使用简洁的表示形式 .

A declarative way out is to use a clean representation instead.

例如,假设我们任意使用v/1来区分仅表示命题常数的变量,则我们有:

For example, suppose we arbitrarily use v/1 to distinguish variables that only denote the propositional constants, then we have:

  • v(X)表示命题变量X
  • A^B表示复合表达式.
  • v(X) to denote the propositional variable X
  • A^B to denote a compound expression.

很明显,由于主要函子和变量(v/1(^)/2)不同,因此我们可以仅通过模式匹配来区分情况.

Clearly, since the principal functors and arities are different (v/1 vs. (^)/2), we can distinguish the cases by pattern matching alone.

使用此 new 表示,您的代码段将变为:

With this new representation, your snippet becomes:


split(v(V), V) :- V = 0.
split(v(V), V) :- V = 1.
split(X^Y, XP ^ YP) :-
        split(X, XP),
        split(Y, YP).

查询示例:


?- split(v(X)^v(Y), R).
X = Y, Y = 0,
R = 0^0 ;
X = 0,
Y = 1,
R = 0^1 ;
X = 1,
Y = 0,
R = 1^0 ;
X = Y, Y = 1,
R = 1^1.

请注意,此 still 可以在所有方向上使用,在最一般的情况下:

Note that this still works in all directions, also in the most general case:


?- split(Expr, R).
Expr = v(0),
R = 0 ;
Expr = v(1),
R = 1 ;
Expr = v(0)^v(0),
R = 0^0 ;
Expr = v(0)^v(1),
R = 0^1 ;
etc.

根据经验,一旦必须在代码中使用像var/1这样的额外逻辑谓词,就几乎没有希望保留其逻辑纯性和单调性.力求使用干净的表示法来保留这些属性.

As a rule of thumb, once you have to use an extra-logical predicate like var/1 in your code, there is little hope to retain its logical purity and monotonicity. Aim for clean representations to preserve these properties.

有时候,不可避免地要使用默认表示,因为您想让用户更容易输入.在这种情况下,力图在开始实际推理之前将它们快速转换为干净的.

Sometimes, it is unavoidable to use defaulty representations, for example, because you want to make the input easier for users. In such cases, aim to quickly convert them to clean ones before starting the actual reasoning.

这篇关于控制Prolog变量值选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆