在控制台中测试

时间:2012-03-26 16:42:58

标签: prolog

咨询?- go(c, g).返回false,但?- go(a, d).的状态为true。我实际上并不理解它,因为我已经添加了适当的规则,并且对于它们中的大多数它都有效。

以下是我正在使用的陈述:

door(a, b).
door(b, c).
door(c, d).
door(b, e).
door(e, f).
door(e, g).

go(FromRoom, ToRoom):- 
    door(FromRoom,ToRoom).

go(FromRoom, ToRoom):- 
    door(ToRoom, FromRoom).

go(FromRoom, ToRoom) :-  
    door(FromRoom, NextRoom),
    go(NextRoom, ToRoom), !.

go(FromRoom, ToRoom):-
    door(ToRoom,NextRoom), 
    go(NextRoom, FromRoom), !.

2 个答案:

答案 0 :(得分:0)

您需要在谓词中添加累加器,以避免卡在inf循环中。

door(a, b).
door(b, c).
door(c, d).
door(b, e).
door(e, f).
door(e, g).

go(From, To, T) :-
    T=[From|T1],
    go(From, To, [To], T1).
go(From, To,T, T) :-
    door(From, To),!.
go(From,To,T,T) :-
    door(To,From),!.
go(From, To, Acc,T) :-
    door(X, Do),!,
    \+ member(X, Acc),
    go(From, X, [X|Acc],T).
go(From,To,Acc,T) :-
    door(X,Z),!,
    \+member(Z,Acc),
    go(X,To,[X|Acc],T). 

答案 1 :(得分:0)

您应该阅读第四条规则

go(FromRoom, ToRoom):- 
 door(ToRoom,NextRoom), 
 go(FromRoom,NextRoom),!.

因为你已经在调用door / 2时交换了搜索顺序,但这会导致循环,正如@whd正确评论的那样。这是一个“返回”路径的版本

go(Room, Room, Path, Path).

go(FromRoom, ToRoom, SoFar, Path) :-
    ( door(FromRoom, NextRoom) ; door(NextRoom, FromRoom) ),
    \+ member(NextRoom, SoFar),
    go(NextRoom, ToRoom, [NextRoom|SoFar], Path).

试验:

enter image description here

?- go(c,g,[],P).
P = [g, e, b, c, d] ;
P = [g, e, b] ;
false.

由于Prolog搜索顺序,在返回之前,它会在d中进行“巡视”。在顶级调用时,很容易避免对SoFar参数进行操作...