Upload
renaud-chretien
View
111
Download
0
Embed Size (px)
Citation preview
Techniques de Réécriture et
TransformationsPierre-Etienne Moreau
Manipulation de listes
Représentation des listes
Habituellement, on considère une liste vide nil, et un opérateur de concaténation consnil : L
cons : E x L L
On représente ainsi la liste a.b.c par
cons(a,cons(b,cons(c,nil)))
Question
Comment retrouver un élément donné ?
appartient(cons(a,cons(b,cons(c,nil))),a) ?
appartient(cons(a,cons(b,cons(c,nil))),b) ?
appartient(cons(a,cons(b,cons(c,nil))),d) ?
Une réponse
appartient(cons(x,l),x) true
appartient(cons(y,l),x) appartient(l,x)
appartient(nil,x) false
Une autre réponse
Dans Tom on peut écrireappartient( (_*,x,_*) , x) true
appartient( l , x) false
Symboles associatifs
f est associatif si :f(x,f(y,z)) = f(f(x,y),z)
Dans ce cas, a-t-on : f(a,f(b,f(c,d))) = f(f(a,b),f(c,d)) ? tel que f(x,f(c,y)) = f(f(a,b),f(c,d)) ? f(x,f(c,y)) << f(f(a,b),f(c,d)) ? f(x,f(c,y)) << f(a,f(b,f(c,d))) ? f(x,f(d,y)) << f(a,f(b,f(c,d))) ?
Associativité avec élément neutre
f(x,f(y,z)) = f(f(x,y),z)f(x,e) = f(e,x) = xDans ce cas, a-t-on :
f(x,f(c,y)) << f(a,f(b,f(c,d))) ? f(x,f(d,y)) << f(a,f(b,f(c,d))) ?
Associativité dans Tom
On considère les formes aplaties : f(a,b,c,d) f(x,c,y)
On peut écrire : f(x,c,y) << f(a,b,c,d) f(x,d,y) << f(a,b,c,d)
Questions
Comment savoir s’il y a un ‘a’ suivi d’un ‘b’ ? f(x,a,y,b,z) << f(a,b,c,d)
Avec exactement un terme entre les deux ? On ne peut pas l’exprimer
Signature
f est d’arité variable et a pour profil : f : E x … x E -> L
On le note : f( E* ) -> L
Cela permet d’écrire : f(a(),b(),c(),d()) f(x,a(),y,b(),z)
Questions
Quel est le type de x,y et z dans f(x,a(),y,b(),z) ? réponse : E
Comment exprimer f(x,c(),y) tel que cela filtre vers f(a(),b(),c(),d()) ? Il faut des variables de type L On les note f(x*,c(),y*)
Exercice
Exprimer la fonction d’appartenance sur des listes associativesappatient(f(_*,x,_*),x) -> True
appatient(f(_*),x) -> False
Exercice
Comment éliminer les doublons ? f(X*,e,e,Z*) -> f(X*,e,Z*) élimine les doublons consécutifs
Comment éliminer les doublons distants f(X*,e,Y*,e,Z*) -> f(X*,e,Y*,Z*)
Exercice
Etant donné un ordre sur les élémentsExprimer un algorithme de tri
f(X*,e1,e2,Y*) -> f(X*,e2,e1,Y*) if e2<e1
Implanter le en Tom
Demo
Implantation d’un algorithme de filtrage
syntaxiqueUtiliser des symboles associatifsQuelle signature choisir ?Variable(name:String) -> TermAppl(name:String, args:TermList) -> Termconc( Term* ) -> TermListTrue -> Term False -> TermMatch(pattern:Term, subject:Term) -> TermAnd( l:TermList ) -> Term
Codage des règles et des termes
%rule {
// PropagateClash
And(conc(X*,True(),Y*)) -> And(conc(X*,Y*))And(conc(X*,True(),Y*)) -> And(conc(X*,Y*))And(conc(X*,c,Y*,c,Z*)) -> And(conc(X*,c,Y*,Z*))And(conc()) -> True()
}
Term p2 = `Appl("f",conc(Variable("x"),Appl("g",conc(Variable("y")))));Term s2 = `Appl("f",conc(Appl("a",conc()),Appl("g",conc(Appl("b",conc())))));
// PropagateSuccess And(conc(_*,False(),_*)) -> False()
Stratégies
Programmation par réécriture
Avantages le filtrage est un mécanisme expressif les règles expriment des transformations
élémentairesLimitations
les systèmes de règles sont souvent non-terminant et/ou non confluent
en général, on ne veut pas appliquer toutes les règles en même temps
Exemple de système non terminant
And(Or(x,y),z) Or(And(x,z),And(y,z))
And(z,Or(x,y)) Or(And(z,x),And(z,y))
Or(And(x,y),z) And(Or(x,z),Or(y,z))
Or(z,And(x,y)) And(Or(z,x),Or(z,y))
Not(Not(x)) x
Not(And(x,y)) Or(Not(x),Not(y))
Not(Or(x,y)) And(Not(x),Not(y))
And(Or(a,b),c) Or(And(a,c),And(b,c))
And(Or(a, And(b,c)),Or(c, And(b,c)))
…
Codage du contrôle dans les règles
Solution classique introduire un nouvel opérateur f pour
restreindre l’ensemble de règles permettant de normaliser
l r devient f(l) r’ on normalise un terme f(t) l’opérateur f permet de contrôler les règles
à appliquer
Encodage du contrôle
f(And(x,y)) and(x,y)f(Not(x)) not(x)f(Or(x,y)) Or(f(x),f(y)) and(Or(x,y),z) Or(and(x,z),and(y,z))and(z,Or(x,y)) Or(and(z,x),and(z,y))and(x,y) And(x,y) not(Not(x)) x not(And(x,y)) Or(not(x),not(y)) not(Or(x,y)) and(not(x),not(y))not(x) Not(x)
f(And(Or(a,b),c)) and(Or(a,b),c)) Or(and(a,c),and(b,c)) Or(And(a,c),And(b,c))
Conséquences
Il faut définir la congruence explicitement, pour chaque règle et chaque constructeur
Il n’y a plus de séparation entre transformation et contrôle cela rend la compréhension plus difficile les règles sont moins réutilisables
Ce qu’on voudrait
pouvoir contrôler l’application des règlespouvoir spécifier simplement la
« traversée » d’un terme (i.e. appliquer une règles dans les sous-termes)
tout en séparant règle et contrôle
Solution
Utiliser des stratégies Combiner des transformations élémentaires Exemples
disjunctive normal formdnf = innermost(DAOL <+ DAOR <+ DN <+…)DAOL : And(Or(x,y),z) Or(And(x,z),And(y,z))DAOR : And(z,Or(x,y)) Or(And(z,x),And(z,y)) DN : Not(Not(x)) x conjunctive normal form cnf = innermost(DOAL <+ DOAR <+ DN <+…)
Stratégies élémentaires
Règle de réécriture
Une règle R : g d est une stratégie élémentaire
Exemples : R = a b (R)[a] = b (R)[b] = fail (R)[f(a)] = fail
Identité et échec
id : ne fait rien, mais n’échoue pasfail : échoue tout le tempsExemples
(id)[a] = a (id)[b] = b (fail)[a] = fail
Composition
S1 ; S2Applique S1, puis S2Echoue si S1 ou S2 échoueExemples
(a b ; b c)[a] = c (a b ; c d)[a] = fail (b c ; a b)[a] = fail
Choix
S1 <+ S2Applique S1. Si cela échoue, applique S2Exemples
(a b <+ b c)[a] = b (b c <+ a b)[a] = b (b c <+ c d)[a] = fail (b c <+ id)[a] = a
Quelques lois
id ; s = s s ; id = s id <+ s = s s <+ id ≠s fail <+ s = s s <+ fail = s fail ; s = fail s ; fail ≠fail (pourquoi ?)
Stratégies paramétrées
try(s) = s <+ idrepeat(s) = try(s ; repeat(s))Exemples
(try(b c))[a] = a (repeat(a b))[a] = b (repeat(b c <+ a b))[a] = c (repeat(b c))[a] = a
Primitives pour traverser
applique une stratégie à un ou plusieurs fils directes
Congruence applique une stratégie différente à chaque fils d’un
constructeurall
applique une stratégie à tous les filsone
applique une stratégie à un fils
Congruence
c(S1,…,Sn) pour chaque constructeur c
Exemples (f(a b))[a] = fail (f(a b))[f(a)] = f(b) (f(a b))[f(b)] = fail (g(try(b c) <+ try(a b)))[g(a,a)] = g(a,b)
Exercice définir la stratégie map sur les liste (cons,nil)
Congruence générique
all(S), échoue si S échoue sur un des fils Exemples
(all(a b))[f(a)] = f(b) (all(a b))[g(a,a)] = g(b,b) (all(a b))[g(a,b)] = fail (all(a b))[a] = a (all(try(a b)))[g(a,c)] = g(b,c)
Congruence générique
one(S), échoue si S ne peut pas s’appliquer sur un des fils
Exemples (one(a b))[f(a)] = f(b) (one(a b))[g(a,a)] = g(a,b) (one(a b))[g(b,a)] = g(b,b) (one(a b))[a] = fail
Stratégies de parcours
bottomup(S) = all(bottomup(S)) ; S topdown(S) = S ; all(topdown(S)) innermost(S) = bottomup(try(S ; innermost(S))) oncebu(S) = one(oncebu(S)) <+ S oncetd(S) = S <+ one(oncetd(S)) innermost(S) = repeat(oncebu(innermost(S))) outermost(S) = repeat(oncetd(outermost(S)))
Stratégies en Tom
Constructeurs élémentaires
Identity Fail Sequence Choice All One mu
Utilisation
Une stratégie est de type VisitableVisitor VisitableVisitor s = `Identity();
Un terme est de type Visitable Visitable t = `a();
Une stratégie peut s’appliquer sur un terme Visitable result = s.visit(t);
Une stratégie préserve le type Term t = `a(); Term result = (Term) s.visit(t);
Définition de stratégiesVisitableVisitor Try(VisitableVisitor S) {
return `Choice(S,Identity());}
VisitableVisitor Repeat(VisitableVisitor S) {return `mu(MuVar("x"),Choice(Sequence(S,MuVar("x")),Identity()));
}
VisitableVisitor OnceBottomUp(VisitableVisitor S) {return `mu(MuVar("x"),Choice(One(MuVar("x")),S)) }
} Exercice
implanter innermost(a b)
Stratégie élémentaire en Tom
%strategy RewriteSystem extends `Fails() {
visit Term {
a() -> { return `b(); }
}
}
VisitableVisitor S = `Repeat(OnceBottomUp(RewriteSystem()))
Term result = S.visit(`f(a(),g(b(),a())));
Utilisations
VisitableVisitor rule = new RewriteSystem();
Term subject = `f(g(g(a,b),g(a,a)));
`OnceBottomUp(rule).visit(subject);
`Innermost(rule).visit(subject);
`Repeat(OnceBottomUp(rule)).visit(subject);
(mode paranoïaque)VisitableVisitor rule = new RewriteSystem();Term subject = `f(g(g(a,b),g(a,a)));VisitableVisitor onceBottomUp =
`mu(MuVar("x"),Choice(One(MuVar("x")),rule));onceBottomUp.visit(subject));
VisitableVisitor innermostSlow = `mu(MuVar("y"),Choice(Sequence(onceBottomUp,MuVar("y")),Identity()));innermostSlow.visit(subject));
VisitableVisitor innermost = `mu(MuVar("x"),Sequence(All(MuVar("x")),Choice(Sequence(rule,MuVar("x")),Identity)));
innermost.visit(subject));
Questions
Comment calculer des ensembles de résultats
Exemples f(g(g(a,b),g(a,b))) trouver les x tels que g(x,b) filtre un sous
terme
Solution
considerer s(col) : g(x,b) col.add(x)
appliquer Try(BottomUp(s(col)))
énumérer col
Codage %strategy RewriteSystem(c:Collection) extends Identity() {
visit Term { g(x,b()) -> { collection.add(`x); } }}
Collection collection = new HashSet();VisitableVisitor rule = `RewriteSystem(collection);Term subject = `f(g(g(a,b),g(c,b)));`Try(BottomUp(rule)).visit(subject);System.out.println("collect : " + collection);
Stratégie Oméga
OmégaPosition
Replace et Subterm
Etant donnée une position p getReplace(t’) retourne une stratégie qui, appliquée
sur un terme donné, remplace le sous-terme à la position p donnée par le terme t’
getSubterm() retourne une stratégie qui retourne le sous-terme à la position p
ces stratégies encodent les l’accès à un sous-terme et l’opération de remplacement
cela permet d’encoder de l’exploration traversée + non-déterministe
Exemple complexe
Xmas
Principales applications