/* CS:5810 Formal Methods in Software Engineering Fall 2015 The University of Iowa Instructor: Cesare Tinelli */ // Bank account example // showcasing the idea of (heap) frames class Trans { var total: int; } class Account { // public variables ghost var Bal: int; // the current balance of the account ghost var Frame: set; // set of all objects (in the heap) // that methods can read or modify // private variables var deposits: Trans; // stores the total amount of deposits var withdrawls: Trans; // stores the total amount of withdrawls function Valid(): bool reads this, Frame; { // concrete state invariants deposits != null && withdrawls != null && deposits != withdrawls && // Frame invariants this in Frame && deposits in Frame && withdrawls in Frame && // connection between abstract and concrete state Bal == deposits.total - withdrawls.total } constructor Init() modifies this; ensures Valid(); ensures Bal == 0; { deposits := new Trans; withdrawls := new Trans; deposits.total := 0; withdrawls.total := 0; Bal := 0; // establishes the initial frame Frame := {this} ; Frame := Frame + {deposits, withdrawls}; } method GetBalance() returns (b: int) requires Valid(); ensures Valid(); ensures b == Bal; { b := deposits.total - withdrawls.total; } method Deposit(a: int) modifies Frame; requires Valid(); ensures Valid(); ensures Bal == old(Bal) + a; { deposits.total := deposits.total + a; Bal := Bal + a; } method Withdraw(a: int) modifies Frame; requires Valid(); ensures Valid(); ensures Bal == old(Bal) - a; { withdrawls.total := withdrawls.total + a; Bal := Bal - a; } }