abstract data type stack
    
  signature
    function new : stack;
    function push( x : element, s : stack ) -> stack; 
    function empty( s : stack) -> boolean;
    function pop( s : stack ) -> stack;
    function top( s : stack ) -> element;
    
  preconditions
    pre: pop( s : stack ) = not empty(s)
    pre: top( s : stack ) = not empty(s)
    
  axioms
    empty( new ) = true
    empty( push(x,s) ) = false
    top( push(x,s) ) = x
    pop( push(x,s) ) = s