// 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_unwindbound100__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++<100) //@ invariant integer(&counter, ?veri_inv_counter) &*& (((((((q * y) + r) + (a * y)) == (b + x)) && (veri_req_counter == 0)) && (1 <= y)) && (b == (a * y))); { __VERIFIER_assert(b == y*a); __VERIFIER_assert(x == q*y + r); if (!(r >= y)) break; a = 1; b = y; while (counter++<100) //@ invariant integer(&counter, ?veri_inv_counter) &*& (((((1 <= r) && ((((q * y) + r) + (a * y)) == (b + x))) && (veri_req_counter == 0)) && (1 <= y)) && (b == (a * y))); { __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; }