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

fix: Fix new resolution of unary minus #4737

Merged
merged 9 commits into from
Jan 3, 2024
Prev Previous commit
Next Next commit
Add test for unary minus
  • Loading branch information
RustanLeino committed Nov 2, 2023
commit 3c5856422881c034471fd13917706b2da3586556
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,54 @@ module StaticReceivers {
}
}

module UnaryMinus {
// This modules contains some regression tests to make sure that -nat is an int, not a nat.
// This remains a problem in the old resolver, and was once a problem (for different reasons)
// in the new resolver.

predicate Simple(n: nat, d: nat) {
var x := -d; // type of x should be inferred to be int, not nat
n == x
}

function Abs(n: int): nat {
if n < 0 then -n else n
}

predicate IsNat(n: int)
ensures IsNat(n) <==> 0 <= n
{
AtMost(n, 0)
}

predicate AtMost(n: int, d: nat)
requires d <= Abs(n)
ensures AtMost(n, d) <==> d <= n
decreases Abs(n) - d
{
n == d || (n + d != 0 && AtMost(n, d + 1))
}

predicate AtMost'(n: int, d: nat)
requires d <= Abs(n)
ensures AtMost'(n, d) <==> d <= n
decreases Abs(n) - d
{
if n == d then
true
else if n == -d then // the -d here should not pose any problems
false
else
AtMost'(n, d + 1)
}

lemma Same(n: int, d: nat)
requires d <= Abs(n)
ensures AtMost(n, d) == AtMost'(n, d)
{
}
}


/****************************************************************************************
******** TO DO *************************************************************************
Expand Down Expand Up @@ -1000,33 +1048,4 @@ datatype Tree =
// Dafny rejects the call to MaxF, claiming that forall t | t in ts :: default <= f(t) might not hold. But default is 0 and f(t)
// has type nat, so it should hold — and in fact just uncommenting the definition of fn above solves the issue… even if fn isn’t used.

// ------------------
// In this program, one has to write "n + d != 0" instead of "n != -d", because of a previously known problem with type inference

predicate method ge0'(n: int)
ensures ge0'(n) <==> 0 <= n
{
downup_search'(n, 0)
}

function method Abs(n: int): nat {
if n < 0 then -n else n
}

predicate method downup_search'(n: int, d: nat)
requires d <= Abs(n)
ensures downup_search'(n, d) <==> d <= n
decreases Abs(n) - d
{
n == d || (n + d != 0 && downup_search'(n, d + 1))
/*
if n - d == 0 then
true
else if n + d == 0 then
false
else
downup_search'(n, d + 1)
*/
}

****************************************************************************************/
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ TypeInferenceRefresh.dfy(633,24): Error: value does not satisfy the subset const
TypeInferenceRefresh.dfy(145,30): Error: element might not be in domain
TypeInferenceRefresh.dfy(216,26): Error: result of operation might violate newtype constraint for 'int8'

Dafny program verifier finished with 77 verified, 10 errors
Dafny program verifier finished with 83 verified, 10 errors
Loading