如何"不"在Prolog中工作?

时间:2015-05-04 19:18:23

标签: prolog

我正在阅读Prolog中的代码片段,我看到了以下代码:

r(a).
q(b).
p(X) :- not r(X)

问题:

?-q(X), p(X)     // Result: b
?-p(X), q(X)     //  Result: no

那么,为什么? - q(X),p(X)我们得到&#34; b&#34; ? - p (X),q(X)? - q(X),p(X)完全相同我们得到&#34; no&#34; < / strong>?

2 个答案:

答案 0 :(得分:2)

?-q(X), p(X)     // Result: b

q(X) eventually unifies with q(b), which then calls p(b), which calls not r(b), which is true.

?-p(X), q(X)     //  Result: no

p(X) calls not r(X), which causes X to unify with a, which causes the preceding clause to evaluate to not r(a), which is false, and the conjuction operator short circuits to no.

答案 1 :(得分:2)

实际上这两个查询不是完全相同的,因为Prolog“连接”运算符(逗号)通常不是可交换的:

  1. 执行是从左到右,因此变量实例化的顺序在这些查询中是不同的
  2. 如果您只使用纯逻辑谓词,即不使用额外逻辑谓词(如not/1或if-then-else构造)定义的谓词,也不具有副作用的谓词(如I / O)那些需要预先实例化一些参数的谓词(如is/2),实例化顺序的变化不会影响交换性
  3. 但是,由于您的某个谓词使用not/1,如果其参数为r(_)r(b),如C.B.答案中所述,其行为不同,则可换行性不成立。
  4. 您可能知道not/1没有实现纯逻辑否定:它实现所谓的否定为失败意味着如果其参数的执行失败并且以其他方式失败(如果失败)则成功参数是一个自由变量,你得到一个实例化错误)。由于执行是从左到右,你不能指望它的行为受到在>调用之后的一些实例化的影响。