-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

述語に IO とロジックを混在させないようにしてください。コードのテスト、デバッグ、推論が困難になり、バックトレースで非常に紛らわしい出力が生成されます。

ここでは、再帰中に道路をリストに保持できます。

例として、3 番目の引数を指定すると、次のようになります。

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 に答える
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 に答える
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 に答える