Pregunta

¿Hay una manera de hacer un caso en el prólogo, por ejemplo, si una variable es 0, entonces hacer algunas acciones (texto de escritura a la terminal). Una persona no es incluso necesario, pero no puedo encontrar ninguna documentación del caso.

¿Fue útil?

Solución

Un predicado prólogo estándar hará esto.

   isfive(5). 

se evaluará como true si se llama con 5 y falla (return false) si se ejecuta con cualquier otra cosa. Para no igual se utiliza \ =

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

Técnicamente se trata de unificar no lo hace, pero es similar a no es igual.

Learn Prolog Ahora es un buen sitio web para el aprendizaje de prólogo.

Editar: Para añadir otro ejemplo.

isEqual(A,A). 

Otros consejos

Sí, hay tal construcción de control A en ISO Prolog, llamado ->. Se utiliza de esta manera:

( condition -> then_clause ; else_clause )

Este es un ejemplo que utiliza una cadena de Else-si-cláusulas:

(   X < 0 ->
    writeln('X is negative.  That's weird!  Failing now.'),
    fail
;   X =:= 0 ->
    writeln('X is zero.')
;   writeln('X is positive.')
)

Tenga en cuenta que si se omite la cláusula else, la condición no significa que toda sentencia if fallará. Por lo tanto, recomiendo siempre que incluye la cláusula else (incluso si es sólo true).

Prolog predicados 'unificar' -

Por lo tanto, en un langauge imperativo que escribiría

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

En Prolog me gustaría escribir

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

, que, cuando se comprende ambos estilos, es en realidad mucho más clara.
"Estoy bazoo para el caso especial cuando foo es 5"
"Estoy bazoo para el caso normal cuando foo no es 5"

He encontrado útil esta información utilizando un si declaración en regla.

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

Gracias a http: //cs.union. edu / ~ striegnk / aprender-prólogo-ahora / html / node89.html

En primer lugar, vamos a recordar algunos lógica de primer orden clásico:

  

" Si P entonces Q else R" es equivalente a "(P y Q) o (non_P y R)".


¿Cómo podemos expresar "if-then-else" como que en Prolog?

Tomemos el siguiente ejemplo concreto:

  

X es un miembro de la lista [1,2] después es igual a X 2 else es igual a X 4.

puede igualar por encima de patrón ( " P después Q else R") si ...

  • condición P es list_member([1,2],X),
  • negado condición non_P es non_member([1,2],X),
  • Q consecuencia es X=2, y
  • R alternativa es X=4.

Para expresar la lista (no) la pertenencia a una forma pura, definimos:

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

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

cheque Vamos a cabo diferentes formas de expresar "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.
    
    puntuación

    La corrección 5/5. Eficiencia puntuación de 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
    
    puntuación

    La corrección 2/5. Eficiencia puntuación de 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
    
    puntuación

    La corrección 3/5. Eficiencia puntuación de 1/5.


(preliminar) Resumen:

  1. (P,Q ; non_P,R) es correcta, pero necesita una aplicación discreta de non_P.

  2. (P -> Q ; R) pierde semántica declarativa cuando instanciación es insuficiente.

  3. (P *-> Q ; R) es "menos" incompleta de (P -> Q ; R), pero todavía tiene los problemas similares.


Por suerte para nosotros, hay son alternativas: Introduzca el if_/3 de control constructo lógicamente monótona!

if_/3 junto con la lista de miembros cosificado-predicado memberd_t/3 este modo:

?-      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.
puntuación

La corrección 5/5. Eficiencia puntuación de 4/5.

Lo mejor que puede hacer es utilizar la llamada cuts, que tiene el símbolo !.

if_then_else(Condition, Action1, Action2) :- Condition, !, Action1.  
if_then_else(Condition, Action1, Action2) :- Action2.

Lo anterior es la estructura básica de una función de estado.

Para ejemplificar, aquí está la función max:

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

Me sugerir la lectura más documentación sobre los recortes, pero en general son como puntos de ruptura. Ej .: En el caso de la primera función max devuelve un valor verdadero, la segunda función no se verifica.

PS: Estoy bastante nuevo en Prolog, pero esto es lo que he descubierto

.

Existen básicamente tres formas diferentes de cómo expresar algo como if-then-else en Prolog. Para comparar los consideran char_class/2. Para a y b la clase debe ser ab y other para todos los otros términos. Se podría escribir esta torpeza de este modo:

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

Para escribir las cosas de forma más compacta, un if-then-else es necesaria construcción. Prolog ha incorporado en uno:

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

Mientras que esta respuesta es sonido, es incompleta. Sólo se da la primera respuesta de ( Ch = a ; Ch = b ). Las otras respuestas son picados de distancia. No es muy relacional, de hecho.

Una mejor construcción, a menudo llamado un "corte suave" (no creo que el nombre, un corte es un corte es un corte), da mejores resultados ligeramente (esto es, en YAP):

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

Alternativamente, SICStus tiene if/3 con la semántica muy similares:

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

Así que la última respuesta sigue siendo suprimida. A continuación, introduzca library(reif) para SICStus , YAP , y SWI . Instalarlo y decir:

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

Tenga en cuenta que toda la if_/3 se compila distancia a un violentamente anidados if-then-else para

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

que se expande en YAP 6.3.4 a:

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

programa Prolog realidad es grande condición de "si" con "y luego" que imprime "se alcanza Goal" y "otro", que imprime "No se encontró sloutions". A, Bmeans "A es verdadero y B es verdadero", la mayoría de los sistemas de prólogo no tratará de satisfacer "B" si "A" no es accesible (es decir X=3, write('X is 3'),nl imprimirá 'X es 3' cuando X = 3, y no hará nada si X = 2).

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

Se requiere que la parte else

Debe leer Learn Prolog Ahora! Capítulo 10.2 Uso de cortar . Esto proporciona un ejemplo:

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

que decir,

Z es igual a Y IF ! es cierto (que siempre es) y X es <= Y.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top