2

最初のリストと2番目のリストの同じインデックスの2つの要素が等しいかどうかに応じて、3番目のリストがTとの値で構成されている場合に真となる述語を作成しようとしています。Fのようなクエリtruth_list(['abc','def'],['zui','def'],L).はを与える必要がありますL=['F','T']

これが私の試みです:

truth_list([],[],_).
truth_list([H1|T1],[H2|T2],TL):-
    (H1==H2)->(H3='T');(H3='F'),
    Temp=TL,
    TL=[H3|Temp],
    truth_list(T1,T2,TL).

なぜこれが期待通りに機能しないのか、誰かが説明してくれたらありがたいです。

4

2 に答える 2

2

したがって、私たちはすべて同じページにいます。クエリを実行すると、次の結果が得られました。

L = ['F'|L].

したがって、最初に頭に浮かぶのは、おそらく変数を再利用しているということです。実際、次の句は疑わしいように見えます。

Temp=TL,
TL=[H3|Temp],

Prologの変数は、他の言語のように実際には「割り当て可能」ではありません。実際にできることはバインディングを確立することだけなので、上記のコードは次のように言うのと同じです。

TL=[H3|TL]

これが、結果が次のように見える理由です:L = ['F'|L]。問題を修正するためにボディを少し書き直し、次のコードで終了しました。

truth_list([H1|T1],[H2|T2],[H3|TL]):-
    (H1=H2 -> H3='T' ; H3='F'),
    truth_list(T1,T2,TL).

条件全体を括弧で囲む必要があります。そうしないと、奇妙な動作が発生します。そこから、不要なTLバインディングを削除しました(Prologの変数は割り当て可能ではないため、とにかく機能しません)。これらの問題を修正すると、別の問題が見つかります。それは、次のような問題が発生することです。

L = ['F', 'T'|_G297].

明らかでない場合、これは基本ケースがあいまいすぎるためであり、代わりに次のようになります。

truth_list([], [], []).

したがって、最終的に修正されたバージョンは次のようになります。

truth_list([],[],[]).
truth_list([H1|T1],[H2|T2],[H3|TL]):-
    (H1=H2 -> H3='T' ; H3='F'),
    truth_list(T1,T2,TL).

これは通常、@ falseが表示され、さまざまなインスタンス化で述語を使用する際に問題があることを指摘する場所です。そこで、今それを確認して、怒りを避けましょう。

?- truth_list(['abc','def'],['zui','def'],['T','F']).
false.
?- truth_list(['abc','def'],['zui','def'],['F','T']).
true.
?- truth_list(['abc','def'],['zui','def'],['F','T','T']).
false.
?- truth_list(['abc','def'],['zui','def','def'],['F','T','T']).
false.

これらはすべて問題ないように見えるので、すべての引数がインスタンス化されたときに嘘を幻覚化しているようには見えません。それは良い。次に、部分的なインスタンス化を確認しましょう。

?- truth_list([X, 'def'], ['abc', Y], ['T', 'T']).
X = abc,
Y = def.

かっこいい、うまくいった。

?- truth_list([X, 'def'], ['abc', Y], ['F', 'T']).
false.

ええ まあ、Prologはその'F'値のために他のバインディングを幻覚化することを知らないようです。それが問題かどうかはわかりませんが、明らかな解決策は見当たりません。つまり、次のことはおそらく機能しません。

?- truth_list(X, Y, ['T', 'T']).
X = Y, Y = [_G296, _G302].

驚くべきことですが、実際には機能し、2つの未知数の同じリストの両方に割り当てられました。涼しい。調子はいいと思います。

編集:@falseの改善を取り入れましょう。次に、次のようになります。

truth_list([], [], []).
truth_list([H1|T1], [H2|T2], [H3|TL]) :-
  (H1 = H2, H3 = 'T' ; dif(H1,H2), H3 = 'F'),
  truth_list(T1, T2, TL).

これで、目的の動作が得られます。

?- truth_list([X, 'def'], ['abc', Y], ['F', 'T']).
Y = def,
dif(X, abc) ;

したがって、PrologはYが「def」であると推測し、Xは少なくとも「abc」ではないと結論付けたので、これは改善です。

于 2013-01-20T06:10:27.360 に答える
2

maplist / 4は、コードを単純化できます。

truth_list(A, B, C) :-
  maplist(truth_, A, B, C).
truth_(A, B, C) :-
  A == B -> C = 'T' ; C = 'F'.

(最終的に)再利用できるようにコードを拡張することも検討できます。

任意の定数「T」、「F」の代わりに、and 、または、などの呼び出し可能な述語を使用して、CLP(FD)で直接使用できる式を取得できます。truefalse10

于 2013-01-20T08:40:32.953 に答える