Prolog意味着否定的谓词

时间:2011-06-13 15:29:35

标签: prolog negate implication

如何在PROLOG中编写以下规则:如果P则不是Q

我知道您可以轻松编写如果P然后Q 谓词如q(X) :- p(X),但是如何否定q/1谓词?我不想用non_q/1等其他语义定义新的谓词。

4 个答案:

答案 0 :(得分:13)

条款“如果P则不是Q”在逻辑上等同于否定条款“不是P或不是Q”。因此它是Horn clause没有正文字,并且作为SLD定理证明和Horn子句的对应的应用,可以在Prolog编程中表示为目标子句或“查询”:

?- P, Q.

让我们在一分钟内回到这个想法。

但是目标条款可能不是你想到的那种表现形式。构成Prolog“知识库”的事实和规则是明确的条款,即Horn条款,每个条款都有一个正面的文字。 “如果P不是Q”没有正面文字,那么在这个意义上它就不能表示(作为一个明确的条款)。

上面显示的目标条款“询问”是否可以证明P和Q. Prolog提供了“否定为失败”的概念,因此“询问”“不是P或不是Q”的更自然的方式是:

?- not((P,Q)).

如果P或Q失败,我们就会获得成功,如果两者都失败,我们就会失败。

但是,如果您的目的是断言知识库中的否定,Prolog自然不支持这一点。根据您的应用程序,可能有一种合理的方法来解决Prolog语法并完成所需的操作(总是有一种不合理的方法来执行它,正如您所暗示的那样,使用 non_q 谓词)

答案 1 :(得分:6)

你听说过Prolog的剪辑吗?

无论如何,我对Prolog标准知之甚少,但在SWI-Prolog中,符号\+意味着否定。我知道它不需要在每个Prolog的翻译中工作。

你可以用Prolog的剪辑来做出谓词否定。谓词的定义如下:

not(Goal) :- call(Goal),!,fail.
not(Goal). 

这意味着无法证明目标,而不是目标是错误的。 也许这个Prolog & Cut链接很有用。

答案 2 :(得分:2)

“......如果P不是Q”可以通过-> if-then控制流谓词(例如GNU)表示,以及\+否定(或“不可证明”)运算符(例如GNU),如下所示:

(P -> \+ Q),

请注意,\+通常会实现所谓的negation-as-failure;即,如果\+ Q不能,则子目标/表达式Q将成功。请注意,Q\+的评估不会影响执行时表达式Q中存在的任何变量的绑定。

例如,考虑:

foo(a).
bar(b).

鉴于以下事实,以下内容:

foo(a) -> \+ bar(a). % succeeds, as bar(a) is not provable.
foo(a) -> \+ bar(b). % fails, as bar(b) is provable.
foo(a) -> \+ bar(X). % fails, as bar(X) is provable; note that X remains unbound.
foo(X) -> \+ bar(X). % succeeds, as bar(X) where X unified to 'a' isn't provable.

正如您所描述的那样,实现类似于\+ q(X) :- p(X)的内容(就“规则”而言)并不简单,但潜在的黑客攻击是:

q(X) :- p(X), !, fail.

此定义仅反映q(X)对于X p(X)失败的意图,q(X)如果之前其他任何句子{em>>成功{1}},但可能不太理想。

答案 3 :(得分:0)

您可以使用最小逻辑来定义负头。在最小的逻辑 ~A可以被视为A - > FF。因此以下

P -> ~Q

可以视为:

P -> (Q -> ff).

现在,如果我们采用以下身份(A - >(B - > C))=(A& B - > C),我们 看到以上内容相当于:

P & Q -> ff.

现在有一个问题,我们如何才能提出否定查询?有一个 利用与否定不同的最小逻辑的方法 失败。这个想法是对表单的查询:

G |- A -> B
通过暂时将A添加到prolog程序G来回答

,然后 试图解决B,即执行以下操作:

G, A |- B

现在让我们转到Prolog表示法,我们将显示p和p - > 〜流量 通过执行(最小逻辑)Prolog程序来暗示~q。该 prolog程序是:

p.
ff :- p, q.

查询是:

?- q -: ff.

我们首先需要定义新的连接词( - :)/ 2。快速解决方案 如下:

(A -: B) :- (assert(A); retract(A), fail), B, (retract(A); assert(A), fail).

在这里,您可以看到SWI Prolog中这种最小逻辑否定的实现:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 5.10.4)
Copyright (c) 1990-2011 University of Amsterdam, VU Amsterdam

1 ?- [user].
:- op(1200,xfy,-:).
|: (A -: B) :- (assertz(A); retract(A), fail), B, (retract(A); assertz(A), fail).
|: p.
|: ff :- p, q.
|:
% user://1 compiled 0.02 sec, 1,832 bytes
true.

2 ?- q -: ff.
true .

最好的问候

参考: 统一证明作为逻辑程序设计的基础(1989) 作者:Dale Miller,Gopalan Nadathur,Frank Pfenning,Andre Scedrov