/* 22c181: Formal Methods in Software Engineering Fall 2013 The University of Iowa Instructor: Cesare Tinelli */ class Cell { var data: int; } class Counter { // public variable ghost var Value: int; ghost var R: set; // private variables var incs: Cell; var decs: Cell; function Valid(): bool reads this, R; { this in R && incs in R && decs in R && null !in R && incs != decs && Value == incs.data - decs.data } constructor Init() modifies this; ensures Valid(); ensures fresh(R - {this}); ensures Value == 0; { incs, decs := new Cell, new Cell; incs.data, decs.data, Value := 0, 0, 0; R := {this}; R := R + {incs, decs}; } method GetValue() returns (x: int) requires Valid(); ensures x == Value; { x := incs.data - decs.data; } method Inc() requires Valid(); modifies R; ensures Valid(); ensures Value == old(Value) + 1; ensures fresh(R - old(R)); { incs.data, Value := incs.data + 1, Value + 1; } method Dec() requires Valid(); modifies R; ensures Valid(); ensures fresh(R - old(R)); ensures Value == old(Value) - 1; { decs.data, Value := decs.data + 1, Value - 1; } } method Main() { var c := new Counter.Init(); c.Inc(); c.Inc(); c.Dec(); c.Inc(); assert c.Value == 2; }