1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
typedef struct {
int balance;
} purse;
//@ predicate purse_inv(purse *p) { \valid(p) && p->balance >= 0 }
/*@ requires purse_inv(p) && s >= 0
@ ensures purse_inv(p) && p->balance == \old(p->balance) + s
@*/
void credit0(purse *p,int s) {
p->balance = p->balance + s;
}
/*@ requires purse_inv(p) && 0 <= s <= p->balance
@ ensures purse_inv(p) && p->balance == \old(p->balance) - s
@*/
void withdraw0(purse *p,int s) {
p->balance = p->balance - s;
}
#if 0
/*@ requires purse_inv(p1) && purse_inv(p2)
@ ensures \result == 0
@*/
int test0(purse *p1, purse *p2) {
p1->balance = 0;
credit0(p2,100);
return p1->balance;
}
#endif
/* using assigns clauses */
/*@ requires purse_inv(p) && s >= 0
@ assigns p->balance
@ ensures purse_inv(p) && p->balance == \old(p->balance) + s
@*/
void credit(purse *p,int s) {
p->balance = p->balance + s;
}
/*@ requires purse_inv(p) && 0 <= s <= p->balance
@ assigns p->balance
@ ensures purse_inv(p) && p->balance == \old(p->balance) - s
@*/
void withdraw(purse *p,int s) {
p->balance = p->balance - s;
}
/*@ requires purse_inv(p1) && purse_inv(p2) && p1 != p2
@ ensures \result == 0
@*/
int test1(purse *p1, purse *p2) {
p1->balance = 0;
credit(p2,100);
return p1->balance;
}
/* example of memory allocation
* currently does not work
*/
//@ assigns \nothing ensures \fresh(\result) && purse_inv(\result)
purse *new_purse();
//@ ensures \result == 150
int test2() {
purse *p1 = new_purse();
purse *p2 = new_purse();
credit(p1,100);
credit(p2,200);
withdraw(p1,50);
withdraw(p2,100);
return p1->balance + p2->balance;
}
|