我写这个程序给我这个结果: “X =约翰” “Y =简”
likes(john,mary).
likes(mary,jane).
likes(l,k).
likes(X,Y) :- likes(X,Z), likes(Z,Y).
但如果运行此程序,则此结果为: 我认为程序进入循环! 我想在真正回答后停止!
1 ?- likes(X,Y).
X = john,
Y = mary ;
X = mary,
Y = jane ;
X = l,
Y = k ;
X = john,
Y = jane ;
ERROR: Out of local stack
我有错误! 如何解决这个问题?
通过调试:
[debug] 3 ?- likes(john,Y).
T Call: (6) likes(john, _G2162)
T Exit: (6) likes(john, mary)
Y = mary ;
T Redo: (6) likes(john, _G2162)
T Call: (7) likes(john, _G2267)
T Exit: (7) likes(john, mary)
T Call: (7) likes(mary, _G2162)
T Exit: (7) likes(mary, jane)
T Exit: (6) likes(john, jane)
Y = jane ;
T Redo: (7) likes(mary, _G2162)
T Call: (8) likes(mary, _G2267)
T Exit: (8) likes(mary, jane)
T Call: (8) likes(jane, _G2162)
T Call: (9) likes(jane, _G2267)
T Call: (10) likes(jane, _G2267)
T Call: (11) likes(jane, _G2267)
T Call: (12) likes(jane, _G2267)
T Call: (13) likes(jane, _G2267)
T Call: (14) likes(jane, _G2267)
T Call: (15) likes(jane, _G2267)
等等.. 为什么喜欢(简,_G2267)??????
答案 0 :(得分:3)
您的查询({1}}和X
都是变量)对于您定义Y
尝试
likes/2
prolog引擎有什么作用?好吧,它在其事实数据库中搜索。
首先它发现(第一条规则)
?- likes(john, Y).
所以约翰喜欢玛丽。
然后它找到了
likes(john, mary).
所以它问自己:对于什么Z,likes(john,Y) :-
likes(john,Z),
likes(Z,Y).
是真的吗?好吧,数据库说likes(john,Z)
,所以likes(john, mary)
。让我们把它放在规则中:
Z = mary
所以它问自己:因为{是{1}}的Y是真的吗?好吧,数据库说likes(john,Y) :-
likes(john,mary),
likes(mary,Y).
,所以likes(mary,Y)
。让我们把它放在规则中:
likes(mary, jane)
所以 john喜欢jane 。
现在我们遇到了问题。仔细查看第二个查询:
Y = jane
UH-哦。
约翰喜欢某人如果约翰喜欢某人(和,......)
好吧,第一次尝试我们很幸运:Prolog引擎找到了likes(john,jane) :-
likes(john,mary),
likes(mary,jane).
,因为我们有以下规则
likes(john,Y) :-
likes(john,Z),
.....
它停了下来。但后来它再次问自己:
Y = jane, Z = mary
我们已经使用了前两个规则,所以让我们尝试使用第三个规则:
likes(john,mary).
likes(mary,jane).
麻烦!
likes(john,Y) ?
依旧......
答案 1 :(得分:3)
如果您需要“X = john”“Y = jane”,那么您必须重命名:
likes(X,Y) :- likes(X,Z), likes(Z,Y).
其他名称,例如:
likestransitive(X,Y) :- likes(X,Z), likes(Z,Y).
因此,您可以获得所需的解决方案:
1 ?- transitivelikes(X,Y).
X = john,
Y = jane;
false.
答案 2 :(得分:2)
您的代码:
likes(john,mary). % {1}
likes(mary,jane). % {2}
likes(l,k). % {3}
likes(X,Y) :- % {4}
likes(X,Z), % {5}
likes(Z,Y). % {6}
查询likes(john,Y)
如下:
likes(john,Y)?
%% {1} Y = mary. ; redo
%% {4} likes(john,Y) :-
%% {5} likes(john,Z)?
%% {1} Z=mary.
%% {6} likes(mary,Y)?
%% {2} Y=jane. ; redo
%% {4} likes(mary,Y) :-
%% {5} likes(mary,Z2)?
%% {2} Z2=jane,
%% {6} likes(jane,Y)?
%% {4} likes(jane,Y):-
%% {5} likes(jane,Z3)?
%% {4} likes(jane,Z3):-
%% {5} likes(jane,Z4)?
............
这就是你在调试器中看到的内容。
要防止出现此问题,请重命名transitive closure谓词,如下所示:
likes(john,mary). % {1b}
likes(mary,jane). % {2b}
likes(l,k). % {3b}
pals(X,Y) :- % {4b}
likes(X,Z), % {5b}
pals(Z,Y). % {6b}