我写这个程序是为了得到这个结果:"X=john“"Y=jane”
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)?
发布于 2013-04-11 17:58:47
你的代码:
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}发布于 2013-04-11 04:35:55
您的查询( X和Y都是变量)对于您定义likes/2的方式来说太“宽泛”了
试一试
?- likes(john, Y).prolog引擎做些什么?嗯,它在它的事实数据库中搜索。
首先,它发现(第一条规则)
likes(john, mary).所以玛丽·约翰喜欢。
然后它会发现
likes(john,Y) :-
likes(john,Z),
likes(Z,Y).所以它会问自己:什么Z是真的,likes(john,Z)?数据库上说likes(john, mary)所以Z = mary.让我们把它放在规则中:
likes(john,Y) :-
likes(john,mary),
likes(mary,Y).所以它会问自己:likes(mary,Y)是什么意思?数据库上说likes(mary, jane)所以Y = jane.让我们把它放在规则中:
likes(john,jane) :-
likes(john,mary),
likes(mary,jane).所以简·约翰喜欢。
现在我们有问题了。仔细观察第二个问题:
likes(john,Y) :-
likes(john,Z),
.....啊哦。
如果约翰喜欢某人,约翰就会喜欢上他(……)(……)
在第一次尝试时,我们很幸运: Prolog引擎找到了Y = jane, Z = mary,因为我们有以下规则
likes(john,mary).
likes(mary,jane).然后它停了下来。但随后它再一次问自己:
likes(john,Y) ?我们已经使用了前两个规则,所以让我们尝试第三个规则:
likes(X,Y) :-
likes(X,Z),
likes(Z,Y).麻烦!
likes(john,Someone) :-
likes(john,Someone2), .....
likes(john,Someone2) :-
likes(john,Someone3), .....
likes(john,Someone3) :-
likes(john,Someone4), .....以此类推..
发布于 2013-04-11 04:43:32
如果您需要"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.https://stackoverflow.com/questions/15935053
复制相似问题