About CLRS The following Oz code is derived from the examples provided in the book:
      "Introduction To Algorithms, Second Edition" by Thomas H. Corman, Charles E. Leiserson, Ronald L. Rivest and Clifford Stein.
      http://mitpress.mit.edu/algorithms/

Chapter #11 Examples in Oz

% Utility functions
proc {While Expr Stmt}
   if {Expr} then {Stmt} {While Expr Stmt} end
end

proc {RepeatUntil Stmt Expr}
   {Stmt}
   if {Not {Expr}} then {RepeatUntil Stmt Expr} end
end

fun {MakeLinkedList}
   linkedlist(head:{NewCell nil})
end

fun {MakeLinkedListNode K X}
   linkedlistnode(key:K data:X next:{NewCell nil} prev:{NewCell nil})
end

fun {ListSearch L K}
   X = {NewCell @(L.head)}
in
   {While
      fun {$} @X \= nil andthen @X.key \= K end
      proc {$} X := @(@X.next) end}
   @X
end

proc {ListInsert L X}
   (X.next) := @(L.head)
   if @(L.head) \= nil then
      (@(L.head).prev) := X
   end
   (L.head) := X
   (X.prev) := nil
end

proc {ListDelete L X}
   if @(X.prev) \= nil then
      (@(X.prev).next) := @(X.next)
   else
      (L.head) := @(X.next)
   end
   if @(X.next) \= nil then
      (@(X.next).prev) := @(X.prev)
   end
end

% 11.1 DirectAddress Table
fun {DirectAddressSearch T Key}
   T.Key
end

proc {DirectAddressInsert T X=Value#Key}
   T.Key := Value
end

proc {DirectAddressDelete T X=_#Key}
   T.Key := nil
end

local
   T = {Tuple.toArray nil#nil#nil#nil#nil}
in
   {DirectAddressInsert T 10#1}
   {DirectAddressInsert T 20#2}
   {DirectAddressInsert T 30#3}
   {DirectAddressInsert T 40#4}
   {DirectAddressInsert T 50#5}
   {Browse 'DirectAddressSearch'#{DirectAddressSearch T 1}}
   {DirectAddressDelete T _#1}
   {Browse 'DirectAddressSearch'#{DirectAddressSearch T 1}}
end

% 11.2 ChainedHashInsert
fun {SillyHash X}
   case X
   of a then 1
   [] b then 1
   [] c then 1
   [] d then 2
   [] e then 2
   end
end

proc {ChainedHashInsert T X=Value#Key}
   I = {SillyHash Key}
in
   if T.I == nil then
      T.I := {MakeLinkedList}
   elseif {ListSearch T.I Key} \= nil then
      {ChainedHashDelete T X}
   end
   {ListInsert T.I {MakeLinkedListNode Key Value}}
end

fun {ChainedHashSearch T Key}
   I = {SillyHash Key}
in
   if T.I == nil then
      nil
   else
      case {ListSearch T.I Key}
      of linkedlistnode(data:Value key:_ next:_ prev:_) then Value
      else nil
      end
   end
end

proc {ChainedHashDelete T X=Value#Key}
   I = {SillyHash Key}
in
   {ListDelete T.I {ListSearch T.I Key}}
end

local
   T = {Tuple.toArray nil#nil#nil#nil#nil}
in
   {ChainedHashInsert T 10#a}
   {ChainedHashInsert T 20#b}
   {ChainedHashInsert T 30#c}
   {ChainedHashInsert T 40#d}
   {ChainedHashInsert T 50#e}
   {Browse 'ChainedHashSearch'#{ChainedHashSearch T a}}
   {ChainedHashDelete T _#a}
   {ChainedHashDelete T _#b}
   {ChainedHashInsert T 15#a}
   {Browse 'ChainedHashSearch'#{ChainedHashSearch T a}}
   {Browse 'ChainedHashSearch'#{ChainedHashSearch T b}}
   {Browse 'ChainedHashSearch'#{ChainedHashSearch T c}}
end

% 11.3 Division Hash
fun {DivisionHash K M}
   K mod M
end

% 11.3 Multiplication Hash
fun {IsPowerOf2 N}
   {BitAnd N N-1} == 0
end

fun {BitAnd X Y}
   case X#Y
   of 0#_ then 0
   [] _#0 then 0
   else
      2 * {BitAnd (X div 2) (Y div 2)} +
         if X mod 2 == Y mod 2 then X mod 2 else 0 end
   end
end

fun {ShiftRight X N}
   X div {Pow 2 N}
end

fun {MultiplicationHash K Size}
   if {IsPowerOf2 Size} then
      local
         R = 2654435769 * K
         ShiftAmount
         BitMask = Size - 1
      in
         {BitAnd {ShiftRight R ShiftAmount} BitMask}
      end
   else
      local
         Multiplier = 0.6180339887
         X
         %double x = o.hashCode() * MULTIPLIER;
      in
         %x -= Math.floor(x); // take the fractional part
         %x *= tableSize;  // multiply by the table size
         {FloatToInt X}
      end
   end
end

% 11.4 Hash
M = 100
fun {Hash K I}
   _
end
fun {HashInsert T K}
   Return = {NewCell nil}
   I = {NewCell 0}
in
   {RepeatUntil
      proc {$}
         J = {Hash K I}
      in
         if T.J == nil then
            T.J := K
            Return := J
         else
            I := @I + 1
         end
      end
      fun {$} @Return \= nil orelse @I == M end}
   if @Return \= nil then
      @Return
   else
      raise error('hash table overflow') end
   end
end

fun {HashSearch T K}
   Return = {NewCell nil}
   I = {NewCell 0}
   J = {NewCell _}
in
   {RepeatUntil
      proc {$}
         J := {Hash K I}
         if T.@J == K then
            Return := J
         else
            I := @I + 1
         end
      end
      fun {$} @Return \= nil orelse T.@J == nil orelse I == M end}
   @Return
end

Chris Rathman / Chris.Rathman@tx.rr.com