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

Prove false with bitvectors #2511

Closed
MikaelMayer opened this issue Jul 28, 2022 · 3 comments · Fixed by #2512
Closed

Prove false with bitvectors #2511

MikaelMayer opened this issue Jul 28, 2022 · 3 comments · Fixed by #2512
Assignees
Labels
kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label logic An inconsistency in Dafny's logic (e.g. in the Boogie prelude) part: verifier Translation from Dafny to Boogie (translator)

Comments

@MikaelMayer
Copy link
Member

I have no idea why, but I can prove false with the following code:

lemma false_lemma(a:bv64, b: bv64)
  requires a != b
  ensures false
{
  var tmp := a ^ b;
  while tmp != 0
    decreases tmp
  {
    tmp := tmp >> 1;
  }
  assert false;
}
lemma ensures_false()
  ensures false
{
  false_lemma(0, 1);
}
@MikaelMayer MikaelMayer added kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label logic An inconsistency in Dafny's logic (e.g. in the Boogie prelude) part: verifier Translation from Dafny to Boogie (translator) labels Jul 28, 2022
@cpitclaudel
Copy link
Member

Ouch, nice find!

Here is an even smaller example:

lemma false_lemma()
  ensures false
{
  var tmp: bv64 := 1;
  while tmp != 0
    decreases tmp
  {
    tmp := tmp >> 1;
  }
  assert false;
}

I have a fix coming up, I think.

@cpitclaudel
Copy link
Member

Another variant:


method Infloop(b: bv8)
  requires b == 3
  ensures false
  decreases b
{
  Infloop'(b + 1);
}

method Infloop'(b: bv8)
  requires b == 4
  decreases b, 0
  ensures false
{
  Infloop(b - 1);
}

method Boom()
  ensures false
{
  Infloop(3);
}

@cpitclaudel
Copy link
Member

And another one:

  trait T {
    method Infloop(b: bv8)
      requires b == 3
      ensures false
      decreases b
  }

  class C extends T {
    method Infloop(b: bv8)
      requires b == 3
      ensures false
      decreases b + 1, 0
    {
      (this as T).Infloop(b);
    }
  }

cpitclaudel added a commit that referenced this issue Jul 28, 2022
Dafny adds a free invariant on each loops that states that the loop variable is
smaller than or equal to its initial value.  For bitvectors, Dafny produced ≥
instead of ≤, possibly due to a typo?

Specifically, the issue was:

- In `Translator.TrStatement.cs` (`TrLoop`):

  ```
  // include a free invariant that says that all completed iterations so far have only decreased the termination metric
  …
  Bpl.Expr decrCheck = DecreasesCheck(toks, types, types, decrs, initDecr, null, null, true, false);
  ```

- In `Translator.cs` (`DecreasesCheck`):

  ```
  Bpl.Expr less, atmost, eq;
  ComputeLessEq(toks[i], types0[i], types1[i], ee0[i], ee1[i], out less, out atmost, out eq, includeLowerBound);
  ```

- In `Translator.cs` (`ComputeLessEq`):

  ```
  } else if (ty0 is BitvectorType) {
    BitvectorType bv = (BitvectorType)ty0;
    eq = Bpl.Expr.Eq(e0, e1);
    less = FunctionCall(tok, "lt_bv" + bv.Width, Bpl.Type.Bool, e0, e1);
    atmost = FunctionCall(tok, "ge_bv" + bv.Width, Bpl.Type.Bool, e0, e1);
  ```

  `"ge_bv"` is wrong.

* `Source/Dafny/Verifier/Translator.cs`
  (`ComputeLessEq`): Change `ge` into `le`.
* `Test/git-issues/git-issue-2511.dfy`:
  New file, showing the issue in all places where `ComputeLessEq` was used.

Introduced in 3f899b9.

Closes #2511.
cpitclaudel added a commit that referenced this issue Jul 28, 2022
Dafny adds a free invariant on each loops that states that the loop variable is
smaller than or equal to its initial value.  For bitvectors, Dafny produced ≥
instead of ≤, possibly due to a typo?

Specifically, the issue was:

- In `Translator.TrStatement.cs` (`TrLoop`):

  ```
  // include a free invariant that says that all completed iterations so far have only decreased the termination metric
  …
  Bpl.Expr decrCheck = DecreasesCheck(toks, types, types, decrs, initDecr, null, null, true, false);
  ```

