2016-11-20 9 views
1

私はカウントダウンゲームを作っています。リストに別のリストの要素があるかどうかをチェックしたいと思います。2つのリストのカバー述語

考える二つのリスト、第二のリストは、それが最初のリストにK回発生するすべての項目は、少なくとも第二のK回発生したか否かをチェックするものであり、第一カバーするかどうかをチェック:

私は実践的な例をたくさん与えている紙を次のようにしています。私は今までは大丈夫でしたが、これは私が少し休憩しています。私は任意のポインタが 、

cover([],_). 
cover([Head|Tail], List2):- 
    member(Head, List2), 
    cover(Tail, List2). 

問題は、それは私が時間のための私の頭を悩まてきた、

を、リスト内の倍のKの数を考慮していない、で、これをだろう書かれている

素晴らしいよ

答えて

2

非常に近い解決策です!私たちはこのような場合に使用しなければならないビルディングブロックは、たくさんmember/2のようなものですが、次のひねりを加えた:私たちは、第三 引数が何を意味してみましょうmember/2のわずかな一般化を検討し、完全にそれを解決するために

が残っていますリスト は、を除き、の 「メンバー」のリストを意味します。

伝統的に、この述語はselect/3と呼ばれています。これは、述語を一方向にしか使用できないことを示唆しているため、かなり悪い名前です。それはむしろ命令のです。

私はより説明、宣言型名を使用してselection/3これを呼び出します。我々は残りの リストを気にしませ、selection/3の面でmember/2を定義することができますので、あなたは、selection/3の特殊なケースとしてmember/2と考えることができ

 
selection(E, [E|Ls], Ls). 
selection(E, [L|Ls], [L|Rest]) :- 
     selection(E, Ls, Rest). 

は、このようなこの関係について考えます: selection/3を使用して

 
member(E, Ls) :- selection(E, Ls, _). 

、我々は書くことができます。

 
list_cover([], _). 
list_cover([L|Ls], Cs0) :- 
     selection(L, Cs0, Cs), 
     list_cover(Ls, Cs). 

次のように我々は、第二項を読むことができます:

LCs0の部材であり、Cs残りのリスト(すなわち、ある場合  Lせず、Cs0)、Csは  Lsを覆い、次いでCs0は  [L|Ls]を覆っています。

名前付け規則に注意してください。命名規則は、それぞれの引数の意味を明確にしています。当社の の場合、の第2のの引数はで、  のリストです。これを単にcover/2と呼ぶと は実際には の表記を示す引数を明確にしません。

サンプルクエリと回答:

 
?- list_cover([a,e,i,o], [m,o,n,k,e,y,b,r,a,i,n]). 
true . 

?- list_cover([a,a,a], [a,a]). 
false. 

?- list_cover([a,a,a], [a,a,b,a]). 
true . 

、さらに:

 
?- list_cover(Ls, Cs). 
Ls = [] ; 
Ls = [_1900], 
Cs = [_1900|_1908] ; 
Ls = [_1900, _1912], 
Cs = [_1900, _1912|_1920]. 

かなりクール、ありませんか?それはかなり一般的です!

+1

素晴らしい回答です。 – Enigmativity

+1

絶対に輝かしい、ありがとう、私の男。 – Hidden