write reglas operadores not negacion explicados ejercicios conocimiento prolog prolog-dif

operadores - reglas en prolog



¿Cuál es el ''no'' lógico en Prolog? (5)

Como complemento a la respuesta del usuario "falso" anterior, es decir

"En lugar de no (X = Y) necesitas escribir / + X = Y,"

Esto podría dar la impresión de que:

a. "no" y "/ +" son cosas diferentes

segundo. El / + funcionará mientras que el no lo hará, err, no.

Tengo entendido que "no" y "/ +" son equivalentes, pero que / + es el preferido en los programas modernos de Prolog, porque transmite un sentido que es más intuitivo. Específicamente, mientras que "no" podría sugerir "no es verdad" para el codificador incauto, "/ +" sugiere "no es comprobable", lo cual está mucho más cerca de la verdad de lo que esa operación realmente está diciendo. En Prolog, el "no" es un ejemplo de "negación como fracaso", pero se cree que / + le dejará más claro al programador exactamente qué se afirma exactamente en cualquier regla dada. Entonces, PUEDE usar "no" (la mayoría de las implementaciones de PL lo mantienen por compatibilidad con versiones anteriores), pero para ser un programador PL moderno e idiomático, probablemente prefiera usar / +.

El problema al que me enfrento es un poco trivial. Quiero usar lógica no en Prolog, pero parece que not/1 no es lo que quiero:

course(ai). course(pl). course(os). have(X,Y) :- course(X),course(Y),not(X = Y).

Pregunto:

have(X,Y), write(X-Y), nl , fail.

Y no obtengo el resultado que quiero :(


Como dijiste, OP, esto es trivial.

Tratar

course(ai). course(pl). course(os). have(X,Y) :- course(X), course(Y), X /== Y).

Eso debería arreglar tu predicado.

Sin embargo, mirando un paso adelante, fraseando matemáticamente, probablemente esté buscando la solución a (n C 2) en oposición a (n P 2) que su predicado proporciona actualmente: combinación en lugar de permutación, elección de selección en oposición a arreglos de opciones de selección. Esto es lo que creo.

Si esto es lo que quieres, te sugiero que intentes

course(ai). course(pl). course(os). have(X,Y) :- course(X), course(Y), X @< Y).

Lo que evitaría duplicar los resultados invertidos.

@< significa atómicamente menos que. < es para enteros, @< es para átomos.


En lugar de not(X = Y) necesita escribir /+ X = Y o X /= Y Pero considere usar dif(X,Y) lugar. dif/2 está presente en B, SWI, YAP, SICStus. Para ver la diferencia:

?- X = b, dif(a, X). X = b. ?- X = b, /+ a = X. X = b.

Hasta ahora todo parece estar bien. Pero, ¿qué pasa si simplemente cambiamos el orden de los dos objetivos?

?- /+ a = X, X = b. false. ?- dif(a, X), X = b. X = b.

(/+)/1 ahora nos da un resultado diferente, porque hay una respuesta para a = X , el objetivo /+ a = X fallará.

(/+)/1 es, pues, negación, sino que significa que no es demostrable en este momento .

También es posible una aproximación segura de dif/2 en ISO Prolog.


Leyendo el book Samuel Kamin sobre el capítulo 8, prólogo, encontré esta solución que también encaja aquí y explica cómo usar el cut :

El corte es una forma de darle al programador un control adicional sobre el cómputo permitiéndole indicar los lugares donde el retroceso es inadmisible. Específicamente, el corte está escrito como un signo de exclamación (!) Que aparece como un objetivo en el lado derecho de una cláusula, como por ejemplo:

G :- H, !, R.

Supongamos que esta cláusula se elige para satisfacer una meta g con la que G unifies . Se intenta satisfacer a H. Si tiene éxito, se demuestra R. Si la prueba de R tiene éxito, entonces g está probado ; en este caso, el corte no tiene parte para jugar. Sin embargo, si la prueba de R falla , en lugar de retroceder e intentar volver a probar H, la presencia del corte hace que la meta g falle inmediatamente ; esto ocurre incluso si hay otras cláusulas que pueden aplicarse a g. Un ejemplo es la definición de no iguales :

equals(X, X). not-equals(X, Y) :- equals(X, Y), !, fail. not-equals(X, Y).

not-equals(X, Y) deberían tener éxito si X no es igual a Y, y fallar si lo es; X e Y deberían estar ligados a las expresiones básicas (es decir, no tienen variables libres) cuando se intenta satisfacer este objetivo.


Tanto en SWI-Prolog como en GNU Prolog, lo siguiente debería funcionar:

have(X, Y) :- course(X), course(Y), X /= Y.

En SWI-Prolog, también puede usar dif/2 , que puede ser más conveniente ya que puede usarlo anteriormente en el predicado:

have(X, Y) :- dif(X, Y), course(X), course(Y).