Semi-unification

Objet

Ecrire, en Lisp, un programme qui, recevant en donnée des règles de réécriture et un énoncé, applique ces règles tant que c'est possible et restitue l'énoncé transformé.

Principe

Données

On lit la liste des symboles qui seront "substituables" dans les règles (traditionnellement, U, V, W...).
On lit les règles (par exemple sous forme d'une liste ((PG1 PD1)(PG2 PD2)... (PGn PDn)).
On lit l'énoncé. Celui-ci devant être modifié au cours du déroulement, on pourra le mettre dans une variable globale. L'énoncé ne doit évidemment contenir aucun symbole substituable.
On lit une variable (globale elle aussi) d'aide au debugging, qui rend le programme d'autant plus bavard que sa valeur est grande.

Traitement

On ajoute à la P-list de chaque symbole substituable un couple attribut/valeur, par exemple : substituable/oui.

On fait une boucle infinie, dont on ne sortira que lorsque plus aucune règle ne s'appliquera.
- on considère le premier symbole de l'énoncé;
- on fait une boucle sur les règles;
- si la partie gauche d'une règle colle, on réécrit sa partie droite, en tenant compte du contenu de la table d'unification, et on sort de la boucle sur les règles pour remonter à la boucle infinie;
- si on est sorti sans succès de la boucle sur les règles, on passe au symbole suivant de l'énoncé, et on recommence;
- si on sort sans succès de cette récursion, on sort de la boucle infinie, en renvoyant la valeur courante de l'énoncé.


Détail

Pour savoir si une règle colle à un terme.

Il faut que leurs cars collent et leurs cdrs aussi.
Si le terme courant de la règle est un atome :
- si le terme courant de l'énoncé est identique, ok ;
- sinon, si le terme de la règle est substituable,
- - s'il est déjà dans la table avec une valeur différente, échec ;
- - sinon, ajouter les deux éventuellement à la table ;
- sinon, échec.

Pour réécrire la partie droite

Recopier la liste, sauf quand on trouve un substituable, qu'il faut remplacer par l'expression de la table.

Pour réécrire l'énoncé

Recopier l'ancien, sauf quand on trouve l'expression qui a collé à la partie gauche, que l'on remplace par la nouvelle partie droite.

Astuces

On pourra, pour la table, utiliser deux piles. On push le substituable sur l'une et la liste sur l'autre. Pour récupérer la valeur d'un substituable, il suffit de prendre le n-ème élément de la seconde, n étant la position du substituable dans la première, donnée par (position symb pile).
Pour qu'une fonction renvoie deux valeurs, il suffit qu'elle renvoie (cons v1 v2). On récupère v1 par car et v2 par cdr, à condition d'avoir mis le résultat de la fonction dans une variable locale.

Attention!

Dans l'énoncé et dans les règles, le car d'une liste peut être une liste.
NIL est une liste ET un atome.

Exemples d'exécution

? (tp)
Donnez la liste des substituables
(u v)
Donnez les regles
(
((d (+ u v)) (+ (d u) (d v)))
((d (* u v)) (+ (* (d u) v) (* u (d v))))
((d (exp u v)) (* v (* (exp u (- v 1)) (d u))))
((d a) 0)
((d b) 0)
((d c) 0)
((d x) 1)
)
Donnez l'enonce
(d (+ (* a (exp x 2)) (+ (* b x) c)))
Donnez le niveau de bavardise
1
En appliquant : (D (+ U V))
on obtient : (+ (D (* A (EXP X 2))) (D (+ (* B X) C)))
En appliquant : (D (* U V))
on obtient : (+ (+ (* (D A) (EXP X 2)) (* A (D (EXP X 2)))) (D (+ (* B X) C)))
En appliquant : (D A)
on obtient : (+ (+ (* 0 (EXP X 2)) (* A (D (EXP X 2)))) (D (+ (* B X) C)))
En appliquant : (D (EXP U V))
on obtient : (+ (+ (* 0 (EXP X 2)) (* A (* 2 (* (EXP X (- 2 1)) (D X))))) (D (+ (* B X) C)))
En appliquant : (D X)
on obtient : (+ (+ (* 0 (EXP X 2)) (* A (* 2 (* (EXP X (- 2 1)) 1)))) (D (+ (* B X) C)))
En appliquant : (D (+ U V))
on obtient : (+ (+ (* 0 (EXP X 2)) (* A (* 2 (* (EXP X (- 2 1)) 1)))) (+ (D (* B X)) (D C)))
En appliquant : (D (* U V))
on obtient : (+ (+ (* 0 (EXP X 2)) (* A (* 2 (* (EXP X (- 2 1)) 1)))) (+ (+ (* (D B) X) (* B (D X))) (D C)))
En appliquant : (D B)
on obtient : (+ (+ (* 0 (EXP X 2)) (* A (* 2 (* (EXP X (- 2 1)) 1)))) (+ (+ (* 0 X) (* B (D X))) (D C)))
En appliquant : (D X)
on obtient : (+ (+ (* 0 (EXP X 2)) (* A (* 2 (* (EXP X (- 2 1)) 1)))) (+ (+ (* 0 X) (* B 1)) (D C)))
En appliquant : (D C)
on obtient : (+ (+ (* 0 (EXP X 2)) (* A (* 2 (* (EXP X (- 2 1)) 1)))) (+ (+ (* 0 X) (* B 1)) 0))
(+ (+ (* 0 (EXP X 2)) (* A (* 2 (* (EXP X (- 2 1)) 1)))) (+ (+ (* 0 X) (* B 1)) 0))

? (tp)
Donnez la liste des substituables
(u v)
Donnez les regles
(
((d (+ u v)) (+ (d u) (d v)))
((d (* u v)) (+ (* (d u) v) (* u (d v))))
((d (exp u v)) (* v (* (exp u (- v 1)) (d u))))
((d a) 0)
((d b) 0)
((d c) 0)
((d x) 1)
((+ u 0) u)
((+ 0 u) u)
((* u 0) 0)
((* 0 u) 0)
((* u 1) u)
((* 1 u) u)
((- 2 1) 1)
((exp x 1) x)
)

Donnez l'enonce
(d (+ (* a (exp x 2)) (+ (* b x) c)))
Donnez le niveau de bavardise
0
(+ (* A (* 2 X)) B)
?

Modalités de contrôle

Fichier accessible aux enseignants, ou dossier ?
Date?
Corrigé.
L'URL de ce document est http://www710.univ-lyon1.fr/~fouet/Dir_lic_mai/TP/sunif