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

Unable to verify function with parameters that are subset types only with '--type-system-refresh' #6116

Open
alexstaeding opened this issue Feb 19, 2025 · 0 comments
Labels
kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label part: resolver Resolution and typechecking

Comments

@alexstaeding
Copy link

alexstaeding commented Feb 19, 2025

Dafny version

4.10.0

Code to produce this issue

ghost predicate IsCommutativePartial<T(!new), R>(op: (T, T) --> R) {
  forall x, y :: op.requires(x, y) && op.requires(y, x) ==> op(x, y) == op(y, x)
}

ghost predicate IsCommutativeTotal<T(!new), R>(op: (T, T) -> R) {
  forall x, y :: op(x, y) == op(y, x)
}

function SumInt(a: int, b: int): int { a + b }
function SumNat(a: nat, b: nat): nat { a + b }

lemma SumIsCommutative()
  ensures IsCommutativePartial(SumNat)
  ensures IsCommutativePartial(SumInt)
  ensures IsCommutativeTotal(SumNat)
  ensures IsCommutativeTotal(SumInt)
{}
``

Command to run and resulting output

$ dafny verify Test.dfy

Dafny program verifier finished with 3 verified, 0 errors


$ dafny verify --type-system-refresh Test.dfy
Test.dfy(13,31): Error: value does not satisfy the subset constraints of '(int, int) --> nat' (possible cause: it may have read effects)
   |
13 |   ensures IsCommutativePartial(SumNat)
   |                                ^^^^^^

Test.dfy(15,29): Error: value does not satisfy the subset constraints of '(int, int) -> nat' (possible cause: it may be partial or have read effects)
   |
15 |   ensures IsCommutativeTotal(SumNat)
   |                              ^^^^^^

Test.dfy(17,0): Error: a postcondition could not be proved on this return path
   |
17 | {}
   | ^

Test.dfy(13,30): Related location: this is the postcondition that could not be proved
   |
13 |   ensures IsCommutativePartial(SumNat)
   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Test.dfy(2,2): Related location: this proposition could not be proved
  |
2 |   forall x, y :: op.requires(x, y) && op.requires(y, x) ==> op(x, y) == op(y, x)
  |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Test.dfy(17,0): Error: a postcondition could not be proved on this return path
   |
17 | {}
   | ^

Test.dfy(15,28): Related location: this is the postcondition that could not be proved
   |
15 |   ensures IsCommutativeTotal(SumNat)
   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^

Test.dfy(6,2): Related location: this proposition could not be proved
  |
6 |   forall x, y :: op(x, y) == op(y, x)
  |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Dafny program verifier finished with 2 verified, 4 errors

What happened?

It seems that Dafny incorrectly instantiates T using int rather than nat when using the type system refresh. If I instead use only one type paramter, like in:

ghost predicate IsCommutativePartial<T(!new)>(op: (T, T) --> T) {
  forall x, y :: op.requires(x, y) && op.requires(y, x) ==> op(x, y) == op(y, x)
}

(also for IsCommutativePartial), the code verifies.

What type of operating system are you experiencing the problem on?

Mac

@alexstaeding alexstaeding added the kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label label Feb 19, 2025
@fabiomadge fabiomadge added the part: resolver Resolution and typechecking label Feb 24, 2025
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 part: resolver Resolution and typechecking
Projects
None yet
Development

No branches or pull requests

2 participants