/* CookieJar ADT in Scala H. Conrad Cunningham Version #1: 15 March 2010 Version #1a: 23 March 2010 Corrected postconditions on putIn & eat, added ' 123456789012345678901234567890123456789012345678901234567890123456789012345678 This example presents a Scala implementation of the CookieJar ADT described in exercises #4 and #5 on page 33 of Nell Dale and Henry M. Walker's textbook _Abstract Data Types: Specifications, Implementations, and Applications_ (D.C. Heath and Company, 1996). These exercises were assigned to the Spring 2010 Software Design and Scala Programming class. Drafting code for this ADT was also a question on Examination 1. This program is an enhanced Scala version of a Ruby program the author wrote in Fall 2006. This version uses a trait to define the ADT and gives several concrete classes that extend that trait. MODEL: The model for CookieJar ADT is a mathematical bag. A bag is an collection of values in which each value may occur one or more times. The bag notation used in this documentation includes: {| |} denotes empty bag {| 2, 3, 2, 1 |} denotes a bag with four elements including two 2's, one 3, and one 1. The order is not significant! There may be one or more occurrences of an element. IN denotes the bag membership operation. x IN B if there are one or more occurrences of the value x in bag B. UNION denotes bag union. The resulting bag has the total number of occurrences of elements from the two bags. {| 3, 1, 1, 3 |} UNION {| 1, 2 |] = [| 1,1,1,2,3,3 |} (Remember order is not significant.) DIFF denotes bag difference. A DIFF B removes each occurrence of elements in B from A. The resulting bag has the number of occurrence in bag A minus the number of occurrences in bag B. If there are more occurrence in B than A, then the result has no occurrences. {| 1, 1, 2, 1 }} DIFF {| 2,1,1 |} = {| 1 |} OCCURRENCES denotes occurrence counting. OCCURENCES(x,B) returns the number of times element x appears in bag B. In postconditions, a variable like Bag' (with a ' appended to the name) represents the value of the variable before the call. The symbol without the ' denotes the value of the variable at the return from the call. For some function func, the symbol func_return refers to the returned value of the function. */ /* Trait CookieJar specifies the interface for concrete implementations of the CookieJar ADT. MODEL: The values of specification variable Bag, which is a mathematical bag. INTERFACE INVARIANT: Bag != UNDEFINED Note: Remember that an interface invariant must be made true by the class constructors and each public method of the class must preserve it. That is, it is both a precondition and postcondition on all mutator and accessor methods. An interface invariant refers only to the model, not to the data structures of any concrete implementation. */ trait CookieJar[CookieType] { /* The Dale and Walker book defines an operation Create that will be implemented as constructors of a class that extends CookieJar. The constructor must satisfy the following specifications. PRE: true POST: Bag == {| |} */ /* Method putIn adds cookie to the cookie jar. Method putIn is called PutIn in the Dale and Walker book. PRE: true POST: Bag == Bag' UNION {| cookie |} */ def putIn(cookie: CookieType) /* Method eat removes cookie from the cookie jar. Method eat is called Eat in the Dale and Walker book. PRE: has(cookie) POST: Bag == Bag' DIFF {| cookie |} */ def eat(cookie: CookieType) /* Method isEmpty returns true iff the bag is empty. Method isEmpty is called IsEmpty in the Dale and Walker book. PRE: true POST: isEmpty_return == ( Bag == {| |} ) */ def isEmpty: Boolean /* Method "has" returns true iff cookie occurs in the cookie jar. Method "has" is called IsIn in the Dale and Walker book. PRE: true POST: has_return == (cookie IN Bag) */ def has(cookie: CookieType): Boolean }