'Si' en el prólogo?
-
27-09-2019 - |
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.
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 aX
2
else es igual aX
4
.
puede igualar por encima de patrón ( " P después Q else R") si ...
- condición
P
eslist_member([1,2],X)
, - negado condición
non_P
esnon_member([1,2],X)
, -
Q
consecuencia esX=2
, y -
R
alternativa esX=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!
-
(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ónLa corrección 5/5. Eficiencia puntuación de 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
puntuaciónLa corrección 2/5. Eficiencia puntuación de 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
puntuaciónLa corrección 3/5. Eficiencia puntuación de 1/5.
(preliminar) Resumen:
-
(P,Q ; non_P,R)
es correcta, pero necesita una aplicación discreta denon_P
. -
(P -> Q ; R)
pierde semántica declarativa cuando instanciación es insuficiente. -
(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, B
means "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
.