-
Notifications
You must be signed in to change notification settings - Fork 61
Program transformation solution attempts
syntax Exp ::= "x" | "y" | "z" | Exp "*" Exp
rule [s] x => z
Applies s
to all t
's subterms, and succeeds if all subterms succeed.
s(x * x) => z * z
s(x * y) => x * y
It could be seen as a generalization of k's strict
. It applies s
to all children and succeeds if s
succeeds for all of them. strict
could be seen as doing the same thing, where "succeeds" means isResult
.
This brings forward a more interesting discussion:
Could we make a parallel between "stuck" and "failed". Could we see a computation that is stuck with something atop the k cell as a computation that failed. Inversely, could we encode strategy failure as "stuck" with something atop the "monitor" (or different cell)?
##Deprecated discussion
Something along the lines of the following (partial) implementation for all
:
rule <k> T(C1 R) => C1 ~> T(HOLE(C1) R) </k> <s> all(S) => S ~> all(S) ...</s>
rule STUCK <k> _ ~> T(HOLE(C1) R) => T(C1 R) </k> <s> S ~> all(S) => false ...</s>
rule <k> T(R) </k> <s> S ~> all(S) => true</s> if isResult(R)
Assuming T
is AC.
A problem with this approach is that if S
has side effects, they will not be rolled back on failure. Whether this is a good thing or not is an open discussion.
Now, slowly through the operators:
Assuming that when no rule can be applied, the engine adds a cell <blocked/>
. We also have the rule:
rule <blocked/> <s> X => false ...</s>
rule <s> A <* B => A ~> HOLE <* B ...</s> <k> X => X ~> SNAPSHOT(X) ... </k>
rule <s> true <* B => B ...</s>
rule <s> false <* B => false ...</s>
rule <s> true ~> HOLE <* B => true <* B ...</s> <k> X ~> SNAPSHOT(_) => X ...</k>
rule <s> false ~> HOLE <* B => true <* B ...</s> <k> _ ~> SNAPSHOT(X) => X ...</k>
rule <s> A <+ B => A ~> HOLE <+ B ...</s>
rule <s> false <+ B => B ...</s>
rule <s> true <+ B => true ...</s>
rule <s> true ~> HOLE <+ B => true <* B ...</s> <k> X ~> SNAPSHOT(_) => X ...</k>
rule <s> false ~> HOLE <+ B => true <* B ...</s> <k> _ ~> SNAPSHOT(X) => X ...</k>
rule <s> child(A) => A ~> child(HOLE) ...</s> <k> O(X) => X ~> O(HOLE(X)) ...</k>
rule <s> true ~> child(HOLE) => true ...</s> <k> X ~> O(HOLE(_)) => O(XRes) ...</k>
rule <s> false ~> child(HOLE) => false ...</s> <k> _ ~> O(HOLE(X)) => O(X) ...</k>
The ideea is to have the strategy expression "evaluated" like any other expression in a language. The strategy expression to evaluate lives in the <s>
cell, which is a k-like cell with some special heating/cooling rules.
We get rid of the else
on rules and replace it with a very simple <blocked/>
marker which works as following:
When the computation cannot proceed anymore, a <blocked/>
marker cell is added.
The following rules interprets the <blocked/>
marker in the context of the strategy language:
rule <blocked/> <s> E => false ...</s>
I exemplify this for a strategy language where true
means the strategy succeeded, and false
means it failed. We could have other encoding if we wanted to.
rule <s> true ~> S => S[true/HOLE] ...</s> <k> X ~> E => E[X/HOLE(_)] </k>
rule <s> false ~> S => S[false/HOLE] ...</s> <k> _ ~> E => E[X/HOLE(X)] </k>
Notice that the HOLE
now saves the current state of the expression.
Also, the heating cooling rules are generic and assume a E[X/HOLE(X)]
replacement which I don't think k currently supports. We can overcome this by either implementing this feature, or generating cooling rules for each production.
List in a normal programming language, if
is the essential building block in the strategy language.
rule <s> if C then A else B => C ~> if HOLE then A else B ...</s> <k> X => X ~> HOLE(X) ...</k>
rule <s> if true then A else B => A ...</s> <k> X => X ~> HOLE(X) ...</k>
rule <s> if false then A else B => B ...</s> <k> X => X ~> HOLE(X) ...</k>
"or" with a short circuit.
rule <s> A <+ B => if A then true else B ... </s>
"and" with a short circuit.
rule <s> A <* B => if A then B else false ... </s>
"or" without the short circuit.
rule <s> A + B => if A then true else B ...</s>
rule <s> A + B => if B then true else A ...</s>
An attempt to express the strictness annotation in our strategy language.
Yhe rule which is a bit stranger, but should cover heating, with cooling solved by the strategy cooling (actually, we will need a special version of cooling strategies above cooling that check for isResult(E)
)
rule <s> A => HOLE(A) ...</s> <k> E(Y R) => Y ~> E(HOLE(Y) R) ... </k> if strict(1,E)
repeat until failure. On failure of A
, return the result (i.e. the overall strategy succeeds).
rule <s> repeat(A) => if A then repeat(A) else true ...</s>
This applies A
to the entire tree, in a bottom-up postfix fashion.
This is a bit vague, but something along these lines should do it:
rule <s> bottomup(A) => bottomup(A) ~> HOLE + bottomup(A) ... </s> <k> E(S:KList A) => A ~> E(S:KList with a HOLE) ... </k>
rule <s> bottomup(A) => A ... </s> <k> E(no subterms) => E </k>
one possible implementation is
rule <s> anywhere(A) => repeat(bottomup(A)) </s>
-
x[y+2] = z + 3
needs matching on two k elements
- can I (currently) match on a variable which is a KLabel?
- can I iterate of the elements of a KList ?