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

44
demandé sur mat 2010-05-17 16:38:46

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). 
46
répondu stonemetal 2014-02-23 23:35:15

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

80
répondu Matthias Benkard 2011-06-11 08:25:59

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"

23
répondu Anniepoo 2012-02-11 23:35:10

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

8
répondu Tom Howard 2012-12-07 00:20:03

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.

6
répondu skipper 2015-09-25 15:04:10

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:

SiX est un membre de la liste [1,2]X égale 2 sinonX égale 4.

On peut faire correspondre au-dessus de modèle ("Si P Q sinon R") Si ...

  • condition Plist_member([1,2],X),
  • condition annulée non_Pnon_member([1,2],X),
  • conséquence QX=2, et
  • autres RX=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!

  1. (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.

  2. (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.

  3. (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é:

  1. (P,Q ; non_P,R) est correct, mais nécessite une implémentation discrète de non_P.

  2. (P -> Q ; R) perd sa sémantique déclarative lorsque l'instanciation est insuffisante.

  3. (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.

6
répondu repeat 2017-05-23 10:31:35

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
     )
   ).
5
répondu false 2016-05-06 10:44:39

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

4
répondu ony 2010-05-17 13:57:12
(  A == B ->
     writeln("ok")
;
     writeln("nok")
),

La partie est obligatoire

2
répondu Dieter 2014-07-07 21:53:26