Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
1 Strategic Programming in Java Pierre-Etienne Moreau Antoine Reilles Stratego User Day, December, 1st, 2006 http://tom.loria.fr 1 2 Context • Protheo group, Nancy (C. Kirchner) • 4 permanent researchers • 12 PhD students • Application domain: improve the quality of software • • • semantics of (rule and graph based) languages: Rho calculus theorem provers: deduction modulo, termination rule based programming: Elan, …, Tom – 4 PhD students involved – program analysis – compilation – certification – language design (constraint, business rule) http://tom.loria.fr 2 3 Motivations After 20 years of research in rewriting We are convinced that: • specifying by rewriting is a nice idea But, we now want to: • • make rewriting usable in practice integrate rewriting into existing programming environments http://tom.loria.fr 3 4 Motivations • Our approach: • • take the best of ASF+SDF, ELAN, Maude, and Stratego design and develop a set of Java tools that offer similar constructs: – algebraic data-type (Gom) – equational pattern matching (Tom) – strategic programming (Java Library + Gom) – simplification rules (Tom + Gom) http://tom.loria.fr 4 5 Short presentation of Tom • A Java program is a Tom program import pil.term.types.*; import java.util.*; public class Pil { … public final static void main(String[] args) { Expr p1 = …; System.out.println("p1 = " + p1); … } } http://tom.loria.fr 5 6 Tom adds algebraic data-types to Java • Gom supports many-sorted first order signature %gom { module Term imports int String import java.util.*; abstract syntax public class Pil { Bool = … | True() public final static void main(String[] args) { | False() | Eq(e1:Expr, e2:Expr) Expr p1 = …; Expr = System.out.println("p1 = " + p1); | Var(name:String) | Let(var:Expr, e:Expr, body:Expr) … | Seq(i1:Expr, i2:Expr) } | If(cond:Bool, e1:Expr, e2:Expr) } | a() | b() } import pil.term.types.*; http://tom.loria.fr 6 7 An algebraic term is a Java object • Back-quote (`) to build a term %gom { import pil.term.types.*; module Term imports int String import java.util.*; abstract syntax public class Pil { Bool = … | True() public final static void main(String[] args) { | False() | Eq(e1:Expr, e2:Expr) Let(Var("y"),b(),Var("x"))); Expr p1 = `Let(Var("x"),a(), Expr = System.out.println("p1 = " + p1); | Var(name:String) | Let(var:Expr, e:Expr, body:Expr) … | Seq(i1:Expr, i2:Expr) } | If(cond:Bool, e1:Expr, e2:Expr) | a() } | b() } http://tom.loria.fr 7 8 Tom adds pattern matching to Java • %match supports syntactic and associative pattern matching import pil.term.types.*; import java.util.*; public class Pil { public static String pretty(Object o) { %match(o) { Var(name) -> { return `name; } … Let(var,expr,body) -> { public final static void main(String[] args) { " + pretty(`var) + return "let " <- " + pretty(`expr) + Expr p1 = …; " in " + pretty(`body); System.out.println("p1 = " }+ p1); …(pretty(p1)); … } } return o.toString(); … } http://tom.loria.fr } 8 9 Summary • Tom offers 3 new constructs: • • • %gom ` %match : generate a typed data structure : build a term : syntactic matching and list-matching Data structure Gom Tom Pattern matching Tom+Java Java http://tom.loria.fr 9 10 Demo 10 11 Strategies in Tom • Tom is powerful, but clearly not enough • There is no separation between Transformation and Control • Question: • • • starting from the JJTraveler library (J. Visser, OOPSLA 2001) studying ASF+SDF, ELAN and Stratego can we design a powerful strategy language, usable in Java ? • The answer is Yes http://tom.loria.fr 11 12 First inspiration: Stratego [E. Visser] • Elementaty strategies • • • Id Fail Transformation rule • Basic strategies • • • • • Sequence Choice All One Not • Parameterized and recursive strategies • • • • Try(s) = Choice(s,Identity) Repeat(s) = Try(Sequence(s,Repeat(s))) Repeat(s) = mu x . Try(Sequence(s,x)) BottomUp(s) = mu x . Sequence(All(x),s) http://tom.loria.fr 12 13 Second inspiration: JJTraveler [J. Visser] public interface Visitor { /** Pay a visit to any visitable object. */ public Visitable visit(Visitable any) throws VisitFailure; } public interface Visitable { /** Returns the number of children of any visitable. */ public abstract int getChildCount(); /** Returns the ith child of any visitable. */ public abstract Visitable getChildAt(int i); /** Replaces the ith child of any visitable, and returns this visitable. */ public abstract Visitable setChildAt(int i, Visitable child); } http://tom.loria.fr 13 14 Visitor combination and traversal control module term T1 = a() | b() | f(arg:T1) T2 = … class termForward { Visitable visit(Visitable v) { return ((termAbstractType)v).accept(this); } T1 visit_T1(T1 arg) { return default.visit(arg); } T2 visit_T2(T2 arg) { return default.visit(arg); } } class T1 extends termAbstractType { termAbstractType accept(termVisitor v) { v.visit_T1(this); } } class Rule extends termForward { public Rule() { super(new Fail()); } T1 visit_T1(T1 arg) { // code that implements lhs -> rhs // … return new Fail().visit(arg); } } http://tom.loria.fr abstract class termAbstractType { termAbstractType accept(termVisitor v); } interface termVisitor { T1 visit_T1(T1 arg); T2 visit_T2(T2 arg); } This is a Strategy! 14 15 TopDown(Rule) T1 t = `f(a,f(a,b)); Visitor v = new TopDown(new Rule()); v.visit(t); Sequence TopDown(s) = mu x . Sequence(s,All(x)) s All public class TopDown extends Sequence { public TopDown(Visitor s) { super(s,new All(this)); super(s,null); then = new All(this); } } public class Sequence implements Visitor { public Visitor first; public Visitor then; … public Visitable visit(Visitable any) throws VisitFailure { return then.visit(first.visit(any)); } } http://tom.loria.fr 15 16 Comparison with Stratego • Each elementary strategy is an object • Execution is done via interpretation (method call) • Failure is implemented via Java exception http://tom.loria.fr 16 17 Elementary strategies in Tom • A Rule is an elementary strategy %strategy RenameVar(n1:String,n2:String) extends Identity() { visit Expr { Var(n) -> { if(`n==n1) return `Var(n2); } } } • Identity and Fail are also elementary strategies Expr p1 = `Let(Var("x"),a(), Let(Var("y"),b(),Var("x"))); Expr p2 = `RenameVar("x","z").visit(p1); > Let(Var("x"),a(), Let(Var("y"),b(),Var("x"))) • • • a strategy is built using ` “x” and “z” are parameters of sort String the rule is applied once, at root position http://tom.loria.fr 17 18 Basic strategies Expr p1 = `Let(Var("x"),a(), Let(Var("y"),b(),Var("x"))); Expr p2 = `BottomUp(RenameVar("x","z”)).visit(p1); > Let(Var(”z"),a(), Let(Var("y"),b(),Var(”z"))) • Big difference wrt. JJTraveler: • BottomUp is user defined using the mu operator public Strategy BottomUp(Strategy s) { return `mu(MuVar("x"),Sequence(All(MuVar("x")),s)); } http://tom.loria.fr 18 19 Key ingredients • A strategy is a term • • • can be built matched traversed • Mu-expansion is done by applying a BottomUp Mu Mu x Sequence x Rule Sequence All Rule All x http://tom.loria.fr 19 20 How does it work? %typeterm Strategy { implement { VisitableVisitor } equals(t1,t2) { t1.equals(t2) } } %op Strategy Fail() { is_fsym(t) { t instanceof Fail } make() { new Fail() } } %op Strategy Choice(s1, s2) { is_fsym(t) get_slot(s1,t) get_slot(s2,t) make(first,then) } http://tom.loria.fr • `Choice(Rule(),Fail()); • is equivalent to: • new Choice(new Rule(), new Fail()) • We have Choice(x,y) << s • `BottomUp(Expand()).apply(s) returns a new Strategy { t instanceof Choice} { t.getChildAt(FIRST) } { t.getChildAt(THEN) } { new Choice(first,then) } 20 21 Current library: basic.tom composed.tom 21 22 Parameterized strategies • a strategy can be parameterized by values: %strategy RenameVar(n1:String,n2:String) extends Identity() { … } • a strategy can do side effects: %strategy CollectVar(c:Collection) extends Identity() { visit Expr { v@Var(_) -> { c.add(v) } } } Collection set = new HashSet(); `BottomUp(CollectVar(set)).apply(p1); http://tom.loria.fr 22 23 Strategies parameterized by a strategy Mu • sometimes we need to recursively call the current calling strategy `BottomUp(Rule()).visit() x Sequence %strategy Rule() extends Identity() { visit Expr { Sequence … } All Let(v,e,body) -> { … `BottomUp(Rule()).visit(body); } } %strategy Rule(s:Strategy) extends Identity() { Debug Rule visit Expr { Let(v,e,body) -> { • this breaks {separation between rules and control %match(s) Mu(x, Choice(…)) -> { Strategy `debugWeaver().visit(s); • solution: give ds the= calling context as argument … `ds.visit(body); `mu(MuVar(“s”),BottomUp(Rule(MuVar(“s”)).visit() } }%strategy Rule(s:Strategy) extends Identity() { } visit Expr { } Let(v,e,body) -> { … `s.apply(body); } } } } http://tom.loria.fr 23 24 Demo 24 25 From ASF+SDF, ELAN, Maude and Stratego • From ASF+SDF • list-matching (associative matching with neutral element) • From Stratego • • traversal strategies (All, One) naming and semantics of operators • From ELAN • • • • statically typed rules and strategies non-determinism experience no AC, no backtracking strategy as a term • New in Tom • • • identity based strategies strategy can be applied on a strategy notion of position http://tom.loria.fr 25 26 Identity based strategies %strategy Rule() extends Fail() { // a -> b // default: failure } Innermost(s) = mu x . All(x) ; ((s ; x) <+ Id) `Innermost(Rule()).visit(t); %strategy RuleId() extends Identity() { // a -> b // default: x -> x } InnermostId(s) = mu x . All(x) ; SequenceId(s,x) `InnermostId(RuleId()).visit(t); http://tom.loria.fr 26 27 Other nice features • A strategy knows where it is applied (global information) • useful to implement non-deterministic search (prover, model checker) • Gom provides a hook mechanism • useful to maintain terms in canonical form (sorted list) • Anti-pattern matching • car(white,!ecological) • XML pattern matching • <A>(_*, x, _*, x, _*)</A> -> { … } • Strategy library for graphs • useful for bytecode analysis http://tom.loria.fr 27 28 Conclusion • There are many similarities with Stratego • Integration of rules and strategies in a Java environment • Pure Java implementation • Main advantages: • • • • Tom and Java data-structures are compliant makes debugging easier any Java program is a Tom program no deployment problem • Room for improvements: • • • better integration into Java connection to SDF support for concrete syntax http://tom.loria.fr 28