0

I'm trying to prove the simple gcd algorithm in Dafny, so I wrote the following, but it seems I can not use the method divides inside the loop invariants:

method divides(d: int, x: int) returns (result: bool)
    requires d > 0
    requires x > 0
    ensures (result == true ) ==> (exists q : int :: (d * q == x))
    ensures (result == false) ==> (forall q : int :: (d * q != x))
{
    // code omitted
}

method gcd(a: int, b: int) returns (result: int)
    requires a > 0
    requires b > 0
    ensures (forall d : int :: ((exists q1 : int :: q1 * d == a) && (exists q2 :: (q2 * d == b))) ==>
                 (exists q3 : int :: (q3 * d == result)))
{
    var x := a;
    var y := b;
    var fuel := a+b;
    while ((x != y) && (fuel > 0))
        decreases fuel
        invariant x > 0
        invariant y > 0
        invariant (forall d : int :: (divides(d,x) && divides(d,y)) ==> (divides(d,a) && divides(d,b)))
    {
        // code omitted
    }
    return x;
}

Is there anyway to use a divides method/function/macro inside invariants?

OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87

1 Answers1

1

Unlike methods, functions can appear in expressions. You can create a function:

function div(d: int, x: int): bool
{
    if (d != 0 && x % d == 0) then true else false
}

Then in your method divides, you can have

ensures result == div(d,x)

and in your method gcd you can use the function div in your invariant.

Note, from the Dafny guide: One caveat of functions is that not only can they appear in annotations, they can only appear in annotations. Functions are never part of the final compiled program, they are just tools to help us verify our code.

Watermelon
  • 72
  • 1
  • 6