/* CS:5810 Formal Methods in Software Engineering Fall 2014 The University of Iowa Instructor: Cesare Tinelli */ // Parametric FIFO queue class Queue { ghost var Contents: seq; // container for the queue's elements var a: array; // size of the queue var n: nat; predicate Valid() reads this, a; { // concrete state invariants a != null && n <= a.Length && 0 < a.Length && // connection between abstract and concrete state Contents == a[0..n] } constructor init() modifies this, a; ensures Valid(); ensures Contents == []; { a := new T[5]; n := 0; Contents := []; } method enqueue(e: T) modifies a, this; requires Valid(); ensures Valid(); ensures Contents == old(Contents) + [e]; { if (n == a.Length) { var b := new T[2 * a.Length]; // use keyword "forall" instead of "parallel" with newer versions of Dafny parallel (i | 0 <= i < n) { b[i] := a[i]; } a := b; } a[n] := e; n := n + 1; Contents := a[0..n]; } method dequeue() returns (e: T) modifies this, a; requires Contents != []; requires Valid(); ensures Valid(); ensures [e] + Contents == old(Contents); { e := a[0]; n := n - 1; // use keyword "forall" instead of "parallel" with newer versions of Dafny parallel (i | 0 <= i < n ) { a[i] := a[i + 1]; } Contents := a[0..n]; } }