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

Method Calls in Loops #134

Open
DavePearce opened this issue Nov 12, 2021 · 5 comments
Open

Method Calls in Loops #134

DavePearce opened this issue Nov 12, 2021 · 5 comments
Labels
bug Something isn't working

Comments

@DavePearce
Copy link
Member

DavePearce commented Nov 12, 2021

(@utting @leavens keeping you in the loop)

The following program generates a strange error message indeed:

method g(&int p) -> (int r):
    return 0

method f(&int p, int[] xs):
    //
    for i in 0..|xs|:
        g(p)

UPDATE: this is related to debug=true in the wy.toml file.

@DavePearce DavePearce added the bug Something isn't working label Nov 12, 2021
@DavePearce
Copy link
Member Author

DavePearce commented Nov 12, 2021

Summary:

  • When debug=true this example doesn't verify because of a generated loop invariant involving HEAP for p
  • Since the loop invariant was generated, there is no source information --- hence why the error is wierd.

But why doesn't it fail when debug=false ?

@DavePearce
Copy link
Member Author

DavePearce commented Nov 12, 2021

When debug=true loop invariant is:

   invariant (forall r:Ref :: Ref#within(HEAP$173,r,p) || (HEAP$173[r] == Void) || (HEAP$173[r] == HEAP[r]));

When debug=false we have:

   invariant (forall r:Ref :: Ref#within(HEAP$173,r,p$78) || (HEAP$173[r] == Void) || (HEAP$173[r] == HEAP[r]));

Hmmm that's not it

@DavePearce
Copy link
Member Author

DavePearce commented Nov 12, 2021

Ok, here we go:

When debug=true we have this for g():

free ensures (forall p:Ref :: Ref#within(old(HEAP),p,p) || ...);

When debug=false we have this:

free ensures (forall p:Ref :: Ref#within(old(HEAP),p,p$23) || ...);

These are not equivalent.

@utting
Copy link
Collaborator

utting commented Nov 12, 2021

In the earlier version of the translator to Boogie, I used a weaker version of this 'debug' name mapping, maintained a map from each fully qualified name to its 'printable' name.

For example, for a base name of 'p', the first printable name would be just 'p', then other fully qualified variants of it would be mapped to 'p1', 'p2', etc. (a separate counter for each base name). This allows the most common cases (identifiers that appear only once) to retain their original names, but it still disambiguates other names when needed, with a short and readable name.

(One could make this even more sophisticated by taking detailed scopes into consideration, but a simple version that has just two levels of scope, global and local, would work pretty well I think).

@DavePearce
Copy link
Member Author

Hey,

In general, expressions are already associated with a unique identifier and I typically use this. Not sure what's going wrong here. Its not a ideal, but not a big drama now I know the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants