Solution

ID: past-exam-of-the-year-1-of-the-computer-science-course-of-the-university-of-oxford/2022/imperative-programming-resit/3/a/solution

The abstract FIFO queue state is a finite sequence , initially empty. Because the interface returns Int length, use the representable-size model . Its operations are:
trait Queue[A] {
  // State q: finite sequence of A; initially [].
  // Pre: length(q) < Int.MaxValue. Post: q = q0 ++ [x].
  def enqueue(x: A): Unit

  // Pre: q is nonempty. Post: return head(q0); q = tail(q0).
  def dequeue(): A

  // Post: q = [].
  def clear(): Unit

  // Post: q unchanged; return q.isEmpty.
  def isEmpty: Boolean

  // Post: q unchanged; return length(q).
  def length: Int
}
The unchanged-state clauses on the two queries are part of their postconditions. dequeue removes exactly the oldest remaining element, while clear discards all entries regardless of the old state. The size bound can be omitted in an unbounded mathematical model, but it must be reconciled with fixed-width lengths in an implementation.

New to topics? Read the docs here!