r éé criture pour la programmation et la preuve claude kirchner pierre-etienne moreau

Post on 03-Apr-2015

105 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Réécriture pour la programmation et la

preuveClaude Kirchner

Pierre-Etienne Moreau

Application à XML

Document XML

XML permet de décrire des documents structurés

<?xml version="1.0" encoding="UTF-8"?>

<Persons>

<Person Age="30"> <FirstName> Paul </FirstName> </Person>

<Person Age="42"> <FirstName> Mark </FirstName> </Person>

<Person Age="21"> <FirstName> Jurgen </FirstName> </Person>

<Person Age="21"> <FirstName> Julien </FirstName> </Person>

<Person Age="24"> <FirstName> Pierre </FirstName> </Person>

</Persons>

On peut voir un document XML comme un arbre

Transformation de documents XML

On a envie de pouvoir manipuler ces données pour y rechercher de l’information pour générer de nouveaux documents (HTML, LaTeX, PDF, XML, etc.)

Quels sont les outils permettant de le faire XSLT / XPath Xquery Xduce / Cduce DOM …

Peu permettent de manipuler un document XML en Java Les manipulations se font souvent en utilisant DOM directement

Exemple

On veut savoir s’il existe un noeud de la forme <Person><FirstName> Julien </FirstName></Person>

<?xml version="1.0" encoding="UTF-8"?>

<Persons>

<Person Age="30"> <FirstName> Paul </FirstName> </Person>

<Person Age="42"> <FirstName> Mark </FirstName> </Person>

<Person Age="21"> <FirstName> Jurgen </FirstName> </Person>

<Person Age="21"> <FirstName> Julien </FirstName> </Person>

<Person Age="24"> <FirstName> Pierre </FirstName> </Person>

</Persons>

Filtrage

Il faut savoir si un pattern XML filtre vers un noeud de document XML

On aimerait pouvoir écrire%match(t) {

<Person><FirstName> Julien </FirstName></Person> -> {

// Noeud trouvé

}

}

Ou plus généralement :<Person><FirstName> X </FirstName></Person> -> { … }

Modèle de donnée (simplifié)

ElementNode(name:str, attrList:TNodeList,

childList:TNodeList) -> TNode

AttributeNode(name:str, value:str) -> TNode

TextNode(data:str) -> TNode

conc(TNode*) -> TNodeList

XML vs. Term

Un document XML peut se voir comme un arbre<A a="at1"><B/></A>

est représenté par :

ElementNode("A",

conc(AttributeNode("a", "at1")),

conc(ElementNode("B",conc(),conc()))

)

Pattern XML

On veut pouvoir écrire un pattern de la forme<A a="at1">X</A>

qui sera encodé par :

ElementNode("A",

conc(AttributeNode("a", "at1")),

conc(X)

)

Questions

A-t-on : <A a="at1">X</A> << <A a="at1"><B/></A> ? <A a="at1">X</A> << <A a="at1"><B/><C/></A> ?

Quel est le type de X ? TNode ? TNodeList ? On voudrait pouvoir écrire

<A a="at1">X*</A> << <A a="at1"><B/><C/></A>

Quelles sont les solutions ?

Questions

En fonction du parseur, <A a="at1"><B/></A> peut être reconnu comme <A a="at1"><B/></A>

A-t-on : <A a="at1">X</A> << <A a="at1"><B/></A> ? <A a="at1">X*</A> << <A a="at1"><B/></A> ?

Comment est encodé <A a="at1"><B/></A> ?ElementNode("A",

conc(AttributeNode("a", "at1")),conc(

TextNode(""),ElementNode("B",conc(),conc()),TextNode(""))

) Est-ce que cela filtre ?

Notation explicite

<A a="at1">(_*,X,_*)</A>

qui correspond à :

<A a="at1">conc(_*,X,_*)</A>

A-t-on <A a="at1">(_*,X,_*)</A> << <A a="at1"><B/></A> ?

Oui, il y a 3 solutions

Notation implicite

<A a="at1">(_*,X,_*)</A>

qui correspond à :

<A a="at1">[X]</A>

qui correspond également à

<A a="at1">X</A>

A-t-on <A a="at1">X</A> << <A a="at1"><B/></A> ?

Oui, il y a 3 solutions

Attributs

Les attributs sont représentés par une liste de couples (nom,valeur)

Il existe également des notations implicites et explicites

