src/Tools/Metis/src/Heap.sml
author desharna
Thu, 09 Jul 2020 11:39:16 +0200
changeset 72004 913162a47d9f
parent 39502 cffceed8e7fa
permissions -rw-r--r--
Update Metis to 2.4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     1
(* ========================================================================= *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     2
(* A HEAP DATATYPE FOR ML                                                    *)
72004
913162a47d9f Update Metis to 2.4
desharna
parents: 39502
diff changeset
     3
(* Copyright (c) 2001 Joe Leslie-Hurd, distributed under the BSD License     *)
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     4
(* ========================================================================= *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     5
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     6
structure Heap :> Heap =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     7
struct
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     8
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     9
(* Leftist heaps as in Purely Functional Data Structures, by Chris Okasaki *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    10
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    11
datatype 'a node = E | T of int * 'a * 'a node * 'a node;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    12
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    13
datatype 'a heap = Heap of ('a * 'a -> order) * int * 'a node;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    14
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    15
fun rank E = 0
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    16
  | rank (T (r,_,_,_)) = r;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    17
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    18
fun makeT (x,a,b) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    19
  if rank a >= rank b then T (rank b + 1, x, a, b) else T (rank a + 1, x, b, a);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    20
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    21
fun merge cmp =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    22
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    23
      fun mrg (h,E) = h
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    24
        | mrg (E,h) = h
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    25
        | mrg (h1 as T (_,x,a1,b1), h2 as T (_,y,a2,b2)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    26
          case cmp (x,y) of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    27
            GREATER => makeT (y, a2, mrg (h1,b2))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    28
          | _ => makeT (x, a1, mrg (b1,h2))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    29
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    30
      mrg
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    31
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    32
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    33
fun new cmp = Heap (cmp,0,E);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    34
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    35
fun add (Heap (f,n,a)) x = Heap (f, n + 1, merge f (T (1,x,E,E), a));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    36
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    37
fun size (Heap (_, n, _)) = n;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    38
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    39
fun null h = size h = 0;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    40
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    41
fun top (Heap (_,_,E)) = raise Empty
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    42
  | top (Heap (_, _, T (_,x,_,_))) = x;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    43
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    44
fun remove (Heap (_,_,E)) = raise Empty
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    45
  | remove (Heap (f, n, T (_,x,a,b))) = (x, Heap (f, n - 1, merge f (a,b)));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    46
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    47
fun app f =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    48
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    49
      fun ap [] = ()
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    50
        | ap (E :: rest) = ap rest
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    51
        | ap (T (_,d,a,b) :: rest) = (f d; ap (a :: b :: rest))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    52
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    53
      fn Heap (_,_,a) => ap [a]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    54
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    55
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    56
fun toList h =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    57
    if null h then []
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    58
    else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    59
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    60
        val (x,h) = remove h
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    61
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    62
        x :: toList h
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    63
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    64
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    65
fun toStream h =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    66
    if null h then Stream.Nil
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    67
    else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    68
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    69
        val (x,h) = remove h
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    70
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    71
        Stream.Cons (x, fn () => toStream h)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    72
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    73
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    74
fun toString h =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    75
    "Heap[" ^ (if null h then "" else Int.toString (size h)) ^ "]";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    76
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    77
end