En lógica y ciencias de la computación , específicamente en razonamiento automatizado , la unificación es un proceso algorítmico de resolución de ecuaciones entre expresiones simbólicas , cada una de las cuales tiene la forma Lado izquierdo = Lado derecho . Por ejemplo, utilizando x , y , z como variables y tomando f como una función no interpretada , el conjunto de ecuaciones singleton { f (1, y ) = f ( x ,2)} es un problema de unificación sintáctica de primer orden que tiene la sustitución { x ↦ 1, y ↦ 2} como su única solución.
Las convenciones difieren en cuanto a qué valores pueden asumir las variables y qué expresiones se consideran equivalentes. En la unificación sintáctica de primer orden, las variables abarcan términos de primer orden y la equivalencia es sintáctica. Esta versión de unificación tiene una única "mejor" respuesta y se utiliza en la programación lógica y en la implementación de sistemas de tipos de lenguajes de programación , especialmente en algoritmos de inferencia de tipos basados en Hindley-Milner . En la unificación de orden superior, posiblemente restringida a la unificación de patrones de orden superior , los términos pueden incluir expresiones lambda y la equivalencia depende de la reducción beta. Esta versión se utiliza en asistentes de prueba y programación lógica de orden superior, por ejemplo Isabelle , Twelf y lambdaProlog . Finalmente, en la unificación semántica o E-unificación, la igualdad está sujeta a conocimientos previos y las variables abarcan una variedad de dominios. Esta versión se utiliza en solucionadores SMT , algoritmos de reescritura de términos y análisis de protocolos criptográficos .
Un problema de unificación es un conjunto finito E ={ l 1 ≐ r 1 , ..., l n ≐ r n } de ecuaciones a resolver, donde l i , r i están en el conjunto de términos o expresiones . Dependiendo de qué expresiones o términos se permite que aparezcan en un conjunto de ecuaciones o problema de unificación, y qué expresiones se consideran iguales, se distinguen varios marcos de unificación. Si se permiten variables de orden superior, es decir, variables que representan funciones , en una expresión, el proceso se denomina unificación de orden superior , en caso contrario unificación de primer orden . Si se requiere una solución para hacer que ambos lados de cada ecuación sean literalmente iguales, el proceso se denomina unificación sintáctica o libre , en caso contrario unificación semántica o ecuacional , o E-unificación , o teoría de unificación módulo .
Si el lado derecho de cada ecuación es cerrado (sin variables libres), el problema se denomina coincidencia (de patrones) . El lado izquierdo (con variables) de cada ecuación se denomina coincidencia de patrones . [1]
Formalmente, un enfoque de unificación presupone
Como ejemplo de cómo el conjunto de términos y la teoría afectan al conjunto de soluciones, el problema de unificación sintáctica de primer orden { y = cons (2, y ) } no tiene solución sobre el conjunto de términos finitos . Sin embargo, tiene la única solución { y ↦ cons (2, cons (2, cons (2,...))) } sobre el conjunto de términos de árbol infinitos . De manera similar, el problema de unificación semántica de primer orden { a ⋅ x = x ⋅ a } tiene cada sustitución de la forma { x ↦ a ⋅...⋅ a } como solución en un semigrupo , es decir, si (⋅) se considera asociativo . Pero el mismo problema, visto en un grupo abeliano , donde (⋅) se considera también conmutativo , tiene cualquier sustitución como solución.
Como ejemplo de unificación de orden superior, el conjunto singleton { a = y ( x ) } es un problema de unificación sintáctica de segundo orden, ya que y es una variable de función. Una solución es { x ↦ a , y ↦ ( función identidad ) }; otra es { y ↦ ( función constante que asigna cada valor a a ), x ↦ ( cualquier valor ) }.
Una sustitución es una aplicación de variables a términos; la notación se refiere a una sustitución que asigna cada variable al término , para , y cada otra variable a sí misma; deben ser distintos por pares. La aplicación de esa sustitución a un término se escribe en notación de posfijo como ; significa (simultáneamente) reemplazar cada ocurrencia de cada variable en el término por . El resultado de aplicar una sustitución a un término se llama una instancia de ese término . Como un ejemplo de primer orden, aplicar la sustitución { x ↦ h ( a , y ), z ↦ b } al término
Si un término tiene una instancia equivalente a un término , es decir, si para alguna sustitución , entonces se dice que es más general que , y se dice que es más especial que, o está subsumido por, . Por ejemplo, es más general que si ⊕ es conmutativo , ya que entonces .
Si ≡ es identidad literal (sintáctica) de términos, un término puede ser más general y más especial que otro solo si ambos términos difieren solo en sus nombres de variable, no en su estructura sintáctica; tales términos se llaman variantes o renombramientos entre sí. Por ejemplo, es una variante de , ya que y Sin embargo, no es una variante de , ya que ninguna sustitución puede transformar el último término en el primero. El último término es, por lo tanto, propiamente más especial que el primero.
Para arbitrario , un término puede ser a la vez más general y más especial que un término estructuralmente diferente. Por ejemplo, si ⊕ es idempotente , es decir, si siempre , entonces el término es más general que , [nota 2] y viceversa, [nota 3] aunque y tengan una estructura diferente.
Una sustitución es más especial que, o está subsumida por, una sustitución si está subsumida por para cada término . También decimos que es más general que . De manera más formal, tomemos un conjunto infinito no vacío de variables auxiliares de modo que ninguna ecuación en el problema de unificación contenga variables de . Entonces, una sustitución está subsumida por otra sustitución si hay una sustitución tal que para todos los términos , . [2] Por ejemplo, está subsumida por , usando , pero no está subsumida por , ya que no es una instancia de . [3]
Una sustitución σ es una solución del problema de unificación E si l i σ ≡ r i σ para . Dicha sustitución también se denomina unificador de E . Por ejemplo, si ⊕ es asociativo , el problema de unificación { x ⊕ a ≐ a ⊕ x } tiene las soluciones { x ↦ a }, { x ↦ a ⊕ a }, { x ↦ a ⊕ a ⊕ a }, etc., mientras que el problema { x ⊕ a ≐ a } no tiene solución.
Para un problema de unificación dado E , un conjunto S de unificadores se denomina completo si cada sustitución de solución está subsumida por alguna sustitución en S . Siempre existe un conjunto de sustitución completo (por ejemplo, el conjunto de todas las soluciones), pero en algunos marcos (como la unificación de orden superior sin restricciones) el problema de determinar si existe alguna solución (es decir, si el conjunto de sustitución completo no está vacío) es indecidible.
El conjunto S se denomina mínimo si ninguno de sus miembros subsume a otro. Dependiendo del marco, un conjunto de sustitución completo y mínimo puede tener cero, uno, un número finito o infinito de miembros, o puede no existir en absoluto debido a una cadena infinita de miembros redundantes. [4] Por lo tanto, en general, los algoritmos de unificación calculan una aproximación finita del conjunto completo, que puede ser mínimo o no, aunque la mayoría de los algoritmos evitan los unificadores redundantes cuando es posible. [2] Para la unificación sintáctica de primer orden, Martelli y Montanari [5] dieron un algoritmo que informa la insolubilidad o calcula un único unificador que por sí mismo forma un conjunto de sustitución completo y mínimo, llamado el unificador más general .
La unificación sintáctica de términos de primer orden es el marco de unificación más ampliamente utilizado. Se basa en que T es el conjunto de términos de primer orden (sobre un conjunto dado V de variables, C de constantes y F n de símbolos de funciones n -arias) y en que ≡ es la igualdad sintáctica . En este marco, cada problema de unificación resoluble { l 1 ≐ r 1 , ..., l n ≐ r n } tiene un conjunto de soluciones singleton completo y obviamente mínimo { σ } . Su miembro σ se llama el unificador más general ( mgu ) del problema. Los términos en el lado izquierdo y derecho de cada ecuación potencial se vuelven sintácticamente iguales cuando se aplica el mgu, es decir, l 1 σ = r 1 σ ∧ ... ∧ l n σ = r n σ . Cualquier unificador del problema es subsumido [nota 4] por el mgu σ . La mgu es única hasta variantes: si S 1 y S 2 son ambos conjuntos de soluciones completas y mínimas del mismo problema de unificación sintáctica, entonces S 1 = { σ 1 } y S 2 = { σ 2 } para algunas sustituciones σ 1 y σ 2 , y xσ 1 es una variante de xσ 2 para cada variable x que aparece en el problema.
Por ejemplo, el problema de unificación { x ≐ z , y ≐ f ( x ) } tiene un unificador { x ↦ z , y ↦ f ( z ) }, porque
Este es también el unificador más general. Otros unificadores para el mismo problema son, por ejemplo, { x ↦ f ( x 1 ), y ↦ f ( f ( x 1 )), z ↦ f ( x 1 ) }, { x ↦ f ( f ( x 1 )), y ↦ f ( f ( f ( x 1 ))), z ↦ f ( f ( x 1 )) }, y así sucesivamente; hay infinitos unificadores similares.
Como otro ejemplo, el problema g ( x , x ) ≐ f ( y ) no tiene solución con respecto a que ≡ sea una identidad literal, ya que cualquier sustitución aplicada al lado izquierdo y derecho mantendrá los g y f más externos , respectivamente, y los términos con diferentes símbolos de función más externos son sintácticamente diferentes.
Los símbolos se ordenan de tal manera que las variables preceden a los símbolos de función. Los términos se ordenan de acuerdo con su longitud escrita creciente; los términos igualmente largos se ordenan lexicográficamente . [6] Para un conjunto T de términos, su camino de desacuerdo p es el camino lexicográficamente más pequeño en el que dos términos miembros de T difieren. Su conjunto de desacuerdo es el conjunto de subtérminos que comienzan en p , formalmente: { t | p : }. [7]
Algoritmo: [8]
Given a set T of terms to be unified
Let initially be the identity substitutiondo forever
if
is a singleton setthen
return
fi
let D be the disagreement set of
let s, t be the two lexicographically least terms in D
if
s is not a variableor
s occurs in tthen
return
"NONUNIFIABLE"
fi
done
Jacques Herbrand discutió los conceptos básicos de unificación y esbozó un algoritmo en 1930. [9] [10] [11] Pero la mayoría de los autores atribuyen el primer algoritmo de unificación a John Alan Robinson (cf. recuadro). [12] [13] [nota 5] El algoritmo de Robinson tenía un comportamiento exponencial en el peor de los casos tanto en el tiempo como en el espacio. [11] [15] Numerosos autores han propuesto algoritmos de unificación más eficientes. [16] Los algoritmos con comportamiento lineal en el peor de los casos fueron descubiertos independientemente por Martelli y Montanari (1976) y Paterson y Wegman (1976) [nota 6] Baader y Snyder (2001) utilizan una técnica similar a Paterson-Wegman, por lo tanto es lineal, [17] pero como la mayoría de los algoritmos de unificación en tiempo lineal es más lento que la versión de Robinson en entradas de tamaño pequeño debido a la sobrecarga de preprocesar las entradas y posprocesar la salida, como la construcción de una representación DAG . El algoritmo de de Champeaux (2022) también tiene una complejidad lineal en cuanto al tamaño de entrada, pero es competitivo con el algoritmo de Robinson en entradas de tamaño pequeño. La aceleración se obtiene mediante el uso de una representación orientada a objetos del cálculo de predicados que evita la necesidad de preprocesamiento y posprocesamiento, y en su lugar hace que los objetos variables sean responsables de crear una sustitución y de lidiar con el aliasing. De Champeaux afirma que la capacidad de agregar funcionalidad al cálculo de predicados representado como objetos programáticos también brinda oportunidades para optimizar otras operaciones lógicas. [15]
El siguiente algoritmo es de uso común y tiene su origen en Martelli y Montanari (1982). [nota 7] Dado un conjunto finito de ecuaciones potenciales, el algoritmo aplica reglas para transformarlo en un conjunto equivalente de ecuaciones de la forma { x 1 ≐ u 1 , ..., x m ≐ u m } donde x 1 , ..., x m son variables distintas y u 1 , ..., u m son términos que no contienen ninguna de las x i . Un conjunto de esta forma puede leerse como una sustitución. Si no hay solución, el algoritmo termina con ⊥; otros autores usan "Ω" o " fail " en ese caso. La operación de sustituir todas las ocurrencias de la variable x en el problema G con el término t se denota G { x ↦ t }. Para simplificar, los símbolos de constantes se consideran símbolos de función que tienen cero argumentos.
Un intento de unificar una variable x con un término que contenga a x como un subtérmino estricto x ≐ f (..., x , ...) conduciría a un término infinito como solución para x , ya que x aparecería como un subtérmino de sí mismo. En el conjunto de términos de primer orden (finitos) como se definió anteriormente, la ecuación x ≐ f (..., x , ...) no tiene solución; por lo tanto, la regla de eliminación solo se puede aplicar si x ∉ vars ( t ). Dado que esa verificación adicional, llamada happen check , ralentiza el algoritmo, se omite, por ejemplo, en la mayoría de los sistemas Prolog. Desde un punto de vista teórico, omitir la verificación equivale a resolver ecuaciones sobre árboles infinitos, consulte #Unificación de términos infinitos a continuación.
Para la prueba de terminación del algoritmo, considere una tripleta donde n var es el número de variables que ocurren más de una vez en el conjunto de ecuaciones, n lhs es el número de símbolos de función y constantes en los lados izquierdos de ecuaciones potenciales, y n eqn es el número de ecuaciones. Cuando se aplica la regla delete , n var disminuye, ya que x se elimina de G y se mantiene solo en { x ≐ t }. La aplicación de cualquier otra regla nunca puede aumentar n var nuevamente. Cuando se aplica la regla decompose , conflict o swap , n lhs disminuye, ya que al menos la f más externa del lado izquierdo desaparece. La aplicación de cualquiera de las reglas restantes delete o check no puede aumentar n lhs , pero disminuye n eqn . Por lo tanto, cualquier aplicación de regla disminuye la tripleta con respecto al orden lexicográfico , lo que es posible solo un número finito de veces.
Conor McBride observa [18] que "al expresar la estructura que explota la unificación" en un lenguaje de tipos dependientes como Epigram , el algoritmo de unificación de Robinson puede hacerse recursivo en el número de variables , en cuyo caso una prueba de terminación separada se vuelve innecesaria.
En la convención sintáctica de Prolog, un símbolo que comienza con una letra mayúscula es un nombre de variable; un símbolo que comienza con una letra minúscula es un símbolo de función; la coma se utiliza como operador lógico y . Para la notación matemática, x, y, z se utilizan como variables, f, g como símbolos de función y a, b como constantes.
El unificador más general de un problema de unificación sintáctica de primer orden de tamaño n puede tener un tamaño de 2 n . Por ejemplo, el problema tiene el unificador más general , véase la imagen. Para evitar la complejidad temporal exponencial causada por tal explosión, los algoritmos de unificación avanzados funcionan en gráficos acíclicos dirigidos (dags) en lugar de árboles. [19]
El concepto de unificación es una de las ideas principales detrás de la programación lógica . En concreto, la unificación es un elemento básico de la resolución , una regla de inferencia para determinar la satisfacibilidad de una fórmula. En Prolog , el símbolo de igualdad =
implica una unificación sintáctica de primer orden. Representa el mecanismo de vinculación de los contenidos de las variables y puede considerarse como una especie de asignación única.
En Prolog:
+
, -
, *
, /
, no se evalúan con =
. Por lo tanto, por ejemplo, 1+2 = 3
no es satisfacible porque son sintácticamente diferentes. El uso de restricciones aritméticas de números enteros #=
introduce una forma de E-unificación para la cual se interpretan y evalúan estas operaciones. [20]Los algoritmos de inferencia de tipos se basan normalmente en la unificación, en particular la inferencia de tipos Hindley-Milner , que utilizan los lenguajes funcionales Haskell y ML . Por ejemplo, al intentar inferir el tipo de la expresión Haskell True : ['x']
, el compilador utilizará el tipo a -> [a] -> [a]
de la función de construcción de listas (:)
, el tipo Bool
del primer argumento True
y el tipo [Char]
del segundo argumento ['x']
. La variable de tipo polimórfica a
se unificará con Bool
y el segundo argumento [a]
se unificará con [Char]
. a
no pueden ser ambos Bool
y Char
al mismo tiempo, por lo tanto, esta expresión no está tipificada correctamente.
Al igual que para Prolog, se puede proporcionar un algoritmo para la inferencia de tipos:
La unificación se ha utilizado en diferentes áreas de investigación de la lingüística computacional. [21] [22]
La lógica ordenada por orden permite asignar untipo a cada término y declarar un tipo s 1 como un subtipo de otro tipo s 2 , comúnmente escrito como s 1 ⊆ s 2 . Por ejemplo, cuando se razona sobre criaturas biológicas, es útil declarar que un tipo perro es un subtipo de un tipo animal . Siempre que se requieraun término de algún tipo s , se puede proporcionar en su lugar un término de cualquier subtipo de s . Por ejemplo, suponiendo una declaración de función mother : animal → animal , y una declaración de constante lassie : dog , el término mother ( lassie ) es perfectamente válido y tiene el tipo animal . Para proporcionar la información de que la madre de un perro es a su vez un perro, se puede emitir otra declaración mother : dog → dog ; esto se llama sobrecarga de funciones , similar a la sobrecarga en lenguajes de programación .
Walther dio un algoritmo de unificación para términos en lógica ordenada, requiriendo que para cualesquiera dos ordenaciones declaradas s 1 , s 2 su intersección s 1 ∩ s 2 también se declare: si x 1 y x 2 son variables de orden s 1 y s 2 , respectivamente, la ecuación x 1 ≐ x 2 tiene la solución { x 1 = x , x 2 = x }, donde x : s 1 ∩ s 2 . [23] Después de incorporar este algoritmo en un demostrador de teoremas automatizado basado en cláusulas, pudo resolver un problema de referencia traduciéndolo a lógica ordenada, reduciéndolo así a un orden de magnitud, ya que muchos predicados unarios se convirtieron en ordenaciones.
Smolka generalizó la lógica de ordenación ordenada para permitir el polimorfismo paramétrico . [24] En su marco, las declaraciones de subclasificación se propagan a expresiones de tipo complejas. Como ejemplo de programación, se puede declarar una lista de clasificación paramétrica ( X ) (siendo X un parámetro de tipo como en una plantilla de C++ ), y a partir de una declaración de subclasificación int ⊆ float se infiere automáticamente la relación list ( int ) ⊆ list ( float ), lo que significa que cada lista de números enteros es también una lista de números flotantes.
Schmidt-Schauß generalizó la lógica ordenada para permitir declaraciones de términos. [25] Como ejemplo, asumiendo declaraciones de subordenamiento even ⊆ int y odd ⊆ int , una declaración de término como ∀ i : int . ( i + i ) : even permite declarar una propiedad de la suma de números enteros que no podría expresarse mediante una sobrecarga ordinaria.
Antecedentes sobre los árboles infinitos:
Algoritmo de unificación, Prolog II:
Aplicaciones:
La E-unificación es el problema de encontrar soluciones a un conjunto dado de ecuaciones , teniendo en cuenta un cierto conocimiento ecuacional previo E. Este último se da como un conjunto de igualdades universales . Para algunos conjuntos particulares E , se han ideado algoritmos de resolución de ecuaciones (también conocidos como algoritmos de E-unificación ); para otros, se ha demostrado que no pueden existir tales algoritmos.
Por ejemplo, si a y b son constantes distintas, la ecuación no tiene solución con respecto a la unificación puramente sintáctica , donde no se sabe nada sobre el operador . Sin embargo, si se sabe que es conmutativo , entonces la sustitución { x ↦ b , y ↦ a } resuelve la ecuación anterior, ya que
El conocimiento previo E podría establecer la conmutatividad de mediante la igualdad universal " para todo u , v ".
Se dice que la unificación es decidible para una teoría si se ha ideado un algoritmo de unificación que termina para cualquier problema de entrada solucionable , pero que puede seguir buscando eternamente soluciones para un problema de entrada irresoluble.
La unificación es decidible para las siguientes teorías:
La unificación es semidecidible para las siguientes teorías:
Si hay un sistema de reescritura de términos convergentes R disponible para E , se puede utilizar el algoritmo de paramodulación unilateral [38] para enumerar todas las soluciones de las ecuaciones dadas.
Partiendo de que G es el problema de unificación a resolver y S es la sustitución de identidad, se aplican reglas de forma no determinista hasta que el conjunto vacío aparece como el G real , en cuyo caso el S real es una sustitución unificadora. Según el orden en que se aplican las reglas de paramodulación, la elección de la ecuación real de G y la elección de las reglas de R en mutate , son posibles diferentes caminos de cálculo. Solo algunos conducen a una solución, mientras que otros terminan en un G ≠ {} donde no se aplica ninguna otra regla (por ejemplo, G = { f (...) ≐ g (...) }).
Por ejemplo, se utiliza un sistema de reescritura de términos R que define el operador de adición de listas construidas a partir de cons y nil ; donde cons ( x , y ) se escribe en notación infija como x . y para abreviar; p. ej., app ( a . b . nil , c . d . nil ) → a . app ( b . nil , c . d . nil ) → a . b . app ( nil , c . d . nil ) → a . b . c . d . nil demuestra la concatenación de las listas a . b . nil y c . d . nil , empleando las reglas de reescritura 2,2 y 1. La teoría ecuacional E correspondiente a R es el cierre de congruencia de R , ambas vistas como relaciones binarias en términos. Por ejemplo, app ( a . b . nil , c . d . nil ) ≡ a . b . c . d . nil ≡ app ( a . b . c . d . nil , nil ). El algoritmo de paramodulación enumera soluciones a ecuaciones con respecto a esa E cuando se alimenta con el ejemplo R .
A continuación se muestra un ejemplo exitoso de ruta de cálculo para el problema de unificación { app ( x , app ( y , x )) ≐ a . a . nil }. Para evitar conflictos de nombres de variables, las reglas de reescritura se renombran consistentemente cada vez antes de su uso mediante la regla mutate ; v 2 , v 3 , ... son nombres de variables generados por computadora para este propósito. En cada línea, la ecuación elegida de G se resalta en rojo. Cada vez que se aplica la regla mutate , la regla de reescritura elegida ( 1 o 2 ) se indica entre paréntesis. Desde la última línea, se puede obtener la sustitución unificadora S = { y ↦ nil , x ↦ a . nil } . De hecho, app ( x , app ( y , x )) { y ↦ nil , x ↦ a . nil } = app ( a . nil , app ( nil , a . nil )) ≡ app ( a . nil , a . nil ) ≡ a . app ( nil , a . nil ) ≡ a . a . nil resuelve el problema dado. Una segunda ruta de cálculo exitosa, obtenible eligiendo "mutate(1), mutate(2), mutate(2), mutate(1)" conduce a la sustitución S = { y ↦ a . a . nil , x ↦ nil }; no se muestra aquí. Ninguna otra ruta conduce al éxito.
Si R es un sistema de reescritura de términos convergentes para E , una alternativa a la sección anterior consiste en la aplicación sucesiva de " pasos de reducción "; esto eventualmente enumerará todas las soluciones de una ecuación dada. Un paso de reducción (cf. figura) consiste en
Formalmente, si l → r es una copia renombrada de una regla de reescritura de R , que no tiene variables en común con un término s , y el subtérmino s | p no es una variable y es unificable con l a través del mgu σ , entonces s puede reducirse al término t = sσ [ rσ ] p , es decir al término sσ , con el subtérmino en p reemplazado por rσ . La situación en la que s puede reducirse a t se denota comúnmente como s ↝ t . Intuitivamente, una secuencia de pasos de estrechamiento t 1 ↝ t 2 ↝ ... ↝ t n puede considerarse como una secuencia de pasos de reescritura t 1 → t 2 → ... → t n , pero con el término inicial t 1 siendo instanciado cada vez más, según sea necesario para hacer aplicable cada una de las reglas utilizadas.
El cálculo de paramodulación del ejemplo anterior corresponde a la siguiente secuencia de estrechamiento ("↓" indica instanciación aquí):
El último término, v 2 . v 2 . nil se puede unificar sintácticamente con el término original del lado derecho a . a . nil .
El lema de estrechamiento [39] asegura que siempre que una instancia de un término s pueda reescribirse en un término t mediante un sistema de reescritura de términos convergente, entonces s y t pueden estrecharse y reescribirse en un término s ′ y t ′ , respectivamente, de modo que t ′ sea una instancia de s ′ .
Formalmente: siempre que sσ t se cumple para alguna sustitución σ, entonces existen términos s ′ , t ′ tales que s s ′ y t t ′ y s ′ τ = t ′ para alguna sustitución τ.
Muchas aplicaciones requieren que se considere la unificación de términos lambda tipados en lugar de términos de primer orden. Dicha unificación a menudo se denomina unificación de orden superior . La unificación de orden superior es indecidible , [40] [41] [42] y dichos problemas de unificación no tienen la mayoría de los unificadores generales. Por ejemplo, el problema de unificación { f ( a , b , a ) ≐ d ( b , a , c ) }, donde la única variable es f , tiene las soluciones { f ↦ λ x .λ y .λ z . d ( y , x , c ) }, { f ↦ λ x .λ y .λ z . d ( y , z , c ) }, { f ↦ λ x .λ y .λ z . d ( y , a , c ) }, { f ↦ λ x .λ y .λ z . d ( b , x , c ) }, { f ↦ λ x .λ y .λ z . d ( b , z , c ) } y { f ↦ λ x .λ y .λ z . d ( b , a , c ) }. Una rama bien estudiada de la unificación de orden superior es el problema de unificar términos lambda simplemente tipados módulo la igualdad determinada por las conversiones αβη. Gérard Huet dio un algoritmo de (pre-)unificación semidecidible [43] que permite una búsqueda sistemática del espacio de unificadores (generalizando el algoritmo de unificación de Martelli-Montanari [5] con reglas para términos que contienen variables de orden superior) que parece funcionar suficientemente bien en la práctica. Huet [44] y Gilles Dowek [45] han escrito artículos que analizan este tema.
Varios subconjuntos de unificación de orden superior se comportan bien, en el sentido de que son decidibles y tienen un unificador más general para problemas solucionables. Uno de estos subconjuntos son los términos de primer orden descritos anteriormente. La unificación de patrones de orden superior , debido a Dale Miller, [46] es otro de estos subconjuntos. Los lenguajes de programación lógica de orden superior λProlog y Twelf han pasado de la unificación de orden superior completa a implementar solo el fragmento de patrón; sorprendentemente, la unificación de patrones es suficiente para casi todos los programas, si cada problema de unificación que no sea de patrones se suspende hasta que una sustitución posterior coloque la unificación en el fragmento de patrón. Un superconjunto de unificación de patrones llamado unificación de funciones como constructores también se comporta bien. [47] El demostrador de teoremas Zipperposition tiene un algoritmo que integra estos subconjuntos de buen comportamiento en un algoritmo de unificación de orden superior completo. [2]
En lingüística computacional, una de las teorías más influyentes de la construcción de elipses es que las elipses se representan mediante variables libres cuyos valores se determinan luego mediante la unificación de orden superior. Por ejemplo, la representación semántica de "a Jon le gusta Mary y a Peter también" es like( j , m ) ∧ R( p ) y el valor de R (la representación semántica de la elipsis) se determina mediante la ecuación like( j , m ) = R( j ) . El proceso de resolver tales ecuaciones se denomina unificación de orden superior. [48]
Wayne Snyder dio una generalización tanto de la unificación de orden superior como de la E-unificación, es decir, un algoritmo para unificar términos lambda módulo una teoría ecuacional. [49]
{{cite book}}
: CS1 maint: multiple names: authors list (link)