-1

比如go(a, d)。我希望它也打印路线,例如路线 a、路线 b、路线、c 和路线 d

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(FromRoom, NextRoom),
 go(NextRoom, ToRoom).
4

3 回答 3

2

一个好方法是简单地将 go/2 转换为也考虑路由的关系。正如描述列表时经常出现的情况一样,DCG 非常适合:

go(From, To) --> [From, To], { door(From, To) }.
go(From, To) --> [From],
        { door(From, Next) },
        go(Next, To).

例子:

?- phrase(go(a, d), Rooms).
Rooms = [a, b, c, d] ;
false.

关于 write/1:这很少需要,因为我们通常可以让顶层负责打印答案。如果需要,format/2 通常比 write/1 更适合格式化输出,例如,而不是:

write('['), write(From), write(':'), write(To), write(']')

你可以写:

format("[~w: ~w]", [From, To])
于 2012-03-25T15:45:49.127 回答
2

请尽量不要在谓词中混合 IO 和逻辑。这将使您的代码难以测试、调试和推理,并且会在回溯时产生非常混乱的输出。

在这里,您可以在递归期间将道路保留在列表中。

一个例子是,带有第三个参数:

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

go(FromRoom, ToRoom, [FromRoom|Path]) :-
    door(FromRoom, NextRoom),
    go(NextRoom, ToRoom, Path).

查询正确返回路径:

?- go(a, g, Path).
Path = [a, b, e, g] ;
false.

Path如有必要,您可以在输出时格式化输出列表。但现在这是一个非常简单的问题:在递归期间格式化列表而不是输出内容。

于 2012-03-25T12:08:27.857 回答
1

您需要为此使用写谓词,如下所示

go(FromRoom, ToRoom):-
    door(FromRoom,ToRoom),
    write('['), write(FromRoom), write(':'), write(ToRoom), write(']').

go(FromRoom, ToRoom) :-  
    door(FromRoom, NextRoom),
    write('['), write(FromRoom), write(':'), write(NextRoom), write(']'),
    go(NextRoom, ToRoom).

或者,您想要的格式的路线是

go(FromRoom, ToRoom):-
   door(FromRoom,ToRoom),
   write(FromRoom), write(' route '), write(ToRoom).

go(FromRoom, ToRoom) :-  
   door(FromRoom, NextRoom),
   write(FromRoom), write(' route '),
   go(NextRoom, ToRoom).
于 2012-03-25T09:44:45.583 回答