Question

Y at-il un moyen de faire une si Prolog, par exemple si une variable est 0, puis de faire quelques actions (texte d'écriture sur le terminal). Un autre est même pas nécessaire, mais je ne peux trouver aucune documentation si.

Était-ce utile?

La solution

Un prédicat standard Prolog fera.

   isfive(5). 

évaluera true si vous l'appelez avec 5 et échouez (faux retour) si vous l'exécutez avec quoi que ce soit d'autre. Pour ne pas être égal que vous utilisez \ =

isNotEqual(A,B):- A\=B.

Techniquement, il est ne pas Unify, mais il est similaire à pas égal.

En savoir Prolog est maintenant un bon site pour apprendre Prolog.

Edit: Pour ajouter un autre exemple.

isEqual(A,A). 

Autres conseils

Oui, il y a une telle construction de contrôle dans la norme ISO Prolog, appelé ->. Vous pouvez l'utiliser comme ceci:

( condition -> then_clause ; else_clause )

Voici un exemple qui utilise une chaîne d'autre, si les 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 l'autre article, la condition ne signifie que toute instruction if échouera. Par conséquent, je recommande toujours compris l'autre article (même si elle est juste true).

Prolog prédicats Unify '-

Alors, dans un langauge impératif j'écrire

function bazoo(integer foo)
{
   if(foo == 5)
       doSomething();
   else
       doSomeOtherThing();
}

Dans Prolog j'écrirait

bazoo(5) :-  doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.

qui, quand vous comprenez les deux styles, est en fait beaucoup plus claire.
« Je suis bazoo pour le cas particulier où foo est 5 »
« Je suis bazoo pour le cas normal lorsque foo n'est pas 5 »

J'ai trouvé cela utile pour utiliser une instruction si dans une règle.

max(X,Y,Z) :-
    (  X =< Y
    -> Z = Y
    ;  Z = X
    ).

Merci à http: //cs.union. edu / ~ striegnk / apprendre-Prolog-now / html / node89.html

D'abord, rappeler une certaine logique du premier ordre classique:

  

" Si P puis Q autre R" est équivalent à « (P et Q) ou (non_P et R) ».


Comment pouvons-nous exprimer "if-then-else" comme que Prolog?

Prenons l'exemple concret suivant:

  

Si X est membre de la liste [1,2] puis X égal 2 autre X égal 4.

Nous pouvons correspondre au-dessus de motif ( " Si P puis Q autre R") si ...

  • état P est list_member([1,2],X),
  • état non_P niée est non_member([1,2],X),
  • conséquence Q est X=2 et
  • autre R est X=4.

Pour exprimer liste des membres (non) d'une manière pure que nous définissons:

list_memberd([E|Es],X) :-
   (  E = X
   ;  dif(E,X),
      list_memberd(Es,X)
   ).

non_member(Es,X) :-
   maplist(dif(X),Es).

chèque de Let différentes façons d'exprimer "if-then-else" en 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.
    

    Correctness Score 5/5. Le score 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
    

    Correctness score de 2/5. Le score Efficacité 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
    

    Correctness 3/5 marquer. Le score Efficacité 1/5.


Résumé (préliminaire):

  1. (P,Q ; non_P,R) est correcte, mais a besoin d'une implémentation discrète de non_P.

  2. (P -> Q ; R) perd la sémantique déclaratives lorsque instanciation est insuffisante.

  3. (P *-> Q ; R) est "moins" incomplète que (P -> Q ; R), mais il a encore malheurs similaires.


Heureusement pour nous, il sont alternatives: Entrer la construction de contrôle de la voix monotone de logique if_/3!

Nous pouvons utiliser if_/3 ainsi que la liste-membres réifiée prédicat 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.

Correctness Score 5/5. Le score Efficacité 4/5.

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 donner un exemple, voici la fonction max:

max(X,Y,X):-X>Y,!.  
max(X,Y,Y):-Y=<X.

Je vous suggère de lire plus de documentation sur les coupes, mais en général ils sont comme des points d'arrêt. Ex .: Dans le cas où la première fonction de max renvoie une valeur vraie, la seconde fonction est pas vérifiée.

PS: Je suis assez nouveau pour Prolog, mais ce que j'ai trouvé

.

Il existe essentiellement trois façons différentes la façon d'exprimer quelque chose comme if-then-else dans Prolog. Pour les comparer considèrent char_class/2. Pour a et b la classe doit être pour tous les autres termes et ab other. On pourrait écrire cette gauchement 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 les choses d'écriture plus compacte, un if-then-else construction est nécessaire. Prolog a intégré un:

?- ( ( Ch = a ; Ch = b ) -> Class = ab ; Class = other ).
   Ch = a, Class = ab.

Bien que cette réponse est le son, il est incomplet. Juste la première réponse de ( Ch = a ; Ch = b ) est donnée. Les autres réponses sont coupées loin. Pas très relationnelle, en effet.

Une meilleure construction, souvent appelée « coupe douce » (ne croyez pas le nom, une coupe est une coupe est une coupe), donne des résultats légèrement meilleurs (ce qui est en YAP):

?- ( ( Ch = a ; Ch = b ) *-> Class = ab ; Class = other ).
   Ch = a, Class = ab
;  Ch = b, Class = ab.

En variante, SICStus a if/3 avec une sémantique très semblables:

?- if( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
   Ch = a, Class = ab
;  Ch = b, Class = ab.

Ainsi, la dernière réponse est encore supprimée. Maintenant, entrez library(reif) SICStus , YAP et SWI . Installez-le et dire:

?- 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é loin à un imbriquée d'une manière extravagante si-then-else pour

char_class(Ch, Class) :-
   if_( ( Ch = a ; Ch = b ), Class = ab , Class = other ).

qui se dilate en 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
     )
   ).

programme Prolog est en fait grand état de « si » avec « puis » qui affiche « Le but est atteint » et « autre », qui imprime « Aucun sloutions n'a été trouvé ». A, Bmeans « A est vrai et B est vrai », la plupart des systèmes Prolog ne tentera pas de satisfaire « B » si « A » est pas accessible (c.-à-X=3, write('X is 3'),nl imprimera « X est 3 » lorsque X = 3, et ne fera rien si X = 2).

(  A == B ->
     writeln("ok")
;
     writeln("nok")
),

La partie autre est nécessaire

Vous devriez lire En savoir Prolog Now! Chapitre 10.2 Utiliser Cut. Cela donne un exemple:

max(X,Y,Z) :- X =< Y,!, Y = Z.

à dire,

Z est égal à Y IF ! est vrai (ce qui est toujours) X est <= Y.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top