Prolog Call、Exit 和 Redo 不匹配指定的规则
Prolog Call, Exit and Redo not matching specified rules
我在尝试跟踪序言时遇到了一些问题。跟踪日志如下:
parent_of(X,Y).
Call: (6) parent_of(_G2780, _G2781) ? creep
Exit: (6) parent_of(warren, jerry) ? creep
X = warren
Y = jerry ;
Redo: (6) parent_of(_G2780, _G2781) ? creep
Exit: (6) parent_of(maryalice, jerry) ? creep
X = maryalice
Y = jerry ;
Redo: (6) parent_of(_G2780, _G2781) ? creep
Call: (7) brother(_G2865, _G2781) ? creep
Exit: (7) brother(jerry, kather) ? creep
Call: (7) father(_G2780, jerry) ? creep
Call: (8) parent_of(_G2780, jerry) ? creep
Exit: (8) parent_of(warren, jerry) ? creep
Call: (8) male(warren) ? creep
Exit: (8) male(warren) ? creep
Exit: (7) father(warren, jerry) ? creep
Exit: (6) parent_of(warren, kather) ? creep
但是,我声明我的事实和规则如下:
male(jerry).
male(stuart).
male(warren).
male(peter).
female(kather).
female(maryalice).
female(ann)
brother(jerry,stuart).
brother(jerry,kather).
brother(peter, warren).
sister(ann, maryalice).
sister(kather,jerry).
parent_of(warren,jerry).
parent_of(maryalice,jerry).
parent_of(X,Z):- brother(Y,Z),(father(X,Y);mother(X,Y)).
father(X,Y) :- parent_of(X,Y), male(X).
mother(X,Y) :- parent_of(X,Y), female(X).
我以为第一个Call按理应该处死哥哥和(爸爸妈妈)?怎么马上给了我 Exit 是 Warren 是 Jerry 的parent?
提前致谢!
Prolog 按照声明的顺序查找事实和规则。由于您在规则 parent_of/2
之前声明了一些事实 parent_of/2
,因此首先会找到这些事实。你没有显示你的完整踪迹,但它找到事实后,它追踪到规则:
[trace] ?- parent_of(X,Y).
Call: (7) parent_of(_G1353, _G1354) ? creep
Exit: (7) parent_of(warren, jerry) ? creep
X = warren,
Y = jerry ;
Redo: (7) parent_of(_G1353, _G1354) ? creep
Exit: (7) parent_of(maryalice, jerry) ? creep
X = maryalice,
Y = jerry ;
Redo: (7) parent_of(_G1353, _G1354) ? creep
Call: (8) brother(_G1444, _G1354) ? creep
Exit: (8) brother(jerry, stuart) ? creep
Call: (8) father(_G1353, jerry) ? creep
Call: (9) parent_of(_G1353, jerry) ? creep
Exit: (9) parent_of(warren, jerry) ? creep
Call: (9) male(warren) ? creep
Exit: (9) male(warren) ? creep
Exit: (8) father(warren, jerry) ? creep
Exit: (7) parent_of(warren, stuart) ? creep
X = warren,
Y = stuart ;
Redo: (9) parent_of(_G1353, jerry) ? creep
Exit: (9) parent_of(maryalice, jerry) ? creep
Call: (9) male(maryalice) ? creep
Fail: (9) male(maryalice) ? creep
Redo: (9) parent_of(_G1353, jerry) ? creep
Call: (10) brother(_G1444, jerry) ? creep
Fail: (10) brother(_G1444, jerry) ? creep
Fail: (9) parent_of(_G1353, jerry) ? creep
Fail: (8) father(_G1353, jerry) ? creep
Redo: (7) parent_of(_G1353, stuart) ? creep
Call: (8) mother(_G1353, jerry) ? creep
Call: (9) parent_of(_G1353, jerry) ? creep
Exit: (9) parent_of(warren, jerry) ? creep
Call: (9) female(warren) ? creep
Fail: (9) female(warren) ? creep
Redo: (9) parent_of(_G1353, jerry) ? creep
Exit: (9) parent_of(maryalice, jerry) ? creep
Call: (9) female(maryalice) ? creep
Exit: (9) female(maryalice) ? creep
Exit: (8) mother(maryalice, jerry) ? creep
Exit: (7) parent_of(maryalice, stuart) ? creep
X = maryalice,
Y = stuart
...
不过,我建议您将规则名称设为不同于事实名称。所以我会做类似的事情:
parent(warren,jerry).
parent(maryalice,jerry).
然后:
parent_of(X,Z) :-
parent(X, Z).
parent_of(X,Z) :-
brother(Y,Z),
( father(X,Y); mother(X,Y) ).
但也要注意多余的事实。看起来您的 parent 关系可能已经由涉及 father/2
和 mother/2
的事实定义。所以不清楚你为什么需要 parent/2
事实。
请注意,您的代码在此处存在语法错误:
female(ann)
brother(jerry,stuart).
您可能忽略了这个错误。但是如果没有句点,Prolog 将忽略以上两个事实,然后给出您所看到的结果。
另一方面,您的代码有很多不好的循环逻辑。 parent_of/2
依赖于 father/2
和 mother/2
然后 father/2
和 mother/2
调用 parent_of/2
。这是将事实与谓词分开的另一个重要原因。
我在尝试跟踪序言时遇到了一些问题。跟踪日志如下:
parent_of(X,Y).
Call: (6) parent_of(_G2780, _G2781) ? creep
Exit: (6) parent_of(warren, jerry) ? creep
X = warren
Y = jerry ;
Redo: (6) parent_of(_G2780, _G2781) ? creep
Exit: (6) parent_of(maryalice, jerry) ? creep
X = maryalice
Y = jerry ;
Redo: (6) parent_of(_G2780, _G2781) ? creep
Call: (7) brother(_G2865, _G2781) ? creep
Exit: (7) brother(jerry, kather) ? creep
Call: (7) father(_G2780, jerry) ? creep
Call: (8) parent_of(_G2780, jerry) ? creep
Exit: (8) parent_of(warren, jerry) ? creep
Call: (8) male(warren) ? creep
Exit: (8) male(warren) ? creep
Exit: (7) father(warren, jerry) ? creep
Exit: (6) parent_of(warren, kather) ? creep
但是,我声明我的事实和规则如下:
male(jerry).
male(stuart).
male(warren).
male(peter).
female(kather).
female(maryalice).
female(ann)
brother(jerry,stuart).
brother(jerry,kather).
brother(peter, warren).
sister(ann, maryalice).
sister(kather,jerry).
parent_of(warren,jerry).
parent_of(maryalice,jerry).
parent_of(X,Z):- brother(Y,Z),(father(X,Y);mother(X,Y)).
father(X,Y) :- parent_of(X,Y), male(X).
mother(X,Y) :- parent_of(X,Y), female(X).
我以为第一个Call按理应该处死哥哥和(爸爸妈妈)?怎么马上给了我 Exit 是 Warren 是 Jerry 的parent?
提前致谢!
Prolog 按照声明的顺序查找事实和规则。由于您在规则 parent_of/2
之前声明了一些事实 parent_of/2
,因此首先会找到这些事实。你没有显示你的完整踪迹,但它找到事实后,它追踪到规则:
[trace] ?- parent_of(X,Y).
Call: (7) parent_of(_G1353, _G1354) ? creep
Exit: (7) parent_of(warren, jerry) ? creep
X = warren,
Y = jerry ;
Redo: (7) parent_of(_G1353, _G1354) ? creep
Exit: (7) parent_of(maryalice, jerry) ? creep
X = maryalice,
Y = jerry ;
Redo: (7) parent_of(_G1353, _G1354) ? creep
Call: (8) brother(_G1444, _G1354) ? creep
Exit: (8) brother(jerry, stuart) ? creep
Call: (8) father(_G1353, jerry) ? creep
Call: (9) parent_of(_G1353, jerry) ? creep
Exit: (9) parent_of(warren, jerry) ? creep
Call: (9) male(warren) ? creep
Exit: (9) male(warren) ? creep
Exit: (8) father(warren, jerry) ? creep
Exit: (7) parent_of(warren, stuart) ? creep
X = warren,
Y = stuart ;
Redo: (9) parent_of(_G1353, jerry) ? creep
Exit: (9) parent_of(maryalice, jerry) ? creep
Call: (9) male(maryalice) ? creep
Fail: (9) male(maryalice) ? creep
Redo: (9) parent_of(_G1353, jerry) ? creep
Call: (10) brother(_G1444, jerry) ? creep
Fail: (10) brother(_G1444, jerry) ? creep
Fail: (9) parent_of(_G1353, jerry) ? creep
Fail: (8) father(_G1353, jerry) ? creep
Redo: (7) parent_of(_G1353, stuart) ? creep
Call: (8) mother(_G1353, jerry) ? creep
Call: (9) parent_of(_G1353, jerry) ? creep
Exit: (9) parent_of(warren, jerry) ? creep
Call: (9) female(warren) ? creep
Fail: (9) female(warren) ? creep
Redo: (9) parent_of(_G1353, jerry) ? creep
Exit: (9) parent_of(maryalice, jerry) ? creep
Call: (9) female(maryalice) ? creep
Exit: (9) female(maryalice) ? creep
Exit: (8) mother(maryalice, jerry) ? creep
Exit: (7) parent_of(maryalice, stuart) ? creep
X = maryalice,
Y = stuart
...
不过,我建议您将规则名称设为不同于事实名称。所以我会做类似的事情:
parent(warren,jerry).
parent(maryalice,jerry).
然后:
parent_of(X,Z) :-
parent(X, Z).
parent_of(X,Z) :-
brother(Y,Z),
( father(X,Y); mother(X,Y) ).
但也要注意多余的事实。看起来您的 parent 关系可能已经由涉及 father/2
和 mother/2
的事实定义。所以不清楚你为什么需要 parent/2
事实。
请注意,您的代码在此处存在语法错误:
female(ann)
brother(jerry,stuart).
您可能忽略了这个错误。但是如果没有句点,Prolog 将忽略以上两个事实,然后给出您所看到的结果。
另一方面,您的代码有很多不好的循环逻辑。
parent_of/2
依赖于 father/2
和 mother/2
然后 father/2
和 mother/2
调用 parent_of/2
。这是将事实与谓词分开的另一个重要原因。