我已经阅读了很多关于Prolog 失败否定的内容,其中Prolog是为了证明\+Goal
试图证明Goal
失败。
这与 CWA (近距离假设)高度相关,例如,如果我们查询\+P(a)
(其中P
是arity 1的谓词),我们没有导致证明P(a)
Prolog的线索假定(由于CWA)not P(a)
持有\+P(a)
成功。P(a)
成功。
从我搜索的内容来看,这是一种解决经典逻辑弱点的方法,如果我们对\+P(a)
没有任何线索,那么我们无法回答X=1, \+X==1.
是否成立。
上面介绍的是在Prolog中引入非单调推理的方法。此外,有趣的部分是 Clark 证明了Negation by Failure与经典否定相容/类似仅适用于地面条款。我理解这一点:
\+X==1, X=1.
:应该在Prolog(以及经典逻辑)中返回false。
\+X==1.
:在经典逻辑中应该返回false,但是在检查NF的时候它在Prolog中成功,X不受限制,这与经典纯逻辑不同。
\\+(Goal) :- when(ground(Goal), \+Goal).
:在X绑定之前,不应该给经典逻辑提供任何答案,但在Prolog中它返回false(可能打破经典逻辑的弱点),这与纯逻辑不相同/兼容。
我的尝试是模拟经典否定,感谢@ false的评论中的建议,目前的实施是:
?- \\+(X==1).
when(ground(X), \+X==1).
?- X=1, \\+(X==1).
false.
?- \\+(X==1), X=1.
false.
一些测试:
x(t)=a+(n/w)*(cos(w*t)-1)-((g/w**2)*sin(l)-m/w)*(sin(w*t)+(g*t/w)*sin(l))
y(t)=b+((g/w**2)*sin(l)-m/w)*(cos(w*t)-1)+(n/w)*sin(w*t)
我的问题:
以上是对经典否定的正确解释吗? (是否有任何明显的极端情况,它错过了?我在使用/ 2时关注逻辑纯度,可以安全地假设上面是纯粹的吗?)。
答案 0 :(得分:2)
Prolog不能做经典否定。既然没有 使用经典推理。即使在克拉克的面前 完成后,它无法检测到以下内容 两个经典法则:
非矛盾定律:〜(p / \ ~p)
排除中间的法则:p \ / ~p
这是一个例子,拿这个逻辑程序 和这些查询:
class AcoesForm(ModelForm):
#bunch of fields definitions
#...
#
class Meta:
model = Acoes
fields = ['id_pedido','bl_msg','tb_msg','bl_shell','tb_shell','obs','ativo']
Clark完成逻辑程序是 如下,否定为失败查询 执行产生以下内容:
p :- p
?- \+(p, \+p)
?- p; \+p
Clark完成解决了谓词定义的问题 和负面信息。另见5.2 Rules and their Completion部分。另一方面,当没有谓词时 定义在附近,CLP(X)有时可以做两个定律, 当一个否定运算符被定义为deMorgan样式。这是 CLP的否定算子(B):
p <-> p
loops
loops
这是一些执行:
?- listing(neg/1).
neg((A;B)) :-
neg(A),
neg(B).
neg((A, _)) :-
neg(A).
neg((_, A)) :-
neg(A).
neg(neg(A)) :-
call(A).
neg(sat(A)) :-
sat(~A).
当否定影响域时,CLP(X)也会出现问题, 通常是有限的,然后会变得无限。因此对于 例如,(#=)/ 2,...等约束应该不是问题, 因为它可以用约束(#\ =)/ 2,...。
代替但是当应用于约束时,CLP(FD)的否定通常不起作用 (在)/ 2。如果CLP(X)系统提供,情况可以稍微减轻 物化。在这种情况下,可以使分离比仅使用Prolog回溯分离更加智能。
答案 1 :(得分:1)
在 SWI-Prolog 中,可以实现 Constraint Handling Rules 中经典逻辑的推理规则,包括 de Morgan 定律和非矛盾定律:
:- use_module(library(chr)).
:- chr_constraint is_true/1.
:- chr_constraint animal/2.
:- initialization(main).
:- set_prolog_flag('double_quotes','chars').
is_true(A),is_true(A) <=> is_true(A).
is_true(A=B) ==> A=B.
is_true(A\=B) ==> not(A=B).
is_true(not(A)),is_true(A) ==> false.
is_true(not((A;B))) ==> is_true((not(A),not(B))).
is_true(not((A,B))) ==> is_true((not(A);not(B))).
is_true((A,B)) ==> is_true(A),is_true(B).
is_true((A;B)) ==> is_true(A),(is_true(B);is_true(not(B)));is_true(B),(is_true(A);is_true(not(A))).
is_true(not(not(A))) ==> is_true(A).
然后,您可以像这样使用求解器:
is_true(animal(X,A)),is_true(animal((Y,A))) ==> X \= Y,false;X==Y.
is_true((A->B)) ==> is_true(((A;not(A)),B));is_true(((not(A);A),not(B))).
main :- is_true(((X=cat;X=dog;X=moose),(not((animal(dog,tom);animal(moose,tom))),animal(X,tom)))),writeln(animal(X,tom)).
该程序打印 animal(cat,tom)
。
但是这个公式可以使用不同的算法更有效地求解,例如 DPLL。