import java.util.*;

/**
 * A simple stack example illustrating use of JML.
 */
public abstract class Stack {

  public final int maxSize = 20000;
  public List<Object> items;

  /*@ public invariant items.size() < maxSize;  @*/
  // An invariant is true throughout the lifetime of an object.  You can think
  // of it as an extra clause in every method precondition.

  /** Standard initializing constructor
  public Stack() {
    items = null;
  }

  /*@ requires items.size() != 0;  @*/          // pre: stack not empty
  /*@ ensures items.equals(\old(items)) &&      // post: stack not mutated, and
      \result == items.get(0);  @*/             //       result is top item
  public abstract Object top();

  /*@ assignable items;  @*/                    // declares items as mutable
  /*@ requires items.size() != 0;               // pre: stack not empty
  /*@ ensures items.equals(                     // post: items are
       \old(items).subList(1,\old(items).size())) //  everything but first, and
       && \result == \old(items).get(0);  @*/     //  result is orginal top item
  public abstract Object pop();

  
  /*@ assignable items;  @*/                    // declares items mutable
  /*@ requires items.size() < maxSize; @*/      // pre: stack not full
  /*@ ensures items.equals(                     // post: items are
               \old(items).add(x));  @*/        //    orginal items plus new one
  public abstract void push(Object x);

}