Frage

Im Moment arbeite ich an einem sehr kurzen Projekt auf Prolog und wurde gerade stecken versuchen, einen „Filter“ ich auf eine Liste erstellt haben, anzuwenden. Ich habe, was Sie könnte der Filter bereit nennen, aber ich kann es nicht anwendbar. Es wäre besser, wenn ich zeigen:

filter(A, B) 

... Ausgänge 'true', wenn bestimmte Bedingungen erfüllt sind.

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

... gibt eine Liste, die alle Elemente aus dem zweiten Argument enthält, die die Filterausgabe false machen. (So, wenn die Filter (A, X) wahr ist, ist der Ausgang [Y, Z]).

Ich habe die „Filter“ -Funktion bereit, aber jetzt muss ich es auf eine Liste anwenden, wie auf dem zweiten Beispiel gezeigt, ohne alle Elemente, für die der Filter true zurückgibt, wenn es mit dem ersten Argument angewendet.

Also, wenn die Filter ein einfacher A == B ist, wird die Funktion soll ein [A, B, A, C, D, A] und Ausgang [B, C, D] erhalten, entfernt hat alle Elemente, für die der Filter angewendet wird, offensichtlich.

Ich habe Probleme mit der Grundstruktur der Funktion, also wenn jemand eine Prinzipskizze für eine Funktion wie diese liefern könnte es eine große Hilfe sein würde. Ich habe meine Situation so weit wie möglich vereinfacht, so kann ich nehmen, was Sie in der Lage sein können, zur Verfügung zu stellen und ändern Sie es für meine Bedürfnisse.

Vielen Dank im Voraus!

War es hilfreich?

Lösung

Wenn Sie für Funktionen höherer Ordnung in Prolog suchen, dann sollten Sie auf jeden Fall konsultieren Naish (1995) , eine sehr gute Ressource zu diesem Thema.

Seine Definition von filter/3 folgenden ist (er verwendet Unterschied-Liste Notation, also entkommt mit filter/4 definieren):


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

ich Sie Fragen zu diesem Prädikat haben, fragen Sie mich bitte in dem Kommentar. die Zeitung zu lesen ist sehr zu empfehlen auch, es auch definess map, foldr und compose! Beachten Sie, dass viele der Einschränkungen erwähnt er (wie zum Beispiel eines fehlende call/3 oder eine höhere Ordnung apply gilt nicht mehr. SWI-Prolog hat den =.. Operator, der alle seine Bedenken Adressen und macht beliebige n-ter Ordnung Logik möglich.

Andere Tipps

SWI-Prolog bietet exclude/3 und andere solche Meta-Prädikate. Ihr ursprüngliches Problem kann wie folgt codiert werden:

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

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

Anwendungsbeispiel:

?- filterList(A, [A, B, A, C, D, A], Out).
Out = [B, C, D].

Es ist ein inhärentes Problem mit Filterfunktionen, die den Erfolg oder Misserfolg eines Prädikats als Kriterium für die Filterung übernehmen: Das resultierende Programm ist nicht mehr ein reines monotones Programm. Es verliert daher alle ihre Aussage Eigenschaften - die einzige Bedeutung, die Interpretation ein Verfahrensschritt-für-Schritt bleibt. Hier ist eine reine, verdinglicht Version Filterung 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).

Das erste Argument ist also ein Verschluss / Fortsetzung, das zwei weitere Argumente erhalten. Das Element und der daraus resultierende Wahrheitswert

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

Nun, die Ergebnisse bleiben präzise:

| ?- 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

Es gibt vier Möglichkeiten, wie eine Liste von zwei Elementen kann X durch das Kriterium der gleich gefiltert werden. Jedes Element kann gleich oder anders sein könnte.

Der Nachteil dieses Ansatzes ist, dass eine verdinglichte Versionen aller Kriterien zu bieten hat.

Nun was hat Sie wissen, habe ich es einfach aus. Also ich, hier ist eine Antwort auf meine eigene Frage vorlegt, wie erwartet eine wirklich kurze Funktion, um die Arbeit geleistet haben:

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.
   ).

Ich bekomme die Erwachsenen eines Landes // Obtengo los adultos de un pais, Land = Pais, Menschen = Personas, Person = una sola Persona

habitants(USA, [juan, pedro, david])

adults(Adults, Country) :-
     findall(Person, (habitants(Country,People), member(People, Person), adult(Person)), Adults)

Dies ist ein Filter in Prolog // Asi es un Filter en Prolog

filter(_,[],[]).
filter(Predicate,[First|Rest],[First|Tail]) :-
   filter(Predicate,Rest,Tail).
filter(Predicate,[_|Rest],Result) :-
   filter(Predicate,Rest,Result).
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top