Unification
En informatique et en logique, l'unification est un processus algorithmique qui, étant donnés deux termes, trouve une substitution qui appliquée aux deux termes les rend identiques[1]. Par exemple, et peuvent être rendus identiques par la substitution et , qui donne quand on l'applique à chacun de ces termes le terme . Dit autrement, l'unification est la résolution d'une équation dans l'algèbre des termes (unification syntaxique) ou dans une algèbre quotient par un ensemble d'identités (unification modulo une théorie) ; la solution de l'équation est la substitution qui rend les deux termes identiques et que l'on appelle l'unificateur. L'unification a des applications en inférence de types, programmation logique, en démonstration automatique de théorèmes, en système de réécriture, en traitement du langage naturel[1].
Souvent, on s'intéresse à l'unification syntaxique où il faut que les termes obtenus par application de l'unificateur soient syntaxiquement égaux, comme dans l'exemple ci-dessus. Par exemple, le problème d'unification syntaxique ayant pour données et n'a pas de solution[2]. Le filtrage par motif (ou pattern matching) est une restriction de l'unification où l'unificateur n'est appliquée qu'à un seul des deux termes. Par exemple, et sont rendus égaux par la substitution .
La fin de l'article présente aussi l'unification modulo une théorie, qui est le cas où on dispose de connaissances supplémentaires sur les fonctions (par exemple, est commutatif).
Histoire
modifierInvention de la notion d'unification
modifierLe premier chercheur à évoquer un algorithme d'unification est Jacques Herbrand dans sa thèse en 1930[3]. Il s'agit d'un algorithme non-déterministe pour unifier deux termes. Herbrand était intéressé par la résolution d'équations. En 1960, Prawitz et Voghera[4] ont généralisé le calcul propositionnel à des formules du premier ordre non instanciées, ou tout au moins en les instanciant a minima. L'unification a ensuite été redécouverte en 1963, mais l'article qui la décrit est publié seulement en 1965, par John Alan Robinson[5],[6] dans le cadre de sa méthode de résolution en démonstration automatique. Selon Baader et Snyder[7], c'est Knuth et Bendix[8],[9], en 1970, qui ont introduit le concept de "substitution la plus générale" dans leur travail sur la confluence locale d'un système de réécriture. Un an avant la publication de l'article de Robinson, soit en 1964, Guard a indépendamment étudié le problème d'unification sous le nom de matching[10].
Course vers l'efficacité
modifierL'algorithme originel de Robinson est inefficace car il s'exécute en temps exponentiel et demande une quantité de mémoire exponentielle. Robinson écrit alors une note en 1971 où il exhibe une représentation des termes plus concise[11]. L'algorithme utilise alors un espace mémoire polynomial. Boyer et Moore donnent aussi un algorithme qui utilise un espace mémoire polynomial en temps exponentiel dans le pire cas[12]. Venturini-Zilli introduit un système de marquage pour que l'algorithme de Robinson s'exécute en temps quadratique, dans le pire cas, en la taille des termes[13]. Huet travaille sur l'unification d'ordre supérieur et améliore le temps d'exécution de l'algorithme syntaxique du premier ordre : son algorithme est quasi linéaire[14]. D'autres chercheurs ont exhibé des algorithmes quasi linéaires[15],[16],[17].
Une étape importante est ensuite la découverte d'algorithmes linéaires en 1976 par Martelli et Montanari[18], Paterson et Wegman[19],[20] et Huet[réf. nécessaire]. Comme les articles de Paterson et Wegman sont courts, Dennis de Champeaux a réexpliqué l'idée de l'algorithme en 1986[20].
En 1982, Martelli et Montanari présentent un algorithme presque-linéaire mais plus efficace en pratique[21].
En 1984, Dwork et al. démontrent que l'unification est P-complet[22], ce qui signifie qu'a priori l'unification est difficile à paralléliser. Par opposition, le problème de filtrage par motif (pattern matching) est dans NC[22], c'est-à-dire facile à paralléliser.
Prolog a aussi beaucoup contribué à sa popularisation[évasif]. Des algorithmes spécifiques pour les termes de certaines théories, appelés aussi unification équationnelle (en particulier associative et commutative par Stickel) ont été proposés (voir ci-dessus).
Description
modifierProblèmes d'unification
modifierUn problème d'unification peut être présenté comme la donnée de deux termes, ou alors comme une équation, ou alors comme un ensemble de termes à unifier, ou alors comme un ensemble de couples de termes, ou alors comme un ensemble d'équations. Le problème d'unification a une solution car substituer (i.e. remplacer) le terme à la variable et le terme à la variable , dans les deux termes et donne le même terme . En revanche, le problème d'unification n'a pas de solution et le problème d'unification non plus.
Solution principale
modifierUn problème d'unification peut avoir une infinité de solutions. Par exemple, a une infinité de solutions : , , , etc. De toutes ces solutions, on exhibe des solutions dites principales car elles permettent de construire toutes les autres solutions : c'est le concept de solution principale, ou unificateur le plus général (most general unifier, mgu).
Tout d'abord, une solution d'un problème d'unification est dite plus générale qu'une solution , si est obtenue en substituant des termes à des variables dans . Par exemple, si on considère le problème d'unification , alors la solution est plus générale que la solution qui est obtenue en substituant le terme à la variable dans . De même, la solution est plus générale que la solution , qui est obtenue en substituant le terme à la variable dans la solution .
Une solution d'un problème d'unification est dite principale si elle est plus générale que toutes les solutions de ce problème, c'est-à-dire si toute solution est obtenue en substituant des termes à des variables dans . Dans cet exemple, la solution est une solution principale du problème .
Le théorème de la solution principale exprime que si un problème d'unification a une solution, alors il a une solution principale. Un algorithme d'unification calcule une solution principale ou échoue si les termes ne sont pas unifiables.
Exemples
modifierLa table suivante donne des exemples de problèmes d'unification. En plus, nous donnons aussi, dans la colonne de gauche, les exemples avec la syntaxe de Prolog : une variable commence par une majuscule, les constantes et symboles de fonction commencent par une minuscule. Pour les notations mathématiques, x,y,z sont des variables, , f,g sont des symboles de fonction et a,b sont des constantes.
Notation Prolog | Notation mathématique | Solution (principale) | Explication |
---|---|---|---|
a = a
|
{ a = a } | {} | L'unification réussit car nous avons le même symbole de constante a de part et d'autre de l'égalité. |
a = b
|
{ a = b } | échoue | L'unification échoue. En effet, a et b sont des symboles de constantes différents Donc il est impossible de rendre les deux termes de part et d'autre de l'égalité syntaxiquement égaux. |
X = X
|
{ x = x } | {} | L'unification réussit car nous avons la même variable de part et d'autre de l'égalité. |
a = X
|
{ a = x } | { x ↦ a } | La variable x est unifié avec la constante a. |
X = Y
|
{ x = y } | { x ↦ y } | La variable x est unifié avec y. |
f(a,X) = f(a,b)
|
{ f(a,x) = f(a,b) } | { x ↦ b } | Les symboles de fonction sont les mêmes. x est unifié avec la constante b |
f(a) = g(a)
|
{ f(a) = g(a) } | échoue | f et g sont des symboles de fonction différents. On ne peut donc pas rendre les deux termes syntaxiquement égaux. |
f(X) = f(Y)
|
{ f(x) = f(y) } | { x ↦ y } | x est unifié avec y |
f(X) = g(Y)
|
{ f(x) = g(y) } | échoue | f et g sont des symboles de fonction différents |
f(X) = f(Y,Z)
|
{ f(x) = f(y,z) } | échoue | Le symbole de fonction f est d'arité 1 dans la partie gauche et d'arité 2 dans la partie droite. |
f(g(X)) = f(Y)
|
{ f(g(x)) = f(y) } | { y ↦ g(x) } | y est unifié avec g(x) |
f(g(X),X) = f(Y,a)
|
{ f(g(x),x) = f(y,a) } | { x ↦ a, y ↦ g(a) } | x est unifié avec la constante a, et y est unifié avec g(a) |
X = f(X)
|
{ x = f(x) } | échoue | échoue car x apparaît dans f(x). Le test d'appartenance de x dans le terme droit f(x) s'appelle occur check. Il existe des implémentations de Prolog où il n'y a pas d'occur check. Pour ces dernières, on unifie x avec le terme infini x=f(f(f(f(...)))) .
|
X = Y, Y = a
|
{ x = y, y = a } | { x ↦ a, y ↦ a } | x et y sont unifiés avec la constante a |
a = Y, X = Y
|
{ a = y, x = y } | { x ↦ a, y ↦ a } | x et y sont unifiés avec la constante a |
X = a, b = X
|
{ x = a, b = x } | échoue | a et b sont des symboles de constantes différents. x ne peut s'unifier avec les deux à la fois. |
Applications
modifierFiltrage par motif dans les langages de programmation
modifierLe filtrage par motif est la restriction de l'unification dans laquelle, dans chaque équation, les variables n'apparaissent que dans le terme de gauche. Par exemple, le problème est un problème de filtrage, car le terme ne contient pas de variables. Le filtrage est utilisé dans les langages fonctionnels comme Haskell, Caml, LISP.
Dans le cas du filtrage, l'algorithme de Martelli et Montanari se simplifie.
On choisit une équation dans le système.
Si cette équation a la forme
on la remplace par les équations , ..., et on résout le système obtenu.
Si cette équation a la forme
où et sont des symboles différents, on échoue.
Si cette équation a la forme
on substitue le terme à la variable dans le reste du système, on résout le système obtenu, ce qui donne une solution et on retourne la solution .
Programmation logique
modifierL'unification est ce qui distingue le plus le langage de programmation Prolog des autres langages de programmation.
En Prolog, l’unification est associée au symbole « = » et ses règles sont les suivantes :
- une variable X non-instanciée (c'est-à-dire ne possédant pas encore de valeur) peut être unifiée avec une autre variable (instanciée ou pas); les deux variables deviennent alors simplement des synonymes l'une de l'autre et représenteront dorénavant le même objet (ou la même structure) ;
- une variable X non-instanciée peut être unifiée avec un terme ou un atome et représentera dorénavant ce terme ou atome ;
- un atome peut être unifié seulement avec lui-même ;
- un terme peut être unifié avec un autre terme : si leurs noms[Quoi ?] sont identiques, si leur nombres d'arguments sont identiques et si chacun des arguments du premier terme est unifiable avec l'argument correspondant du second terme.
En raison de sa nature déclarative, l'ordre dans une suite d'unifications ne joue aucun rôle.
Algorithmes
modifierAlgorithme de Robinson
modifierL'algorithme de Robinson de 1965 a été reformulé, par Corbin et Bidoit en 1983 [23], puis amélioré par Ruzicka et Prívara en 1989[24], puis repris par Melvin Fitting en 1990 comme un algorithme non-déterministe[25], présentation également reprise par Apt en 1996[26]. Nous présentons cette version également. L'algorithme prend en entrée deux termes t1 et t2 à unifier, donnés sous la forme de deux arbres. Il repose sur la notion de disagreement pair qui est la donnée d'un sous-terme de t1 et d'un sous-terme de t2, dont les nœuds dans les arbres de t1 et t2 sont à la même position depuis les racines mais avec des étiquettes différentes. Une telle disagreement pair est simple si l'un des sous-termes est une variable qui n'apparaît pas dans l'autre sous-terme. L'algorithme calcule une substitution, initialement vide. L'algorithme continue tant que la substitution ne rend pas les deux termes égaux. Il choisit de façon non-déterministe un disagreement pair. S'il n'est pas simple, l'algorithme échoue. Sinon, il enrichit la substitution.
entrée : deux termes t1, t2 sortie : vrai si les termes sont unifiables, non sinon fonction unifier(t1, t2) σ := id tant que σ(t1) différent de σ(t2) choisir une disagreement pair (w, u) si (w, u) est simple soit γ la substitution donnée par (w, u) σ := σγ sinon retourner faux; retourner vrai
Algorithme de Martelli et Montanari
modifierEn 1982, Martelli et Montanari décrivent un algorithme sous la forme d'un ensemble de règles qui transforment un ensemble d'équations[21]. L'algorithme est présenté dans des ouvrages pédagogiques[27],[28],[29]. Il est similaire à l'algorithme proposé par Herbrand dans sa thèse[30]. Selon Baader et Snyder[31], un algorithme sous la forme d'un ensemble de règles dégage les concepts essentiels et permet de démontrer la correction de plusieurs algorithmes pratiques en même temps.
On se donne un ensemble fini d'équations G = { s1 ≐ t1, ..., sn ≐ tn } où les si et ti sont des termes du premier ordre. L'objectif est de calculer une substitution la plus générale. On applique alors les règles suivantes à l'ensemble G jusqu'à épuisement :
G ∪ { t ≐ t } | ⇒ | G | supprimer | |
G ∪ { f(s1,...,sk) ≐ f(t1,...,tk) } | ⇒ | G ∪ { s1 ≐ t1, ..., sk ≐ tk } | décomposer | |
G ∪ { f(t⃗) ≐ x } | ⇒ | G ∪ { x ≐ f(t⃗) } | échanger | |
G ∪ { x ≐ t } | ⇒ | G{x↦t} ∪ { x ≐ t } | si x ∉ vars(t) et x ∈ vars(G) | éliminer |
La règle supprimer supprime une équation t ≐ t, c'est-à-dire où les termes de la partie gauche et de la partie droite sont les mêmes. La règle décomposer supprime une équation de la forme f(s1,...,sk) ≐ f(t1,...,tk) et la remplace par les équations s1 ≐ t1, ..., sk ≐ tk. La règle échanger oriente les équations pour que la variable x soit en partie gauche. En présence d'une équation x ≐ t où la variable x n'apparaît pas dans le terme t, la règle éliminer remplace les occurrences de x par t dans les autres équations.
Les règles suivantes sont également ajoutées en guise d'optimisation[29] :
G ∪ { f(s⃗) ≐ g(t⃗) } | ⇒ | ⊥ | si f ≠ g or k ≠ m | conflit |
G ∪ { x ≐ f(s⃗) } | ⇒ | ⊥ | si x ∈ vars(f(s⃗)) | vérifier (occurs-check) |
Si l'ensemble contient une équation de la forme f(s⃗) ≐ g(t⃗) où f et g ne sont pas les mêmes symboles de fonctions ou alors si les nombres d'arguments ne sont pas les mêmes (k ≠ m) la règle conflit fait échouer le processus d'unification. La règle vérifier (occurs-check), quant à elle, fait échouer l'unification si l'ensemble contient une équation x ≐ f(s⃗) où x apparaît dans f(s⃗).
L'algorithme est en temps exponentiel et demande un espace mémoire au plus exponentiel si l'on représente les termes par leurs arbres syntaxiques. Néanmoins, on peut n'utiliser qu'un espace mémoire linéaire si on représente les termes par des graphes.
Améliorations de l'algorithme de Robinson
modifierImplémentation avec des graphes
modifierEn implémentant l'algorithme avec des graphes, l'espace mémoire est linéaire en la taille de l'entrée même si le temps reste exponentiel dans le pire des cas. L'algorithme prend en entrée deux termes sous la forme de graphes, c'est-à-dire un graphe acyclique où les nœuds sont les sous-termes. En particulier, il y a un unique nœud par variables (cf. figure à droite). L'algorithme retourne en sortie une substitution la plus générale : elle est écrite en place dans le graphe représentant les termes à l'aide de pointeurs (en bleu dans la figure à droite). c'est-à-dire, en plus du graphe décrivant la structure des termes (qui sont des pointeurs aussi), nous avons des pointeurs particuliers pour représenter la substitution. Par exemple si x := h(1) est la substitution courante, x pointe vers le nœud correspondant au terme h(1).
entrée : deux termes t1, t2 sortie : vrai si les termes sont unifiables, non sinon fonction unifier(t1, t2) t1 = find(t1); t2 = find(t2); si t1 = t2 retourner vrai; sinon etude de cas sur (t1, t2) (x, y): faire pointer x vers y retourner vrai; (x, t) ou (t, x): si x apparaît dans t retourner faux sinon faire pointer x vers t retourner vrai; (f(L), g(M)): si f = g retourner unifierlistes(L, M) sinon retourner faux
où unifierListes unifient les termes de deux listes :
entrée : deux listes de termes L, M sortie : vrai si les termes des listes sont deux à deux sont unifiables, non sinon fonction unifierlistes(L, M) etude de cas sur (L, M) ([], []): retourner vrai; ([], t::t') ou (t::t', []): retourner faux; (s::L', t::M'): si unifier(s, t) retourner unifierlistes(L', M') sinon retourner faux
où find trouve la fin d'une chaîne :
entrée : un terme t sortie : le terme en bout de chaîne de t fonction find(t) si t n'est pas une variable retourner t sinon si t est déjà assigné à un terme u retourner find(u) sinon retourner t
et où une implémentation naïve de "x apparaît dans t" est donné par :
entrée : une variable x et un terme t sortie : vrai si la variable x apparaît dans le terme t, non sinon fonction apparaîtdans(x, t) etude de cas sur t y: retourner x = y f(L): retourner apparaîtdansliste(x, L) entrée : une variable x et une liste de termes L sortie : vrai si la variable x apparaît dans l'un des termes de L, non sinon fonction apparaîtdansliste(x, L) etude de cas sur L []: retourner faux t::L': si apparaîtdans(x, find(t)) retourner vrai sinon retourner apparaîtdansliste(x, L')
Algorithme quadratique
modifierL'algorithme présenté dans cette sous-section est dû à Corbin et Bidoit (1983)[32]. Pour avoir une complexité quadratique, il y a deux améliorations de l'algorithme précédent.
Tester qu'une variable apparaît dans un sous-terme
modifierL'implémentation pour tester si une variable x apparaît dans un sous-terme t est a priori en temps exponentiel. L'idée est d'éviter de parcourir plusieurs fois les mêmes nœuds. On marque les nœuds visités comme dans un parcours en profondeur de graphe. Une fois un test d'appartenance effectué, il faut a priori démarquer les nœuds. Au lieu de cela, on les marque avec le "temps actuel". On ajoute alors un champ aux nœuds du graphe que l'on appelle poinçon qui contient le "temps actuel". Nous disposons d'une variable globale "temps actuel" qui est incrémenté à chaque test d'appartenance.
entrée : une variable x et un terme t sortie : vrai si la variable x apparaît dans le terme t, non sinon fonction apparaîtdans(x, t) temps actuel := temps actuel + 1 retourner apparaîtdans'(x, t) entrée : une variable x et un terme t sortie : vrai si la variable x apparaît dans le terme t, non sinon (ne change pas le temps) fonction apparaîtdans'(x, t) etude de cas sur t y: retourner x = y f(s): si f(s) est poinçonné au temps actuel retourner faux sinon poinçonner f(s) au temps actuel retourner apparaîtdansliste(x, s) entrée : une variable x et une liste de termes L sortie : vrai si la variable x apparaît dans l'un des termes de t, non sinon fonction apparaîtdansliste(x, L) etude de cas sur t []: retourner faux t::L': si apparaîtdans'(x, find(t)) retourner vrai sinon retourner apparaîtdansliste(x, L')
Éviter des appels inutiles à unifier
modifierPour éviter des appels inutiles à la procédure qui cherche à unifier deux termes, on utilise des pointeurs pour tous les nœuds et pas seulement les variables. On peut montrer que le nombre d'appels à la procédure qui unifie est O(|A|) où |A| est le nombre d'arcs dans le graphe. Le traitement interne utilise un parcours de pointeurs "find" en O(|S|) où |S| est le nombre de sommets et un test d'appartenance d'une variable dans un terme qui est en O(|S|+|A|) = O(|A|) car le graphe est connexe. Donc l'algorithme est bien quadratique.
entrée : un terme t sortie : le terme en bout de chaîne de t fonction find(t) si t pointe vers un terme u retourner find(u) sinon retourner t
et
entrée : deux termes t1, t2
sortie : vrai si les termes sont unifiables, non sinon
fonction unifier(t1, t2)
t1 = find(t1);
t2 = find(t2);
si t1 = t2
retourner vrai;
sinon etude de cas sur (t1, t2)
(x, y):
faire pointer x vers y
retourner vrai;
(x, t) ou (t, x):
si x apparaît dans t
retourner faux
sinon
faire pointer x vers t
retourner vrai;
(f(L), g(M)):
si f = g
faire pointer f(L) vers g(M)
retourner unifierlistes(L, M)
sinon
retourner faux
Algorithme quasi linéaire
modifierL'algorithme[29] est inspiré de l'algorithme quadratique de la section précédente. Le test de savoir si x apparaît dans t n'est plus effectué au cours de l'algorithme mais uniquement à la fin : à la fin, on vérifie que le graphe est acyclique. Enfin, les pointeurs de la substitution et "find" sont implémentés à l'aide d'une structure de données Union-find. Plus précisément, on conserve les pointeurs dans la structure mais on dispose en plus une structure annexe Union-find. Dans la structure de données Union-find, les classes d'équivalence ne contiennent soit que des variables soit que des termes complexes. Pour passer d'une variable à un terme complexe, on utilise les pointeurs éventuels qui sont dans le graphe.
entrée : deux termes t1, t2 sortie : vrai si les termes sont unifiables ou que le graphe final est acyclique, non sinon fonction unifier(t1, t2) t1 = find(t1); t2 = find(t2); si t1 = t2 retourner vrai; sinon etude de cas sur (t1, t2) (x, y): Union(x, y) retourner vrai; (x, t) ou (t, x): si x apparaît dans t retourner faux sinon faire pointer x vers t retourner vrai; (f(L), g(M)): si f = g Union(f(L), g(M)) retourner unifierlistes(L, M) sinon retourner faux
Construction de graphes à partir d'arbres
modifierPour construire un graphe à partir d'un arbre, on parcourt l'arbre et on utilise une table de symboles (implémenté avec une table de hachage ou un arbre binaire de recherche) pour les variables car il faut garantir l'unicité du nœud x pour une variable x.
Unification modulo une théorie
modifierL'unification modulo une théorie, aussi appelée (unification équationnelle, E-unification, unification dans une théorie) est l'extension de l'unification syntaxique dans les cas où les opérateurs sont assujettis à des axiomes, formant une théorie E. Généralement cette théorie est décrite par un ensemble d'égalités universelles. Par exemple, une théorie E peut contenir l'identité où les variables et sont implicitement quantifiées universellement et qui dit que l'opérateur est commutatif. Dès lors, bien que les termes et ne soient pas syntaxiquement unifiables, ils sont E-unifiables :
{x ↦ b, y ↦ a} = en appliquant la substitution = car est commutatif. = {x ↦ b, y ↦ a} en appliquant la substitution
Exemple de théories E
modifier∀ u,v,w | u*(v*w) | = | (u*v)*w | A | Associativité de * |
∀ u,v | u*v | = | v*u | C | Commutativité de * |
∀ u,v,w | u*(v+w) | = | u*v+u*w | Dl | Distributivité gauche de * sur + |
∀ u,v,w: | (v+w)*u | = | v*u+w*u | Dr | Distributivité droite de * sur + |
∀ u: | u*u | = | u | I | Idempotence de * |
∀ u: | n*u | = | u | Nl | n est élément neutre gauche de * |
u: | u*n | = | u | Nr | n est élément neutre droit de * |
L'E-unification est décidable pour une théorie E s'il existe un algorithme pour cette théorie qui termine sur chaque entrée et résout le problème d'E-unification. Il est semi-décidable s'il existe un algorithme qui se termine pour les entrées qui ont une solution et qui peut boucler pour des équations sans solution.
L'E-unification est décidable pour les théories suivantes :
- A[33]
- A,C[34]
- A,C,I[35]
- A,C,Nl[36],[35]
- A,I[37]
- A,Nl,Nr (monoïde)[38]
- C[39]
- Anneaux booléens[40],[41]
- Groupes abéliens, avec des symboles supplémentaire (du moment qu'ils ne sont pas assujetti à des axiomes)[42]
- Algèbres modales K4[43]
L'E-unification est semi-decidable pour les théories suivantes :
Unification et logique d'ordre supérieur
modifierSi on se place en logique d'ordre supérieur, c'est-à-dire si on s'autorise à utiliser des variables comme symboles de fonction ou comme prédicats, on perd la décidabilité et l'unicité de l'unificateur quand il existe. Au pire, deux termes peuvent même avoir une infinité d'unificateurs tous différents, dans le sens suivant: soit t et t´ deux termes qu'on veut unifier, il peut exister un ensemble infini U d'unificateurs de t et t´ tel que si σ et ρ sont dans U, alors σ n'est pas plus général que ρ et ρ n'est pas plus général que σ.
Liens externes
modifierNotes et références
modifier- Kevin Knight, « Unification: A Multidisciplinary Survey », ACM Comput. Surv., vol. 21, no 1, , p. 93–124 (ISSN 0360-0300, DOI 10.1145/62029.62030, lire en ligne, consulté le )
- Attention, n'est pas une solution car les termes et sont syntaxiquement différents.
- Jacques Herbrand, « Recherches sur la théorie de la démonstration », Thèse, (lire en ligne, consulté le )
- Dag Prawitz, Ha\a a kan Prawitz et Neri Voghera, « A Mechanical Proof Procedure and Its Realization in an Electronic Computer », J. ACM, vol. 7, no 2, , p. 102–128 (ISSN 0004-5411, DOI 10.1145/321021.321023, lire en ligne, consulté le )
- J. A. Robinson, « A Machine-Oriented Logic Based on the Resolution Principle », J. ACM, vol. 12, no 1, , p. 23–41 (ISSN 0004-5411, DOI 10.1145/321250.321253, lire en ligne, consulté le )
- John Alan Robinson: Logic and Logic Programming. Commun. ACM 35(3): 40-65 (1992)
- Franz Baader et Wayne Snyder, Unification Theory, (lire en ligne), p. 443
- DE Knuth et PB Bendix, Computational problems in abstract algebra, Pergamon Press, (lire en ligne), p. 263–297
- Donald Knuth, All Questions Answered, 318. NOTICES OF THE AMS. VOLUME 49, NUMBER 3
- (en) James R. Guard, « AUTOMATED LOGIC FOR SEMI-AUTOMATED MATHEMATICS », Scientific report, (www.dtic.mil/dtic/tr/fulltext/u2/602710.pdf)
- « Computational logic: the unification computation | AITopics », sur aitopics.org (consulté le )
- « The sharing of structure in theorem-proving programs | AITopics », sur aitopics.org (consulté le )
- (en) M. Venturini Zilli, « Complexity of the unification algorithm for first-order expressions », CALCOLO, vol. 12, no 4, , p. 361–371 (ISSN 0008-0624 et 1126-5434, DOI 10.1007/BF02575754, lire en ligne, consulté le )
- Gérard Huet, Résolution d’équations dans les langages d’ordre 1, 2 ..., Omega, Université Paris VII (lire en ligne)
- Jeffrey Scott Vitter et Roger A. Simons, « Parallel Algorithms for Unification and Other Complete Problems in P », Proceedings of the 1984 Annual Conference of the ACM on The Fifth Generation Challenge, ACM, aCM '84, , p. 75–84 (ISBN 089791144X, DOI 10.1145/800171.809607, lire en ligne, consulté le )
- (en) « An algebraic semantics approach to the effective resolution of type equations - ScienceDirect », sur www.sciencedirect.com (consulté le )
- (en) Lewis Denver Baxter, An Efficient Unification Algorithm, Applied Analysis & Computer Science, , 34 pages
- Martelli, Alberto et Montanari, Ugo, « Unification in linear time and space: a structured presentation », Internal note IEI-B76-16, (lire en ligne, consulté le )
- M. S. Paterson et M. N. Wegman, « Linear Unification », Proceedings of the Eighth Annual ACM Symposium on Theory of Computing, ACM, sTOC '76, , p. 181–186 (DOI 10.1145/800113.803646, lire en ligne, consulté le )
- (en) « Linear unification - ScienceDirect », sur www.sciencedirect.com (consulté le )
- Alberto Martelli et Ugo Montanari, « An Efficient Unification Algorithm », ACM Trans. Program. Lang. Syst., vol. 4, no 2, , p. 258–282 (ISSN 0164-0925, DOI 10.1145/357162.357169, lire en ligne, consulté le )
- Cynthia Dwork, Paris Kanellakis et John C. Mitchell, « On the Sequential Nature of Unification », J. Log. Program., vol. 1, no 1, , p. 35–50 (ISSN 0743-1066, DOI 10.1016/0743-1066(84)90022-0, lire en ligne, consulté le )
- Jacques Corbin, Michel Bidoit: A Rehabilitation of Robinson's Unification Algorithm. IFIP Congress 1983: 909-914
- Peter Ruzicka, Igor Prívara: An Almost Linear Robinson Unification Algorithm. Acta Inf. 27(1): 61-71 (1989)
- (en) Melvin Fitting, First-Order Logic and Automated Theorem Proving : Springer (DOI 10.1007/978-1-4612-2360-3, lire en ligne)
- (en) Krzysztof R. Apt, From Logic Programming to Prolog, Londres, Prentice-Hall, Inc., , 328 p. (ISBN 0-13-230368-X, lire en ligne)
- Alg.1, p.261. Leur règle (a) correspond à notre règle échanger, (b) à supprimer, (c) à décomposer et conflit, et (d) à éliminer et vérifier.
- René Lalement, Logique, réduction, résolution, Paris/Milan/Barcelone, Masson, , 370 p. (ISBN 2-225-82104-6), p. 222
- Franz Baader et Tobias Nipkow, Term Rewriting and All That, Cambridge University Press, , 301 p. (ISBN 0-521-45520-0, lire en ligne)
- (en) Krzysztof Apt, Principles of Constraint Programming, Cambridge, Cambridge University Press, , 407 p. (ISBN 0-521-82583-0, lire en ligne), p. 134 Bibliographic remarks
- Franz Baader et Wayne Snyder, Unification Theory, (lire en ligne), p. 446
- Jacques Corbin et Michel Bidoit, « A Rehabilitation of Robinson's Unification Algorithm », IFIP congress, , p. 909–914 (lire en ligne, consulté le )
- Gordon D. Plotkin, Lattice Theoretic Properties of Subsumption, Memorandum MIP-R-77, Univ. Edinburgh, Jun 1970
- Mark E. Stickel, A Unification Algorithm for Associative-Commutative Functions, J. Assoc. Comput. Mach., vol.28, no.3, pp. 423–434, 1981
- F. Fages, Associative-Commutative Unification, J. Symbolic Comput., vol.3, no.3, pp. 257–275, 1987
- En présence de C, Nl et Nr sont equivalents, de même pour Dl et Dr
- Franz Baader, Unification in Idempotent Semigroups is of Type Zero, J. Automat. Reasoning, vol.2, no.3, 1986
- J. Makanin, The Problem of Solvability of Equations in a Free Semi-Group, Akad. Nauk SSSR, vol.233, no.2, 1977
- (en) F. Fages, « Associative-Commutative Unification », J. Symbolic Comput., vol. 3, no 3, , p. 257–275 (DOI 10.1016/s0747-7171(87)80004-4)
- (en) Martin, U., Nipkow, T., Proc. 8th CADE, vol. 230, Jörg H. Siekmann, coll. « LNCS », , 506–513 p., « Unification in Boolean Rings »
- (en) A. Boudet, J.P. Jouannaud et M. Schmidt-Schauß, « Unification of Boolean Rings and Abelian Groups », Journal of Symbolic Computation, vol. 8, , p. 449–477 (DOI 10.1016/s0747-7171(89)80054-9, lire en ligne)
- Baader and Snyder (2001), p. 486.
- F. Baader and S. Ghilardi, Unification in modal and description logics, Logic Journal of the IGPL 19 (2011), no. 6, pp. 705–730.
- P. Szabo, Unifikationstheorie erster Ordnung (First Order Unification Theory), Thesis, Univ. Karlsruhe, West Germany, 1982
- Jörg H. Siekmann, Universal Unification, Proc. 7th Int. Conf. on Automated Deduction, Springer LNCS vol.170, pp. 1–42, 1984