Prolog 为什么这会导致无限递归?
我在prolog中有一个程序,我基本上定义了一个人的图表,我需要做一些谓词,告诉我哪些人是有联系的,哪些是集团。事实如下:Prolog 为什么这会导致无限递归?,prolog,failure-slice,non-termination,Prolog,Failure Slice,Non Termination,我在prolog中有一个程序,我基本上定义了一个人的图表,我需要做一些谓词,告诉我哪些人是有联系的,哪些是集团。事实如下: graph([person(susan, [reed, jen, andrzej, jessica]), person(reed, [tony, jessica]), person(jessica, [jen,susan]), person(tony, []), person(ken, [andrzej]), person(jen, [tony
graph([person(susan, [reed, jen, andrzej, jessica]),
person(reed, [tony, jessica]),
person(jessica, [jen,susan]),
person(tony, []),
person(ken, [andrzej]),
person(jen, [tony, susan, jessica]),
person(andrzej, [susan, ken])]).
这是我的谓词clique的定义。它将图G和一个人员列表作为参数,并尝试检查列表中的人员是否确实是朋友团(这意味着谓词goodfriends对于列表中的每对人员都是true)
派克所做的是:如果名单上只有两个人,那么就检查这两个人是否是好朋友。如果这是真的,那么他们之间就有一个派系。如果名单中有两个以上的人,那么对于名单中的每个人,即每个人,检查他是否与名单尾部的其他人是好朋友,并递归地对所有人进行检查。
下面定义了其余的帮助器谓词,以便该组工作
goodfriends(G, FriendOne, FriendTwo):-
getPerson(G, FriendOne, PersonOne),
getPerson(G, FriendTwo, PersonTwo),
hasFriend(PersonOne, FriendTwo),
hasFriend(PersonTwo, FriendOne).
%% checks if this friend is goodfriend with all these friends
goodFriendWith(_, _, []).
goodFriendWith(G, FriendOne, [FriendTwo | FriendList]):-
goodFriendWith(G, FriendOne, FriendList),
goodfriends(G, FriendOne, FriendTwo).
%% gets specific person by a name from the graph
getPerson([person(Name, Friends)|_], Name, person(Name, Friends)).
getPerson([_|T], Name, Result):-
getPerson(T, Name, Result).
%% checks if a person has a certain friend
hasFriend(person(_, Friends), Friend):-
member_(Friend, Friends).
member_(X, [X|_]).
member_(X, [_|Tail]) :- member_(X, Tail).
atLeastOneElement([_|_]).
atLeastTwoElements([_,_|_]).
问题:
当我创建名为runner的谓词来测试谓词“clique”时:
我希望它返回图表中的所有派系,但我的结果是:
?- runner(R).
R = [susan, jessica] ;
R = [susan, jen] ;
R = [susan, andrzej] ;
R = [jessica, susan] ;
R = [jessica, jen] ;
R = [ken, andrzej] ;
R = [jen, susan] ;
R = [jen, jessica] ;
R = [andrzej, susan] ;
R = [andrzej, ken] ;
R = [jen, susan, jessica] ;
R = [jessica, susan, jen] ;
R = [jen, jessica, susan] ;
R = [susan, jessica, jen] ;
R = [jessica, jen, susan] ;
R = [susan, jen, jessica] ;
ERROR: Out of local stack
递归有什么问题?我知道我得到了正确的结果,但是由于某种原因,所有的结果都显示出来了,它一直在递归
提前感谢您。像您这样的纯单调程序中有一种简单的调试技术。只需将
false
目标添加到您的计划中即可。如果生成的程序仍然循环,则必须修复剩余的可见部分。(可能会有更多错误,但只要该部分未修复,您就不会修复该问题)
以下是我到目前为止得到的信息:
runner(R):-
graph(G),
clique(G, R), false.
?- goodFriendWith([person(susan,[jessica]),person(jessica,[susan])],susan,L).
L = [] ;
L = [jessica] ;
L = [jessica, jessica] ;
L = [jessica, jessica, jessica] ;
L = [jessica, jessica, jessica, jessica] ;
L = [jessica, jessica, jessica, jessica, jessica]
这个目标必须产生有限多的解决方案。然而,有无限多
由于您对结果感到惊讶,让我们继续调试。为了让它更加明显,我现在将添加额外的目标(=)/2
。这些目标也将使该计划专业化:
同样,查询循环!您现在真的应该看到问题了。请添加您对
至少两个元素的定义。如果你能简单地说明member
,为什么要说member
?你在回答中添加的集团没有递归调用。列表中的所有人不应该都有递归吗?你在答案中添加的小团体没有递归调用。还有,你认为好朋友有什么问题?我不明白怎么会有无限的解。我的意思是它在有限的列表中“迭代”。@sokras:它产生无限多的解!如果你期望它终止,那就大错特错了。这怎么能产生无穷多个解呢。我不明白:/goodfriends的代码简单明了。遍历列表,如果列表为空则结束,如果不为空,则检查列表的下一个元素,因此我仍然不明白为什么会进行无限次迭代。:/我知道它确实以我的方式进行无限迭代,我可以看到我一次又一次地得到相同的结果,但我不明白为什么它会这样继续下去。我是说不应该,是吗?
?- length(L,N),
maplist(=(jessica),L),
goodFriendWith(
[ person(susan,[reed,jen,andrzej,jessica]),
person(reed,[tony,jessica]),
person(jessica,[jen,susan]),
person(tony,[]),
person(ken,[andrzej]),
person(jen,[tony,susan,jessica]),
person(andrzej,[susan,ken])],
susan,
L).
L = [],
N = 0 ;
L = [jessica],
N = 1 ;
L = [jessica, jessica],
N = 2 ;
L = [jessica, jessica, jessica],
N = 3 ;
L = [jessica, jessica, jessica, jessica],
N = 4 ;
L = [jessica, jessica, jessica, jessica, jessica],
N = 5 ...
?- goodFriendWith([person(susan,[jessica]),person(jessica,[susan])],susan,L).
L = [] ;
L = [jessica] ;
L = [jessica, jessica] ;
L = [jessica, jessica, jessica] ;
L = [jessica, jessica, jessica, jessica] ;
L = [jessica, jessica, jessica, jessica, jessica]
goodFriendWith(_, _, []) :- false.
goodFriendWith(G, FriendOne, [FriendTwo | FriendList]):-
FriendOne = susan,
FriendTwo = jessica,
goodfriends(G, FriendOne, FriendTwo),
goodFriendWith(G, FriendOne, FriendList), false.
?- goodFriendWith([person(susan,[jessica]),person(jessica,[susan])],susan,L).