2016-11-17 12 views
0

私は、双方向性の述語を持ち、ノードが別のノードに接続されているかどうかを伝えます。 など。到達可能なノードをすべてリストする

has(a, b). 
has(b, c). 
has(d, b). 

ここで、(特定のノードから)特定のステップ数で到達できるすべてのノードをリストしたいと思います。

connected_nodes(a, T, 2). 

はずので、出力

T = c 
T = d 

私の現在のコードは次のようになります。

これは二があるので、これは、Tの= cに対してではなく、T = Dのために働く
connected_nodes(A, B, 0) :- write(A). 
connected_nodes(A, B, N) :- 
    N > 0, M is N - 1, 
    has(A, X), 
    connected_nodes(X, B, M). 

方向性の関係。

再帰の点で正しく考えていますか、あるいはどのように他の方法でこの問題を解決しなければなりませんか?

+0

サイクルを含めるかどうかを指定しますか? – false

答えて

1

connected述語はうまくいくようです。ベースケースをhasに依存させるのは意味がありましたが、それはあなた次第です。

has述語は「双方向」ですが、これを示すルールを明示的に作成していないとします。しかし、あなたのクエリが今あまりにも可能解答としてaを返すこと

has(a, b). 
has(b, c). 
has(d, b). 

bi_has(X,Y) :- has(X,Y). 
bi_has(X,Y) :- has(Y,X). 

connected_nodes(A, B, 0) :- write(A). 
connected_nodes(A, B, N) :- 
    N > 0, M is N - 1, 
    bi_has(A, X), 
    connected_nodes(X, B, M). 

注:

次のコードは、コードの「双方向」バージョンです。これは、2つのステップの後に同じ要素に戻ることを望まないことを明示していないので、以後です。

この動作をしたくない場合は、これまでに訪問した要素のリスト(アキュムレータ)も保持し、要素を再訪していないことを確認する必要があります。

+0

ありがとう!私は以前の訪問先ノードを保存し、見つかったノードと等しいときにfalseを返す追加の変数を渡すことによって、アキュムレータなしで "バックステッピング"を解決しました。 – Henry

+0

さて、それは2のステップ番号のためだけに働くように聞こえます。しかし、一般的なケースを気にしなければ、それは問題ありません。 :) –

+0

循環参照がない限り、それは私にとってはうまくいくと思います:) – Henry

関連する問題