Best viewed in 24pt and full-screen
next up previous contents
Next: U Up: A-Z Previous: S

T

type hanoi int -> string -> string -> string -> ((list mv) -> (list mv)) -> o .
dynamic hanoi .
hanoi 1 A _B C ztex2html_wrap_inline56812[(mouvement A C)|z] .
hanoi N A B C ztex2html_wrap_inline56812(M1 (M2 (M3 z))) :- N > 1 , N1 is N-1 ,
      hanoi N1 A C B M1 , hanoi 1 A B C M2 , hanoi N1 B A C M3 .

type tours_hanoi_memo int -> int -> string -> string -> string -> ((list mv) -> (list mv)) -> o .
tours_hanoi_memo I N A B C M :- I < N , I1 is I+1 ,
      pi atex2html_wrap_inline56812(pi btex2html_wrap_inline56812(pi ctex2html_wrap_inline56812( hanoi I a b c (MI a b c) , ! ))) ,
      ( pi Atex2html_wrap_inline56812(pi Btex2html_wrap_inline56812(pi Ctex2html_wrap_inline56812( hanoi I A B C (MI A B C) ))) => tours_hanoi_memo I1 N A B C M ) .
tours_hanoi_memo N N A B C M :- hanoi N A B C M .


Résolution du problème des tours de Hanoi par mémoïsation. Elle est faite à l´aide de l´implication, sans modifier le programme naïf (hanoi). Appeler (tours_hanoi_memo 1 NbDisques "1" "2" "3" Mouvements).

tex2html_wrap_inline56836-Terme. n.m. (tex2html_wrap_inline55796 ex.progr. déclaration l_terme*) Terme du tex2html_wrap_inline56836-calcul* construit avec la tex2html_wrap_inline56836-abstraction*, l´application* et éventuellement un jeu de constantes.

Terme rationnel. n.m. Terme éventuellement infini et composé d'un nombre fini de sous-termes différents. Un terme fini (par exemple, un terme de l´univers de Herbrand*) est évidemment rationnel. Dans la figure suivante, le terme de gauche, qui représente essentiellement la liste des entiers, n'est pas rationnel, tandis que celui du milieu l'est. Il représente essentiellement une liste de 0 et de 1 alternés.

  tex2html_wrap56674

Un terme rationnel, même infini, peut être représenté finiment par un graphe dont les sommets sont les sous-termes différents qui le composent et les arcs représentent la relation de sous-terme. Dans la figure ci-dessus, le graphe de droite est la représentation finie du terme du milieu.

L´unification* des termes rationnels est unitaire, décidable et même relativement aisée [Huet 76]. L'unification mise en tex2html_wrap52064uvre pratiquement dans les systèmes Prolog est incorrecte à cause de l'omission du test d´occurrence*. Remplacer les termes de Prolog par des termes rationnels est une réponse à ce problème.

tex2html_wrap_inline56836-Terme simplement typé. n.m. (tex2html_wrap_inline55796 ex.progr. déclaration l_terme_st*) Les tex2html_wrap_inline56836-termes simplement typés sont engendrés par la grammaire suivante :

displaymath56258

La grammaire est essentiellement la même que celle des tex2html_wrap_inline56836-termes non-typés, mais les non-terminaux sont ici décorés d'attributs qui sont des types. L'accord en type doit être vérifié lors de toute dérivation utilisant cette grammaire. Les tex2html_wrap_inline56302 et tex2html_wrap_inline56304 sont respectivement des identificateurs de constantes et de variables dont le type est tex2html_wrap_inline55774.

Terzo. Dernière en date (1997) des implémentations de tex2html_wrap_inline56836Prolog. C'est un interpréteur écrit en Standard tex2html_wrap_inline54612. C'est un travail commencé par Frank Pfenning et Conal Eliott à l'université de Carnegie Mellon, poursuivi par Amy Felty au laboratoire Bell Labs de tex2html_wrap_inline53924, et finalisé par Philip Wickline à l'université de Pennsylvanie (UPenn).

Test d´occurrence. n.m. Test préalable à la formation d'une substitution tex2html_wrap_inline56356 par lequel on vérifie que tex2html_wrap_inline56486 et tex2html_wrap_inline56402 sont compatibles. En Prolog, ce test consiste à vérifier que tex2html_wrap_inline56486 n'a pas d'occurrence dans tex2html_wrap_inline56402.

