2009-06-27 13 views
-1

私はPrologを使い始めていますが、私はそれが期待どおりに動作しない理由を理解できません。 リストL2がL1に含まれている場合にtrueを返す述語を作成しようとしています。 これは私が書いたものである:Prolog述語の問題

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で、その後真である」と同等になります考え出し含まれていると(、 L1、L2)は、すべてのメンバがトラバースされ、最後のオプションが残されるか、またはL1にないメンバを見つけるまで再帰的に変換され、述語には失敗します。

残念ながら、それはそのように動作していないようです。 ([1,2,3]、[1,4,5])パスは含まれていますが、([1,2,3]、[4、 1,5])はそうではない。

私は間違っていますか?

+0

使用しているPrologの実装は? SWI-Prologで問題を再現することはできません。 – mercator

+0

SWI-Prologバージョン2.7.12 –

+3

2.7.12?本当に?! 5.6.xや5.7.xのような新しいものを試してみてください。 – Kaarel

答えて

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(contains(_, [])). 

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

Yes 

を実行し、Prologのプロンプトにassert/1を使いたいlisting/0を使用した場合。

?- listing. 

:- dynamic contains/2. 

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

Yes 

あなた自身の答えで示しているように、「自由変数を宣言する」問題はないと思います。むしろ、ブラケットを確認してください。

+0

私はあなたが尋ねたことを試してみましたが、同じ問題があります:contains([1,2,3]、[1,2,4])を呼び出すと、 "yes"と返答します –

+0

私の場合、 "偽" – Kaarel

-2

自由変数にアサーションを使用すると、(少なくともこのバージョンでは)問題が発生する可能性があるため、誤動作しています。アサートを破棄し、consult(file)コマンドを使用することでこれが解決されました。

+0

あなたのオリジナルの質問は、アサートについて何も言わない。あなたは正確に何を主張しましたか? – Kaarel

+0

私は基本的にプロンプ​​トでそれを書いたので、私はすべてを主張しました。投稿されたコードにアサーションを追加しました。 –