PFDS Chapter #06 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]}
STREAM =
functor
export
append : Append
take : Take
drop : Drop
reverse : Reverse
fromList : FromList
toList : ToList
define
fun lazy {Append L1 L2}
case L1
of nil then L2
[] H|T then H|{Append T L2}
end
end
fun {Take L N}
if N == 0 then
nil
else
case L
of H|T then H|{Take T N-1}
[] nil then nil
end
end
end
fun {Drop L N}
if N == 0 then
L
else
case L
of H|T then {Drop T N-1}
[] nil then nil
end
end
end
fun lazy {Reverse L}
fun {Iter L1 L2}
case L1
of H|T then {Iter T H|L2}
[] nil then L2
end
end
in
{Iter L nil}
end
fun {FromList L} L end
fun {ToList L} L end
end
[Stream] = {Module.apply [STREAM]}
% 6.3 BankersQueue
BANKERSQUEUE =
functor
export
empty : Empty
isEmpty : IsEmpty
snoc : Snoc
head : Head
tail : Tail
define
Empty = 0#nil#0#nil
fun {IsEmpty Q}
case Q
of LenF#_#_#_ then LenF == 0
else false
end
end
fun {Check Q=LenF#F#LenR#R}
if LenR =< LenF then
Q
else
LenF+LenR#{Stream.append F {Stream.reverse R}}#0#nil
end
end
fun {Snoc Q=LenF#F#LenR#R X}
{Check LenF#F#(LenR+1)#(X|R)}
end
fun {Head Q}
case Q
of LenF#(H|T)#LenR#R then H
else raise empty end
end
end
fun {Tail Q}
case Q
of LenF#(H|T)#LenR#R then {Check (LenF-1)#T#LenR#R}
else raise empty end
end
end
end
[BankersQueue] = {Module.apply [BANKERSQUEUE]}
{QueueTest BankersQueue}
% 6.4 LazyBinomialHeap
LAZYBINOMIALHEAP =
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 Tree=node(R X C)} R end
fun {Root Tree=node(R X C)} X end
fun {Link Tree1=node(R X1 C1) Tree2=node(_ X2 C2)}
if {Element.leq X1 X2} then
node(R+1 X1 Tree2|C1)
else
node(R+1 X2 Tree1|C2)
end
end
fun {InsTree Tree Heap}
case Heap
of nil then [Tree]
[] H|T then
if {Rank Tree} < {Rank H} then
Tree|Heap
else
{InsTree {Link Tree H} T}
end
end
end
fun lazy {Insert X Heap}
{InsTree node(0 X nil) Heap}
end
fun lazy {Merge Heap1 Heap2}
case Heap1#Heap2
of _#nil then Heap1
[] nil#_ then Heap2
[] (H1|T1)#(H2|T2) then
if {Rank H1} < {Rank H2} then
H1|{Merge T1 Heap2}
elseif {Rank H2} < {Rank H1} then
H2|{Merge Heap1 T2}
else
{InsTree {Link H1 H2} {Merge T1 T2}}
end
end
end
fun {RemoveMinTree Heap}
case Heap
of [Tree] then Tree#nil
[] H|T then
local
A#B = {RemoveMinTree T}
in
if {Element.leq {Root H} {Root A}} then
H#T
else
A#(H|B)
end
end
else raise empty end
end
end
fun {FindMin Heap}
Tree#_ = {RemoveMinTree Heap}
in
{Root Tree}
end
fun lazy {DeleteMin Heap}
node(_ X Ts1)#Ts2 = {RemoveMinTree Heap}
in
{Merge {List.reverse Ts1} Ts2}
end
end
[LazyBinomialHeap] = {Module.apply [LAZYBINOMIALHEAP]}
{LazyBinomialHeap.initialize OrderedValue}
{HeapTest LazyBinomialHeap}
% 6.4 PhysicistsQueue
PHYSICISTSQUEUE =
functor
export
empty : Empty
isEmpty : IsEmpty
snoc : Snoc
head : Head
tail : Tail
define
Empty = nil#0#nil#0#nil
fun {IsEmpty Q}
case Q
of _#LenF#_#_#_ then LenF == 0
else false
end
end
fun {CheckW Q}
case Q
of nil#LenF#F#LenR#R then
{Wait F}
F#LenF#F#LenR#R
else Q
end
end
fun {Check Q=W#LenF#F#LenR#R}
if LenR =< LenF then
{CheckW Q}
else
{Wait F}
{CheckW F#(LenF+LenR)#{fun lazy {$} {Append F {List.reverse R}} end}#0#nil}
end
end
fun {Snoc Q=W#LenF#F#LenR#R X}
{Check W#LenF#F#(LenR+1)#(X|R)}
end
fun {Head Q}
case Q
of (X|W)#LenF#F#LenR#R then X
else raise empty end
end
end
fun {Tail Q}
case Q
of (X|W)#LenF#F#LenR#R then
{Check W#(LenF-1)#{fun lazy {$} F.2 end}#LenR#R}
else raise empty end
end
end
end
[PhysicistsQueue] = {Module.apply [PHYSICISTSQUEUE]}
{QueueTest PhysicistsQueue}
% 6.4 BottomUpMergeSort
BOTTOMUPMERGESORT =
functor
export
initialize : Initialize
empty : Empty
add : Add
sort : Sort
define
Element
proc {Initialize OrderedSet} Element = OrderedSet end
Empty = 0#nil
fun {Mrg Set1 Set2}
case Set1#Set2
of nil#_ then Set2
[] _#nil then Set1
[] (H1|T1)#(H2|T2) then
if {Element.leq H1 H2} then
H1 | {Mrg T1 Set2}
else
H2 | {Mrg Set1 T2}
end
end
end
fun {Add X Set=Size#Segs}
fun {AddSeg Seg Segs Size}
if Size mod 2 == 0 then
Seg | Segs
else
{AddSeg {Mrg Seg Segs.1} Segs.2 (Size div 2)}
end
end
in
(Size+1)#{fun lazy {$} {Wait Segs} {AddSeg [X] Segs Size} end}
end
fun {Sort Set=Size#Segs}
fun {MrgAll Xs Ys}
case Ys
of Seg|Segs then {MrgAll {Mrg Xs Seg} Segs}
[] nil then Xs
end
end
in
{Wait Segs}
{MrgAll nil Segs}
end
end
[BottomUpMergeSort] = {Module.apply [BOTTOMUPMERGESORT]}
{BottomUpMergeSort.initialize OrderedValue}
{SortableTest BottomUpMergeSort}
% 6.5 LazyPairingHeap
LAZYPAIRINGHEAP =
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 {Merge Heap1 Heap2}
case Heap1#Heap2
of _#nil then Heap1
[] nil#_ then Heap2
[] tree(X _ _)#tree(Y _ _) then
if {Element.leq X Y} then
{Link Heap1 Heap2}
else
{Link Heap2 Heap1}
end
end
end
fun {Link Heap A}
case Heap
of tree(X nil M) then tree(X A M)
[] tree(X B M) then tree(X nil {fun lazy {$} {Wait M} {Merge {Merge A B} M} end})
end
end
fun {Insert X Heap}
{Merge tree(X nil nil) Heap}
end
fun {FindMin Heap}
case Heap
of tree(X _ _) then X
else raise empty end
end
end
fun {DeleteMin Heap}
case Heap
of tree(X A B) then {Merge A B}
else raise empty end
end
end
end
[LazyPairingHeap] = {Module.apply [LAZYPAIRINGHEAP]}
{LazyPairingHeap.initialize OrderedValue}
{HeapTest LazyPairingHeap}
|