Le test d'occurrence s'interprète logiquement en termes d´élimination de quantificateurs*. En effet, dans une formule tex2html_wrap_inline56324, la variable tex2html_wrap_inline53958 peut dépendre de tex2html_wrap_inline53952, mais pas dans une formule tex2html_wrap_inline56330. Par exemple, on prouve tex2html_wrap_inline56332 en prenant tex2html_wrap_inline53952 égal à tex2html_wrap_inline53958, mais on n'a pas le droit de prouver tex2html_wrap_inline56338 de cette façon. La dépendance peut être indirecte comme dans tex2html_wrap_inline56376tex2html_wrap_inline56342 semble pouvoir dépendre de tex2html_wrap_inline53952, mais ne le peut pas car il est en fait synonyme de tex2html_wrap_inline53958 qui ne peut pas dépendre de tex2html_wrap_inline53952.

Une des manières qu'a l'élimination des quantificateurs de représenter les dépendances entre variables est de remplacer les variables essentiellement universelles par des termes dans lesquelles figurent les variables essentiellement existentielles qui ne peuvent pas en dépendre (c'est-à-dire celles qui sont quantifiées plus à gauche). C'est la skolémisation*. Une autre manière est de remplacer les variables existentielles par des applications de fonctions inconnues aux variables universelles dont elles peuvent dépendre (c'est-à-dire celles qui sont quantifiées plus à gauche). C'est l´antiskolémisation*.

En Prolog, tout se passe comme si l'élimination des quantificateurs existentiels etait faite statiquement par skolémisation en utilisant la première manière. En tex2html_wrap_inline56836Prolog, les possibilités d'imbrications des quantifications sont plus variées et les deux manières sont utilisées : la première, statiquement, pour ce qui est compatible avec Prolog et la deuxième, dynamiquement, pour les quantifications de tex2html_wrap_inline56836Prolog qui ne sont pas réductibles à celles de Prolog. Dans le dernier cas, on n'énumère pas vraiment les variables universelles dont une variable existentielle peut dépendre. On numérote les variables universelles par ordre d'imbrication de leurs quantifications et on ne note que le plus grand des numéros des variables universelles dont elle peut dépendre.

En tex2html_wrap_inline56836Prolog, le test d'occurrence préalable à la substitution tex2html_wrap_inline56356 consiste donc à vérifier que tex2html_wrap_inline56486 et aucune variable universelle interdite dans tex2html_wrap_inline56486 n'ont d'occurrence rigide* dans tex2html_wrap_inline56402, et à propager dans les variables existentielles de tex2html_wrap_inline56402 les variables universelles interdites de tex2html_wrap_inline56486. Par exemple, la recherche d'une preuve de tex2html_wrap_inline56376 se déroule comme suit, où on note pour chaque variable existentielle les variables universelles dont elle peut dépendre. Ainsi, tex2html_wrap_inline56368 dénote que tex2html_wrap_inline56486 peut dépendre de tex2html_wrap_inline56416 et de tex2html_wrap_inline56418, et que donc toutes les autres variables universelles sont interdites.

Le but : tex2html_wrap_inline56376 .

Élimination de tex2html_wrap_inline56426. Reste tex2html_wrap_inline56380 .

Élimination de tex2html_wrap_inline56430. Reste tex2html_wrap_inline56384 .

Élimination de tex2html_wrap_inline56386. Reste tex2html_wrap_inline56388 .

Substitution tex2html_wrap_inline56390 où le test d'occurrence propage les interdits de tex2html_wrap_inline56392 à tex2html_wrap_inline52400. Reste tex2html_wrap_inline56396 .

Échec dû à un test d'occurrence négatif : tex2html_wrap_inline56398 ne peut pas dépendre de tex2html_wrap_inline53952.

Dans le cas où le terme tex2html_wrap_inline56402 a une occurrence flexible*, soit de la variable tex2html_wrap_inline56486, soit de variables universelles interdites dans tex2html_wrap_inline56486, il faut que l'une des occurrences flexibles sur le chemin qui y mène soit remplacée par un terme qui «coupe» le chemin. Par exemple, la recherche d'une preuve de tex2html_wrap_inline26852 se déroule comme suit. Ici, tex2html_wrap_inline56416 et tex2html_wrap_inline56418, et tex2html_wrap_inline56448 et tex2html_wrap_inline56450, sont des constantes et des variables d'un environnement visible de la formule. On ne connaît pas les relations qu'entretiennent tex2html_wrap_inline56416, tex2html_wrap_inline56418, tex2html_wrap_inline56448 et tex2html_wrap_inline56450.

Le but : tex2html_wrap_inline26852.

Élimination de tex2html_wrap_inline56426. Reste tex2html_wrap_inline26856.

Élimination de tex2html_wrap_inline56430. Reste tex2html_wrap_inline26860.

Substitution tex2html_wrap_inline26862 .

Dans cet exemple, le test d'occurrence détecte un chemin flexible vers l'occurrence interdite tex2html_wrap_inline53952. Ce chemin devra être coupé soit en tex2html_wrap_inline56448, tex2html_wrap_inline56440, soit en tex2html_wrap_inline56450, tex2html_wrap_inline56444, soit aux deux applications flexibles. Comme il n'est pas facile de gérer une disjonction de substitutions, le système tex2html_wrap_inline52896* suspend la résolution du problème d'unification comme il est souvent fait en programmation logique avec contraintes. La résolution du problème sera reprise quand soit tex2html_wrap_inline56448 soit tex2html_wrap_inline56450 se sera précisée.

En général, les systèmes Prolog n'implémentent pas le test d'occurrence, ou alors il n'est actif qu'à la demande. Cela fait de ces systèmes des démonstrateurs incorrects en toute généralité, mais on observe que le test d'occurrence est le plus souvent inutile, et on connaît assez bien les situations où on peut prouver qu'il l'est [Deransart et al. 91].

Inversement, on observe qu'en tex2html_wrap_inline56836Prolog la partie du test d'occurrence qui est spécifique (propagation des variables universelles interdites) est le plus souvent utile car elle conditionne la bonne formation des tex2html_wrap_inline56836-abstractions*. C'est lié à la notion de variables essentiellement universelles* qui fait correspondre variables universelles et tex2html_wrap_inline56836-variables*. La partie commune avec Prolog reste le plus souvent inutile, mais la formalisation des conditions de son inutilité n'a pas encore été faite.

Une solution pour affranchir Prolog du test d'occurrence est de changer son domaine de calcul. Si on remplace les termes de Prolog par des termes rationnels* comme en Prolog tex2html_wrap_inline56458 (tex2html_wrap_inline55796 Colmerauer*), il est assez facile de réaliser une implémentation pour laquelle l'unification n'est pas plus coûteuse que l'unification de Prolog sans test d'occurrence [Le Huitouze 88]. On ne peut pas suivre cette approche en tex2html_wrap_inline56836Prolog car cela fait perdre la propriété de normalisation forte*. En effet, on peut très facilement représenter un combinateur de point-fixe avec un tex2html_wrap_inline56836-terme rationnel, même s'il est simplement typé. Le tex2html_wrap_inline56836-terme rationnel Y' suivant est un combinateur de point fixe.

  tex2html_wrap56678

Il est facile de constater que (F ( Y' F)) est égal à ( Y' F) modulo l'égalité des termes rationnels. Le tex2html_wrap_inline56836-terme rationnel Y' se comporte donc comme un combinateur de point-fixe.

tex2html_wrap_inline56490. Une opération élémentaire ajoutée au semi-algorithme de Huet* dans son implémentation.

Une paire flexible-rigide* n'est pas passée directement à la procédure tex2html_wrap_inline56476*, non plus qu'une paire flexible-flexible n'est automatiquement suspendue. Une telle paire est d'abord passée à la procédure tex2html_wrap_inline56490, qui essaie de la résoudre en appliquant des heuristiques «simples». Si aucune heuristique ne s'applique, la paire est alors passée à tex2html_wrap_inline56476 ou suspendue.

Les heuristiques reconnaissent des paires tex2html_wrap_inline56478 (dites «paires triviales») sous des formes diverses. Si une telle paire est reconnue et si la variable tex2html_wrap_inline56486 n'apparaît pas dans le terme tex2html_wrap_inline55774, alors la substitution tex2html_wrap_inline56484 est un unificateur de cette paire. Le test d´occurrence* est plus compliqué que son homologue du premier ordre car les occurrences de tex2html_wrap_inline56486 dans tex2html_wrap_inline55774 ne causent pas toutes un échec. Il se complique encore avec l'introduction des quantifications.

Une bonne procédure tex2html_wrap_inline56490 doit reconnaître une paire triviale sous les formes suivantes.

Type abstrait. n.m. Les quantifications de tex2html_wrap_inline56836Prolog fournissent un support naturel pour définir des types abstraits et leurs méthodes [Miller 89a]. L'idée est d'exploiter l'identité suivante :

displaymath56259

Cette identité montre qu'en tex2html_wrap_inline56836Prolog on peut aussi avoir des quantifications existentielles au niveau des clauses, mais à la condition qu'elles soient complètement extérieures à une clause, car alors on pourra les remplacer par des quantifications universelles au niveau d'un but. D'après les règles d'élimination des quantificateurs, ces quantifications existentielles seront éliminées en remplaçant les variables quantifiées par de nouvelles constantes. Par définition, ces constantes ne peuvent pas être connues du programmeur. On peut donc les considérer comme des constructeurs cachés d'un type abstrait dont les méthodes sont les prédicats laissés visibles. Par exemple, les déclarations et définitions suivantes,

kind pile type -> type .

type est_vide (pile A) -> o .

type sommet A -> (pile A) -> (pile A) .

type hauteur (pile A) -> int -> o .

sigma videtex2html_wrap_inline56812(sigma empilertex2html_wrap_inline56812(

      est_vide vide ,

      pi Stex2html_wrap_inline56812(pi Ptex2html_wrap_inline56812( sommet S P (empiler S P) )) ,

      hauteur vide zéro ,

      pi Stex2html_wrap_inline56812(pi Ptex2html_wrap_inline56812(pi Htex2html_wrap_inline56812( hauteur (empiler S P) (succ H) :- hauteur P H ))) )) .

introduisent un type abstrait pile, dont les constructeurs vide et empiler sont cachés, mais dont les méthodes est_vide, sommet et hauteur sont visibles.

Type inductif. n.m. Se dit du type d'une structure de données dont les constructeurs n'ont des sous-termes de ce type dans leurs arguments qu'en des occurrences positives [Böhm et Berarducci 85, Pierce et al. 89]. Il faut se rappeler que selon la correspondance de Curry-Howard* la flèche des types simples est l'analogue de l'implication du calcul des propositions. Comme elle, elle introduit une notion d'occurrences négatives* et positives* selon la définition suivante :

displaymath56260

Par exemple, pour un type tex2html_wrap_inline56402 égal à tex2html_wrap_inline56554, on a tex2html_wrap_inline56556 et tex2html_wrap_inline56558.

En tex2html_wrap_inline56836Prolog, la notion de type inductif permet de décider sans avoir recours au raisonnement opérationnel s'il faut utiliser l'implication dans les buts dans une induction structurelle (tex2html_wrap_inline55796 induction structurelle en tex2html_wrap_inline56836Prolog*). Si le type d'une structure de données est inductif alors on en déduit facilement une fonction d'induction structurelle sur ses constructeurs [Böhm et Berarducci 85, Pierce et al. 89], sans utiliser l'implication. En revanche, si le type n'est pas inductif, l'induction structurelle standard ne suffit pas. Dans tous les cas (inductif ou non), la quantification universelle dans les buts sera nécessaire pour les arguments d'ordre supérieur. De plus, dans le cas non-inductif, l'implication dans les buts sera aussi nécessaire pour les occurrences négatives.

Les occurrences négatives correspondent aux types des variables universelles utilisées pour interpréter les abstractions. Donc, si le type d'intérêt a une occurrence négative, il faudra utiliser l'implication pour augmenter le programme afin de prendre en compte la constante universelle utilisée pour interpréter la quantification universelle.

L'exemple d'induction structurelle sur les formules (tex2html_wrap_inline55796 prédicat norm_nég*) n'utilise pas l'implication. C'est parce que le type formule* est inductif. Ses constructeurs sont soit des connecteurs (et, etc.), soit des quantificateurs (qqsoit, etc.). Le type de tous les arguments de et est formule. Le type de l'unique argument de qqsoit est individutex2html_wrap_inline55796formule. Or, on a neg(formule)=tex2html_wrap_inline56570 et neg(individutex2html_wrap_inline55796formule)=tex2html_wrap_inline56590individutex2html_wrap_inline56592. Aucun ne contient formule, donc le type formule est inductif.

Cette exemple montre aussi que les quantifications du métalangage sont utilisées pour interpréter la structure des formules objet, indépendamment de leur sémantique. Ici, la même quantification universelle est utilisée pour traiter les quantifications existentielles et les quantifications universelles des formules objet.

Au contraire, tous les exemples présentés sur les tex2html_wrap_inline56836-termes objets (tex2html_wrap_inline55796 prédicats bien_typé* et de_bruijn*) utilisent l'implication. Montrons que le type l_terme* n'est pas inductif. Ses constructeurs sont app et abs, et le type de abs est (l_termetex2html_wrap_inline55796l_terme)tex2html_wrap_inline55796l_terme. Le type de l'unique argument de abs est donc l_termetex2html_wrap_inline55796l_terme. Or neg(l_termetex2html_wrap_inline55796l_terme)=tex2html_wrap_inline56590l_termetex2html_wrap_inline56592. Le type l_terme a une occurrence négative dans le type d'un argument d'un de ces constructeurs ; il n'est donc pas inductif.

Type oublié. n.m. Instance d'une variable de type qui est oubliée par un type oublieur*. Avec les types des variables logiques, ce sont les seuls types qu'il est nécessaire de représenter à l'exécution [Brisset et Ridoux 92b, Brisset et Ridoux 94].

Type oublieur. n.m. Type qui viole la condition de transparence*. Par exemple, tous les types de prédicats polymorphiques sont oublieurs.

Type paramétrique. n.m. [Louvet et Ridoux 96, Louvet 96] La discipline de typage du tex2html_wrap_inline56836-calcul* polymorphique du second ordre, tex2html_wrap_inline53106 (tex2html_wrap_inline55796 cube de Barendregt*), peut être transposée à la programmation logique. Cela permet de s'affranchir de la condition de tête* et de décrire convenablement la représentation des types à l'exécution. Le système obtenu en appliquant cette discipline à tex2html_wrap_inline56836Prolog est appelé tex2html_wrap_inline53106Prolog (voir la section «Typage polymorphe paramétrique»*).

Type produit. n.m. Un type produit tex2html_wrap_inline56604 est celui de «fonctions» dont le type du résultat, tex2html_wrap_inline56606, peut dépendre de la valeur du paramètre, tex2html_wrap_inline53968. Un type flèche tex2html_wrap_inline56610 peut être considéré comme une abréviation d'un type produit lorsque le type du résultat de dépend pas de la valeur du paramètre.

Pourquoi ce nom de «type produit» ? L'explication pour les fonctions d'un type fini tex2html_wrap_inline56448 dans un autre type fini tex2html_wrap_inline56450 est assez simple. Elles sont complètement déterminées par leurs graphes, qui sont des vecteurs de tex2html_wrap_inline56616. On peut donc noter le type de ces fonctions par tex2html_wrap_inline56636, et cette notation s'étend sans difficulté au cas où tex2html_wrap_inline56450 n'est pas fini, et avec un peu plus de difficulté au cas où tex2html_wrap_inline56448 ne l'est pas. Considérons maintenant des fonctions d'un type fini tex2html_wrap_inline56448 dans des types finis tex2html_wrap_inline56634 déterminés pour chaque élément de tex2html_wrap_inline56448. Elles sont encore complètement déterminées par leurs graphes, qui sont des vecteurs de tex2html_wrap_inline56630, qu'il est plus commode de noter tex2html_wrap_inline56632. À nouveau cette notation s'étend au cas infini. Si tous les tex2html_wrap_inline56634 sont les mêmes, on retrouve naturellement la notation tex2html_wrap_inline56636.

Si les tex2html_wrap_inline56416 sont des types, alors le type produit modélise la notion de polymorphisme paramétrique (voir la section «Typage polymorphe paramétrique»*). Cette faculté correspond à la face «non prédicative» (aussi notée tex2html_wrap_inline56640) du cube de Barendregt* (tex2html_wrap_inline55796 figure 1*). Si les tex2html_wrap_inline56416 sont des termes, alors le type produit modélise la notion de type dépendant. Cette faculté correspond à la face des «preuves» (aussi notée tex2html_wrap_inline56646).

Type simple. n.m. Les types simples [Church 40, Barendregt 91] sont engendrés par la grammaire suivante :

displaymath56261

Les tex2html_wrap_inline56648 sont des identificateurs de constructeurs de type d'arité tex2html_wrap_inline53198. La deuxième règle est la règle de formation des types de fonctions ; le type tex2html_wrap_inline56652 peut être interprété comme celui des fonctions de tex2html_wrap_inline56448 vers tex2html_wrap_inline56450. On admet que la flèche tex2html_wrap_inline55796 est associative à droite, ce qui rend certaines parenthèses inutiles : par exemple, otex2html_wrap_inline55796otex2html_wrap_inline55796o dénote le même type que (otex2html_wrap_inline55796(otex2html_wrap_inline55796o)). La notation concrète de tex2html_wrap_inline55796 dans les programmes est ->.

La représentation en tex2html_wrap_inline56836Prolog des types simples de niveau objet est la suivante :

kind type_simple type .

type flèche type_simple -> type_simple -> type_simple .

type base type_simple .

Les règles de bon typage au niveau objet sont les suivantes :

type bien_typé l_terme -> type_simple -> o .

bien_typé (app E F) Tau :- bien_typé E (flèche Sigma Tau) , bien_typé F Sigma .

bien_typé (abs E) (flèche Sigma Tau) :- pi xtex2html_wrap_inline56812( bien_typé x Sigma => bien_typé (E x) Tau ) .


next up previous contents
Next: U Up: A-Z Previous: S

Olivier Ridoux
Mon Apr 27 11:10:23 MET DST 1998