'Wenn' in Prolog?
-
27-09-2019 - |
Frage
Gibt es eine Möglichkeit ein, wenn in Prolog zu tun, zum Beispiel wenn eine Variable 0 ist, dann einige Aktionen (Schreib Text zum Terminal) zu tun. Ein anderes ist nicht einmal nötig, aber ich kann keine Dokumentation, wenn finden.
Lösung
Ein Standard-Prolog-Prädikat wird dies tun.
isfive(5).
wird zu true ausgewertet, wenn Sie es mit 5 anrufen und scheitern (return false), wenn Sie es mit etwas anderem führen. Für nicht gleich verwenden Sie \ =
isNotEqual(A,B):- A\=B.
Technisch ist es nicht unify, aber es ist ähnlich nicht gleich sind.
Erfahren Prolog Jetzt eine gute Website ist Prolog für das Lernen.
Edit: Um ein anderes Beispiel hinzuzufügen.
isEqual(A,A).
Andere Tipps
Ja, es ist so ein Kontrollkonstrukt in ISO Prolog, genannt ->
. Sie verwenden es wie folgt aus:
( condition -> then_clause ; else_clause )
Hier ist ein Beispiel, das eine Kette von else-if-Klauseln verwendet:
( X < 0 ->
writeln('X is negative. That's weird! Failing now.'),
fail
; X =:= 0 ->
writeln('X is zero.')
; writeln('X is positive.')
)
Beachten Sie, dass, wenn Sie die else-Klausel weglassen, andernfalls die Bedingung bedeutet, dass die gesamte if-Anweisung fehl. Daher empfehle ich immer mit der Else-Klausel (auch wenn es nur true
ist).
Prolog Prädikate 'unify' -
Also, in einem imperativen Langauge würde ich schreiben
function bazoo(integer foo)
{
if(foo == 5)
doSomething();
else
doSomeOtherThing();
}
In Prolog Ich würde schreiben
bazoo(5) :- doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.
, die, wenn man beide Arten verstehen, ist eigentlich viel klarer.
„Ich bin bazoo für den speziellen Fall, wenn foo 5“
„Ich bin bazoo für den Normalfall, wenn foo nicht 5“
Ich fand diese Informationen hilfreich für die Verwendung einer , wenn Aussage in der Regel.
max(X,Y,Z) :-
( X =< Y
-> Z = Y
; Z = X
).
Dank http: //cs.union. edu / ~ striegnk / Lern-prolog-now / html / node89.html
Lassen Sie uns zunächst einige klassische Logik erster Ordnung erinnern:
" Wenn P und Q else R" entspricht „(P und Q) oder (non_P und R)“.
Wie können wir "if-then-else" wie , die in Prolog?
auszudrückenNehmen wir folgendes konkretes Beispiel:
Wenn
X
ein Mitglied der Liste[1,2]
ist undX
gleich2
sonstX
gleich4
.
Wir können oben Muster entsprechen ( " Wenn P und Q else R"), wenn ...
- Bedingung
P
istlist_member([1,2],X)
, - negiert Bedingung
non_P
istnon_member([1,2],X)
, - Folge
Q
istX=2
und - Alternative
R
istX=4
.
Liste Um auszudrücken, (Nicht-) Mitgliedschaft in einer reinen Art und Weise, wir definieren:
list_memberd([E|Es],X) :- ( E = X ; dif(E,X), list_memberd(Es,X) ). non_member(Es,X) :- maplist(dif(X),Es).
Lassen Sie sich heraus unterschiedliche Weise zum Ausdruck zu bringen "if-then-else" in Prolog!
-
(P,Q ; non_P,R)
?- (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4). X = 2 ; X = 4. ?- X=2, (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=2. X = 2 ; false. ?- (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=2. X = 2 ; false. ?- X=4, (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=4. X = 4. ?- (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=4. X = 4.
Correctness Note 5/5. Effizienz-Score 05.03.
-
(P -> Q ; R)
?- (list_memberd([1,2],X) -> X=2 ; X=4). false. % WRONG ?- X=2, (list_memberd([1,2],X) -> X=2 ; X=4), X=2. X = 2. ?- (list_memberd([1,2],X) -> X=2 ; X=4), X=2. false. % WRONG ?- X=4, (list_memberd([1,2],X) -> X=2 ; X=4), X=4. X = 4. ?- (list_memberd([1,2],X) -> X=2 ; X=4), X=4. false. % WRONG
Correctness Score 2/5. Effizienz-Score 05.02.
-
(P *-> Q ; R)
?- (list_memberd([1,2],X) *-> X=2 ; X=4). X = 2 ; false. % WRONG ?- X=2, (list_memberd([1,2],X) *-> X=2 ; X=4), X=2. X = 2 ; false. ?- (list_memberd([1,2],X) *-> X=2 ; X=4), X=2. X = 2 ; false. ?- X=4, (list_memberd([1,2],X) *-> X=2 ; X=4), X=4. X = 4. ?- (list_memberd([1,2],X) *-> X=2 ; X=4), X=4. false. % WRONG
Correctness Score 3/5. Effizienz-Score 1/5.
(Preliminary) Zusammenfassung:
-
(P,Q ; non_P,R)
ist richtig, aber braucht eine diskrete Implementierung vonnon_P
. -
(P -> Q ; R)
verliert deklarative Semantik, wenn Instanziierung unzureichend ist. -
(P *-> Q ; R)
ist "weniger" unvollständig als(P -> Q ; R)
, hat aber immer noch ähnliche Leiden.
Zum Glück für uns, es ist Alternativen:
Geben Sie die logisch monotone Steuerkonstrukt if_/3
!
Wir verwenden if_/3
zusammen mit der verdinglichten list-Mitgliedschaft Prädikat memberd_t/3
etwa so:
?- if_(memberd_t(X,[1,2]), X=2, X=4). X = 2 ; X = 4. ?- X=2, if_(memberd_t(X,[1,2]), X=2, X=4), X=2. X = 2. ?- if_(memberd_t(X,[1,2]), X=2, X=4), X=2. X = 2 ; false. ?- X=4, if_(memberd_t(X,[1,2]), X=2, X=4), X=4. X = 4. ?- if_(memberd_t(X,[1,2]), X=2, X=4), X=4. X = 4.
Correctness Note 5/5. Effizienz-Score 4/5.
Das Beste, was zu tun ist, die so genannten cuts
zu verwenden, das das Symbol !
hat.
if_then_else(Condition, Action1, Action2) :- Condition, !, Action1.
if_then_else(Condition, Action1, Action2) :- Action2.
Das oben ist die Grundstruktur einer Bedingung Funktion.
Zur Veranschaulichung hier die max
Funktion:
max(X,Y,X):-X>Y,!.
max(X,Y,Y):-Y=<X.
Ich schlage vor, das Lesen mehr Dokumentation auf Kürzungen, aber im Allgemeinen sind sie wie Breakpoints.
Bsp .: Bei der ersten max
Funktion einen wahren Wert zurückgibt, wird die zweite Funktion nicht überprüft.
PS: Ich bin ziemlich neu in Prolog, aber das ist, was habe ich herausgefunden habe
. Es gibt im Wesentlichen drei verschiedene Möglichkeiten, wie so etwas wie if-then-else in Prolog zum Ausdruck bringen. So vergleichen Sie sie char_class/2
betrachten. Für a
und b
sollte die Klasse ab
und other
für alle anderen Bedingungen sein. Man könnte diese plump schreiben wie folgt:
char_class(a, ab).
char_class(b, ab).
char_class(X, other) :-
dif(X, a),
dif(X, b).
?- char_class(Ch, Class).
Ch = a, Class = ab
; Ch = b, Class = ab
; Class = other,
dif(Ch, a), dif(Ch, b).
Um Schreib Dinge kompakte, ein if-then-else-Konstrukt benötigt. Prolog hat einen eingebauten ein:
?- ( ( Ch = a ; Ch = b ) -> Class = ab ; Class = other ).
Ch = a, Class = ab.
Während diese Antwort Ton, es ist unvollständig. Nur die erste Antwort von ( Ch = a ; Ch = b )
gegeben. Die anderen Antworten werden gehackt weg. Nicht sehr relational, in der Tat.
Ein besseres Konstrukt, oft ein „weicher Schnitt“ genannt (nicht den Namen glaubt, ein Schnitt ist ein Schnitt ein Schnitt ist), gibt etwas bessere Ergebnisse (dies ist in YAP):
?- ( ( Ch = a ; Ch = b ) *-> Class = ab ; Class = other ).
Ch = a, Class = ab
; Ch = b, Class = ab.
Alternativ hat SICStus if/3
mit sehr ähnlicher Semantik:
?- if( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
Ch = a, Class = ab
; Ch = b, Class = ab.
So ist die letzte Antwort wird immer noch unterdrückt. Geben Sie jetzt library(reif)
für SICStus YAP und SWI . Installieren Sie es und sagen:
?- use_module(library(reif)).
?- if_( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
Ch = a, Class = ab
; Ch = b, Class = ab
; Class = other,
dif(Ch, a), dif(Ch, b).
Beachten Sie, dass alle if_/3
zu einem wild zusammen entfernt verschachtelt if-then-else für
char_class(Ch, Class) :-
if_( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
, die in YAP 6.3.4 erweitert:
char_class(A,B) :-
( A\=a
->
( A\=b
->
B=other
;
( A==b
->
B=ab
)
;
A=b,
B=ab
;
dif(A,b),
B=other
)
;
( A==a
->
B=ab
)
;
A=a,
B=ab
;
dif(A,a),
( A\=b
->
B=other
;
( A==b
->
B=ab
)
;
A=b,
B=ab
;
dif(A,b),
B=other
)
).
Prolog-Programm ist eigentlich große Bedingung für „if“ mit „und dann“ dem Druck „Ziel erreicht“ und „else“, der Druck „Keine sloutions wurde gefunden“. A, B
means „A ist wahr und B ist wahr“, wird nicht die meisten Prologs Systeme versuchen „B“ zu erfüllen, wenn „A“ nicht erreichbar ist (dh X=3, write('X is 3'),nl
druckt ‚X 3‘, wenn X = 3, und wird nichts tun, wenn X = 2).
( A == B ->
writeln("ok")
;
writeln("nok")
),
Der else-Teil ist erforderlich
Sie sollten lesen Erfahren Prolog Now! Kapitel 10.2 Verwendung von Einzel . Dies ist ein Beispiel:
max(X,Y,Z) :- X =< Y,!, Y = Z.
zu sagen,
Z
gleich Y
IF !
gilt (was es immer ist) und X
ist <= Y
.