2012-03-22 3 views
2

私はPrologの述語iscontained/2作るしようとしている:iscontained(List, Search)ない場合Searchが与えられListfalse.内にリストされている場合、それはtrue.を返します。そして、それが入力された変数であれば、それはリストの各要素に等しいことを返します。プロローグ機能が含まれていますか?

例:あなたがそれを行うための簡単な方法を知っている限り

?- iscontained([a, b, c], a). 

true. 

?- iscontained([a, b, c], d). 

false. 

?- iscontained([a, b, c], A). 

A = a; 
A = b; 
A = c; 
false. 

私は、手のために求めていない、右方向に突き出すが必要です。どんな助けでも感謝しています。

+1

btw 'メンバー/ 2'述語は、スイッチされたパラメータを使用していますが、これを行います。 – m09

答えて

1

2つのケースを考慮する必要があります。私は規則の体をあなたに任せます。

  • iscontained([A|Xs],A)
  • iscontained([X|Xs],A)

[空のリストへの参照を削除するために、編集:空のリストには何が含まれていません:。遭遇した場合、述語は失敗]

+0

ありがとうございました。 – user1205956

+2

最初のケースは必要ありません – m09

+0

@モグ:ああ、ありがとう:) –

3

今、あなた確かにすでにその解決策が思い付きましたが、私は1つのことを言いたいと思います:

古典的なバージョン:

 
member(Item, [Item|_List]). 
member(Item, [_Head|List]) :- member(Item, List). 

すなわち、可能な最後の要素を発見した後、選択ポイントを残し:

 
?- member(A, [1, 2, 3]). 
A = 1; 
A = 2; 
A = 3; 
false. 

 
member2(Item, [Head|List]) :- 
    member2(List, Item, Head). 

member2(_List, Item, Item). 
member2([Head|List], Item, _PreviousHead) :- 
    member2(List, Item, Head). 

が最後の要素と同時に空のリストを扱い、可能にしながら、最適化:

 
?- member2(A, [1, 2, 3]). 
A = 1; 
A = 2; 
A = 3. 

これはその逆ですSWI-Prolog(そして確かにJekejeke Prologや多分他の人たち)で使用されています。その著者はGertjan van Noordです。

これは、member/2の実装で自分自身を練習することは優れていますが、後で組み込み機能を使用しないようにしてはいけません。

+0

うん、http://stackoverflow.com/questions/8436568/code-for-member-2-with-some-determinism –

3

頻繁に提案member/2述語がまったくリストされていないソリューションを認めていることに注意してください:

 
?- member(e,[e|nonlist]). 
true. 

これは、多くの状況では大きな問題ではありませんが、それにもかかわらず、言及されるべきです。

のみリストを認める天然、対称的な定義はDCGsを使用する:

 
... --> [] | [_], ... . 

iscontained(Es, E) :- 
    phrase((...,[E],...), Es). 

...は、任意の配列を意味する非末端です。

これは、この小さな例では完全に過剰ですが、より興味深いパターンのテンプレートを提供します。like

 
iscontainedtwice(Es, E) :- 
    phrase((...,[E],...,[E],...), Es). 
関連する問題