PFDS Chapter #09 Examples in Oz % Utility functions for tests proc {HeapTest F} A = {F.insert 1 F.empty} B = {F.insert 3 A} C = {F.insert 7 B} D = {F.insert 5 C} X = {F.insert 2 F.empty} Y = {F.insert 6 X} Z = {F.insert 4 Y} H = {F.merge D Z} in {Browse D} {Browse Z} {Browse H} {Browse {F.findMin H}} {Browse {F.findMin {F.deleteMin H}}} {Browse {F.findMin {F.deleteMin {F.deleteMin H}}}} {Browse {F.findMin {F.deleteMin {F.deleteMin {F.deleteMin H}}}}} {Browse {F.findMin {F.deleteMin {F.deleteMin {F.deleteMin {F.deleteMin H}}}}}} {Browse {F.findMin {F.deleteMin {F.deleteMin {F.deleteMin {F.deleteMin {F.deleteMin H}}}}}}} {Browse {F.findMin {F.deleteMin {F.deleteMin {F.deleteMin {F.deleteMin {F.deleteMin {F.deleteMin H}}}}}}}} end proc {BinaryTest F} A = nil B = {F.inc A} C = {F.inc B} D = {F.inc C} in {Browse D} {Browse {F.dec D}} {Browse {F.dec {F.dec D}}} {Browse {F.dec {F.dec {F.dec D}}}} {Browse {F.add D C}} end proc {RandomAccessListTest F} A = F.empty B = {F.cons 1 A} C = {F.cons 3 B} D = {F.cons 5 C} X = {F.update 0 7 D} Y = {F.update 2 9 X} in {Browse D} {Browse {F.head D}} {Browse {F.head {F.tail D}}} {Browse {F.head {F.tail {F.tail D}}}} {Browse {F.lookup 0 Y}} {Browse {F.lookup 1 Y}} {Browse {F.lookup 2 Y}} end % Functions defined in previous chapters ORDEREDVALUE = functor export eq : EQ lt : LT leq : LEQ define fun {EQ X Y} X == Y end fun {LT X Y} X < Y end fun {LEQ X Y} X =< Y end end [OrderedValue] = {Module.apply [ORDEREDVALUE]} % 9.2 Dense DENSE = functor export inc : Inc dec : Dec add : Add define fun {Inc X} case X of nil then [one] [] zero|T then one|T [] one|T then zero|{Inc T} end end fun {Dec X} case X of [one] then nil [] one|T then zero|T [] zero|T then one|{Dec T} end end fun {Add X Y} case X#Y of _#nil then X [] nil#_ then Y [] (H1|T1)#(zero|T2) then H1|{Add T1 T2} [] (zero|T1)#(H2|T2) then H2|{Add T1 T2} [] (one|T1)#(one|T2) then zero|{Inc {Add T1 T2}} end end end [Dense] = {Module.apply [DENSE]} {BinaryTest Dense} % 9.2 SparseByWeight SPARSEBYWEIGHT = functor export inc : Inc dec : Dec add : Add define fun {Carry X Y} case X#Y of _#nil then [X] [] _#(H|T) then if X < H then X|Y else {Carry 2*X T} end end end fun {Borrow X Y=H|T} if X == H then T else X|{Borrow 2*X Y} end end fun {Inc X} {Carry 1 X} end fun {Dec X} {Borrow 1 X} end fun {Add X Y} case X#Y of _#nil then X [] nil#_ then Y [] (H1|T1)#(H2|T2) then if H1 < H2 then H1|{Add T1 Y} elseif H2 < H1 then H2|{Add X T2} else {Carry 2*H1 {Add T1 T2}} end end end end [SparseByWeight] = {Module.apply [SPARSEBYWEIGHT]} {BinaryTest SparseByWeight} % 9.2 BinaryRandomAccessList BINARYRANDOMACCESSLIST = functor export empty : Empty isEmpty : IsEmpty cons : Cons head : Head tail : Tail lookup : Lookup update : Update define Empty = nil fun {IsEmpty Tree} Tree == Empty end fun {Size Tree} case Tree of leaf(X) then 1 [] node(W Tree1 Tree2) then W end end fun {Link Tree1 Tree2} node({Size Tree1}+{Size Tree2} Tree1 Tree2) end fun {ConsTree Tree1 N} case N of nil then [one(Tree1)] [] zero|T then one(Tree1)|T [] one(Tree2)|T then zero|{ConsTree {Link Tree1 Tree2} T} end end fun {UnconsTree Tree} case Tree of nil then raise empty end [] [one(X)] then X#nil [] one(X)|T then X#(zero|T) [] zero|T then local node(_ Left Right)#Ts = {UnconsTree T} in Left#(one(Right)|Ts) end end end fun {Cons X Tree} {ConsTree leaf(X) Tree} end fun {Head Tree} leaf(X)#_ = {UnconsTree Tree} in X end fun {Tail Tree} _#T = {UnconsTree Tree} in T end fun {LookupTree I Tree} case I#Tree of 0#leaf(X) then X [] _#leaf(X) then raise subscript end [] _#node(W Left Right) then if I < W div 2 then {LookupTree I Left} else {LookupTree (I - W div 2) Right} end end end fun {UpdateTree I Y Tree} case I#Tree of 0#leaf(X) then leaf(Y) [] _#leaf(X) then raise subscript end [] _#node(W Left Right) then if I < W div 2 then node(W {UpdateTree I Y Left} Right) else node(W Left {UpdateTree (I - W div 2) Y Right}) end end end fun {Lookup I Tree} case Tree of nil then raise subscript end [] zero|T then {Lookup I T} [] one(X)|T then if I < {Size X} then {LookupTree I X} else {Lookup I-{Size X} T} end end end fun {Update I Y Tree} case Tree of nil then raise subscript end [] zero|T then zero|{Update I Y T} [] one(X)|T then if I < {Size X} then one({UpdateTree I Y X})|T else one(X)|{Update I-{Size X} Y T} end end end end [BinaryRandomAccessList] = {Module.apply [BINARYRANDOMACCESSLIST]} {RandomAccessListTest BinaryRandomAccessList} % 9.2 SkewBinaryRandomAccessList SKEWBINARYRANDOMACCESSLIST = functor export empty : Empty isEmpty : IsEmpty cons : Cons head : Head tail : Tail lookup : Lookup update : Update define Empty = nil fun {IsEmpty Tree} Tree == Empty end fun {Cons X Tree} case Tree of (W1#T1)|(W2#T2)|T then if W1 == W2 then ((1+W1+W2)#node(X T1 T2))|T else (1#leaf(X))|Tree end else (1#leaf(X))|Tree end end fun {Head Tree} case Tree of nil then raise empty end [] (1#leaf(X))|T then X [] (W#node(X T1 T2))|T then X end end fun {Tail Tree} case Tree of nil then raise empty end [] (1#leaf(X))|T then T [] (W#node(X T1 T2))|T then ((W div 2)#T1)|((W div 2)#T2)|T end end fun {LookupTree W I Tree} case W#I#Tree of 1#0#leaf(X) then X [] 1#_#leaf(X) then raise subscript end [] _#0#node(X T1 T2) then X [] _#_#node(X T1 T2) then if I =< W div 2 then {LookupTree (W div 2) I-1 T1} else {LookupTree (W div 2) (I - 1 - W div 2) T2} end end end fun {UpdateTree W I Y Tree} case W#I#Tree of 1#0#leaf(X) then leaf(Y) [] 1#_#leaf(X) then raise subscript end [] _#0#node(X T1 T2) then node(Y T1 T2) [] _#_#node(X T1 T2) then if I =< W div 2 then node(X {UpdateTree (W div 2) I-1 Y T1} T2) else node(X T1 {UpdateTree (W div 2) (I - 1 - W div 2) Y T2}) end end end fun {Lookup I Tree} case Tree of nil then raise subscript end [] (W#X)|T then if I < W then {LookupTree W I X} else {Lookup I-W T} end end end fun {Update I Y Tree} case Tree of nil then raise subscript end [] (W#X)|T then if I < W then (W#{UpdateTree W I Y X})|T else (W#X)|{Update I-W Y T} end end end end [SkewBinaryRandomAccessList] = {Module.apply [SKEWBINARYRANDOMACCESSLIST]} {RandomAccessListTest SkewBinaryRandomAccessList} % 9.3 SkewBinomialHeap SKEWBINOMIALHEAP = functor export initialize : Initialize empty : Empty isEmpty : IsEmpty insert : Insert merge : Merge findMin : FindMin deleteMin : DeleteMin define Element proc {Initialize OrderedSet} Element = OrderedSet end Empty = nil fun {IsEmpty Heap} Heap == Empty end fun {Rank Heap=node(R X Xs C)} R end fun {Root Heap=node(R X Xs C)} X end fun {Link Heap1=node(R X1 Xs1 C1) Heap2=node(_ X2 Xs2 C2)} if {Element.leq X1 X2} then node(R+1 X1 Xs1 Heap2|C1) else node(R+1 X2 Xs2 Heap1|C2) end end fun {SkewLink X T1 T2} node(R Y Ys C) = {Link T1 T2} in if {Element.leq X Y} then node(R X Y|Ys C) else node(R Y X|Ys C) end end fun {InsTree T1 T2} case T2 of nil then [T1] [] H|T then if {Rank T1} < {Rank H} then T1|H|T else {InsTree {Link T1 H} T} end end end fun {MergeTrees Ts1 Ts2} case Ts1#Ts2 of _#nil then Ts1 [] nil#_ then Ts2 [] (T1|Tsp1)#(T2|Tsp2) then if {Rank T1} < {Rank T2} then T1|{MergeTrees Tsp1 Ts2} elseif {Rank T2} < {Rank T1} then T2|{MergeTrees Ts1 Tsp2} else {InsTree {Link T1 T2} {MergeTrees Tsp1 Tsp2}} end end end fun {Normalize Tree} case Tree of nil then nil [] H|T then {InsTree H T} end end fun {Insert X Heap} case Heap of T1|T2|Rest then if {Rank T1} == {Rank T2} then {SkewLink X T1 T2}|Rest else node(0 X nil nil)|Heap end else node(0 X nil nil)|Heap end end fun {Merge Tree1 Tree2} {MergeTrees {Normalize Tree1} {Normalize Tree2}} end fun {RemoveMinTree Heap} case Heap of nil then raise empty end [] [X] then X#nil [] H|T then local Tree1#Tree2 = {RemoveMinTree T} in if {Element.leq {Root H} {Root Tree1}} then H#T else Tree1#(H|Tree2) end end end end fun {FindMin Heap} Tree#_ = {RemoveMinTree Heap} in {Root Tree} end fun {DeleteMin Heap} node(_ X Xs Ts1)#Ts2 = {RemoveMinTree Heap} fun {InsertAll Xs Heap} case Xs of nil then Heap [] H|T then {InsertAll T {Insert H Heap}} end end in {InsertAll Xs {Merge {List.reverse Ts1} Ts2}} end end [SkewBinomialHeap] = {Module.apply [SKEWBINOMIALHEAP]} {SkewBinomialHeap.initialize OrderedValue} {HeapTest SkewBinomialHeap} |