(* Queue: person on the cho or wait queue New: --> Queue inc: Queue x string --> Queue del: Queue x string --> Queue size: Queue --> int *) datatype Queue = New | inc of Queue * string; fun del( New, s ) = New | del( inc( Q, i ), s ) = if i=s then Q else inc( del( Q, s ), i ); fun front( New ) = "" | front( inc( Q, i ) ) = if front(Q)="" then i else front(Q); fun size( New ) = 0 | size( inc( Q, i ) ) = size(Q) + 1; (* LIB: library new: --> LIB add: LIB x BOOK --> LIB rem: LIB x BOOK --> LIB cko: LIB x BOOK x PERSON --> LIB cki: LIB x BOOK x PERSON --> LIB wait: LIB x BOOK x PERSON --> LIB off: LIB x BOOK x PERSON --> LIB has: LIB x BOOK --> boolean here: LIB x BOOK --> int num: LIB x BOOK --> int *) datatype ('E) LIB = new | entry of ('E) LIB * 'E; fun add( new, b ) = entry( new, (b, New, New, 1) ) | add( entry( S, (i, j, k, c) ), b ) = if i=b then entry( S, (i, j, k, c+1) ) else entry( add( S, b ), (i, j, k, c) ); exception nobookError fun rem( new, b ) = raise nobookError | rem( entry( S, (i, j, k, c) ), b ) = if i=b then if c > 1 then entry( S, (i, j, k, c-1) ) else S else entry( rem(S, b), (i, j, k, c) ); exception nobookAvailable fun cko( new, b, p ) = raise nobookError | cko( entry( S, (i, j, k, c) ), b, p ) = if i=b then if c > size(j) then entry( S, (i, inc(j, p), k, c) ) else raise nobookAvailable else entry( cko( S, b, p ), (i, j, k, c) ); fun cki( new, b, p ) = raise nobookError | cki( entry( S, (i, j, k, c) ), b, p ) = if i=b then if size(k) >= 1 then cko( entry( S, (i, del(j, p), del(k, front(k)), c) ), b, front(k) ) else entry( S, (i, del(j, p), k, c) ) else entry( cki( S, b, p ), (i, j, k, c) ); fun wait( new, b, p ) = raise nobookError | wait( entry( S, (i, j, k, c) ), b, p ) = if i=b then entry( S, (i, j, inc(k, p), c) ) else entry( wait(S, b, p), (i, j, k, c) ); fun off( new, b, p ) = raise nobookError | off( entry( S, (i, j, k, c) ), b, p ) = if i=b then entry( S, (i, j, del(k, p), c) ) else entry( off(S, b, p), (i, j, k, c) ); fun has( new, b ) = false | has( entry( S, (i, j, k, c) ), b ) = if i=b then true else has(S, b); fun here( new, b ) = 0 | here( entry( S, (i, j, k, c) ), b ) = if i=b then c-size(j) else here( S, b ); fun num( new, b ) = 0 | num( entry( S, (i, j, k, c) ), b ) = if i=b then c else num( S, b ); val lib = new; val lib = add( lib, 0 ); val lib = add( lib, 1 ); val lib = add( lib, 0 ); val lib = cko( lib, 0, "Tom" ); val lib = cko( lib, 1, "Jerry" ); val lib = wait( lib, 0, "Amy" ); val lib = cki( lib, 0, "Tom" ); val lib = cki( lib, 1, "Jerry" ); has( lib, 1 ); here( lib, 1 ); num( lib, 1 );