La Coincidencia de patrón - Prólogo vs Haskell


Esta no es una pregunta de tarea, más bien una pregunta de guía de estudio del examen. ¿Cuál es la diferencia entre la coincidencia de patrones en Prolog Vs Haskell?

He hecho algunas investigaciones y leer sobre las teorías detrás de ellos realmente no me da una comprensión sólida entre los dos. Leí que en Prolog, la coincidencia de patrones es diferente porque tiene la capacidad de unificar variables y así poder deducir a través de la resolución y escupir la posible respuesta

eg ?- [a,b] = [a,X]
   X = b

Ahora no estoy claro cómo mostrar la coincidencia de patrones en Haskell. Sé que la misma consulta anterior mostrada en Prolog no funcionará en Haskell porque Haskell no puede unificarse como Prolog. Recuerdo en algún lugar que para obtener la misma respuesta en Haskell, tienes que contarla explícitamente a través de los guardias.

Sé que estoy bastante cerca de entenderlo, pero necesito a alguien que lo rompa al estilo Barney para mí para que pueda entenderlo COMPLETAMENTE y explicárselo a un niño de 12 años. Esto me ha estado molestando durante bastante tiempo y no puedo encontrar una explicación sólida.

Por cierto, el ejemplo mostrado arriba fue solo para mostrarles lo que he aprendido hasta ahora y que en realidad estoy tratando de encontrar una respuesta. Mi pregunta principal no se refiere a los ejemplos anteriores, sino más bien a una comprensión completa de la diferencia entre los dos.

Author: false, 2012-03-20

5 answers

La coincidencia de patrones de Prolog se basa en la unificación, específicamente el algoritmo Martelli-Montanari (menos la comprobación de ocurre, por defecto). Este algoritmo coincide con valores de la misma posición, vinculando variables en un lado a un valor en la posición correspondiente en el otro lado. Este tipo de coincidencia de patrones podría funcionar en ambos sentidos, por lo tanto, en Prolog podría usar argumentos como entrada y salida. Un ejemplo simple, el predicado length/2. Podríamos usar esto para (comentario explica la consulta):

?- length([],0).      % is the length of empty list zero?
?- length([a,b,c],X). % what's the length of list consisting of a,b and c?
?- length(L,5).       % give me all lists that have length of 5

Haskell pattern matching es una coincidencia unidireccional, para enlazar variables a diferentes partes de un valor dado. Una vez encuadernado, realiza la acción correspondiente (el lado derecho). Por ejemplo, en una llamada a una función, la coincidencia de patrones puede decidir a qué función llamar. por ejemplo:

sum []     = 0
sum (x:xs) = x + sum xs

La primera suma enlaza una lista vacía, mientras que la segunda enlaza una lista de al menos 1 elemento. Basado en esto, dado sum <a list>, el resultado podría ser 0 o x + sum xs dependiendo de si sum <a list> coincide con sum [] o sum (x:xs).

 41
Author: LeleDumbo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-20 03:35:26

La diferencia entre la coincidencia de patrones como en Haskell y la unificación de Prolog se deriva del papel fundamentalmente diferente de las variables en ambos idiomas.

En Haskell, las variables tienen valores. Valores concretos. Tal valor podría no haber sido calculado todavía, e incluso podría ser ⊥, pero de lo contrario es un valor concreto. En Haskell no se puede tomar una variable y solo indicar primero algunas propiedades de su valor.

Así que la coincidencia de patrones siempre significa que un concreto el valor se compara con un patrón que contiene algunas variables. El resultado de tal coincidencia es un fallo o una unión de las variables a valores concretos. En Haskell esto se restringe aún más para evitar la necesidad de una comparación general, lo que implicaría que la clase Eq se define para los términos que se comparan.

En Prolog, sin embargo, las variables pueden referirse a un conjunto de posibles soluciones. Las variables pueden ocurrir en cualquier lugar, también en algún lugar entre otros valores. La unificación ahora asegura que las igualdades declaradas todavía se mantienen y el resultado se representa de manera óptima, es decir, se calcula el unificador más general.


| ?- length(L,5).                      
L = [_,_,_,_,_]
| ?- length(L,5), maplist(=(E),L).
L = [E,E,E,E,E]

Así que Prolog no responde aquí con valores concretos como L = [1,1,1,1,1] o L = [[],[],[],[],[]] sino que da el unificador más general como una respuesta que contiene todos esos valores concretos.

 12
Author: false,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-26 10:28:22

Nadie mencionó la siguiente diferencia muy importante. La coincidencia de patrones en Prolog se intenta para cada cláusula de un predicado, incluso si una de las coincidencias anteriores ha tenido éxito (a menos que se interrumpa por un corte ). Pero en Haskell la coincidencia de patrones en las cláusulas solo se intenta hasta el primer éxito. No se prueban otras alternativas (a menos que la partida haya sido rechazada por un guardia ).

La coincidencia de patrones de Prolog establece una restricción de igualdad en sentido más general (ver respuesta por @false para más detalles). Compartir es explícito: A=B, A=5 también establece B=5. Esto es posible porque el logvar de Prolog puede estar en un estado todavía no establecido (es decir, sin fundamento). Esto hace que atar un nudo sea fácil (una técnica de programación básica en realidad, a saber. listas de diferencias ).

En Haskell, cualquier variable se puede definir solo una vez en el nivel de sintaxis . En Prolog un logvar es establecer solo una vez también (sans backtracking), pero se permite apuntar a una estructura incompleta (datos), donde los agujeros están representados por otros logvars aún no instanciados que se pueden establecer en cualquier momento posterior.

En Haskell, una estructura dada definida con recursión protegida se desarrolla progresivamente según lo exige el acceso. En Prolog, después de la instanciación inicial de una variable, cualquier unificación posterior se convierte en verificación de la compatibilidad y posible además (quizás parcial una vez más) instanciación ("llenar" los agujeros explícitamente).

 6
Author: Will Ness,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-20 16:11:24

Añadiendo a la respuesta de LeleDumbo, podríamos decir que Prolog unification construye términos así como los deconstruye, mientras que en Haskell la fase de compilación se exige convenientemente al valor devuelto.

Por supuesto, tal característica es lo que permite en Prolog puro los predicados llamados 'bidireccionales', explotados por ejemplo en DCGs, que con alguna restricción, pueden usarse tanto para analizar como para generar.

 5
Author: CapelliC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-20 07:42:39

Aquí hay un ejemplo que me parece interesante en Prolog para apoyar a @chac (+1 por cierto) mencionar sobre cómo la unificación de Prolog "construye" términos que encontramos en la etiqueta prolog ayer:

swapPairs([],       []).
swapPairs([X],      [X]).
swapPairs([X, Y|T], [Y, X|R]) :- swapPairs(T, R).

Este predicado casi no tiene "cuerpo". Solo usa la unificación de sus argumentos en su cabeza y la recursión.

Como señalan @chac y @LeleDumbo, eso es porque la unificación de Prolog es "en ambos sentidos".

Esto es lo que Una introducción suave a Haskell dice sobre it:

La coincidencia de patrones en Haskell es diferente de la que se encuentra en la lógica lenguajes de programación como Prolog; en particular, se puede ver como coincidencia "unidireccional" , mientras que Prolog permite la coincidencia "bidireccional" (a través de unificación), junto con el retroceso implícito en su evaluación mecanismo.

 5
Author: m09,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-20 09:12:39