Prolog在回溯时保持价值

时间:2014-10-27 14:25:57

标签: prolog backtracking

您好我的家庭作业问题。我的问题涉及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中找到一个蜘蛛。蜘蛛与阴谋者接触,其中一个人不能与另一个阴谋者接触。如果蜘蛛成功,即将返回真实:阴谋者和他们的朋友都是合并的人。即,任何人不得在网外。

0 个答案:

没有答案