// 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 true; //@ ensures true; extern void __assert_fail(const char *, const char *, unsigned int, const char *) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__)); void reach_error() //@ requires false; //@ ensures true; { __assert_fail("0", "cohendiv-ll.c", 8, "reach_error"); } extern int __VERIFIER_nondet_int(void);//@ requires true; //@ ensures true; extern void abort(void); 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_modified, true); //@ ensures junk(); { int x, y; //@ invariant integer(&counter, ?veri_req_counter) &*& (veri_req_counter == 0); 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; }