Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug with Automaton.Rewrite(int,int) #11

Open
DavePearce opened this issue Jun 18, 2015 · 2 comments
Open

Bug with Automaton.Rewrite(int,int) #11

DavePearce opened this issue Jun 18, 2015 · 2 comments

Comments

@DavePearce
Copy link
Member

Issue by DavePearce
Wednesday May 15, 2013 at 00:57 GMT
Originally opened as Whiley/WhileyCompiler#273


There is currently a bug (or feature?) with the method Automaton.rewrite(int from,int to). The essential issue is that the method replaced all occurrences of from with to including those reachable from to.

This causes a problem with the following rule:

reduce Sum[real x, {|Mul... xs|}]:
    => let negs = {| y | y in xs, (*y)[0] < 0.0 |} 
       in Mul[-1.0,{|Sum[x,xs]|}], if x == 0.0 && (|xs| - |negs|) < |negs|

To understand, consider the outermost node as having index 8 and the new Mul has having index 23. Then applying the rule rewrites 8 => 23. Now, let's take a closer look at the automaton:

#20 [2,19], #21 {|8|}, #22 [4,21], #23 1(22) <18>

The key is that, as expected, state 8 is reachable from 23. This reflects the fact that the Mul does indeed contain a reference to the outermost Sum node. Unfortunately, this reference gets rewritten to 23 when applying rewrite, leading to a curious loop in the resulting automaton.

@DavePearce
Copy link
Member Author

Comment by DavePearce
Wednesday May 15, 2013 at 00:59 GMT


The workaround is simply to ensure that Mul doesn't reference exactly the same node. That is, it must reference an equivalent but initially distinct node. That node can then be reduced down, and it'll all work out.

@DavePearce
Copy link
Member Author

Comment by DavePearce
Wednesday May 15, 2013 at 01:10 GMT


For example, I can rewrite the above rule as follows:

reduce Sum[real x, {|Mul... xs|}]:
    => let negs = {| y | y in xs, (*y)[0] < 0.0 |},
           ys   = {| Mul[-(*y)[0],(*y)[1]] | y in xs |}
       in Sum[0,ys], if x == 0.0 && (|xs| - |negs|) < |negs|

This avoids the problem. But, sadly, the system doesn't tell me when I need to avoid the problem!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant