https://svn.lrde.epita.fr/svn/xrm/trunk
Index: ChangeLog from SIGOURE Benoit sigoure.benoit@lrde.epita.fr
Add support for ranges in constant propagation. /!\ This commit has all the debugging messages left in the source of prism-desugar because it seems to trigger a bug in the Stratego compiler. Therefore we'll be able to use this revision to investigate the bug. Roughly, what happens is that a strategy such as: a;b;c;...; (X <+ Y <+ Z ...) is inlined and transformed (in C) as something like: ((a;b;c;...;X) <+ (a;b;c;...;Y) <+ (a;b;c;...;Z) <+ ...) which is totally wrong if a;b;c;... has side effects (such as defining dynamic rules)
* src/str/prism-desugar.str: Add support for ranges. * src/str/reals.str: Fix newbie mistake. * tests/prism/testeq.pm: New. * TODO: Update.
TODO | 20 ++++++------- src/str/prism-desugar.str | 70 +++++++++++++++++++++++++++++++--------------- src/str/reals.str | 4 +- tests/prism/testeq.pm | 21 +++++++++++++ 4 files changed, 81 insertions(+), 34 deletions(-)
Index: src/str/prism-desugar.str --- src/str/prism-desugar.str (revision 37) +++ src/str/prism-desugar.str (working copy) @@ -147,43 +147,69 @@ EvalGtEq: |[ d1 >= d2 ]| -> <compare(geqR)>(d1, d2)
- /* FIXME: The following rules could be generalized - We need to check whether d1 appears in the list at the RHS */ - EvalEq: - |[ d1 = d2 ]| -> <compare(real-eq)>(d1, d2) + EvalSimpleEq: + |[ d1 = d2 ]| -> res + where say(!"@@@ EvalSimpleEq");debug + ; <compare(real-eq)>(d1, d2) => res;debug + + EvalSimpleRangeEq: + |[ e = e1..e2 ]| -> res + where say(!"@@@ EvalSimpleRangeEq range");debug + ; <DesugarRangeEq(|e)>(Range(e1, e2)) => res;debug + + EvalComplexEq: + Eq(e, a*) -> res + where say(!"@@@ EvalComplexEq");<debug>a* + ; !a* + ; map(DesugarRangeEq(|e) <+ \ e2 -> |[ e=e2 ]| );debug + ; foldr(!False(), \ (x, y) -> Or(x, y) ) => res + ; say(!" end of EvalComplexEq:");debug
- /* FIXME: Same thing as EvalEq */ +strategies + + EvalEq = ?a;?Eq(_,_);say(!"@@@ EvalEq starting:");debug;rules(Hello: a); + (?Eq(_, [Eq(_, _)]) <+ EvalSimpleEq <+ EvalSimpleRangeEq <+ (?|[ e = e2 ]| < debug;fail + EvalComplexEq)) + +rules + + + //EvalNeq: + // |[ d1 != d2 ]| -> <compare(not(real-eq))>(d1, d2) EvalNeq: - |[ d1 != d2 ]| -> <compare(not(real-eq))>(d1, d2) + NotEq(e, a*) -> res + where say(!"@@@ EvalNeq");<not(?[_])>a*;<debug>a* + ; map(DesugarRangeNeq(|e) <+ \ e2 -> |[ e!=e2 ]| );debug + ; foldr(!False(), \ (x, y) -> Or(x, y) ) => res;debug + + DesugarRangeEq(|e): + Range(e2, e3) -> |[ e >= e2 & e <= e3]| + + DesugarRangeNeq(|e): + Range(e2, e3) -> |[ e < e2 & e > e3]|
rules -/* FIXME: Can we optimize this in a single rule? - Since the optimization would decrease readability, - is it worth it? - eg: - EvalAnd: - And(x, y) -> True() where x => True(); y => True() - EvalAnd: - And(x, y) -> False() where x => False() + y => False() -*/
EvalAnd: |[ true & true ]| -> |[ true ]| EvalAnd: - |[ true & false ]| -> |[ false ]| + |[ e & false ]| -> |[ false ]| + EvalAnd: + |[ false & e ]| -> |[ false ]| EvalAnd: - |[ false & true ]| -> |[ false ]| + |[ e & true ]| -> |[ e ]| EvalAnd: - |[ false & false ]| -> |[ false ]| + |[ true & e ]| -> |[ e ]|
EvalOr: - |[ true | true ]| -> |[ true ]| + |[ true | e ]| -> |[ true ]| EvalOr: - |[ true | false ]| -> |[ true ]| - EvalOr: - |[ false | true ]| -> |[ true ]| + |[ e | true ]| -> |[ true ]| EvalOr: |[ false | false ]| -> |[ false ]| + EvalOr: + |[ e | false ]| -> |[ e ]| + EvalOr: + |[ false | e ]| -> |[ e ]|
rules
Index: src/str/reals.str --- src/str/reals.str (revision 37) +++ src/str/reals.str (working copy) @@ -16,8 +16,8 @@ divR = (string-to-real, string-to-real); divr; real-to-string
gtR = where((string-to-real, string-to-real); gtr) - geqR = where((string-to-real, string-to-real); ?(x,x) <+ gtr) - ltR = where((string-to-real, string-to-real); not(?(x,x) <+ gtr)) + geqR = where((string-to-real, string-to-real); (?(x,x) <+ gtr)) + ltR = where((string-to-real, string-to-real); (not(?(x,x) <+ gtr))) leqR = where((string-to-real, string-to-real); not(gtr)) maxR = where((string-to-real, string-to-real); maxr) minR = where((string-to-real, string-to-real); minr) Index: tests/prism/testeq.pm --- tests/prism/testeq.pm (revision 0) +++ tests/prism/testeq.pm (revision 0) @@ -0,0 +1,21 @@ +module test + x : [0..42]; + [] 10=10 -> (x'=1); + [] 10=1 -> (x'=2); + [] 10=1 | 10=10 -> (x'=3); + + [] 10<=10 -> (x'=4); + [] 10<10 -> (x'=5); + [] 10>=10 -> (x'=6); + [] 10>10 -> (x'=7); + + [] 1<=10 -> (x'=8); + [] 1<10 -> (x'=9); + [] 1>=10 -> (x'=10); + [] 1>10 -> (x'=11); + + [] 10<=1 -> (x'=12); + [] 10<1 -> (x'=13); + [] 10>=1 -> (x'=14); + [] 10>1 -> (x'=15); +endmodule Index: TODO --- TODO (revision 37) +++ TODO (working copy) @@ -98,16 +98,6 @@ ## Desugarisation ## ## -------------- ##
- * Desugarise ranges (?) - x = 1..5,7,10..13 - ==> (x>=1 & x<=5) | (x=7) | (x>=10 & x<=13) - - * Expand formulas, eg - formula lfree = p2=0..4,6,10; - // ... - [] p1=2 & lfree -> (p1'=4); - ==> [] p1=2 & (p2=0..4,6,10) -> (p1'=4); - ## ------------- ## ## Type checking ## ## ------------- ## @@ -175,3 +165,13 @@ prism-desugar to take these values into account (which will automagically allow things such as x[N] to declare an array for instance, where N is a global const) + + * Expand formulas, eg + formula lfree = p2=0..4,6,10; + // ... + [] p1=2 & lfree -> (p1'=4); + ==> [] p1=2 & (p2=0..4,6,10) -> (p1'=4); + + * Desugarise ranges (?) + x = 1..5,7,10..13 + ==> (x>=1 & x<=5) | (x=7) | (x>=10 & x<=13)