4

私はプロローグ初心者で、「兄弟」関係を作りたいと思っています。

兄弟 (alin, alex)が true である場合、兄弟 (alex, alin)も同様である必要があるように、関係は対称である必要があります。

また、brother(alin, alex)brother(alex, claudiu)が true である場合、brother(alin, claudu ) も true である場合のように、推移的である必要があります。

to プロパティを組み合わせると、brother(alex, alin)brother(alex, claudiu)が true の場合、brother(alin, claudu)も true になるはずです。

これが私のコードです:

r_brother(alin, alex).
r_brother(alin, ciprian).
r_brother(alex, claudiu).

s_brother(X, Y) :- r_brother(X, Y).
s_brother(X, Y) :- r_brother(Y, X).

brother(L1, L2) :-
    t_brother(L1, L2, []).

t_brother(L1, L2, _) :-
    s_brother(L1, L2).

t_brother(L1, L2, IntermediateNodes) :-
    s_brother(L1, L3),
    \+ member(L3, IntermediateNodes),
    t_brother(L3, L2, [L3 | IntermediateNodes]).

r_brother - 基本的な関係です

s_brother - 対称的な兄弟関係です (これはうまくいきます)

t_brother - これは推移的で対称的な関係である必要があります。ループが発生しないように中間ノードを保持します

問題は、次の場合の答えです。

?- brother(X, alin).

は:

X = alex ;
X = ciprian ;
X = alin ;
X = alin ;
X = alin ;
X = alin ;
X = alex ;
X = alex ;
X = alex ;
X = alex ;
X = ciprian ;
X = ciprian ;
X = claudiu ;
X = claudiu ;
false.

トレースを調べたところ、問題の内容は理解できましたが、解決方法がわかりません。

alinは可能な答えであってはならず、他の答えは 1 回だけ現れるべきです。

4

2 に答える 2

3

基本的な問題は、t_brother/3 の最初の節で L2 が既に見つかっているかどうかを確認していないことだと思います。そして、最初の L1 を brother/2 のリストに追加する必要があります:

brother(L1, L2) :-
  t_brother(L1, L2, [L1]).                   % <-- [L1] instead of []

t_brother(L1, L2, IntermediateNodes) :-
  s_brother(L1, L2),
  \+ member(L2, IntermediateNodes).          % <-- added this check

t_brother(L1, L2, IntermediateNodes) :-      % <-- this clause is unchanged
  s_brother(L1, L3),
  \+ member(L3, IntermediateNodes),
  t_brother(L3, L2, [L3 | IntermediateNodes]).

論理和を使用してソリューションを短縮することもできます。

t_brother(L1, L2, IntermediateNodes) :-
  s_brother(L1, L3),
  \+ member(L3, IntermediateNodes),
  ( L2=L3
  ; t_brother(L3, L2, [L3 | IntermediateNodes])).
于 2014-05-08T11:08:24.307 に答える
1

このように兄弟関係を書くことができます (推移的な定義とまったく同じです)。

s_brother(X, Y) :- r_brother(X, Y);r_brother(Y, X).

brother(X,Y) :- s_brother(X, Y).
brother(X,Y) :- s_brother(X, Z),s_brother(Z, Y),X\=Y.

これは、X が Y の兄弟であることを意味します。つまり、X が対称兄弟である場合、または共通の兄弟がいて、異なるという条件を追加します。

コードに X\=Y を追加して、解決策として「alin」を削除してみてください。

于 2014-05-08T11:02:39.893 に答える