我有以下事实和规则:
one(s).
one(t).
two(X,Y) :- one(X), one(Y), three(X), \+three(Y), \+two(Y,X).
three(s).
对于查询two(Y,X).
,我得到以下结果:
?- two(Y,X).
Y = s,
X = t ;
false.
我不明白为什么结果是Y=s
和X=t
。为什么Prolog不会无限次进入\+two(Y,X)
? Prolog是否记得已经处理过哪些谓词?
答案 0 :(得分:1)
之所以成功,是因为Prolog使用求反作为有限失败。
如果我们评估Prolog谓词,则会看到:
[trace] ?- two(X, Y).
Call: (8) two(_660, _662) ? creep
Call: (9) one(_660) ? creep
Exit: (9) one(s) ? creep
Call: (9) one(_662) ? creep
Exit: (9) one(s) ? creep
Call: (9) three(s) ? creep
Exit: (9) three(s) ? creep
Call: (9) three(s) ? creep
Exit: (9) three(s) ? creep
Redo: (9) one(_662) ? creep
Exit: (9) one(t) ? creep
Call: (9) three(s) ? creep
Exit: (9) three(s) ? creep
Call: (9) three(t) ? creep
Fail: (9) three(t) ? creep
Redo: (8) two(s, t) ? creep
Call: (9) two(t, s) ? creep
Call: (10) one(t) ? creep
Exit: (10) one(t) ? creep
Call: (10) one(s) ? creep
Exit: (10) one(s) ? creep
Call: (10) three(t) ? creep
Fail: (10) three(t) ? creep
Fail: (9) two(t, s) ? creep
Redo: (8) two(s, t) ? creep
Exit: (8) two(s, t) ? creep
X = s,
Y = t .
因此在失败的第一个“路径”中,X
和Y
都设置为s
:
two(X,Y) :-
one(X), %% X = s
one(Y), %% Y = s
three(X), %% X = s
\+three(Y), %% Y = s, fail
\+two(Y,X).
但是随后我们回溯了one(Y)
调用,并获得:
two(X,Y) :-
one(X), %% X = s
one(Y), %% Y = t
three(X), %% X = s
\+three(Y), %% Y = t
\+two(Y,X) %% call two(t, s).
现在\+ p(X, Y)
被认为是true
,因为p(X, Y)
无法满足,并且陷入了无限循环。因此,我们将其称为two(t, s)
,但由于以下原因而失败了:
two(t,s) :-
one(t), %% succeeds
one(s), %% succeeds
three(t), %% fails
\+three(s), %%
\+two(s,t) %%
因此three(t)
失败,并且由于这里没有回溯机会,因此two(t, s)
结束了。因此,这意味着two(t, s)
具有有限的故障,因此\+ two(t, s)
成功,因此two(X, Y)
成功并且X = s, Y = t
。
答案 1 :(得分:1)
您定义了以下谓词:
one(s).
one(t).
two(X,Y) :- one(X), one(Y), three(X), \+three(Y), \+two(Y,X).
three(s).
谓词two(X,Y)
等同于
two(X,Y) :- (X=s ; X=t), (Y=s ; Y=t), (X=s), \+(Y=s), \+two(Y,X).
=
two(X,Y) :- (X=s, (Y=s ; Y=t), X=s ; X=t, (Y=s ; Y=t), X=s), \+(Y=s), \+two(Y,X).
=
two(X,Y) :- (X=s, (Y=s ; Y=t), s=s ; X=t, (Y=s ; Y=t), t=s), \+(Y=s), \+two(Y,X).
=
two(X,Y) :- (X=s, (Y=s ; Y=t) ; false), \+(Y=s), \+two(Y,X).
=
two(X,Y) :- ((X=s, Y=s ; false), \+(Y=s) ; (X=s, Y=t ; false), \+(Y=s)), \+two(Y,X).
=
two(X,Y) :- ((X=s, Y=s ; false), \+(s=s) ; (X=s, Y=t ; false), \+(t=s)), \+two(Y,X).
=
two(X,Y) :- (X=s, Y=t ; false), true, \+two(Y,X).
=
two(X,Y) :- (X=s, Y=t, \+two(Y,X) ; false).
=
two(s,t) :- (true, \+two(t,s) ; false).
=
two(s,t) :- (true ; false).
这就是你所得到的。