实现谓词的指南,如dif/2

Fat*_*ize 5 prolog prolog-dif

假设我有一个谓词foo/2,它定义了它的第一个和第二个参数之间的关系.

改变这种实现的最惯用和最有效的方法是什么foo/2:

  • 如果它的两个参数都是基础的,它就像以前一样(如果关系成立则成功,否则失败).

  • 如果两个参数中的一个(或两个)都是空闲的,它会"约束"这两个参数,这样当它们接地时,将检查关系.

换句话说,如何正确地实现由dif/2任何类型的用户定义关系表现出来的行为?

listing(dif/2). 没什么帮助.

mat*_*mat 3

不同的 Prolog 实现提供不同的功能来完成此任务。该机制被称为协程延迟目标约束,Prolog 系统手册将提供更多信息。

这里有两个变体,可在SICStus Prolog和其他一些系统中使用。

block/1指示

block在 SICStus Prolog(可能还有其他一些系统)中,可以通过声明性声明将用户定义的谓词提升为此类受限版本的一种方法。

有趣的是,这不需要对谓词本身进行任何更改!

假设您有 的不纯版本dif/2,使用非单调(\=)/2谓词:

麦迪夫(X,Y):-
    X \= Y。

然后你可以将其变成延迟版本,例如:

:- 阻止 madif(-, ?),
         麦迪夫(?,-)。

麦迪夫(X,Y):-
    X \= Y。

示例查询和答案:

| ?- 麦迪夫(a,b)。
是的
| ?- madif(a, X)。
用户:madif(a,X)?;
不
| ?- madif(a, X), X = b。
X = b ? ;
不
| ?- madif(X, Y)。
用户:madif(X,Y)?;

根据需要,目标的评估将被延迟,直到两个参数都被实例化。

when/2

使用 SICStus Prolog(以及提供此功能的其他系统)实现此目的的第二种方法是使用when/2. 这需要对谓词本身进行更改。

例如,使用,您可以这样when/2实现:madif/2

麦迪夫(X,Y):-
    当((地面(X),
          地面(Y)),X \= Y)。

示例查询和答案:

| ?- madif(X, a)。
序言:trig_ground(X,[],[X],_A,_A),
序言:当(_A,(地面(X),地面(a)),用户:(X \ = a))?;
不
| ?- madif(X, a), X = b。
X = b ? ;

  • ...所以 `madif(X,X)` 陷入困境。 (2认同)