Hi Benjamin,
Thanks for your mail.
> On 26 Aug 2016, at 2:40 AM, Benjamin Gaidioz <
bgai...@gmail.com> wrote:
<snip>
> I was trying to come up with something like this for that case I described before. It would be a strategy which would start at the top, successfully insert expressions in general, but when encountering an exp which is the "then" or "else" of an "if", would stop the recursion. Something of that kind. Maybe it could apply a separate strategy when hitting an "if" in fact.
>
> I read many times the various available strategies and I am afraid I am a bit stuck. Maybe there is something using those which take two strategies as parameters (loop not, etc.) and I am going to give it a try but I think I would benefit a lot from some advices from you :)
I confess that there are many library strategies and choosing which one to use in a given circumstance is not easy. We are developing more comprehensive KIama documentation which hopefully will help this situation eventually.
In your application of sometd, if I’ve understood it correctly, you can get more control over which subtrees are entered by sequentially composing your rule argument with another strategy that guards it. So instead of
rule[Exp] { case e if map.contains(e) => UseVar(map(e))) }
you could use
foo <* rule[Exp] { case e if map.contains(e) => UseVar(map(e))) }
where foo succeeds only on terms that you wish to apply the rule to. If foo fails, the rule will not be applied.
Or possibly it will be easier to state as
not(foo) <* rule[Exp] { case e if map.contains(e) => UseVar(map(e))) }
where foo succeeds only on terms you *don’t* wish to apply the rule to. E.g.,
val foo = rule[Exp] { case e @ … pattern matching if-then-else … => e }
I think this approach should mean that you will never try to do the replacement in those sub-trees that foo succeeds on.
(You can do similar things with the guarded choice combinator s1 < s2 + s3 if you want to try something else (s3) if the guard s1 fails.)
On a related point, you are using collect to find the sub-expressions and collect looks everywhere. At the moment Kiama lacks a fully-developed combinator language for this kind of “type-unifying” strategy (aka a fold). collect, query and some variants are all we have at the moment. In the future (hopefully later this year) you will be able to have more control over where the collection happens in a tree and therefore do things like not even collect sub-expressions from inside if-then-else constructs, for example.
I hope this helps.
regards,
Tony