Post on 06-Jan-2016
description
transcript
Computationally Equivalent Elimination of Conditions
Traian Florin Şerbănuţă
Grigore Roşu
University of Illinois at Urbana-Champaign
Observations and Motivation
• Equational definitions are natural and useful
• Executable equational specifications desirable– Many languages support them– Typically executed by rewriting
• However, many interesting specifications involve conditional equations
• Conditional rewriting harder to implement due to the necessity to handle control contexts
Would it be possible to automatically transform a
conditional rewrite system into an unconditional one, so that a
straightforward and more amenable to optimize unconditional rewriting
engine can be used instead?
Would it be possible to automatically transform a
conditional rewrite system into an unconditional one, so that a
straightforward and more amenable to optimize unconditional rewriting
engine can be used instead?
?
Overview
• Why conditional rules are inconvenient
• Computational equivalence
• Previous transformations
• Proposed solution
• Optimizations & extensions
• Conclusion and future work
Conditional Rules
l->r cl->cr
We here consider normal conditional rules:- one equality in condition, oriented- condition’s rhs cr is a normal form constant- all variables in the rule occur in l(technique not limited to these)
θ(l)
->θ(r)
To apply the rule,one should firstrecursively show
θ(cl) -> cr*
Why Conditional Rules are Inconvenient
l->r cl->cr
θ(l)
->?
t
->?
θ(cl)…
control context
Many rules may apply at the same timeBookkeeping, search, backtracking; complex engines
“Bad” Example
SignaturePeano natural numbers plus …odd, even : Nat -> Bool
Rulesodd(s n) -> true even(n) -> trueodd(s n) -> false even(n) -> falseodd(0) -> false
even(s n) -> true odd(n) -> trueeven(s n) -> false odd(n) -> falseeven(0) -> true
On a 2.4GHz 4GB machine, Maude takes 7.9s and Elan 548.1s to evaluate even(21). Neither finished even(31) in less than 2h.
Analogy with Functional Languages
Consider the following trace of function calls:
f
g
h
f
x
Envf
g
h
f
x
Envg
hf
xf
x
Many functional languages today are applied a CPS transformation and then compiled. This way, all
function calls occur on tail positions, so nested environments not needed
anymore. Thus, the control context is translated into data context. Can we
do a similar thing for conditional rewrite rules and transform them into
unconditional ones?
Many functional languages today are applied a CPS transformation and then compiled. This way, all
function calls occur on tail positions, so nested environments not needed
anymore. Thus, the control context is translated into data context. Can we
do a similar thing for conditional rewrite rules and transform them into
unconditional ones?
!
Get a normal form of the transformed term in R’We would like a normal form of t in RR’ can be used transparently to perform computations in RCreate a better world for t – send it to R’
Computational Equivalence
CTRS R
t
R’
nfR’(φ(t))
R
nfR(t)ψ
TRS R’
φ(t)φ
Extract the normal form of t in the original system
Previous Transformations
… not computationally equivalent, or impose strong restrictions on the
original CTRS, or require strong reduction support from target TRS
… not computationally equivalent, or impose strong restrictions on the
original CTRS, or require strong reduction support from target TRS
Running Example: Bubble-sort
.(x, .(y,l))-> .(y, .(x,l) x>y->true
One-rule CTRS(can be quite efficient on parallel engines – linear time):
Previous Transformations: Unravelings
• Bergstra&Klop, Marchiori, Ohlebusch, ….(x, .(y,l))->.(y, .(x,l) x>y->true
goes to:
• Modular, reflect termination– Useful for analyzing CTRSes
• Not Computationally Equivalent.(2, .(3, .(1,[])))-> U(2>3,2,3,.(1,[]))-> U(false,2,3,.(1,[]))
.(x, .(y,l) -> U(x>y,x,y,l)U(true,x,y,l) -> .(y, .(x,l))
Previous Transformations: Viry (I)
• Fore each operation in the term, store the status of the conditions in all rules applicable at that position
• Not Unravelling (loses modularity)• First step toward computational equivalence
C1,C2,C3,…,Cn
Ci represents the current status of the i-th conditional rule that can be potentially applied on
Normal form in TRSdoes not yieldnormal form in CTRS;… problematic proofs
• Viry proves his transformation – preserves reachability, termination, ground confluence
(some strategies needed – conditional eagerness)– … thus, Computational Equivalence
• However…
2>32
.(x,.(y,l)->.(y,.(x.l) if x>y->true
3
. (1,[])
2>3
1
2
.(3,[])
… therefore, Viry did not solve the problem, despite the special reduction strategies he
requires for the TRS …
… therefore, Viry did not solve the problem, despite the special reduction strategies he
requires for the TRS …
Previous Transformations: Viry (II)
Restrict CTRS to constructor based and left linear
Functional languages are constructor based
!!! Bubble sort not constructor-based; so excluded
!!! Canonical CTRS-es are also “functional”– Rewriting as a programming paradigm
Challenge remains:– Can we transform any CTRS into a computationally
equivalent, unrestricted (wrt evaluation) TRS ?
Previous Transformations:“Fix” by Antoy, Brassel and Hanus
• Bits telling whether conditions can be tried• “Flush” condition bits when needed• No left linearity nor constructor baseness needed• Requires evaluation strategies for the TRS
– if_then_else_fi and equal?(_,_)
Previous Transformations: Rosu
2
3 1,[]
1
1
213,[]
0
1
11
2
3,[]1
0 1 0
0
Our Solution in This Paper• Add Rosu’s “flushing” to Viry’s transformation
• Transform the i-th conditional rule topped in σ
into
• And add rules for “flushing” the conditions
l -> r cl -> cr
(l,,i) -> (l,{(cl)},i)(l,{(cr)},i) -> {(r)}
σ(…,{ti},…,c1,…,ck) -> {σ(…,ti,…,,…,)}{{x}} -> {x}
Example – Bubble Sort
.(x, .(y,l))->.(y, .(x,l) x>y->true
gets translated to:
.(x,.(y,l,b),) -> .(x,.(y,l,b),x>y)
.(x,.(y,l,b),true) -> {.(y,.(x,l,),)}
.(x,{l},b) -> {.(x,l,)}{{l}} -> {l}
2
3 1,[]
213,[]
false
1
3,[]
2>3false
3>1true
2>1true 1
2
3,[]
1>2false
2>3false
Analogy to CPS Transformation
• CPS transformation adds an additional argument to each function, stating the remaining part of the computation
• We do a similar thing, by adding a “tuple” argument to some operations, statingthe status of the conditional rules
Our Results
• Computational Equivalence– canonical CTRS canonical TRS on relevant terms
• Reachability reflected under left-linearity or confluence of the CTRS
• Under left-linearity – confluence yields confluence
– termination yields termination
• Termination, confluence, left-linearity reflected
Optimizations
• Condition Sharing– Compact rules sharing same lhs and cond. lhs
• Non-overlapping rules with same top op. – Share the same additional position
• Constructor-based systems– The “flushing” brackets no longer necessary
Optimized Odd/Evenodd(s n) -> true even(n) -> true
odd(s n) -> false even(n) -> falseodd(0) -> falseeven(s n) -> true odd(n) -> true
even(s n) -> false odd(n) -> falseeven(0) -> true
is transformed to (optimizations included)odd(s n,) -> odd(s n,even(n,,))odd(s n,true) -> trueodd(s n,false) -> falseodd(0, b) -> falseSimilarly for even
Becomes linear due to “condition sharing”
Experimental results (I)
Odd/Even Cond Uncond Optim.
Elan odd(18) 85.79 5.55 ~0
Maude odd(24) 84.97 17.05 ~0
ASF odd(25) 0.02 7.46 0.01
Bubble Sort Cond Optim.
Elan 100 28.19 ~0
Maude 5000 72.34 43.53
ASF 5000 81.64 85.71
Experimental Results (II)
Cond Uncond Optim.
Elan 105/6 10.85 5.82 5.23
Maude 107/2 75.98 67.59 41.61
ASF 106/2 13.96 15.28 14.53
Cond Optim.
Maude 8 18.06 12.76
ASF 8 5.72 14.20
Quotient / Remainder
Simple PL with arrays – permutation generation
Extensions: Matching in conditions
• Matching in conditions powerful and useful; for example, “big-step” SOS rules can be seamlessly expressed:
<E1+E2,S> -> <V1+V2,S2> if <E1,S> -> <V1,S1> & <E2,S1> -> <V2,S2>
encodes the SOS rule
<E1,S> -> <V1,S1> , <E2,S1> -> <V2,S2> <E1+E2,S> -> <V1+V2,S2>
• Our transformation and results extend easily (but tediously) to CTRS-es with matching in conditions
• For example, our transformation produces:
<E1+E2,S,> -> <E1+E2,S,c1(<E1,S,>)> <E1+E2,S,c1(<V1,S1,>)> -> E1+E2,S,c2(<E2,S1,>,V1)> <E1+E2,S,c2(<V2,S2,>,V1)> -> <V1+V2,S2,>
Extensions: Rewriting Modulo Equations?
• Our results work only for restricted rewriting modulo assoc, comm, unit– when for any conditional rule, at most one
matching at any position at any time
• General problem open …– Appears hard
Conclusion and Future Work
• Previous CTRS-to-TRS translations aiming at computational equivalence – have flaws or– impose strong restrictions on CTRS, or– require special support from the TRS
• We proposed a general & automatic transformation avoiding most limitations of previous transformations
• Future work– Extension to non-deterministic CTRSes (rewriting logic)– Implementation & Debugging / Tracing– Can rewriting modulo be supported as well?– Optimize “condition flushing”– Investigate analysis capabilities of the transformation
Additional slides
Simulating join systems by normal ones
• Most people write conditional rules this way:
• With some additional helping operations
• One gets the following normal rule
Signatureeq? : s s -> Bool__ : Bool Bool -> Bool (trivial)
Equationseq?(x,x) = true
l -> r <= cl1=cr1,cl2=cr2,…,cln=crn
l -> r <= eq?(cl1,cr1) … eq?(cln,crn ) -> true
Axiomatizing IF
• We will still need to treat differently the cases when the condition is true/false
• No control context will be created for this purpose, but IF needs to be explicit
Signatureif : Bool s s -> s
Equationsif(true,x,y) = x
if(false,x,y) = y
Analogy with Functional Languages
Consider the following trace of function calls:
f
g
h
f
x
Envf
g
h
f
x
Envg
hf
xf
x
Many functional languages today are applied a CPS transformation and then compiled. This way, all
function calls occur on tail positions, so nested environments not needed
anymore. Thus, the control context is translated into data context. Can we
do a similar thing for conditional rewrite rules and transform them into
unconditional ones?
Many functional languages today are applied a CPS transformation and then compiled. This way, all
function calls occur on tail positions, so nested environments not needed
anymore. Thus, the control context is translated into data context. Can we
do a similar thing for conditional rewrite rules and transform them into
unconditional ones?
!
Towards a Rewriting Virtual Machine 1mai punem asta?
• The proposed transformation can be applied as a front-end to any existing rewriting engines
• On the odd/even example, it already brings a 3x speed increase in Maude and 10x in Elan
One can develop a basic, unconditional and very fast rewrite
virtual machine, and then define higher level languages, like Maude or Elan, by transforming their specs
into unconditional ones
One can develop a basic, unconditional and very fast rewrite
virtual machine, and then define higher level languages, like Maude or Elan, by transforming their specs
into unconditional ones
Towards a Rewriting Virtual Machine 2
• Such an RVM can also be used to define and design programming languages and analysis tools for them
• We have operationally defined as unconditional rewrite systems several (fragments of) languages– BC,Scheme, Java, ML, OCAML
– Continuation-based definitions
– About 2-3 weeks per language
– Actual Scheme is only 50% faster than our unconditional rewrite definition in Maude!
• However, an unconditional RVM can be very fast and highly parallel, so one can get quickly correct and competitive interpreters for programming languages
Previous TransformationsViry (II)
1. For each , number all conditional rules
where l = (t1,…,tn), from 1 to k
2. Add k additional arguments to
l -> r cl -> cr
Previous TransformationsViry (III)
• Transform the i-th such rule ρσ,i
where l = (t1,…,tn), into two rules
(u) adds for extra arguments
(l,X,i) adds distinct variables for extra arguments, except the i-th at root, which is X
ρσ,i: l -> r cl -> cr
(l,,i) -> (l,[(cl),Vars(l)],i)(l,[(cr),Vars(l)],i) -> (r)
Analogy to CPS Transformation
• Functional programs are typically applied a CPS transformation and then compiled– Simpler and more efficient compilers
• CPS transformation adds an additional argument to each function, stating the remaining part of the computation
• We do a similar thing, by adding a “tuple” argument to some operations, statingthe status of the conditional rules