Frage

Ich habe die folgende Funktion im Prolog mit dem folgenden Code implementiert:

abs2(X, Y) :- X < 0, Y is -X.
abs2(X, X) :- X >= 0, !.

Wie kann ich diese Funktion ohne die Verwendung von Cut ("!") Implementieren?

War es hilfreich?

Lösung

Es gibt das "versteckte" Schnitt im If-Then-Else-Konstrukt von Prolog:

abs2(X,Y) :- X < 0 -> Y is -X ; Y = X.

Es ist so etwas wie eine Eigenart, aber Prolog fährt nicht auf dem Subziel zurück, das die "Prämisse" eines if-then- oder if-then-Else-Konstrukts bildet. Wenn X <0 den ersten Versuch erfolgreich ist, dann wird die Wahl von "dann" Klausel über "else" -Klausel begangen (daher die Beschreibung dieses Verhaltens als "versteckter" Schnitt).

Es gibt mehr eine Rolle für einen Schnitt in der Erste Klausel des Prädikats ABS2/2 wie in der Frage geschrieben. Wie Nicholas betont, hat der Schnitt am Ende der zweiten Klausel keinen Effekt (es sind keine Auswahlpunkte übrig, wenn Sie dort ankommen). Aber wie Kaarel betont, gibt es einen Auswahlpunkt offen, wenn die erste Klausel erfolgreich ist.

Was ich also geschrieben hätte und die Verwendung eines Schnitts zugelassen hätte, ist Folgendes:

abs2(X,X) :- X >= 0, !.
abs2(X,Y) :- Y is -X.

Die Kommentare von Nicholas schlagen auch Möglichkeiten vor, den Absolutwert zu "arithmetisieren" (anstatt eine Logikdefinition zu verwenden) und zu vermeiden, dass "geschnitten" werden.

Andere Tipps

Mein Prolog ist ein bisschen verrostet, aber warum brauchst du überhaupt den Schnitt? Wenn Sie das Prädikat richtig schreiben, kann das Backtracking nicht erfolgreich sein, sodass der Schnitt nicht erforderlich ist:

abs(X, Y) :- number(X) , X <  0 , Y is -X .
abs(X, X) :- number(X) , X >= 0 .

Keine Notwendigkeit zu verwenden !

Einfach schreiben:

abs2(X,Y) :- Y is abs(X).
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top