非常に近い解決策です!私たちはこのような場合に使用しなければならないビルディングブロックは、たくさん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).
次のように我々は、第二項を読むことができます:
をL
がCs0
の部材であり、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].
かなりクール、ありませんか?それはかなり一般的です!
素晴らしい回答です。 – Enigmativity
絶対に輝かしい、ありがとう、私の男。 – Hidden