Ainsi : <A a="at1"> correspond à <A [a="at1"]> qui correspond à <A (_*,a="at1",_*)>

Questions

A-t-on : <A a="at1"></A> << <A a="at1"></A> ? <A a="at1"></A> << <A a="at1" b="at2"></A> ?

Pourquoi ? car <A (_*,a="at1",_*)></A> << <A (a="at1" b="at2 »)></A> ?

A-t-on : <A a="at1" b="at2"></A> << <A a="at1" b="at2"></A> ? <A a="at1" b="at2"></A> << <A b="at2" a="at1"></A> ?

Non, car : (_*, a="at1", _*, b="at2", _*) !<< (b="at2", a="at1") Il faudrait du filtrage AC avec élément neutre!

Attributs dans Tom

On considère un ordre sur les noms d’attributs et les formes canoniques où les attributs sont triés Ainsi, <A b="at2" a="at1"></A> est représenté par

ElementNode("A",

conc( AttributeNode("a", "at1"),

AttributeNode("b", "at2")),

conc()) De même, pour les motifs

Utilisation dans Tom

Node sort(Node subject) { %match(subject) { <Persons>(X1*,p1,X2*,p2,X3*)</Persons> -> { if(`compare(p1,p2) > 0) { return sort(`xml(<Persons>

X1* p2 X2* p1 X3*</Persons>));

} } } return subject; }

Comparaison d’attributs

int compare(Node t1, Node t2) { %match(t1, t2) { <Person Age=a1><FirstName> n1 </FirstName></Person>, <Person Age=a2><FirstName> n2 </FirstName></Person> -> { return `a1.compareTo(`a2); } } return 0; }

Ancrage formel

Mapping

Problématique

Comment faciliter l’utilisation du filtrage dans les programmes existants ? en permettant un mélange des syntaxes en permettant de filtrer vers des structures

du langage hôte

Nous avons donc besoin de filtrer « modulo des vues »

Solution adoptée

Tom permet de « voir » les objets en mémoire comme des termes algébrique

Il faut pour cela définir un « ancrage formel » permettant de savoir si un terme commence par un

symbole donné d’accéder à un sous terme donné

Plus formellement

On considère les ensembles : [N], la représentation des entiers naturels [B], la représentation des booléens [F], la représentation des symboles [T(F)], la représentation des termes clos [X], la représentation des variables

Contraintes à respecter

t1,t2T(F),

eq([t1],[t2]) = [t1=t2]

fF, tT(F), is_fsym(t,f) = [Symb(t)=f]

fF, i[1..ar(f)], tT(F) subtermf(t,i) = [t|i]

Structure de données

struct term {int symb;

struct term **subterm;

}

On représente les symboles par des entiers (zero,3), (suc,5), (plus,7), …

Mapping de Nat vers une structure C

%typeterm Nat {

implement

equals(t1,t2)

}

%op Nat zero {

is_fsym(t)

}

%op Nat suc(p:Nat) {

is_fsym(t)

get_slot(p,t)

}

{ struct term* }

{ term_equals(t1,t2) }

{ t!=null && t->symb==3 }

{ t!=null && t->symb==5 }

{ t->subterm[0] }

Mapping

Permet de voir une structure arborescente comme un terme

Plus généralement, permet de voir n’importe quelle structure de donnée comme un terme

Permet de filtrer vers des objets en mémoire

Exercice

Peut-on voir les entiers machine comme des entiers de Peano ?

%typeterm Nat { implement { int }}%op Nat zero { is_fsym(t) { t==0 }}%op Nat suc(p:Nat) { is_fsym(t) { t>0 } get_slot(p,t) { t-1 }}

Peut-on filtrer vers des objets ?

class A { int a; }

class B extends A { int b; }

%typeterm A {

implement { A }

equals(t1,t2) {t1.equals(t2)}

}

%typeterm B {

implement { B }

equals(t1,t2) {t1.equals(t2)}

}

Mapping objet

%op A A(a:int) {

is_fsym(t) { t instanceof A } get_slot(a,t) { t.a } } %op A B(a:int,b:int) { is_fsym(t) { t instanceof B } get_slot(a,t) { t.a }

get_slot(b,t) { t.b } } A[a=x] << new A(3) B[b=x] << new B(2,3) A[a=x] << new B(2,3)

Demo

Questions

Doit-on écrire des mappings ?Que fait %vas au juste ?

Outils autour de Tom

Aterm, SDF, ApiGen, Vas

Bibliothèque ATerm

