En lógica e informática , la unificación es un proceso algorítmico de resolución de ecuaciones entre expresiones simbólicas .
Dependiendo de qué expresiones (también llamadas términos ) pueden ocurrir en un conjunto de ecuaciones (también llamado problema de unificación ), y qué expresiones se consideran iguales, se distinguen varios marcos de unificación. Si en una expresión se permiten variables de orden superior, es decir, variables que representan funciones , el proceso se denomina unificación de orden superior , de lo 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 llama unificación sintáctica o libre , de lo contrario unificación semántica o ecuacional , o unificación E, o teoría del módulo de unificación .
La solución de un problema de unificación se denota como una sustitución , es decir, un mapeo que asigna un valor simbólico a cada variable de las expresiones del problema. Un algoritmo de unificación debe calcular para un problema dado un conjunto de sustitución mínimo y completo , es decir, un conjunto que cubra todas sus soluciones y no contenga miembros redundantes. Dependiendo del marco, un conjunto de sustitución mínimo y completo puede tener como máximo uno, como mucho un número finito, o posiblemente un número infinito de miembros, o puede que no exista en absoluto. [nota 1] [1] En algunos marcos, generalmente es imposible decidir si existe alguna solución. Para la unificación sintáctica de primer orden, Martelli y Montanari [2]proporcionó un algoritmo que informa la insolubilidad o calcula un conjunto de sustitución de singleton mínimo y completo que contiene el llamado unificador más general .
Por ejemplo, usando x , y , z como variables, el conjunto de ecuaciones singleton { cons ( x , cons ( x , nil )) = cons (2, y )} es un problema de unificación sintáctica de primer orden que tiene la sustitución { x ↦ 2, y ↦ cons (2, nil )} como su única solución. 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 árboles infinitos . 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 una solución en un semigrupo , es decir, si (⋅) se considera asociativo ; el mismo problema, visto en un grupo abeliano , donde (⋅) se considera también conmutativo , tiene alguna sustitución como solución. 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 de identidad )}; otro es { y ↦ ( función constante que asigna cada valor a a ), x ↦ (cualquier valor) }.
Un algoritmo de unificación fue descubierto por primera vez por Jacques Herbrand , [3] [4] [5] mientras que una primera investigación formal puede atribuirse a John Alan Robinson , [6] [7] quien usó la unificación sintáctica de primer orden como un bloque de construcción básico de su procedimiento de resolución para la lógica de primer orden, un gran paso adelante en la tecnología de razonamiento automatizado , ya que eliminó una fuente de explosión combinatoria: la búsqueda de la instanciación de términos. Hoy en día, el razonamiento automatizado sigue siendo la principal área de aplicación de la unificación. La unificación sintáctica de primer orden se utiliza en la programación lógica y en el sistema de tipo de lenguaje de programación.implementación, especialmente en algoritmos de inferencia de tipos basados en Hindley-Milner . La unificación semántica se utiliza en solucionadores SMT , algoritmos de reescritura de términos y análisis de protocolos criptográficos . La unificación de orden superior se usa en asistentes de prueba, por ejemplo Isabelle y Twelf , y las formas restringidas de unificación de orden superior (unificación de patrones de orden superior ) se usan en algunas implementaciones de lenguaje de programación, como lambdaProlog , ya que los patrones de orden superior son expresivos , sin embargo, su procedimiento de unificación asociado conserva propiedades teóricas más cercanas a la unificación de primer orden.
Formalmente, un enfoque de unificación presupone
Dado un conjunto de símbolos variables, un conjunto de símbolos constantes y conjuntos de n símbolos de función aria, también llamados símbolos de operador, para cada número natural , el conjunto de términos (de primer orden sin clasificar) se define recursivamente como el conjunto más pequeño con las siguientes propiedades: [8]
Por ejemplo, si es un símbolo de variable, es un símbolo de constante y es un símbolo de función binaria, entonces , y (por lo tanto) por la regla de construcción del primer, segundo y tercer término, respectivamente. El último término generalmente se escribe como , usando notación infija y el símbolo de operador más común + por conveniencia.
Una sustitución es un mapeo de variables a términos; la notación se refiere a una sustitución que asigna cada variable al término , para y todas las demás variables a sí misma. La aplicación de esa sustitución a un término se escribe en notación de sufijo como ; significa reemplazar (simultáneamente) cada ocurrencia de cada variable en el término por . El resultado de aplicar una sustitución a un término se denomina instancia de ese término . Como ejemplo de primer orden, aplicando la sustitución { x ↦ h (a , y ), z ↦ b } al término
rendimientos | |||||
Si un término tiene una instancia equivalente a un término , es decir, si por alguna sustitución , a continuación, se llama más general que , y se llama más especial que, o subsumido por, . Por ejemplo, es más general que si ⊕ es conmutativo , desde entonces .
Si ≡ es una 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; estos términos se denominan 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 anterior. El último término es, por tanto, propiamente más especial que el anterior.
Por arbitrario , un término puede ser 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 3] y viceversa, [nota 4] aunque y son de estructura diferente.
Una sustitución es más especial que, o está subsumida por, una sustitución si es más especial que para cada término . También decimos que es más general que . Por ejemplo, es más especial que , pero no lo es, ya que no es más especial que . [9]
Un problema de la unificación es un conjunto finito { l 1 ≐ r 1 , ..., l n ≐ r n } de ecuaciones potenciales, donde l i , r i ∈ T . Una sustitución σ es una solución de ese problema si l i σ ≡ r i σ para . Tal sustitución también se llama unificador del problema de unificación. 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, un conjunto S de unificadores se llama completo si cada sustitución de solución está subsumida por alguna sustitución σ ∈ S ; el conjunto S se llama mínimo si ninguno de sus miembros subsume a otro.
La unificación sintáctica de términos de primer orden es el marco de unificación más utilizado. Se basa en que T es el conjunto de términos de primer orden (sobre algún conjunto V dado de variables, C de constantes y F n de n símbolos de función aria) y en que ≡ es 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 del lado izquierdo y derecho de cada ecuación potencial se vuelven sintácticamente iguales cuando se aplica mgu, es decir, l 1 σ = r 1 σ ∧ ... ∧ l n σ = r n σ . Cualquier unificador del problema es subsumido [nota 5] por mgu σ . El mgu es único hasta variantes: si S 1 y S 2son conjuntos de solución completa y mínima 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 ocurre en el problema.
Por ejemplo, el problema de unificación { x ≐ z , y ≐ f ( x )} tiene un unificador { x ↦ z , y ↦ f ( z )}, porque
X | { x ↦ z , y ↦ f ( z )} | = | z | = | z | { x ↦ z , y ↦ f ( z )} | , y |
y | { x ↦ z , y ↦ f ( z )} | = | f ( z ) | = | f ( x ) | { x ↦ z , y ↦ f ( z )} | . |
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))) }, etcétera; hay infinitos unificadores similares.
Como otro ejemplo, el problema g ( x , x ) ≐ f ( y ) no tiene solución con respecto a que ≡ sea identidad literal, ya que cualquier sustitución aplicada al lado izquierdo y derecho mantendrá las g y f más externas , respectivamente, y los términos con diferentes símbolos de función más externos son sintácticamente diferentes.
Los símbolos están ordenados de manera que las variables precedan a los símbolos de función. Los términos se ordenan aumentando la longitud del escrito; términos igualmente largos se ordenan lexicográficamente . [10] Para un conjunto T de términos, su camino de desacuerdo p es el camino lexicográficamente mínimo donde dos términos miembros de T difieren. Su conjunto de desacuerdo es el conjunto de subterráneos que comienzan en p , formalmente: { t | p : }. [11]
Algoritmo: [12]
Dado un conjunto T de términos a unificar Sea inicialmente la sustitución de identidad
hazlo para siempre si es un conjunto singleton, luego regresa fi
sea D el conjunto de desacuerdos de sean s , t los dos términos lexicográficamente mínimos en D
si s no es una variable o s aparece en t entonces devuelve "NO UNIFIABLE" fi hecho
El primer algoritmo dado por Robinson (1965) fue bastante ineficiente; cf. caja. El siguiente algoritmo más rápido se originó en Martelli, Montanari (1982). [nota 6] Este artículo también enumera los intentos anteriores de encontrar un algoritmo de unificación sintáctica eficiente, [13] [14] [15] [16] [17] [18] y afirma que los algoritmos de tiempo lineal fueron descubiertos de forma independiente por Martelli, Montanari (1976) [15] y Paterson, Wegman (1978). [16] [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 este formulario se puede leer como 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 apariciones de la variable x en el problema G con el término t se denota G { x ↦ t }. Para simplificar, los símbolos constantes se consideran símbolos de función que tienen cero argumentos.
Eliminar | ||||
descomponer | ||||
si o | conflicto | |||
intercambio | ||||
si y | eliminar [nota 8] | |||
si | cheque |
Un intento de unificar una variable x con un término que contiene x como un subtermo estricto x ≐ f (..., x , ...) conduciría a un término infinito como solución para x , ya que x ocurriría como un subtermo de sí mismo . En el conjunto de términos (finitos) de primer orden como se definió anteriormente, la ecuación x ≐ f (..., x , ...) no tiene solución; por lo tanto, la regla de eliminación solo puede aplicarse si x ∉ vars ( t ). Desde ese cheque adicional, llamado ocurre cheque, 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 en árboles infinitos, ver más abajo .
Para la prueba de terminación del algoritmo, considere un triple 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 el lado izquierdo de las ecuaciones potenciales, y n eqn es el número de ecuaciones. Cuando se aplica la regla eliminar , 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 volver a aumentar n var . Cuando la regla se descompone ,conflicto , o intercambio , n lhs disminuye, ya que al menos desaparece la f más externa del lado izquierdo . La aplicación de cualquiera de las reglas restantes, eliminar o marcar , no puede aumentar n lhs , pero disminuye n eqn . Por tanto, cualquier aplicación de reglas disminuye el triple con respecto al orden lexicográfico , lo que es posible sólo un número finito de veces.
Conor McBride observa [19] que "al expresar la estructura que explota la unificación" en un lenguaje de tipificación dependiente como Epigram , el algoritmo de Robinson puede volverse 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.
Notación de prólogo | Notación matemática | Sustitución unificadora | Explicación |
---|---|---|---|
a = a | { a = a } | {} | Tiene éxito. ( tautología ) |
a = b | { a = b } | ⊥ | una y b no coinciden |
X = X | { x = x } | {} | Tiene éxito. ( tautología ) |
a = X | { a = x } | { x ↦ a } | x se unifica con la constante a |
X = Y | { x = y } | { x ↦ y } | x y y son alias |
f(a,X) = f(a,b) | { f ( a , x ) = f ( a , b )} | { x ↦ b } | los símbolos de función y constante coinciden, x se unifica con la constante b |
f(a) = g(a) | { f ( a ) = g ( a )} | ⊥ | f y g no coinciden |
f(X) = f(Y) | { f ( x ) = f ( y )} | { x ↦ y } | x y y son alias |
f(X) = g(Y) | { f ( x ) = g ( y )} | ⊥ | f y g no coinciden |
f(X) = f(Y,Z) | { f ( x ) = f ( y , z )} | ⊥ | Fracasa. Los símbolos de la función f tienen diferente aridad |
f(g(X)) = f(Y) | { f ( g ( x )) = f ( y )} | { y ↦ g ( x )} | Unifica y con el término |
f(g(X),X) = f(Y,a) | { f ( g ( x ), x ) = f ( y , a )} | { x ↦ a , y ↦ g ( a )} | Unifica x con constante de un , y y con el término |
X = f(X) | { x = f ( x )} | debería ser ⊥ | Devuelve ⊥ en lógica de primer orden y muchos dialectos Prolog modernos (reforzado por la comprobación de ocurre ). Triunfa en Prolog tradicional y en Prolog II, unificando x con término infinito |
X = Y, Y = a | { x = y , y = a } | { x ↦ a , y ↦ a } | Tanto x como y están unificados con la constante a |
a = Y, X = Y | { a = y , x = y } | { x ↦ a , y ↦ a } | Como arriba (el orden de las ecuaciones en el conjunto no importa) |
X = a, b = X | { x = a , b = x } | ⊥ | Fracasa. una y b no coinciden, por lo que x no puede ser unificado con tanto |
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 , cf. fotografía. Para evitar la complejidad de tiempo exponencial causada por tal explosión, los algoritmos de unificación avanzados funcionan en gráficos acíclicos dirigidos (dags) en lugar de árboles. [20]
El concepto de unificación es una de las principales ideas detrás de la programación lógica , más conocida a través del lenguaje Prolog . Representa el mecanismo de vinculación del contenido de las variables y puede verse como una especie de asignación única. En Prolog, esta operación se indica con el símbolo de igualdad =
, pero también se realiza al crear instancias de variables (ver más abajo). También se utiliza en otros idiomas mediante el uso del símbolo de la igualdad =
, sino también en conjunción con muchas operaciones, incluyendo +
, -
, *
, /
. Los algoritmos de inferencia de tipos se basan normalmente en la unificación.
En Prolog:
La unificación se utiliza durante la inferencia de tipos, por ejemplo, en el lenguaje de programación funcional Haskell . Por un lado, el programador no necesita proporcionar información de tipo para cada función, por otro lado, se utiliza para detectar errores de escritura. La expresión de Haskell True : ['x', 'y', 'z']
no está escrita correctamente. La función de lista de construcción (:)
es de tipo a -> [a] -> [a]
, y para el primer argumento True
de la variable de tipo polimórfico a
tiene que ser unificado con True
el tipo 's, Bool
. El segundo argumento`` ['x', 'y', 'z']
es de tipo [Char]
, pero a
no puede ser ambos Bool
y Char
al mismo tiempo.
Al igual que para Prolog, se puede proporcionar un algoritmo para la inferencia de tipos:
Debido a su naturaleza declarativa, el orden en una secuencia de unificaciones no es (generalmente) importante.
Tenga en cuenta que en la terminología de la lógica de primer orden , un átomo es una proposición básica y está unificado de manera similar a un término Prólogo.
La lógica ordenada por orden permite asignar una ordenación o tipo a cada término y declarar una ordenación s 1 como un subgrupo de otra clase s 2 , comúnmente escrito como s 1 ⊆ s 2 . Por ejemplo, al razonar sobre criaturas biológicas, es útil declarar que un perro tipoes un subgrupo de un animal tipo. Siempre que sea un término de algún tipo s se requiere, un término de cualquier subclasificación de s puede ser suministrado en su lugar. Por ejemplo, asumiendo una declaración de función madre : animal →animal , y una declaración constante lassie : perro , el término madre ( lassie ) es perfectamente válido y tiene el género animal . Para proporcionar la información de que la madre de un perro es un perro a su vez, se puede emitir otra declaración madre : perro → perro ; esto se llama sobrecarga de funciones , similar a la sobrecarga en los lenguajes de programación .
Walther dio un algoritmo de unificación para términos en lógica ordenada por orden, requiriendo que dos géneros declarados cualesquiera s 1 , s 2 también se declaren su intersección s 1 ∩ s 2 : si x 1 y x 2 es una variable de género 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 . [21] Después de incorporar este algoritmo en un probador de teoremas automatizado basado en cláusulas, pudo resolver un problema de referencia traduciéndolo a lógica ordenada por orden, reduciéndolo a un orden de magnitud, ya que muchos predicados unarios se convirtieron en clases.
Smolka generalizó la lógica ordenada por orden para permitir el polimorfismo paramétrico . [22] En su marco, las declaraciones de subgrupos se propagan a expresiones de tipos complejos. Como ejemplo de programación, se puede declarar una lista de ordenación paramétrica ( X ) (siendo X un parámetro de tipo como en una plantilla de C ++ ), y desde una declaración de subgrupo int ⊆ float la lista de relaciones ( int ) ⊆ list ( float ) es automáticamente inferido, lo que significa que cada lista de enteros es también una lista de flotantes.
Schmidt-Schauß generalizó la lógica ordenada por orden para permitir declaraciones de términos.[23] Como ejemplo, asumiendo declaraciones de subtipo par ⊆ int e impar ⊆ int , una declaración de término como ∀ i : int . ( i + i ): incluso permite declarar una propiedad de suma de enteros que no podría expresarse mediante una sobrecarga ordinaria.
Antecedentes sobre árboles infinitos:
Algoritmo de unificación, Prolog II:
Aplicaciones:
E-unificación es el problema de encontrar soluciones a un determinado conjunto de ecuaciones , teniendo en cuenta un conocimiento básico ecuacional E . Este último se da como un conjunto de igualdades universales . Para algunos conjuntos E particulares , se han ideado algoritmos de resolución de ecuaciones (también conocidos como algoritmos de unificación E ); para otros, se ha demostrado que tales algoritmos no pueden existir.
Por ejemplo, si un y b son constantes distintas, la ecuación no tiene solución con respecto a puramente unificación sintáctica , donde no se sabe nada sobre el operador . Sin embargo, si se sabe que el es conmutativo , entonces la sustitución { x ↦ b , y ↦ a } resuelve la ecuación anterior, ya que
{ x ↦ b , y ↦ a } | |||
= | por solicitud de sustitución | ||
= | por conmutatividad de | ||
= | { x ↦ b , y ↦ a } | por (inversa) aplicación de sustitución |
El conocimiento de fondo E podría establecer la conmutatividad de por la igualdad universal " para todo u , v ".
∀ u , v , w : | = | A | Asociatividad de | ||
∀ u , v : | = | C | Conmutatividad de | ||
∀ u , v , w : | = | D l | Distributividad izquierda de más | ||
∀ u , v , w : | = | D r | Distributividad derecha de más | ||
∀ u : | = | tu | I | Idempotencia de | |
∀ u : | = | tu | N l | Elemento neutral izquierdo n con respecto a | |
∀ u : | = | tu | N r | Elemento neutro derecho n con respecto a |
Se dice que la unificación es decidible para una teoría, si se ha ideado un algoritmo de unificación para ella que termine con cualquier problema de entrada. Se dice que la unificación es semi-decidible para una teoría, si se ha ideado un algoritmo de unificación para ella que termina para cualquier problema de entrada resoluble , pero puede seguir buscando para siempre soluciones de un problema de entrada irresoluble.
La unificación es decidible por las siguientes teorías:
La unificación es semi-decidible para las siguientes teorías:
Si hay un sistema de reescritura de términos convergente R disponible para E , el algoritmo de paramodulación unilateral [36] puede usarse para enumerar todas las soluciones de ecuaciones dadas.
G ∪ { f ( s 1 , ..., s n ) ≐ f ( t 1 , ..., t n )} | ; S | ⇒ | G ∪ { s 1 ≐ t 1 , ..., s n ≐ t n } | ; S | descomponer | |
G ∪ { x ≐ t } | ; S | ⇒ | G { x ↦ t } | ; S { x ↦ t } ∪ { x ↦ t } | si la variable x no ocurre en t | eliminar |
G ∪ { f ( s 1 , ..., s n ) ≐ t } | ; S | ⇒ | G ∪ { s 1 ≐ u 1 , ..., s n ≐ u n , r ≐ t } | ; S | si f ( u 1 , ..., u n ) → r es una regla de R | mudar |
G ∪ { f ( s 1 , ..., s n ) ≐ y } | ; S | ⇒ | G ∪ { s 1 ≐ y 1 , ..., s n ≐ y n , y ≐ f ( y 1 , ..., y n )} | ; S | si y 1 , ..., y n son nuevas variables | imitar |
Comenzando con G como el problema de unificación a resolver y S como la sustitución de identidad, las reglas se aplican 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. Dependiendo del orden en que se apliquen las reglas de paramodulación, de la elección de la ecuación real de G , y de la elección de las reglas de R en mutado , 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 regla adicional (por ejemplo, G = { f (...) ≐ g(...)}).
1 | aplicación ( cero , z ) | → z |
2 | aplicación ( x . y , z ) | → x . aplicación ( y , z ) |
Por ejemplo, se utiliza un término sistema de reescritura 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 por brevedad; p . ej., aplicación ( a . b . nil , c . d . nil ) → a . aplicación ( b . nil , c . d . nil ) → a. b . aplicación ( nil , c . d . nil ) → una . b . c . d . nil demuestra la concatenación de las listas a . b . cero y c . d . cero , empleando la regla de reescritura 2,2 y 1. La teoría de la ecuación E correspondiente a R es el cierre de congruencia de R , ambas vistas como relaciones binarias en términos. Por ejemplo, app (a . b . cero , c . d . cero ) ≡ a . b . c . d . nil ≡ aplicación ( a . b . c . d . nil , nil ). El algoritmo paramodulation enumera soluciones a las ecuaciones con respecto a ese E cuando son alimentados con el ejemplo R .
Un ejemplo exitoso de ruta de cálculo para el problema de unificación { app ( x , app ( y , x )) ≐ a . a . nil } se muestra a continuación. Para evitar conflictos de nombres de variables, las reglas de reescritura se renombran constantemente cada vez antes de que las use la mutación de reglas ; 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 está resaltada en rojo. Cada vez que se aplica la regla de mutación , la regla de reescritura elegida ( 1 o 2) se indica entre paréntesis. Desde la última línea, la sustitución unificadora S = { y ↦ nil , x ↦ a . nil } se puede obtener. De hecho, app ( x , app ( y , x )) { y ↦ nil , x ↦ a . nil } = aplicación ( a . nil , aplicación ( nil , a . nil )) ≡ aplicación ( a. cero , a . cero ) ≡ a . aplicación ( cero , a . cero ) ≡ a . a . nil resuelve el problema dado. Una segunda ruta de cálculo exitosa, que se puede obtener eligiendo "mutar (1), mutar (2), mutar (2), mutar (1)" conduce a la sustitución S = { y ↦ a . a . nulo , x ↦ nulo }; no se muestra aquí. Ningún otro camino conduce al éxito.
Regla usada | GRAMO | S | |
---|---|---|---|
{ aplicación ( x , aplicación ( y , x )) ≐ a . a . nil } | {} | ||
mutar (2) | ⇒ | { x ≐ v 2 . v 3 , aplicación ( y , x ) ≐ v 4 , v 2 . aplicación ( v 3 , v 4 ) ≐ a . a . nil } | {} |
descomponer | ⇒ | { x ≐ v 2 . v 3 , aplicación ( y , x ) ≐ v 4 , v 2 ≐ a , aplicación ( v 3 , v 4 ) ≐ a . nil } | {} |
eliminar | ⇒ | { Aplicación ( y , v 2 . V 3 ) ≐ v 4 , v 2 ≐ una , aplicación ( v 3 , v 4 ) ≐ una . nil } | { x ↦ v 2 . v 3 } |
eliminar | ⇒ | { aplicación ( y , a . v 3 ) ≐ v 4 , aplicación ( v 3 , v 4 ) ≐ a . nil } | { x ↦ a . v 3 } |
mutar (1) | ⇒ | { y ≐ nil , a . v 3 ≐ v 5 , v 5 ≐ v 4 , app ( v 3 , v 4 ) ≐ a . nil } | { x ↦ a . v 3 } |
eliminar | ⇒ | { y ≐ nil , a . v 3 ≐ v 4 , aplicación ( v 3 , v 4 ) ≐ a . nil } | { x ↦ a . v 3 } |
eliminar | ⇒ | { a . v 3 ≐ v 4 , aplicación ( v 3 , v 4 ) ≐ a . nil } | { y ↦ cero , x ↦ a . v 3 } |
mutar (1) | ⇒ | { a . v 3 ≐ v 4 , v 3 ≐ nil , v 4 ≐ v 6 , v 6 ≐ una . nil } | { y ↦ cero , x ↦ a . v 3 } |
eliminar | ⇒ | { a . v 3 ≐ v 4 , v 3 ≐ nil , v 4 ≐ una . nil } | { y ↦ cero , x ↦ a . v 3 } |
eliminar | ⇒ | { a . nil ≐ v 4 , v 4 ≐ una . nil } | { y ↦ cero , x ↦ a . nil } |
eliminar | ⇒ | { a . nil ≐ a . nil } | { y ↦ cero , x ↦ a . nil } |
descomponer | ⇒ | { a ≐ a , nil ≐ nil } | { y ↦ cero , x ↦ a . nil } |
descomponer | ⇒ | { nil ≐ nil } | { y ↦ cero , x ↦ a . nil } |
descomponer | ⇒ | {} | { y ↦ cero , x ↦ a . nil } |
Si R es un sistema de reescritura de términos convergente para E , un enfoque alternativo a la sección anterior consiste en la aplicación sucesiva de " pasos de estrechamiento "; esto eventualmente enumerará todas las soluciones de una ecuación dada. Un paso de estrechamiento (ver imagen) 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 subtermo s | p no es una variable y es unificables con l a través de la MGU σ , entonces s se puede estrechan con el término t = sσ [ rσ ] p , es decir con el término sσ , con el subtérmino en p sustituye por rσ . La situación que sse puede reducir a t se denota comúnmente como s ↝ t . Intuitivamente, una secuencia de pasos de reducción t 1 ↝ t 2 ↝ ... ↝ t n se puede considerar como una secuencia de pasos de reescritura t 1 → t 2 → ... → t n , pero con el término inicial t 1 siendo más y más instanciado, según sea necesario para que cada una de las reglas utilizadas sean aplicables.
El cálculo de paramodulación del ejemplo anterior corresponde a la siguiente secuencia de estrechamiento ("↓" indica instanciación aquí):
aplicación ( | X | , aplicación ( y , | X | )) | |||||||||||||
↓ | ↓ | x ↦ v 2 . v 3 | |||||||||||||||
aplicación ( | v 2 . v 3 | , aplicación ( y , | v 2 . v 3 | )) | → | v 2 . aplicación ( v 3 , aplicación ( | y | , v 2 . v 3 )) | |||||||||
↓ | y ↦ nada | ||||||||||||||||
v 2 . aplicación ( v 3 , aplicación ( | nulo | , v 2 . v 3 )) | → | v 2 . aplicación ( | v 3 | , v 2 . | v 3 | ) | |||||||||
↓ | ↓ | v 3 ↦ nada | |||||||||||||||
v 2 . aplicación ( | nulo | , v 2 . | nulo | ) | → | v 2 . v 2 . nulo |
El último término, v 2 . v 2 . nil se puede unificar sintácticamente con el término original del lado derecho a . a . cero .
El lema de estrechamiento [37] asegura que siempre que una instancia de un término s se pueda reescribir en un término t mediante un sistema de reescritura de términos convergente, entonces s y t se puedan estrechar y reescribir en un término s ′ y t ′ , respectivamente, tal que t ′ es 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 uno considere la unificación de términos lambda escritos en lugar de términos de primer orden. Tal unificación a menudo se llama unificación de orden superior . Una rama bien estudiada de la unificación de orden superior es el problema de unificar términos lambda simplemente tipados en módulo la igualdad determinada por las conversiones αβη. Tales problemas de unificación no tienen la mayoría de los unificadores generales. Mientras que de orden superior unificación es indecidible , [38] [39] [40] Gérard Huet dio un semi-decidable algoritmo de unificación (pre-) [41] que permite una búsqueda sistemática del espacio de unificadores (generalizar el algoritmo de unificación de Martelli -Montanari [2]con reglas para términos que contienen variables de orden superior) que parece funcionar suficientemente bien en la práctica. Huet [42] y Gilles Dowek [43] han escrito artículos sobre este tema.
Dale Miller ha descrito lo que ahora se llama unificación de patrones de orden superior . [44] Este subconjunto de unificación de orden superior es decidible y los problemas de unificación que se pueden resolver tienen unificadores más generales. Muchos sistemas informáticos que contienen unificación de orden superior, como los lenguajes de programación lógica de orden superior λProlog y Twelf , a menudo implementan solo el fragmento de patrón y no la unificación completa de orden superior.
En lingüística computacional, una de las teorías de elipsis más influyentes es que las elipses están representadas por variables libres cuyos valores se determinan luego mediante la unificación de orden superior (HOU). Por ejemplo, la representación semántica de "A Jon le gusta Mary y a Peter también" es como ( j , m ) ∧ R ( p ) y el valor de R (la representación semántica de la elipsis) está determinado por la ecuación como ( j , m ) = R ( j ) . El proceso de resolución de estas ecuaciones se llama unificación de orden superior. [45]
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 ( segundo , x , c )}, { f ↦ λ x .λ y .λ z . d ( b , z , c )} y { f ↦ λ x .λ y .λ z . d ( b, a , c )}.
Wayne Snyder dio una generalización tanto de la unificación de orden superior como de la unificación E, es decir, un algoritmo para unificar términos lambda módulo una teoría de ecuaciones. [46]