exception Empty exception Impossible_pattern of string let impossible_pat x = raise (Impossible_pattern x) module Elem = struct let eq = (=) let lt = (<) let leq = (<=) end type priority = int type 'a element = priority * 'a type 'a tree = Node of int * 'a element * 'a tree list type 'a queue = 'a tree list exception Queue_is_empty let empty() = [] let is_empty ts = ts = [] let rank (Node (r, _, _)) = r let root (Node (_, x, _)) = x let link (Node (r, x1, c1) as t1) (Node (_, x2, c2) as t2) = if Elem.leq x1 x2 then Node (r + 1, x1, t2 :: c1) else Node (r + 1, x2, t1 :: c2) let rec ins_tree t = function | [] -> [t] | t' :: ts' as ts -> if rank t < rank t' then t :: ts else ins_tree (link t t') ts' let insert ts p a = ins_tree (Node (0, (p, a), [])) ts let rec union ts1 ts2 = match ts1, ts2 with | _, [] -> ts1 | [], _ -> ts2 | t1 :: ts1', t2 :: ts2' -> if rank t1 < rank t2 then t1 :: union ts1' ts2 else if rank t2 < rank t1 then t2 :: union ts1 ts2' else ins_tree (link t1 t2) (union ts1' ts2') let rec remove_min_tree = function | [] -> raise Empty | [t] -> t, [] | t :: ts -> let t', ts' = remove_min_tree ts in if Elem.leq (root t) (root t') then (t, ts) else (t', t :: ts') let find_min ts = let (p, e) = root (fst (remove_min_tree ts)) in (p, e, ts) let delete_min ts = let (p, e, _) = find_min ts in let (Node (_, x, ts1), ts2) = remove_min_tree ts in let q = union (List.rev ts1) ts2 in (p, e, q)