Prologに述語を書くときは、述語が何を意味するのか、それがどのような関係を定義しているのか考える必要があります。あなたの述語が非解答を与える理由は、あなたが述語句に意味を混ぜているということです。彼らはすべて本当に同じことを意味するわけではありません。
我々は、単に我々が得る、上記更新された定義に調整した場合:
subseq([], []).
subseq([_|Xs], Ys) :-
subseq(Xs, Ys).
subseq([X|Xs], [X|Ys]) :-
prefix_subseq(Xs, Ys).
prefix_subseq(_, []).
prefix_subseq([X|Xs], [X|Ys]) :-
prefix_subseq(Xs, Ys).
私が説明することなく、上記のprefix_subseq/2
の定義を提供し、私はあなたがそれを把握することができると思います。あなたのサブリスト(またはサブ配列)を定義するのは興味深い、コンパクトな方法
| ?- subseq([a,b,c,d], R).
R = [a] ? a
R = [a,b]
R = [a,b,c]
R = [a,b,c,d]
R = [b]
R = [b,c]
R = [b,c,d]
R = [c]
R = [c,d]
R = [d]
R = []
(1 ms) yes
append/2
述語を使用して、次のようになります:
これは今得
subseq(L, R) :- append([_, R, _], L).
これはL
はの結果であると述べています付加リスト_
,R
および_
。この単純な実装の小さな欠点は、が複数の方法でappend([_, R, _], L)
のルールを満たしているため、2回以上取得されるということです。
DCGは、シーケンスを扱うために完全であると定義で新鮮な表情を取ると、あなたは、サブシーケンスを定義するためにDCGを使用することができます。
% Empty list is a valid subsequence
subseq([]) --> ... .
% Subsequence is any sequence, followed by sequence we want, followed by any sequence
subseq(S) --> ..., non_empty_seq(S), ... .
% Definition of any sequence
... --> [] | [_], ... .
% non-empty sequence we want to capture
non_empty_seq([X]) --> [X].
non_empty_seq([X|T]) --> [X], non_empty_seq(T).
そして、あなたはphrase/2
でそれを呼び出すことができます。
| ?- phrase(subseq(S), [a,b,c,d]).
S = [] ? ;
S = [a] ? ;
S = [a,b] ? ;
S = [a,b,c] ? ;
S = [a,b,c,d] ? ;
S = [b] ? ;
S = [b,c] ? ;
S = [b,c,d] ? ;
S = [c] ? ;
S = [c,d] ? ;
S = [d] ? ;
no
我々は、この定義を少しreswizzleし、それをよりコンパクトにするのが一般的seq//1
定義を利用することができます:
subseq([]) --> seq(_) .
subseq([X|Xs]) --> seq(_), [X], seq(Xs), seq(_).
% alternatively: seq(_), seq([X|Xs]), seq(_).
seq([]) --> [].
seq([X|Xs]) --> [X], seq(Xs).
[Prologのサブセット](https://stackoverflow.com/questions/4912869/subsets-in-prolog)の可能な複製 –