// Example of using member theorems to describe desired behaviour

// Example of using member theorems to describe desired behaviour of a class.
//
// Copyright 2001 Escher Technologies Ltd. All rights reserved.
// First define the form of word that we wish to spell-check
class Word ^= those x:string :- #x ~= 0;
// The actual dictionary class
class Dictionary ^=
abstract
var words: set of Word;
interface
function check(w: Word): bool
^= w in words;
schema !add(w: Word)
pre ~check(w)
post words! = words.append(w)
assert self'.check(w);
schema !remove(w: Word)
pre check(w)
post words! = words.remove(w)
assert ~self'.check(w);
// Constructor for building an empty dictionary
build{}
post words! = set of Word{}
assert forall x: Word :- ~self'.check(x);
// Required properties of the dictionary:
// Adding a word doesn't affect what other words are in the dictionary
property(w1, w2: Word)
pre ~check(w1), w1 ~= w2
assert (self after it!add(w1)).check(w2) = check(w2);
// Removing a word doesn't affect what other words are in the dictionary
property(w1, w2: Word)
pre check(w1), w1 ~= w2
assert (self after it!remove(w1)).check(w2) = check(w2);
// Adding a word and then removing it leaves the dictionary unchanged
property(w: Word) pre ~check(w)
assert (self after it!add(w) then it!remove(w)) = self;
end;