Aterm AFun ATermAppl ATermList ATermInt ATermReal ATermPlaceholder ATermBlob

ATermFactory

ATerms

Bibliothèque ATerm

Aterm AFun ATermAppl ATermList ATermInt ATermReal ATermPlaceholder ATermBlob

ATermFactory

getAnnotationsetAnnotationtoStringetc.

Bibliothèque ATerm

Aterm AFun ATermAppl ATermList ATermInt ATermReal ATermPlaceholder ATermBlob

ATermFactory

getNamegetArity

Bibliothèque ATerm

Aterm AFun ATermAppl ATermList ATermInt ATermReal ATermPlaceholder ATermBlob

ATermFactory

getAFungetArgumentsetArgumentetc.

Bibliothèque ATerm

Aterm AFun ATermAppl ATermList ATermInt ATermReal ATermPlaceholder ATermBlob

ATermFactory

getFirstgetNextelementAt insertappendconcatetc.

Bibliothèque ATerm

Aterm AFun ATermAppl ATermList ATermInt ATermReal ATermPlaceholder ATermBlob

ATermFactory

makeAFunmakeAppl…parsereadFromFile

etc.

Utilisation des ATerms

Aterm t1 = factory.parse("a")

Aterm t2 = factory.parse("f(a,b)")

t2.getArgument(1) == t1 ?

> true

Aterm t3 = t2.setArgument(t1,2)

> t3 = f(a,a)

Aterm t4 = factory.parse("f(a,f(b))")

> ‘f’ n’a pas de signature particulière

Les Aterms permettent de construire des termes, mais il n’y a pas de sécurité (signature, types)

ApiGen / Vas

A partir d’une signature multi-sortéeGénère des classes, reposant sur les

Aterms, permettant de représenter les termes partage maximal typage fort des termes tout terme typé est un ATerm

Exemple

Module Expressions

true -> Bool

false -> Bool

eq(lhs:Expr, rhs:Expr) -> Bool

id(value:str) -> Expr

nat(value:int) -> Expr

add(lhs:Expr, rhs:Expr) -> Expr

mul(lhs:Expr, rhs:Expr) -> Expr

Classes générées

Classes générées

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))

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)

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ôle l’application des règlespouvoir spécifier simplement le

« traversée » d’une terme (I.e. appliquer une règles dans les sous-termes)

tout en séparant règle et contrôle

Solution

Utiliser des stratégiesCombiner des transformations élémentairesExemples

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 <+…)

Autres stratégies de traverse

simplify = bottomup(repeat(R1 <+ …))simplify = topdown(repeat(R1 <+ …))

… Slide 14

Stratégies en Tom

Constructeurs élémentaires

Identity Fail Not Sequence Choice All One Some IfThenElse Omega mu

Définition de stratégies%op VisitableVisitor Try(s1:VisitableVisitor) {

make(v) { `Choice(v,Identity) }}%op VisitableVisitor Repeat(s1:VisitableVisitor) {

make(v) { `mu(MuVar("x"),Choice(Sequence(v,MuVar("x")),Identity())) }}%op VisitableVisitor TopDown(s1:VisitableVisitor) { make(v) { `mu(MuVar("x"),Sequence(v,All(MuVar("x")))) }

%op VisitableVisitor OnceBottomUp(s1:VisitableVisitor) {make(v) { `mu(MuVar("x"),Choice(One(MuVar("x")),v)) }

}%op VisitableVisitor Innermost(s1:VisitableVisitor) { make(v) { `mu(MuVar("x"), Sequence(All(MuVar("x")),

Try(Sequence(v,MuVar("x"))))) }}

}

Stratégie élémentaire en Tom

class RewriteSystem extends strategy.term.termVisitableFwd {public RewriteSystem() {

}public Term visit_Term(Term arg) throws VisitFailure {

%match(Term arg) { a() -> { return `b(); }

b() -> { return `c(); } g(c(),c()) -> { return `c(); } }

}}

throw new VisitFailure();

super(`Fail());

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 class RewriteSystem extends strategy.term.termVisitableFwd {

Collection collection; public RewriteSystem(Collection c) { super(`Fail()); this.collection = c; } public Term visit_Term(Term arg) throws VisitFailure { g(x,b()) -> { collection.add(`x); } }

return arg;}

}

%match(Term arg) {

Codage

Collection collection = new HashSet();

VisitableVisitor rule = new 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 pgetReplace(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

top related