18

私は現在、Prolog で非常に短いプロジェクトに取り組んでおり、作成した「フィルター」をリストに適用しようとして行き詰まりました。フィルターの準備はできていますが、適用できません。私が説明した方が良いでしょう:

filter(A, B) 

...特定の条件が満たされた場合に「true」を出力します。

filterList(A, [X, Y, Z])

...フィルタ出力をfalseにする 2 番目の引数からのすべての要素を含むリストを出力します。(したがって、filter(A, X) が true の場合、出力は [Y, Z] になります)。

「フィルター」関数の準備ができましたが、最初の引数を適用したときにフィルターが true を返すすべての要素を除外して、2 番目の例に示すようにリストに適用する必要があります。

したがって、フィルターが単純な A == B の場合、関数は A [A,B,A,C,D,A] を受け取り、[B,C,D] を出力することになっています。明らかに、フィルターが適用されます。

関数の基本構造に問題があるので、誰かがこのような関数の基本的な概要を提供できれば、非常に役に立ちます。私は自分の状況を可能な限り単純化したので、あなたが提供できるものは何でも取り、私のニーズに合わせて変更することができます.

前もって感謝します!

4

6 に答える 6

13

SWI-Prolog オファーexclude/3およびその他のそのようなメタ述語。元の問題は次のようにコーディングできます。

are_identical(X, Y) :-
    X == Y.

filterList(A, In, Out) :-
    exclude(are_identical(A), In, Out).

使用例:

?- filterList(A, [A, B, A, C, D, A], Out).
Out = [B, C, D].
于 2008-12-03T21:28:06.753 に答える
10

Prolog で高階関数を探している場合は、これに関する非常に優れたリソースであるNaish (1995)を必ず参照してください。

彼の の定義filter/3は次のとおりです (彼は差分リスト表記を使用しているため、 を定義する必要がありませんfilter/4)。


filter(_,[],[]).
filter(P, A0-As0, As) :-
    (
        call(P, A0) -> As = A0-As1
    ;
        As = As1
    )
    , filter(P, As0, As1).

この述語について質問がある場合は、コメントで質問してください。論文を読むことも強くお勧めしmapます。彼が言及している制限の多くに注意してください (たとえば、欠落や高次などはもはや適用されません。SWI-Prolog には演算子があり、彼のすべての懸念に対処し、任意の n 次ロジックを可能にします。foldrcomposecall/3apply=..

于 2008-11-18T18:21:58.647 に答える
4

述語の成功または失敗をフィルタリングの基準とするフィルター関数には固有の問題があります。結果として得られるプログラムは、もはや純粋な単調プログラムではありません。したがって、宣言的なプロパティはすべて失われます。残っている唯一の意味は、手順の段階的な解釈です。以下は、 を使用したフィルタリングの純粋で具象化されたバージョンですif_/3

tfilter(_CT_2,    [], []).
tfilter(CT_2, [E|Es], Fs0) :-
   if_(call(CT_2,E), Fs0 = [E|Fs], Fs0 = Fs ),
   tfilter(CT_2, Es, Fs).

したがって、最初の引数はクロージャー/継続であり、さらに 2 つの引数を受け取ります: 要素と結果の真理値です。

=(X,X,true).
=(X,Y,false) :- dif(X,Y).

現在、結果は正確なままです。

| ?- tfilter(=(X),[A,B],Xs).
B = A,
X = A,
Xs = [A,A] ? ;
X = A,
Xs = [A],
dif(A,B) ? ;
X = B,
Xs = [B],
dif(B,A) ? ;
Xs = [],
dif(X,A),
dif(X,B) ? ;
no

2 つの要素のリストを に等しいという基準でフィルタリングする方法は 4 通りありますX。各要素は等しい場合も異なる場合もあります。

このアプローチの欠点は、すべての基準の具体化されたバージョンを提供する必要があることです。

于 2014-02-26T21:02:42.620 に答える
0

さて、私はちょうどそれを理解した. だから、ここに私自身の質問への回答を提出します。予想通り、本当に短い関数が仕事をしました:

filterList(_,[],R,R).           % Returns answer when the list is exhausted.
filterList(L,[A|List],Temp,Res) :-
   filterList(L,List,New,Res),  % Recursive call, New is either the same list
   (  filter(L,A),              % in case the filter outputs true, or the list
      New = Temp
   ;  New = [A|Temp]            % plus the current element otherwise.
   ).
于 2008-11-18T06:54:06.350 に答える