-1

私は Prolog を使い始めたばかりで、次のコードが期待どおりに機能しない理由がわかりません。リスト L2 が L1 に含まれている場合に true を返す述語を作成しようとしています。これは私が書いたものです:

assert(contains (L1, L1)).
assert(contains(L1, [X|L2]):-member(X, L1), contains(L1, L2)).
assert(contains(L1, [])).

これは、「'L3=X|L2' の X が L1 にあり、L2 が L1 にある場合は true」と同等であり、contains(L1, L2) は、すべてのメンバーがトラバースされるまで再帰的に変換されると考えました。最後のオプションが残っています。そうしないと、L1 にないメンバーが見つかり、述語が失敗します。

残念ながら、そのようには機能しないようです。member(X, L1) の値のみを返すように見えるので、contains([1,2,3],[1,4,5]) はパスしますが、contains([1,2,3],[4, 1,5]) しません。

私は何を間違っていますか?

4

2 に答える 2

5

私はあなたの質問を完全には理解していませんでしたが、contains/2述語を次のように書きます。

% An empty list is contained by any list
contains(_, []).

% If a list is not empty, then its
% first element must be an element of L1,
% and its tail must be contained by L1.
contains(L1, [X | L2]) :-
    member(X, L1),
    contains(L1, L2).

ところで、最初のルール(事実)に注意してください

contains (L1, L1).

は構文エラーです (述語名の後にスペースがあってはなりません)。また、修正すると、不要な選択ポイントが作成されます。だから、むしろそれを削除してください。

assert/1Prologプロンプトで使用する場合は、実行します

?- assert(contains(_, [])).

Yes
?- assert(contains(L1, [X | L2]) :- (member(X, L1), contains(L1, L2))).

Yes

ナレッジ ベースの内容を確認するには、 を使用しますlisting/0

?- listing.

:- dynamic contains/2.

contains(_, []).
contains(B, [A|C]) :-
    member(A, B),
    contains(B, C).

Yes

あなたが自分の答えで示しているように、問題は「自由変数のアサート」にあるとは思いません。むしろ、ブラケットを確認してください。

于 2009-06-27T22:47:37.750 に答える
-2

どうやら自由変数でアサートを使用すると問題が発生する可能性があるため (少なくともこのバージョンでは)、それが誤動作の理由です。アサートを削除し、consult(file) コマンドを使用すると、これが解決されました。

于 2009-06-29T19:48:53.870 に答える