您好我的家庭作业问题。我的问题涉及prolog回溯功能,由swipl解释。
我已经明白回溯的目的是在被问及时产生答案。如果没有可能的解决方案,它将返回false。如果我们想要锁定或提交到某个执行路径,我们可以使用cut。
我的问题如下:程序将提供一个正确的解决方案(三个(ada,beda,calle))然后当要求更多解决方案时程序失败。当使用跟踪时,程序似乎已经提交到上次成功的变量,这将失败,因为它提供了相同的答案。
单独测试时,输入结果为真
我希望实现的目标:当要求另一个解决方案时,它将尝试其他X:s而不是承诺第一个。如果代码或数据库提供清晰度,我很乐意发布它。
[trace] 4 ?- spider(X).
Call: (6) spider(_G4246) ? creep
Call: (7) persons_generate(_G4317) ? creep
Call: (8) bagof(_G4310, person(_G4310), _G4321) ? creep %^
Call: (14) person(_G4310) ? creep
Exit: (14) person(ada) ? creep
Redo: (14) person(_G4310) ? creep
Exit: (14) person(beda) ? creep
Redo: (14) person(_G4310) ? creep
Exit: (14) person(calle) ? creep
Exit: (8) bagof(_G4310, user:person(_G4310), [ada, beda, calle]) ? creep%^
Exit: (7) persons_generate([ada, beda, calle]) ? creep
Call: (7) lists:delete([ada, beda, calle], _G4246, _G4353) ? creep
Exit: (7) lists:delete([ada, beda, calle], _G4246, []) ? creep
Call: (7) conspirator(_G4246, [], [], [], _G4355, _G4356) ? creep
Exit: (7) conspirator(_G4246, [], [], [], [], []) ? creep
Call: (7) []==[] ? creep
Exit: (7) []==[] ? creep
Exit: (6) spider(_G4246) ? creep
true ;
Redo: (7) conspirator(_G4246, [], [], [], _G4355, _G4356) ? creep
Fail: (7) conspirator(_G4246, [], [], [], _G4355, _G4356) ? creep
Fail: (6) spider(_G4246) ? creep
false.
修改
%DB
person(ada).
person(beda).
person(calle).
knows(ada,beda).
knows(ada,calle).
knows(beda,calle).
CODE
persons_generate(Persons):-
bagof(X,person(X),Persons).
spider(X):-
persons_generate(Persons),
delete(Persons,X,PersonsNoSpider),
conspirator(X, [],PersonsNoSpider,[],_,ListReturn),
%when done the ListReturn should be empty if we have connections
ListReturn == [].
conspirator(_,[],[],ConsList,ConsList,[]).
conspirator(PossibleSpider,FailedConspiratorList,[PossibleConspirator|List1],ConspiratorListIn,ConspiratorListOut,ListReturn):-
%ConspiratorList is the already known conspirators
friend(PossibleConspirator,PossibleSpider),
not(friend_with_list(PossibleConspirator,ConspiratorListIn)),
friendList(PossibleConspirator,ConspiratorsFriends),
subtract(List1,ConspiratorsFriends,ListCut),
subtract(FailedConspiratorList,ConspiratorsFriends,NewFailedConspiratorList),
conspirator(PossibleSpider,NewFailedConspiratorList,ListCut, [PossibleConspirator|ConspiratorListIn],ConspiratorListOut,ListReturn).
conspirator(PossibleSpider,FailedConspirators, [NotPossibleConspirator|List1], ConspiratorListIn,ConspiratorListOut,ListReturn) :- %increase NotConspirator list
not(friend(PossibleSpider,NotPossibleConspirator)),
conspirator(PossibleSpider,[NotPossibleConspirator|FailedConspirators], List1, ConspiratorListIn, ConspiratorListOut, ListReturn).
%checks both ways
friend(X,Y):-
(knows(X,Y);knows(Y,X)).%this is how or is supposed to work right?
friendList(X,FriendList):-
bagof(Y,friend(X,Y), FriendList).
friend_with_list(_,[]):-%searching for a friend in an empty world is difficult
fail.
%returns true if input A knows someone B in list C
friend_with_list(X,[Y|_]):-
friend(X,Y).
%X don't know head of list, let's try again!
friend_with_list(X,[_|Tail]):-
friend_with_list(X,Tail).
解释
因此该程序的目的是在Web中找到一个蜘蛛。蜘蛛与阴谋者接触,其中一个人不能与另一个阴谋者接触。如果蜘蛛成功,即将返回真实:阴谋者和他们的朋友都是合并的人。即,任何人不得在网外。