"si" dans le prologue?
probablement une question stupide, mais je ne peux trouver aucune documentation pour elle. Y a-t-il un moyen de faire un si dans prolog, par exemple si une variable est 0, puis de faire quelques actions (écrire du texte au terminal). Un autre n'est même pas nécessaire, mais je ne trouve aucune implémentation de si.
10 réponses
Un standard prédicat prolog va le faire.
isfive(5).
va évaluer à true si vous l'appelez avec 5 et fail (return false) si vous l'exécutez avec autre chose. Pour ne pas égaux vous utilisez \=
isNotEqual(A,B):- A\=B.
techniquement, il n'est pas unificateur, mais il est similaire à pas égal.
apprendre Prolog est maintenant un bon site web pour apprendre prolog.
Modifier: Pour ajouter un autre exemple.
isEqual(A,A).
Oui, il y a un contrôle de la construire dans la norme ISO Prolog, appelé ->
. Vous l'utilisez comme ceci:
( condition -> then_clause ; else_clause )
Voici un exemple qui utilise une chaîne de sinon-si-clauses:
( X < 0 ->
writeln('X is negative. That's weird! Failing now.'),
fail
; X =:= 0 ->
writeln('X is zero.')
; writeln('X is positive.')
)
notez que si vous omettez la clause else, l'échec de la condition signifiera que toute la déclaration if échouera. Par conséquent, je recommande toujours d'inclure la clause else (même si elle est juste true
).
Prolog prédit 'unify' -
ainsi, dans un langauge impératif j'écrirais
function bazoo(integer foo)
{
if(foo == 5)
doSomething();
else
doSomeOtherThing();
}
dans Prolog, j'écrirais
bazoo(5) :- doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.
qui, quand vous comprenez les deux styles, est en réalité beaucoup plus clair.
"Je suis bazoo pour le cas particulier où foo est de 5"
"Je suis bazoo pour le cas normal lorsque foo n'est pas 5"
j'ai trouvé cela utile pour utiliser un si déclaration d'une règle.
max (X, Y, Z) :- ( X =< Y - >Z = Y ; Z = X).
merci à http://cs.union.edu/~striegnk/learn-prolog-now/html/node89.html
La meilleure chose à faire est d'utiliser la soi-disant cuts
, qui a le symbole !
.
if_then_else(Condition, Action1, Action2) :- Condition, !, Action1.
if_then_else(Condition, Action1, Action2) :- Action2.
ce qui précède est la structure de base d'une fonction de condition.
Pour illustrer, voici le max
fonction:
max(X,Y,X):-X>Y,!.
max(X,Y,Y):-Y=<X.
je suggère de lire plus de documentation sur les coupures, mais en général elles sont comme des points de rupture.
Ex.: Dans le cas où le premier max
la fonction renvoie une valeur vraie, la seconde fonction n'est pas vérifiée.
PS: je suis assez nouveau pour prologue, mais c'est ce que j'ai découvert.
tout d'abord, rappelons une logique classique du premier ordre:
"Si P Q sinon R " est équivalent à "(P et Q)ou (non_P et R)".
Comment pouvons-nous exprimer "si-alors-sinon" comme dans le Prologue?
prenons l'exemple concret suivant:
Si
X
est un membre de la liste[1,2]
X
égale2
sinonX
égale4
.
On peut faire correspondre au-dessus de modèle ("Si P Q sinon R") Si ...
- condition
P
list_member([1,2],X)
, - condition annulée
non_P
non_member([1,2],X)
, - conséquence
Q
X=2
, et - autres
R
X=4
.
Pour exprimer liste (non-)l'adhésion d'une façon pure, on définit:
list_memberd([E|Es],X) :- ( E = X ; dif(E,X), list_memberd(Es,X) ). non_member(Es,X) :- maplist(dif(X),Es).
nous allons vérifier différentes façons d'exprimer "si-then-else" dans 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.
score D'exactitude 5/5. Score d'efficacité 3/5.
(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
score D'exactitude 2/5. Score d'efficacité de l' 2/5.
(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
score D'exactitude 3/5. Score d'efficacité 1/5.
(Préliminaire) résumé:
(P,Q ; non_P,R)
est correct, mais nécessite une implémentation discrète denon_P
.(P -> Q ; R)
perd sa sémantique déclarative lorsque l'instanciation est insuffisante.(P *-> Q ; R)
est "moins" que incomplètes(P -> Q ; R)
, mais a toujours des problèmes similaires.
heureusement pour nous, il alternatives:
entrez la construction de contrôle logiquement monotone if_/3
!
nous pouvons utiliser if_/3
avec le prédicat réifié d'appartenance à une liste memberd_t/3
comme ceci:
?- 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.
score D'exactitude 5/5. Score d'efficacité 4/5.
il y a essentiellement trois façons différentes d'exprimer quelque chose comme si-puis-autrement dans Prolog. Pour les comparer, considérezchar_class/2
. a
et b
la classe doit être ab
et other
pour tous les autres termes. On pourrait écrire maladroitement comme ceci:
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).
pour écrire les choses de façon plus compacte, une construction si-alors-autrement est nécessaire. Prolog a une version intégrée:
?- ( ( Ch = a ; Ch = b ) -> Class = ab ; Class = other ).
Ch = a, Class = ab.
bien que cette réponse soit valable, elle est incomplète. Juste la première réponse de ( Ch = a ; Ch = b )
est donné. Les autres réponses sont coupés à l'écart. Pas très relationnel, en effet.
Une meilleure construction, souvent appelé un "soft-cut" (ne crois pas que le nom, une coupe est une coupe est une coupe), donne des résultats légèrement meilleurs (c'est à YAP):
?- ( ( Ch = a ; Ch = b ) *-> Class = ab ; Class = other ).
Ch = a, Class = ab
; Ch = b, Class = ab.
alternativement, SICStus a if/3
très similaires à la sémantique:
?- if( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
Ch = a, Class = ab
; Ch = b, Class = ab.
Donc la dernière réponse est toujours supprimé. Maintenant, entrez library(reif)
SICStus, YAP, et SWI. Installez-le et dites:
?- 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).
Notez que tous les if_/3
est compilé à partir d'un imbriqué si-then-else pour
char_class(Ch, Class) :-
if_( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
qui s'étend dans YAP 6.3.4 à:
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
)
).
le programme Prolog est en fait une grande condition pour "si" avec "Alors" quelles impressions "le but est atteint" et "autrement"quelles impressions" aucune sloutions n'a été trouvée". A, B
signifie "A est vrai et B est vrai", la plupart des systèmes prolog n'essayeront pas de satisfaire "B" Si " A " n'est pas accessible (i.e. X=3, write('X is 3'),nl
va imprimer 'X est 3' Quand X=3, et ne fera rien si X=2).
( A == B ->
writeln("ok")
;
writeln("nok")
),
La partie est obligatoire
Vous devriez lire Apprenez Prolog Dès Maintenant! Chapitre 10.2 Utilisation De La Découpe--8-->. Cela fournit un exemple:
max(X,Y,Z) :- X =< Y,!, Y = Z.
pour être dit,
Z
est égal à Y
si!
est vraie (c'est toujours le cas) etX
<= Y
.