module M

use int.Int
use ref.Ref

(** 1. A loop increasing [i] up to 10. *)

val i : ref int

let loop1 (_u:unit) requires { !i <= 10 } ensures { !i = 10 }
= while !i < 10 do
    invariant { !i <= 10 } variant { 10 - !i }
    i := !i + 1
  done


(** 2. The same loop, followed by a function call. *)

val x: ref int

let negate (_u:unit) ensures { !x = - (old !x) } = x := - !x

let loop2 (_u:unit) requires { !x <= 10 }
= begin
    while !x < 10 do invariant { !x <= 10 } variant { 10 - !x }
      x := !x + 1
    done;
    assert { !x = 10 };
    if !x > 0 then (negate ());
    assert { !x = -10 }
  end

end
