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

Missing where clause on handle types and incorrect subtyping checks on maps containing arrows #2835

Open
MikaelMayer opened this issue Oct 3, 2022 · 2 comments
Labels
has-workaround: yes There is a known workaround incompleteness Things that Dafny should be able to prove, but can't kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label part: resolver Resolution and typechecking part: verifier Translation from Dafny to Boogie (translator)

Comments

@MikaelMayer
Copy link
Member

MikaelMayer commented Oct 3, 2022

method test(p: (int --> int) --> nat) {
  var m: map<string, (int --> int) --> nat> := map[
    "p" := p];
}

The code should clearly work, however, Dafny reports an error:

value does not satisfy the subset constraints of '(int ~> int) ~> int'

@MikaelMayer MikaelMayer added the incompleteness Things that Dafny should be able to prove, but can't label Oct 3, 2022
@MikaelMayer
Copy link
Member Author

I found a workaround for now

method test(p: (int --> int) --> nat) {
  var m: map<string, (int --> int) --> nat> := map[];
  var m2 := m["p" := p];
}

@cpitclaudel
Copy link
Member

There are two bugs in one here:

First, the resolver doesn't correctly compute the subtyping relation between arrows, and hence it issues a verification condition. This happens for maps but not for sequences:

method test(p: (int --> int) --> nat) {
  var s: seq<(int --> int) --> nat> := [p]; // OK
  var m: map<string, (int --> int) --> nat> := map["p" := p]; // NOK
}

Second, the translator does not produce any assumptions about the type of p. The Boogie code looks like this:

implementation {:verboseName "test (correctness)"} Impl$$_module.__default.test(p#0: HandleType) returns ($_reverifyPost: bool)
{
…
    assert $Is(p#0, Tclass._System.___hFunc1(Tclass._System.___hFunc1(TInt, TInt), TInt));

… that assert should be preceded by an assume saying the exact same thing (or most likely a where clause).

For example, when we write this:

method testNat(n: nat) {
  assert n >= 0;
}

… we get this, with a where clause:

procedure {:verboseName "testNat (well-formedness)"} CheckWellFormed$$_module.__default.testNat(n#0: int where LitInt(0) <= n#0);

@cpitclaudel cpitclaudel added kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label part: resolver Resolution and typechecking part: verifier Translation from Dafny to Boogie (translator) has-workaround: yes There is a known workaround labels Oct 3, 2022
@cpitclaudel cpitclaudel changed the title Dafny typing issue Missing where clause on handle types and incorrect subtyping checks on maps containing arrows Oct 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has-workaround: yes There is a known workaround incompleteness Things that Dafny should be able to prove, but can't kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label part: resolver Resolution and typechecking part: verifier Translation from Dafny to Boogie (translator)
Projects
None yet
Development

No branches or pull requests

2 participants