[英]Why is this causing an infinite recursion?
我在序言中有這個程序,在這里我基本上定義了一個人形圖,我需要做一些謂詞,以告訴我哪些人是聯系的,哪些是集團。 這是事實:
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和一個人的列表為參數,並嘗試檢查列表中的人是否確實是一群朋友(這意味着謂詞好朋友對列表中的每一對人都是正確的)
clique(G, [FriendOne, FriendTwo]):-
goodfriends(G, FriendOne, FriendTwo).
clique(G, [FriendOne | FriendList]):-
atLeastTwoElements(FriendList),
clique(G, FriendList),
goodFriendWith(G, FriendOne, FriendList).
團體的意思是:如果列表僅包含兩個人,則只需檢查這兩個人是否是好朋友。 如果這是真的,那么他們兩個之間就有集團。 如果在人員列表中有兩個以上的人員,則對於該列表的每個頭,即人員,請檢查他是否是好朋友,其余人員在列表的末尾,然后對所有人員列表進行遞歸操作人。 下面定義了使幫派工作的其他輔助謂詞。
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):-
graph(G),
clique(G, R).
我希望它返回圖中的所有集團,但我的結果是:
?- 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.clique(G, [FriendOne, FriendTwo]):- false,goodfriends(G, FriendOne, FriendTwo).clique(G, [FriendOne | FriendList]):- atLeastTwoElements(FriendList), goodFriendWith(G, FriendOne, FriendList), false,clique(G, FriendList).
因此,一個或一個問題在於goodFriendWith
。 我發現讓您的定義成功遍歷無限多個列表有點令人惱火:
?- 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]
這個目標必須產生有限的許多解決方案。 但是,有無限多個。
由於您對結果感到驚訝,因此讓我們繼續進行調試。 為了使其更加明顯,我現在將添加額外的目標(=)/2
。 這些目標也將使該計划專業化:
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).
再次,查詢循環! 您現在真的應該看到問題了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.