// verifast_options{disable_overflow_check target:ILP32} /* Cohen's integer division returns x % y http://www.cs.upc.edu/~erodri/webpage/polynomial_invariants/cohendiv.htm */ extern void abort(void); //@ requires integer(&counter, ?veri_req_counter) &*& true; //@ ensures integer(&counter, ?veri_ens_counter) &*& true; void reach_error() //@ requires false; //@ ensures true; {}extern int __VERIFIER_nondet_int(void); //@ requires integer(&counter, ?veri_req_counter) &*& true; //@ ensures integer(&counter, ?veri_ens_counter) &*& true; void assume_abort_if_not(int cond) //@ requires integer(&counter, ?veri_req_counter) &*& (veri_req_counter == 0); //@ ensures integer(&counter, ?veri_ens_counter) &*& (((cond != 0) && (veri_ens_counter == veri_req_counter)) && (veri_ens_counter == 0)); { if(!cond) {abort();} } void __VERIFIER_assert(int cond) //@ requires integer(&counter, ?veri_req_counter) &*& (cond != 0); //@ ensures integer(&counter, ?veri_ens_counter) &*& ((cond != 0) && (veri_ens_counter == veri_req_counter)); { if (!(cond)) { ERROR: {reach_error();} } return; } int counter = 0; int main() //@ requires module(cohendiv_ll_unwindbound2__verifast_instrumented, true) &*& (counter == 0); //@ ensures (counter == 0) &*& junk(); { //@ open_module(); int x, y; long long q, r, a, b; x = __VERIFIER_nondet_int(); y = __VERIFIER_nondet_int(); assume_abort_if_not(y >= 1); q = 0; r = x; a = 0; b = 0; while (counter++<2) //@ invariant integer(&counter, ?veri_inv_counter) &*& ((veri_req_counter == 0) && (((((2 <= veri_inv_counter) && (((q * y) + r) == x)) && ((((q * y) + r) + (a * y)) == (b + x))) && (1 <= y)) || ((((((a == 0) && (x == r)) && (b == 0)) && (veri_inv_counter == 0)) && (q == 0)) && (1 <= y)))); { __VERIFIER_assert(b == y*a); __VERIFIER_assert(x == q*y + r); if (!(r >= y)) break; a = 1; b = y; while (counter++<2) //@ invariant integer(&counter, ?veri_inv_counter) &*& (((((((((2 <= veri_inv_counter) && (a == 1)) && ((((q * y) + y) + r) == (b + x))) && (1 <= r)) && (b == y)) && (1 <= y)) || ((((((2 <= veri_inv_counter) && (x == r)) && (1 <= r)) && ((r + (a * y)) == (b + x))) && (q == 0)) && (1 <= y))) || (((((((a == 1) && ((y + r) == (b + x))) && (1 <= r)) && (b == y)) && (q == 0)) && (veri_inv_counter == 1)) && (1 <= y))) && (veri_req_counter == 0)); { __VERIFIER_assert(b == y*a); __VERIFIER_assert(x == q*y + r); __VERIFIER_assert(r >= 0); if (!(r >= 2 * b)) break; __VERIFIER_assert(r >= 2 * y * a); a = 2 * a; b = 2 * b; } r = r - b; q = q + a; } __VERIFIER_assert(x == q*y + r); return 0; }