PFDS Chapter #07 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 {QueueTest F} A = F.empty B = {F.snoc A 1} C = {F.snoc B 2} D = {F.snoc C 3} in {Browse D} {Browse {F.head D}} {Browse {F.head {F.tail D}}} {Browse {F.head {F.tail {F.tail D}}}} end proc {SortableTest F} A = F.empty B = {F.add 1 A} C = {F.add 2 B} D = {F.add 4 C} E = {F.add 3 D} L = {F.sort E} in {Browse E} {Browse {Map L fun {$ X} {Wait X} X end}} 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]} % 7.2 RealTimeQueue REALTIMEQUEUE = functor export empty : Empty isEmpty : IsEmpty snoc : Snoc head : Head tail : Tail define Empty = nil#nil#nil fun {IsEmpty Q} case Q of nil#_#_ then true else false end end fun lazy {Rotate Q} case Q of nil#(Y|_)#A then Y|A [] (X|Xs)#(Y|Ys)#A then X|{Rotate Xs#Ys#(Y|A)} end end fun {Exec Q} case Q of F#R#(X|S) then F#R#S [] F#R#nil then local Xs = {Rotate F#R#nil} in Xs#nil#Xs end end end fun {Snoc Q=F#R#S X} {Exec F#(X|R)#S} end fun {Head Q} case Q of (H|T)#R#S then H else raise empty end end end fun {Tail Q} case Q of (H|T)#R#S then {Exec T#R#S} else raise empty end end end end [RealTimeQueue] = {Module.apply [REALTIMEQUEUE]} {QueueTest RealTimeQueue} % 7.3 ScheduledBinomialHeap SCHEDULEDBINOMIALHEAP = 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#nil fun {IsEmpty Heap} case Heap of nil#_ then true else false end end fun {Link Tree1=node(X1 C1) Tree2=node(X2 C2)} if {Element.leq X1 X2} then node(X1 Tree2|C1) else node(X2 Tree1|C2) end end fun lazy {InsTree Tree L} case L of nil then one(Tree)|nil [] zero|T then one(Tree)|T [] one(X)|T then zero|{InsTree {Link Tree X} T} end end fun lazy {Mrg L1 L2} case L1#L2 of _#nil then L1 [] nil#_ then L2 [] (zero|T1)#(H2|T2) then H2|{Mrg T1 T2} [] (H1|T1)#(zero|T2) then H1|{Mrg T1 T2} [] (one(Tree1)|T1)#(one(Tree2)|T2) then zero|{InsTree {Link Tree1 Tree2} {Mrg T1 T2}} end end fun {Normalize L} case L of nil then L [] _|T then _ = {Normalize T} L end end fun {Exec Schedule} case Schedule of nil then nil [] (zero#Job)|T then Job|T [] _|T then T end end fun {Insert X Heap=L#Schedule} Xs = {InsTree node(X nil) L} in Xs#{Exec {Exec Xs|Schedule}} end fun {Merge Heap1=L1#_ Heap2=L2#_} L = {Normalize {Mrg L1 L2}} in L#nil end fun {RemoveMinTree L} case L of nil then raise empty end [] one(Tree)|nil then Tree#nil [] zero|T then local Tree#Lx = {RemoveMinTree T} in Tree#(zero|Lx) end [] one(Tree)|T then local node(X _) = Tree Tx#Dx = {RemoveMinTree T} node(Y _) = Tx in if {Element.leq X Y} then Tree#(zero|T) else Tx#(one(Tree)|Dx) end end end end fun {FindMin Heap=L#_} node(X _)#_ = {RemoveMinTree L} in X end fun {DeleteMin Heap=L#_} node(X C)#Xs = {RemoveMinTree L} Ys = {Mrg {Map {List.reverse C} fun {$ A} one(A) end} Xs} in {Normalize Ys}#nil end end [ScheduledBinomialHeap] = {Module.apply [SCHEDULEDBINOMIALHEAP]} {ScheduledBinomialHeap.initialize OrderedValue} {HeapTest ScheduledBinomialHeap} % 7.4 ScheduledBottomUpMergeSort SCHEDULEDBOTTOMUPMERGESORT = functor export initialize : Initialize empty : Empty add : Add sort : Sort define Element proc {Initialize OrderedSet} Element = OrderedSet end Empty = 0#nil fun lazy {Mrg S1 S2} case S1#S2 of nil#_ then S2 [] _#nil then S1 [] (H1|T1)#(H2|T2) then if {Element.leq H1 H2} then H1 | {Mrg T1 S2} else H2 | {Mrg S1 T2} end end end fun {Exec1 L} case L of nil then nil [] nil|Sched then {Exec1 Sched} [] (H|T)|Sched then T|Sched end end fun {Exec2 Xs#Sched} Xs#{Exec1 {Exec1 Sched}} end fun {Add X Size#Segs} fun {AddSeg Xs Segs Size Rsched} if Size mod 2 == 0 then (Xs#{List.reverse Rsched})|Segs else local (Ys#nil)|L = Segs Zs = {Mrg Xs Ys} in {AddSeg Zs L (Size div 2) Zs|Rsched} end end end L = {AddSeg X|nil Segs Size nil} in (Size+1)#{Map L Exec2} end fun {Sort Size#Segs} fun {MrgAll Xs Ys} case Ys of (Ys#_)|Segs then {MrgAll {Mrg Xs Ys} Segs} [] nil then Xs end end in {MrgAll nil Segs} end end [ScheduledBottomUpMergeSort] = {Module.apply [SCHEDULEDBOTTOMUPMERGESORT]} {ScheduledBottomUpMergeSort.initialize OrderedValue} {SortableTest ScheduledBottomUpMergeSort} |