sistemas sentencia resueltos reglas inteligencia explicados expertos ejercicios ejemplos conocimiento artificial list variables prolog match prolog-dif

list - resueltos - prolog sentencia if



¿Por qué Prolog coincidiría con una variable con un resultado que falla si se conecta directamente? (1)

Primero, felicitaciones por una de las observaciones más declarativas y justificadas que he visto en las preguntas de los principiantes.

Por un lado, es una de las propiedades más básicas y más conocidas que la conjunción es conmutativa en lógica. Por otro lado, muchos principiantes de Prolog no se dan cuenta de que el uso de uno de los predicados no monótonos como (/+)/1 casi invariablemente destruye tales invariantes básicos. Notaste que algo muy inesperado está sucediendo aquí, y tienes razón al esperar un comportamiento más correcto de Prolog. Afortunadamente, las soluciones declarativas para tales problemas ahora están más extendidas que nunca entre los sistemas Prolog.

Primero, considere algunos problemas que surgen pronto si usa (/+)/1 en sus programas:

?- X = d, /+ member(X, [a,b,c]). X = d.

sin embargo, si simplemente intercambiamos los objetivos por conmutatividad de la conjunción, obtenemos la respuesta diferente :

?- /+ member(X, [a,b,c]), X = d. false.

Esto muestra que (/+)/1 no es monotónico: puede hacer que falle una consulta más general, aunque una consulta más específica genera soluciones:

?- /+ member(X, [a,b,c]). false. ?- /+ member(d, [a,b,c]). true.

Por lo tanto, los predicados no monotónicos causan todo tipo de impurezas y violan la semántica declarativa. Declarativamente, sabiendo que hay soluciones, ciertamente esperamos que la consulta más general tenga éxito , pero falla .

En este concreto, para especificar que un término es diferente de todos los otros términos en una lista, use la restricción dif/2 . dif/2 funciona en todas las direcciones y también da respuestas correctas si sus argumentos son variables. Por ejemplo:

not_member(X, Ls) :- maplist(dif(X), Ls).

Esta definición preserva la conmutatividad de la conjunción, ya que deseamos profundamente y de hecho esperamos de las relaciones lógicas puras:

?- not_member(X, [a,b,c]), X = d. X = d. ?- X = d, not_member(X, [a,b,c]). X = d.

Como not_member/2 usa solo predicados puros, usted se ha asegurado, ya por construcción, de que solo da respuestas declarativamente correctas.

Para razonar declarativamente sobre su código, que aplaudo en su enfoque, le recomiendo que se quede en el subconjunto monotónico puro de Prolog. Ver pureza-lógica y prólogo-dif para más información.

Estoy haciendo un programa Prolog que encuentra un subconjunto de un conjunto de listas. Este subconjunto debe coincidir con algunas condiciones específicas, un aspecto del cual es que las listas del subconjunto no pueden ser idénticas. Lo que me confunde es que cuando trato de encontrar una coincidencia para una variable, X, genera resultados que devuelven falso si los conecto a la consulta en lugar de X. Por ejemplo:

?- containsSet(2, [[3],[7],[7]], X). X = [[3], [7]] ; X = [[3], [7]] ; X = [[7], [7]] ; false. ?- containsSet(2, [[3],[7],[7]], [[7],[7]]). false.

¿Cómo podría coincidir X con [[7], [7]] si, cuando se conecta directamente, devuelve falso?

La idea de containsSet es encontrar un subconjunto de listas de longitud-N (en este caso 2) que no tiene elementos coincidentes en las posiciones coincidentes (es decir, no hay dos listas en el subconjunto que tengan el mismo primer elemento, o el mismo segundo elemento, etc.) . En el ejemplo anterior, los primeros (y únicos) elementos de [7] y [7] coinciden, por lo que devuelve falso.