- In `Translator.cs` (`DecreasesCheck`):

  ```
  Bpl.Expr less, atmost, eq;
  ComputeLessEq(toks[i], types0[i], types1[i], ee0[i], ee1[i], out less, out atmost, out eq, includeLowerBound);
  ```

- In `Translator.cs` (`ComputeLessEq`):

  ```
  } else if (ty0 is BitvectorType) {
    BitvectorType bv = (BitvectorType)ty0;
    eq = Bpl.Expr.Eq(e0, e1);
    less = FunctionCall(tok, "lt_bv" + bv.Width, Bpl.Type.Bool, e0, e1);
    atmost = FunctionCall(tok, "ge_bv" + bv.Width, Bpl.Type.Bool, e0, e1);
  ```

  `"ge_bv"` is wrong.

* `Source/Dafny/Verifier/Translator.cs`
  (`ComputeLessEq`): Change `ge` into `le`.
* `Test/git-issues/git-issue-2511.dfy`:
  New file, showing the issue in all places where `ComputeLessEq` was used.

Introduced in 3f899b9.

Closes #2511.
cpitclaudel added a commit that referenced this issue Jul 28, 2022
Dafny adds a free invariant on each loop that states that the loop variable is
smaller than or equal to its initial value.  For bitvectors, Dafny produced ≥
instead of ≤, possibly due to a typo.

Specifically, the issue was:

- In `Translator.TrStatement.cs` (`TrLoop`):

  ```
  // include a free invariant that says that all completed iterations so far have only decreased the termination metric
  …
  Bpl.Expr decrCheck = DecreasesCheck(toks, types, types, decrs, initDecr, null, null, true, false);
  ```

- In `Translator.cs` (`DecreasesCheck`):

  ```
  Bpl.Expr less, atmost, eq;
  ComputeLessEq(toks[i], types0[i], types1[i], ee0[i], ee1[i], out less, out atmost, out eq, includeLowerBound);
  ```

- In `Translator.cs` (`ComputeLessEq`):

  ```
  } else if (ty0 is BitvectorType) {
    BitvectorType bv = (BitvectorType)ty0;
    eq = Bpl.Expr.Eq(e0, e1);
    less = FunctionCall(tok, "lt_bv" + bv.Width, Bpl.Type.Bool, e0, e1);
    atmost = FunctionCall(tok, "ge_bv" + bv.Width, Bpl.Type.Bool, e0, e1);
  ```

  `"ge_bv"` is wrong.

* `Source/Dafny/Verifier/Translator.cs`
  (`ComputeLessEq`): Change `ge` into `le`.
* `Test/git-issues/git-issue-2511.dfy`:
  New file, showing the issue in all places where `ComputeLessEq` was used.

Introduced in 3f899b9.

Closes #2511.
cpitclaudel added a commit that referenced this issue Jul 29, 2022
Dafny adds a free invariant on each loop that states that the loop variable is
smaller than or equal to its initial value.  For bitvectors, Dafny produced ≥
instead of ≤, possibly due to a typo.

Specifically, the issue was:

- In `Translator.TrStatement.cs` (`TrLoop`):

  ```
  // include a free invariant that says that all completed iterations so far have only decreased the termination metric
  …
  Bpl.Expr decrCheck = DecreasesCheck(toks, types, types, decrs, initDecr, null, null, true, false);
  ```

- In `Translator.cs` (`DecreasesCheck`):

  ```
  Bpl.Expr less, atmost, eq;
  ComputeLessEq(toks[i], types0[i], types1[i], ee0[i], ee1[i], out less, out atmost, out eq, includeLowerBound);
  ```

- In `Translator.cs` (`ComputeLessEq`):

  ```
  } else if (ty0 is BitvectorType) {
    BitvectorType bv = (BitvectorType)ty0;
    eq = Bpl.Expr.Eq(e0, e1);
    less = FunctionCall(tok, "lt_bv" + bv.Width, Bpl.Type.Bool, e0, e1);
    atmost = FunctionCall(tok, "ge_bv" + bv.Width, Bpl.Type.Bool, e0, e1);
  ```

  `"ge_bv"` is wrong.

* `Source/Dafny/Verifier/Translator.cs`
  (`ComputeLessEq`): Change `ge` into `le`.
* `Test/git-issues/git-issue-2511.dfy`:
  New file, showing the issue in all places where `ComputeLessEq` was used.

Introduced in 3f899b9.

Closes #2511.
@cpitclaudel cpitclaudel self-assigned this Jul 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label logic An inconsistency in Dafny's logic (e.g. in the Boogie prelude) part: verifier Translation from Dafny to Boogie (translator)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants