2016-12-27 2 views
0

グラフの2つのノードが隣接しているかどうかをチェックする手続きを書こうとしています。プロローグ内でグラフの隣接手続きを書く

私はSWI-prologを使用しています。

私がしようとしています:

adjacent(X,Y,graph(_,E)):- 
    member(e(X,Y), E). 

しかし、これは動作しないと私は理由として困惑しています。

私はこれをテストグラフとして使用しています。

tem(graph([s,t,u,v], [e(a,b), e(b,d), e(b,c), e(c,d)])). 

そして、私はこのようにREPLでそれをチェックしています:

?- tem(graph(_, E)), adjacent(a, b, E). 
false. 

しかし、それはtrueを返す必要がありますので、それらの2が両方とも隣接しています。繰り返すように

答えて

1

、驚くほどを失敗したクエリは次のとおりです。プロローグで

 
?- tem(graph(_, E)), adjacent(a, b, E). 
false. 

、このような問題のexacte 原因を見つけるための良い方法は 宣言だと思うし、体系的に適してみることですプログラムと目標のの特化

はたとえば、それぞれ、変数Aと  Baと  bを置き換えることにより、大幅に、より一般的な上記のクエリを行うことができますので、

 
?- tem(graph(_, E)), adjacent(A, B, E). 
false. 

、このまだが失敗しました!したがって、プログラムが完全におよび  単調であるため、より具体的なクエリは、 でも失敗します。これは、そのような推論を許容します。

は、という単一の目標を一般化します。

の代わりに:私は今、書き

 
adjacent(X,Y,graph(_,E)):- 
    member(e(X,Y), E). 

:もちろん

 
adjacent(X,Y,graph(_,E)) :- 
    true. 

これはかなりより 一般全体述語を作る:オリジナルの述語が成功したすべての場合、この変形例では成功するでしょう  too!エラーが残り一部である必要があり、次のようでエルゴ:検索する

 
?- tem(graph(_, E)), adjacent(A, B, E). 
false. 

そして今、あまり多くの遺跡を:これでもかなり多くの一般的な定義を

、我々はまだを持っているフラグメントは:

 
adjacent(X, Y, graph(_,E)) :- ... 

よく見ると、それが失敗の原因となるこの句ヘッドです:あなたはトンを呼び出しています彼は第3引数として  リストを述語とするが、この定義では、第3引数はではなく、  リストである。

このアプローチは、宣言型デバッグと呼ばれ、あなたはの下でより多くの情報をご覧いただけます。プロローグとロジックプログラミング言語は一般的に、そのような強力なデバッグ手法をアプリケーションに適用するためにはユニークです。 このアプローチは、容易に自動化ことができることに注意してください。単純にこのクエリべきが成功することを主張することにより、 プログラムは、上記のフラグメントを得て、あなたに 問題の正確な原因を示している可能性があります。

0

マットの優れた答えに加えて、隣接する手順では、ファンクタグラフが第3引数として期待されています。

tem(graph(_, E)), adjacent(a, b, E).は、グラフファンクタではなく、adjacentの3番目の引数としてリストに渡されます。

tem(G), adjacent(a, q, G).は、第3引数としてグラフファンクタに渡され、グラフファンクタの一部ではありません。

+1

「s」で終わる変数を* lists *として使用するのが良い命名規則です。例: 'graph(_、Es)'。これは、「Es」がリストであることを明確にします。対照的に、 'adjacent(a、q、G)'を使うときは 'G'がリストではないと期待します。 – mat

関連する問題