(* This file was generated by the "make_metis" script. The BSD License is used with Joe Leslie-Hurd's kind permission. Extract from a September 13, 2010 email written by him:
I hereby give permission to the Isabelle team to release Metis as part of Isabelle, with the Metis code covered under the Isabelle BSD license.
*)
(******************************************************************) (* GENERATED FILE -- DO NOT EDIT -- GENERATED FILE -- DO NOT EDIT *) (* GENERATED FILE -- DO NOT EDIT -- GENERATED FILE -- DO NOT EDIT *) (* GENERATED FILE -- DO NOT EDIT -- GENERATED FILE -- DO NOT EDIT *) (******************************************************************)
(**** Original file: src/Random.sig ****)
(* Title: Tools/random_word.ML Author: Makarius
Simple generator for pseudo-random numbers, using unboxed word arithmetic only. Unprotected concurrency introduces some true randomness.
*)
signature Metis_Random = sig
val nextWord : unit -> word
val nextBool : unit -> bool
val nextInt : int -> int (* k -> [0,k) *)
val nextReal : unit -> real (* () -> [0,1) *)
end;
(**** Original file: src/Random.sml ****)
(* Title: Tools/random_word.ML Author: Makarius
Simple generator for pseudo-random numbers, using unboxed word arithmetic only. Unprotected concurrency introduces some true randomness.
*)
structure Metis_Random :> Metis_Random = struct
(* random words: 0w0 <= result <= max_word *)
(*minimum length of unboxed words on all supported ML platforms*) val _ = Word.wordSize >= 30
orelse raise Fail ("Bad platform word size");
val max_word = 0wx3FFFFFFF; val top_bit = 0wx20000000;
fun change r f = r := f (!r);
local val rand = (*Unsynchronized.*)Unsynchronized.ref 0w1 infun nextWord () = ((*Unsynchronized.*)change rand step; ! rand) end;
(*NB: higher bits are more random than lower ones*) fun nextBool () = Word.andb (nextWord (), top_bit) = 0w0;
(* random integers: 0 <= result < k *)
val max_int = Word.toInt max_word;
fun nextInt k = if k <= 0 orelse k > max_int thenraise Fail ("next_int: out of range") elseif k = max_int then Word.toInt (nextWord ()) else Word.toInt (Word.mod (nextWord (), Word.fromInt k));
(* random reals: 0.0 <= result < 1.0 *)
val scaling = real max_int + 1.0; fun nextReal () = real (Word.toInt (nextWord ())) / scaling;
end;
(**** Original file: src/Portable.sig ****)
(* ========================================================================= *) (* ML COMPILER SPECIFIC FUNCTIONS *) (* Copyright (c) 2001 Joe Leslie-Hurd, distributed under the BSD License *) (* ========================================================================= *)
signature Metis_Portable = sig
(* ------------------------------------------------------------------------- *) (* The ML implementation. *) (* ------------------------------------------------------------------------- *)
val ml : string
(* ------------------------------------------------------------------------- *) (* Pointer equality using the run-time system. *) (* ------------------------------------------------------------------------- *)
fun pointerEqual (x : 'a, y : 'a) = pointer_eq (x, y)
local val lock = Thread.Mutex.mutex (); in fun critical e () = Multithreading.synchronized "metis" lock e end;
val randomWord = Metis_Random.nextWord val randomBool = Metis_Random.nextBool val randomInt = Metis_Random.nextInt val randomReal = Metis_Random.nextReal
fun time f x = f x (* dummy *)
end
datatype'a frag = QUOTE of string | ANTIQUOTE of 'a
(**** Original file: src/Useful.sig ****)
(* ========================================================================= *) (* ML UTILITY FUNCTIONS *) (* Copyright (c) 2001 Joe Leslie-Hurd, distributed under the BSD License *) (* ========================================================================= *)
val mapCompare : ('a -> 'b) -> ('b * 'b -> order) -> 'a * 'a -> order
val revCompare : ('a * 'a -> order) -> 'a * 'a -> order
val prodCompare :
('a * 'a -> order) -> ('b * 'b -> order) -> ('a * 'b) * ('a * 'b) -> order
val lexCompare : ('a * 'a -> order) -> 'a list * 'a list -> order
val optionCompare : ('a * 'a -> order) -> 'a option * 'a option -> order
val boolCompare : bool * bool -> order (* false < true *)
(* ------------------------------------------------------------------------- *) (* Lists: note we count elements from 0. *) (* ------------------------------------------------------------------------- *)
val cons : 'a -> 'a list -> 'a list
val hdTl : 'a list -> 'a * 'a list
val append : 'a list -> 'a list -> 'a list
val singleton : 'a -> 'a list
val first : ('a -> 'b option) -> 'a list -> 'b option
val maps : ('a -> 's -> 'b * 's) -> 'a list -> 's -> 'b list * 's
val mapsPartial : ('a -> 's -> 'b option * 's) -> 'a list -> 's -> 'b list * 's
val zipWith : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list
val zip : 'a list -> 'b list -> ('a * 'b) list
val unzip : ('a * 'b) list -> 'a list * 'b list
val cartwith : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list
val cart : 'a list -> 'b list -> ('a * 'b) list
val takeWhile : ('a -> bool) -> 'a list -> 'a list
val dropWhile : ('a -> bool) -> 'a list -> 'a list
val divideWhile : ('a -> bool) -> 'a list -> 'a list * 'a list
val groups : ('a * 's -> bool * 's) -> 's -> 'a list -> 'a listlist
val groupsBy : ('a * 'a -> bool) -> 'a list -> 'a listlist
val groupsByFst : (''a * 'b) list -> (''a * 'b list) list
val groupsOf : int -> 'a list -> 'a listlist
val index : ('a -> bool) -> 'a list -> int option
val enumerate : 'a list -> (int * 'a) list
val divide : 'a list -> int -> 'a list * 'a list (* Subscript *)
val revDivide : 'a list -> int -> 'a list * 'a list (* Subscript *)
val updateNth : int * 'a -> 'a list -> 'a list (* Subscript *)
val deleteNth : int -> 'a list -> 'a list(* Subscript *)
fun first f [] = NONE
| first f (x :: xs) = (case f x of NONE => first f xs | s => s);
fun maps (_ : 'a -> 's -> 'b * 's) [] = unit []
| maps f (x :: xs) =
bind (f x) (fn y => bind (maps f xs) (fn ys => unit (y :: ys)));
fun mapsPartial (_ : 'a -> 's -> 'b option * 's) [] = unit []
| mapsPartial f (x :: xs) =
bind
(f x)
(fn yo =>
bind
(mapsPartial f xs)
(fn ys => unit (case yo of NONE => ys | SOME y => y :: ys)));
fun zipWith f = let fun z l [] [] = l
| z l (x :: xs) (y :: ys) = z (f x y :: l) xs ys
| z _ _ _ = raise Error "zipWith: lists different lengths"; in
fn xs => fn ys => List.rev (z [] xs ys) end;
fun zip xs ys = zipWith pair xs ys;
local fun inc ((x,y),(xs,ys)) = (x :: xs, y :: ys); in fun unzip ab = List.foldl inc ([],[]) (List.rev ab); end;
fun cartwith f = let fun aux _ res _ [] = res
| aux xsCopy res [] (y :: yt) = aux xsCopy res xsCopy yt
| aux xsCopy res (x :: xt) (ys as y :: _) =
aux xsCopy (f x y :: res) xt ys in
fn xs => fn ys => letval xs' = List.rev xs in aux xs' [] xs' (List.rev ys) end end;
fun cart xs ys = cartwith pair xs ys;
fun takeWhile p = let fun f acc [] = List.rev acc
| f acc (x :: xs) = if p x then f (x :: acc) xs elseList.rev acc in
f [] end;
fun dropWhile p = let fun f [] = []
| f (l as x :: xs) = if p x then f xs else l in
f end;
fun divideWhile p = let fun f acc [] = (List.rev acc, [])
| f acc (l as x :: xs) = if p x then f (x :: acc) xs else (List.rev acc, l) in
f [] end;
fun groups f = let fun group acc row x l = case l of
[] => let val acc = ifList.null row then acc elseList.rev row :: acc in List.rev acc end
| h :: t => let val (eor,x) = f (h,x) in if eor then group (List.rev row :: acc) [h] x t else group acc (h :: row) x t end in
group [] [] end;
fun groupsBy eq = let fun f (x_y as (x,_)) = (not (eq x_y), x) in
fn [] => []
| h :: t => case groups f h t of
[] => [[h]]
| hs :: ts => (h :: hs) :: ts end;
local fun fstEq ((x,_),(y,_)) = x = y;
fun collapse l = (fst (hd l), List.map snd l); in fun groupsByFst l = List.map collapse (groupsBy fstEq l); end;
fun groupsOf n = let fun f (_,i) = if i = 1 then (true,n) else (false, i - 1) in
groups f (n + 1) end;
fun index p = let fun idx _ [] = NONE
| idx n (x :: xs) = if p x then SOME n else idx (n + 1) xs in
idx 0 end;
fun enumerate l = fst (maps (fn x => fn m => ((m, x), m + 1)) l 0);
local fun revDiv acc l 0 = (acc,l)
| revDiv _ [] _ = raise Subscript
| revDiv acc (h :: t) n = revDiv (h :: acc) t (n - 1); in fun revDivide l = revDiv [] l; end;
fun divide l n = letval (a,b) = revDivide l n in (List.rev a, b) end;
fun updateNth (n,x) l = let val (a,b) = revDivide l n in case b of [] => raise Subscript | _ :: t => List.revAppend (a, x :: t) end;
fun deleteNth n l = let val (a,b) = revDivide l n in case b of [] => raise Subscript | _ :: t => List.revAppend (a,t) end;
(* Finding the minimum and maximum element of a list, wrt some order. *)
fun minimum cmp = let fun min (l,m,r) _ [] = (m, List.revAppend (l,r))
| min (best as (_,m,_)) l (x :: r) =
min (case cmp (x,m) of LESS => (l,x,r) | _ => best) (x :: l) r in
fn [] => raise Empty
| h :: t => min ([],h,t) [h] t end;
fun maximum cmp = minimum (revCompare cmp);
(* Merge (for the following merge-sort, but generally useful too). *)
fun merge cmp = let fun mrg acc [] ys = List.revAppend (acc,ys)
| mrg acc xs [] = List.revAppend (acc,xs)
| mrg acc (xs as x :: xt) (ys as y :: yt) =
(case cmp (x,y) of
GREATER => mrg (y :: acc) xs yt
| _ => mrg (x :: acc) xt ys) in
mrg [] end;
(* Merge sort (stable). *)
fun sort cmp = let fun findRuns acc r rs [] = List.rev (List.rev (r :: rs) :: acc)
| findRuns acc r rs (x :: xs) = case cmp (r,x) of
GREATER => findRuns (List.rev (r :: rs) :: acc) x [] xs
| _ => findRuns acc x (r :: rs) xs
fun mergeAdj acc [] = List.rev acc
| mergeAdj acc (xs as [_]) = List.revAppend (acc,xs)
| mergeAdj acc (x :: y :: xs) = mergeAdj (merge cmp x y :: acc) xs
fun mergePairs [xs] = xs
| mergePairs l = mergePairs (mergeAdj [] l) in
fn [] => []
| l as [_] => l
| h :: t => mergePairs (findRuns [] h [] t) end;
fun sortMap _ _ [] = []
| sortMap _ _ (l as [_]) = l
| sortMap f cmp xs = let fun ncmp ((m,_),(n,_)) = cmp (m,n) val nxs = List.map (fn x => (f x, x)) xs val nys = sort ncmp nxs in List.map snd nys end;
fun interval m 0 = []
| interval m len = m :: interval (m + 1) (len - 1);
fun divides _ 0 = true
| divides 0 _ = false
| divides a b = b mod (Int.abs a) = 0;
local fun hcf 0 n = n
| hcf 1 _ = 1
| hcf m n = hcf (n mod m) m; in fun gcd m n = let val m = Int.abs m and n = Int.abs n in if m < n then hcf m n else hcf n m end; end;
val upper = len (String.explode "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
val lower = len (String.explode "abcdefghijklmnopqrstuvwxyz");
fun rotate (n,l) c k = List.nth (l, (k + Option.valOf (index (equal c) l)) mod n); in fun rot k c = if Char.isLower c then rotate lower c k elseif Char.isUpper c then rotate upper c k else c; end;
fun charToInt #"0" = SOME 0
| charToInt #"1" = SOME 1
| charToInt #"2" = SOME 2
| charToInt #"3" = SOME 3
| charToInt #"4" = SOME 4
| charToInt #"5" = SOME 5
| charToInt #"6" = SOME 6
| charToInt #"7" = SOME 7
| charToInt #"8" = SOME 8
| charToInt #"9" = SOME 9
| charToInt _ = NONE;
fun charFromInt 0 = SOME #"0"
| charFromInt 1 = SOME #"1"
| charFromInt 2 = SOME #"2"
| charFromInt 3 = SOME #"3"
| charFromInt 4 = SOME #"4"
| charFromInt 5 = SOME #"5"
| charFromInt 6 = SOME #"6"
| charFromInt 7 = SOME #"7"
| charFromInt 8 = SOME #"8"
| charFromInt 9 = SOME #"9"
| charFromInt _ = NONE;
fun nChars x = let fun dup 0 l = l | dup n l = dup (n - 1) (x :: l) in
fn n => String.implode (dup n []) end;
fun chomp s = let val n = size s in if n = 0 orelse String.sub (s, n - 1) <> #"\n"then s elseString.substring (s, 0, n - 1) end;
local fun chop l = case l of
[] => []
| h :: t => if Char.isSpace h then chop t else l; in val trim = String.implode o chop o List.rev o chop o List.rev o String.explode; end;
val join = String.concatWith;
local funmatch [] l = SOME l
| match _ [] = NONE
| match (x :: xs) (y :: ys) = if x = y thenmatch xs ys else NONE;
fun stringify acc [] = acc
| stringify acc (h :: t) = stringify (String.implode h :: acc) t; in fun split sep = let val pat = String.explode sep
fun div1 prev recent [] = stringify [] (List.rev recent :: prev)
| div1 prev recent (l as h :: t) = casematch pat l of
NONE => div1 prev (h :: recent) t
| SOME rest => div1 (List.rev recent :: prev) [] rest in
fn s => div1 [] [] (String.explode s) end; end;
fun capitalize s = if s = ""then s else str (Char.toUpper (String.sub (s,0))) ^ String.extract (s,1,NONE);
fun mkPrefix p s = p ^ s;
fun destPrefix p = let fun check s = ifString.isPrefix p s then () elseraise Error "destPrefix"
val sizeP = size p in
fn s => let val () = check s in String.extract (s,sizeP,NONE) end end;
fun isPrefix p = can (destPrefix p);
fun stripPrefix pred s = Substring.string (Substring.dropl pred (Substring.full s));
fun mkSuffix p s = s ^ p;
fun destSuffix p = let fun check s = ifString.isSuffix p s then () elseraise Error "destSuffix"
val sizeP = size p in
fn s => let val () = check s
val sizeS = size s in String.substring (s, 0, sizeS - sizeP) end end;
fun isSuffix p = can (destSuffix p);
fun stripSuffix pred s = Substring.string (Substring.dropr pred (Substring.full s));
type columnAlignment = {leftAlign : bool, padChar : char}
fun alignColumn {leftAlign,padChar} column = let val (n,_) = maximum Int.compare (List.mapsize column)
fun pad entry row = let val padding = nChars padChar (n - size entry) in if leftAlign then entry ^ padding ^ row else padding ^ entry ^ row end in
zipWith pad column end;
local fun alignTab aligns rows = case aligns of
[] => List.map (K "") rows
| [{leftAlign = true, padChar = #" "}] => List.map hd rows
| align :: aligns => let val col = List.map hd rows and cols = alignTab aligns (List.map tl rows) in
alignColumn align col cols end; in fun alignTable aligns rows = ifList.null rows then [] else alignTab aligns rows; end;
fun chat s = TextIO.output (TextIO.stdOut, s ^ "\n");
fun chide s = TextIO.output (TextIO.stdErr, s ^ "\n");
local fun err x s = chide (x ^ ": " ^ s); in funtry f x = f x handle e as Error _ => (err "try" (errorToString e); raise e)
| e as Bug _ => (err "try" (bugToString e); raise e)
| e => (err "try""strange exception raised"; raise e);
val warn = err "WARNING";
fun die s = (err "\nFATAL ERROR" s; OS.Process.exit OS.Process.failure); end;
fun timed f a = let val tmr = Timer.startCPUTimer ()
val res = f a
val {usr,sys,...} = Timer.checkCPUTimer tmr in
(Time.toReal usr + Time.toReal sys, res) end;
local val MIN = 1.0;
fun several n t f a = let val (t',res) = timed f a val t = t + t' val n = n + 1 in if t > MIN then (t / Real.fromInt n, res) else several n t f a end; in fun timedMany f a = several 0 0.0 f a end;
val executionTime = let val startTime = Time.toReal (Time.now ()) in
fn () => Time.toReal (Time.now ()) - startTime end;
end
(**** Original file: src/Lazy.sig ****)
(* ========================================================================= *) (* SUPPORT FOR LAZY EVALUATION *) (* Copyright (c) 2007 Joe Leslie-Hurd, distributed under the BSD License *) (* ========================================================================= *)
signature Metis_Lazy = sig
type'a lazy
val quickly : 'a -> 'a lazy
val delay : (unit -> 'a) -> 'a lazy
val force : 'a lazy -> 'a
val memoize : (unit -> 'a) -> unit -> 'a
end
(**** Original file: src/Lazy.sml ****)
(* ========================================================================= *) (* SUPPORT FOR LAZY EVALUATION *) (* Copyright (c) 2007 Joe Leslie-Hurd, distributed under the BSD License *) (* ========================================================================= *)
structure Metis_Lazy :> Metis_Lazy = struct
datatype'a thunk =
Value of'a
| Thunk of unit -> 'a;
datatype'a lazy = Metis_Lazy of 'a thunk Unsynchronized.ref;
fun quickly v = Metis_Lazy (Unsynchronized.ref (Value v));
fun delay f = Metis_Lazy (Unsynchronized.ref (Thunk f));
fun force (Metis_Lazy s) = case !s of
Value v => v
| Thunk f => let val v = f ()
val () = s := Value v in
v end;
fun memoize f = let val t = delay f in
fn () => force t end;
end
(**** Original file: src/Ordered.sig ****)
(* ========================================================================= *) (* ORDERED TYPES *) (* Copyright (c) 2004 Joe Leslie-Hurd, distributed under the BSD License *) (* ========================================================================= *)
signature Metis_Ordered = sig
type t
val compare : t * t -> order
(* PROVIDES
!x : t. compare (x,x) = EQUAL
!x y : t. compare (x,y) = LESS <=> compare (y,x) = GREATER
!x y : t. compare (x,y) = EQUAL ==> compare (y,x) = EQUAL
!x y z : t. compare (x,y) = EQUAL ==> compare (x,z) = compare (y,z)
!x y z : t. compare (x,y) = LESS andalso compare (y,z) = LESS ==> compare (x,z) = LESS
!x y z : t. compare (x,y) = GREATER andalso compare (y,z) = GREATER ==> compare (x,z) = GREATER
*)
end
(**** Original file: src/Ordered.sml ****)
(* ========================================================================= *) (* ORDERED TYPES *) (* Copyright (c) 2004 Joe Leslie-Hurd, distributed under the BSD License *) (* ========================================================================= *)
structure Metis_IntOrdered = structtype t = int val compare = Int.compare end;
structure Metis_IntPairOrdered = struct
type t = int * int;
fun compare ((i1,j1),(i2,j2)) = case Int.compare (i1,i2) of
LESS => LESS
| EQUAL => Int.compare (j1,j2)
| GREATER => GREATER;
(* ========================================================================= *) (* FINITE MAPS IMPLEMENTED WITH RANDOMLY BALANCED TREES *) (* Copyright (c) 2004 Joe Leslie-Hurd, distributed under the BSD License *) (* ========================================================================= *)
signature Metis_Map = sig
(* ------------------------------------------------------------------------- *) (* A type of finite maps. *) (* ------------------------------------------------------------------------- *)
val compare : ('a * 'a -> order) -> ('key,'a) map * ('key,'a) map -> order
val equal : ('a -> 'a -> bool) -> ('key,'a) map -> ('key,'a) map -> bool
(* ------------------------------------------------------------------------- *) (* Converting to and from lists. *) (* ------------------------------------------------------------------------- *)
val keys : ('key,'a) map -> 'key list
val values : ('key,'a) map -> 'a list
val toList : ('key,'a) map -> ('key * 'a) list
val fromList : ('key * 'key -> order) -> ('key * 'a) list -> ('key,'a) map
(* ------------------------------------------------------------------------- *) (* Converting a comparison function to an equality function. *) (* ------------------------------------------------------------------------- *)
fun equalKey compareKey key1 key2 = compareKey (key1,key2) = EQUAL;
datatype ('key,'value) tree =
E
| T of ('key,'value) node
and ('key,'value) node =
Node of
{size : int,
priority : priority,
left : ('key,'value) tree,
key : 'key,
value : 'value,
right : ('key,'value) tree};
fun lowerPriorityNode node1 node2 = let val Node {priority = p1, ...} = node1 and Node {priority = p2, ...} = node2 in
comparePriority (p1,p2) = LESS end;
(*BasicDebug local fun checkSizes tree = case tree of E => 0 | T (Node {size,left,right,...}) => let val l = checkSizes left and r = checkSizes right
val () = if l + 1 + r = size then () else raise Bug "wrong size" in size end;
fun checkSorted compareKey x tree = case tree of E => x | T (Node {left,key,right,...}) => let val x = checkSorted compareKey x left
val () = case x of NONE => () | SOME k => case compareKey (k,key) of LESS => () | EQUAL => raise Bug "duplicate keys" | GREATER => raise Bug "unsorted"
val x = SOME key in checkSorted compareKey x right end;
fun checkPriorities compareKey tree = case tree of E => NONE | T node => let val Node {left,right,...} = node
val () = case checkPriorities compareKey left of NONE => () | SOME lnode => if not (lowerPriorityNode node lnode) then () else raise Bug "left child has greater priority"
val () = case checkPriorities compareKey right of NONE => () | SOME rnode => if not (lowerPriorityNode node rnode) then () else raise Bug "right child has greater priority" in SOME node end; in fun treeCheckInvariants compareKey tree = let val _ = checkSizes tree
val _ = checkSorted compareKey NONE tree
val _ = checkPriorities compareKey tree in tree end handle Error err => raise Bug err; end;
*)
(* ------------------------------------------------------------------------- *) (* Tree operations. *) (* ------------------------------------------------------------------------- *)
fun treeNew () = E;
fun nodeSize (Node {size = x, ...}) = x;
fun treeSize tree = case tree of
E => 0
| T x => nodeSize x;
fun mkNode priority left key value right = let valsize = treeSize left + 1 + treeSize right in
Node
{size = size,
priority = priority,
left = left,
key = key,
value = value,
right = right} end;
fun mkTree priority left key value right = let val node = mkNode priority left key value right in
T node end;
(* ------------------------------------------------------------------------- *) (* Extracting the left and right spines of a tree. *) (* ------------------------------------------------------------------------- *)
fun treeLeftSpine acc tree = case tree of
E => acc
| T node => nodeLeftSpine acc node
and nodeLeftSpine acc node = let val Node {left,...} = node in
treeLeftSpine (node :: acc) left end;
fun treeRightSpine acc tree = case tree of
E => acc
| T node => nodeRightSpine acc node
and nodeRightSpine acc node = let val Node {right,...} = node in
treeRightSpine (node :: acc) right end;
fun mkNodeSingleton priority key value = let valsize = 1 and left = E and right = E in
Node
{size = size,
priority = priority,
left = left,
key = key,
value = value,
right = right} end;
fun nodeSingleton (key,value) = let val priority = randomPriority () in
mkNodeSingleton priority key value end;
fun treeSingleton key_value = let val node = nodeSingleton key_value in
T node end;
(* ------------------------------------------------------------------------- *) (* Appending two trees, where every element of the first tree is less than *) (* every element of the second tree. *) (* ------------------------------------------------------------------------- *)
fun treeAppend tree1 tree2 = case tree1 of
E => tree2
| T node1 => case tree2 of
E => tree1
| T node2 => if lowerPriorityNode node1 node2 then let val Node {priority,left,key,value,right,...} = node2
val left = treeAppend tree1 left in
mkTree priority left key value right end else let val Node {priority,left,key,value,right,...} = node1
val right = treeAppend right tree2 in
mkTree priority left key value right end;
(* ------------------------------------------------------------------------- *) (* Appending two trees and a node, where every element of the first tree is *) (* less than the node, which in turn is less than every element of the *) (* second tree. *) (* ------------------------------------------------------------------------- *)
fun treeCombine left node right = let val left_node = treeAppend left (T node) in
treeAppend left_node right end;
(* ------------------------------------------------------------------------- *) (* Searching a tree for a value. *) (* ------------------------------------------------------------------------- *)
fun treePeek compareKey pkey tree = case tree of
E => NONE
| T node => nodePeek compareKey pkey node
and nodePeek compareKey pkey node = let val Node {left,key,value,right,...} = node in case compareKey (pkey,key) of
LESS => treePeek compareKey pkey left
| EQUAL => SOME value
| GREATER => treePeek compareKey pkey right end;
(* ------------------------------------------------------------------------- *) (* Tree paths. *) (* ------------------------------------------------------------------------- *)
(* Generating a path by searching a tree for a key/value pair *)
fun treePeekPath compareKey pkey path tree = case tree of
E => (path,NONE)
| T node => nodePeekPath compareKey pkey path node
and nodePeekPath compareKey pkey path node = let val Node {left,key,right,...} = node in case compareKey (pkey,key) of
LESS => treePeekPath compareKey pkey ((true,node) :: path) left
| EQUAL => (path, SOME node)
| GREATER => treePeekPath compareKey pkey ((false,node) :: path) right end;
(* A path splits a tree into left/right components *)
fun addSidePath ((wentLeft,node),(leftTree,rightTree)) = let val Node {priority,left,key,value,right,...} = node in if wentLeft then (leftTree, mkTree priority rightTree key value right) else (mkTree priority left key value leftTree, rightTree) end;
fun addSidesPath left_right = List.foldl addSidePath left_right;
fun mkSidesPath path = addSidesPath (E,E) path;
(* Updating the subtree at a path *)
local fun updateTree ((wentLeft,node),tree) = let val Node {priority,left,key,value,right,...} = node in if wentLeft then mkTree priority tree key value right else mkTree priority left key value tree end; in fun updateTreePath tree = List.foldl updateTree tree; end;
(* Inserting a new node at a path position *)
fun insertNodePath node = let fun insert left_right path = case path of
[] => let val (left,right) = left_right in
treeCombine left node right end
| (step as (_,snode)) :: rest => if lowerPriorityNode snode node then let val left_right = addSidePath (step,left_right) in
insert left_right rest end else let val (left,right) = left_right
val tree = treeCombine left node right in
updateTreePath tree path end in
insert (E,E) end;
(* ------------------------------------------------------------------------- *) (* Using a key to split a node into three components: the keys comparing *) (* less than the supplied key, an optional equal key, and the keys comparing *) (* greater. *) (* ------------------------------------------------------------------------- *)
fun nodePartition compareKey pkey node = let val (path,pnode) = nodePeekPath compareKey pkey [] node in case pnode of
NONE => let val (left,right) = mkSidesPath path in
(left,NONE,right) end
| SOME node => let val Node {left,key,value,right,...} = node
val (left,right) = addSidesPath (left,right) path in
(left, SOME (key,value), right) end end;
(* ------------------------------------------------------------------------- *) (* Searching a tree for a key/value pair. *) (* ------------------------------------------------------------------------- *)
fun treePeekKey compareKey pkey tree = case tree of
E => NONE
| T node => nodePeekKey compareKey pkey node
and nodePeekKey compareKey pkey node = let val Node {left,key,value,right,...} = node in case compareKey (pkey,key) of
LESS => treePeekKey compareKey pkey left
| EQUAL => SOME (key,value)
| GREATER => treePeekKey compareKey pkey right end;
(* ------------------------------------------------------------------------- *) (* Inserting new key/values into the tree. *) (* ------------------------------------------------------------------------- *)
fun treeInsert compareKey key_value tree = let val (key,value) = key_value
val (path,inode) = treePeekPath compareKey key [] tree in case inode of
NONE => let val node = nodeSingleton (key,value) in
insertNodePath node path end
| SOME node => let val Node {size,priority,left,right,...} = node
val node =
Node
{size = size,
priority = priority,
left = left,
key = key,
value = value,
right = right} in
updateTreePath (T node) path end end;
(* ------------------------------------------------------------------------- *) (* Deleting key/value pairs: it raises an exception if the supplied key is *) (* not present. *) (* ------------------------------------------------------------------------- *)
fun treeDelete compareKey dkey tree = case tree of
E => raise Bug "Metis_Map.delete: element not found"
| T node => nodeDelete compareKey dkey node
and nodeDelete compareKey dkey node = let val Node {size,priority,left,key,value,right} = node in case compareKey (dkey,key) of
LESS => let valsize = size - 1 and left = treeDelete compareKey dkey left
val node =
Node
{size = size,
priority = priority,
left = left,
key = key,
value = value,
right = right} in
T node end
| EQUAL => treeAppend left right
| GREATER => let valsize = size - 1 and right = treeDelete compareKey dkey right
val node =
Node
{size = size,
priority = priority,
left = left,
key = key,
value = value,
right = right} in
T node end end;
(* ------------------------------------------------------------------------- *) (* Partial map is the basic operation for preserving tree structure. *) (* It applies its argument function to the elements *in order*. *) (* ------------------------------------------------------------------------- *)
fun treeMapPartial f tree = case tree of
E => E
| T node => nodeMapPartial f node
and nodeMapPartial f (Node {priority,left,key,value,right,...}) =
--> --------------------
--> maximum size reached
--> --------------------
¤ Dauer der Verarbeitung: 0.53 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.