Theory Prio_List
section ‹Priority Lists›
theory Prio_List
imports Main
begin
ML ‹
signature PRIO_LIST = sig
type T
type item
val empty: T
val add_first: T -> item -> T
val add_last: T -> item -> T
val add_before: T -> item -> item -> T
val add_after: T -> item -> item -> T
val delete: item -> T -> T
val prio_of: (item -> bool) -> (item * item -> bool) -> T -> int
val contains: T -> item -> bool
val dest: T -> item list
val merge: T * T -> T
val merge': T * T -> item list * T
end
functor Prio_List (
type item;
val eq: item * item -> bool
): PRIO_LIST = struct
type item = item
type T = item list
val empty = []
fun add_first l e = remove eq e l@[e]
fun add_last l e = e::remove eq e l
fun add_before l e a = let
val l = remove eq e l
val (l1,(l2,l3)) = chop_prefix (fn x => not (eq (x,a))) l ||> chop 1
in l1@l2@e::l3 end;
fun add_after l e b = let
val l = remove eq e l
val (l1,l2) = chop_prefix (fn x => not (eq (x,b))) l
in l1@e::l2 end
val delete = remove eq
fun prio_of P prefer l = let
fun do_prefer _ NONE = true
| do_prefer x (SOME (_,y)) = prefer (x,y)
fun pr [] _ st = (case st of NONE => ~1 | SOME (i,_) => i)
| pr (x::l) i st = if P x andalso do_prefer x st then
pr l (i+1) (SOME (i,x))
else
pr l (i+1) st
in
pr l 0 NONE
end
val contains = member eq
fun dest l = l
fun merge' (l1,l2) = let
val l1' = map (fn ty => (Library.member eq l2 ty,ty)) l1;
val l2' = map (fn ty => (Library.member eq l1 ty,ty)) l2;
fun m [] [] = []
| m [] l = map (apfst (K false)) l
| m l [] = map (apfst (K false)) l
| m ((true,t1)::l1) ((true,t2)::l2) =
(not (eq (t1,t2)),t2) :: m l1 l2
| m ((false,t1)::l1) ((true,t2)::l2) =
(false,t1) :: m l1 ((true,t2)::l2)
| m ((true,t1)::l1) ((false,t2)::l2) =
(false,t2) :: m ((true,t1)::l1) l2
| m ((false,t1)::l1) ((false,t2)::l2) =
(false,t2)::(false,t1)::m l1 l2
val r = m l1' l2'
in
(map #2 (filter #1 r), map #2 r)
end;
fun merge (l1,l2) = #2 (merge' (l1,l2))
end
›
end