Theory Tries
section "Tries (List Version)"
theory Tries
imports Trie
begin
text‹This is a specialization of tries where values are lists.›
type_synonym ('k,'v)tries = "('k,'v list)trie"
definition lookup_tries :: "('k,'v)tries ⇒ 'k list ⇒ 'v list" where
"lookup_tries t ks = (case lookup_trie t ks of None ⇒ [] | Some vs ⇒ vs)"
definition update_with_tries ::
"'k list ⇒ ('v list ⇒ 'v list) ⇒ ('k, 'v) tries ⇒ ('k, 'v) tries" where
"update_with_tries ks f =
update_with_trie ks (λvo. case vo of None ⇒ f [] | Some vs ⇒ f vs)"
definition insert_tries :: "'k list ⇒ 'v ⇒ ('k,'v)tries ⇒ ('k,'v)tries" where
"insert_tries ks v =
update_with_trie ks (λvo. case vo of None ⇒ [v] | Some vs ⇒ v#vs)"
definition inserts_tries :: "('v ⇒ 'k list) ⇒ 'v list ⇒ ('k,'v)tries ⇒ ('k,'v)tries" where
"inserts_tries key = fold (%v. insert_tries (key v) v)"
definition tries_of_list :: "('v ⇒ 'k list) ⇒ 'v list ⇒ ('k,'v)tries" where
"tries_of_list key vs = inserts_tries key vs (Trie None [])"
definition set_tries :: "('k,'v)tries ⇒ 'v set" where
"set_tries t = Union {gs. ∃a. gs = set(lookup_tries t a)}"
definition all_tries :: "('v ⇒ bool) ⇒ ('k,'v)tries ⇒ bool" where
"all_tries P = all_trie (list_all P)"
subsection ‹@{const lookup_tries}›
lemma lookup_Nil[simp]:
"lookup_tries (Trie vo ps) [] = (case vo of None ⇒ [] | Some vs ⇒ vs)"
by (simp add: lookup_tries_def)
lemma lookup_Cons[simp]: "lookup_tries (Trie vo ps) (a#as) =
(case map_of ps a of None ⇒ [] | Some at ⇒ lookup_tries at as)"
by (simp add: lookup_tries_def split: option.split)
lemma lookup_empty[simp]: "lookup_tries (Trie None []) as = []"
by(case_tac as, simp_all add: lookup_tries_def)
theorem lookup_update:
"lookup_tries (update_trie as vs t) bs =
(if as=bs then vs else lookup_tries t bs)"
by(auto simp add: lookup_tries_def lookup_update)
theorem lookup_update_with:
"lookup_tries (update_with_tries as f t) bs =
(if as=bs then f(lookup_tries t as) else lookup_tries t bs)"
by(auto simp add: lookup_tries_def update_with_tries_def lookup_update_with_trie
split: option.split)
subsection ‹@{const insert_tries}, @{const inserts_tries}, @{const tries_of_list}›
lemma invar_insert_tries: "invar_trie t ⟹ invar_trie(insert_tries as v t)"
by(simp add: insert_tries_def invar_update_with_trie split: option.split)
lemma invar_inserts_tries:
"invar_trie t ⟹ invar_trie (inserts_tries key xs t)"
by(induct xs arbitrary: t)(auto simp: invar_insert_tries inserts_tries_def)
lemma invar_of_list: "invar_trie (tries_of_list key xs)"
by(simp add: tries_of_list_def invar_inserts_tries)
lemma set_lookup_insert_tries: "set (lookup_tries (insert_tries ks a t) ks') =
(if ks' = ks then Set.insert a (set(lookup_tries t ks')) else set(lookup_tries t ks'))"
by(simp add: lookup_tries_def insert_tries_def lookup_update_with_trie set_eq_iff split: option.split)
lemma in_set_lookup_inserts_tries:
"(v ∈ set(lookup_tries (inserts_tries key vs t) (key v))) =
(v ∈ set vs ∪ set(lookup_tries t (key v)))"
by(induct vs arbitrary: t)
(auto simp add: inserts_tries_def set_lookup_insert_tries)
lemma in_set_lookup_of_list:
"v ∈ set(lookup_tries (tries_of_list key vs) (key v)) = (v ∈ set vs)"
by(simp add: tries_of_list_def in_set_lookup_inserts_tries)
lemma in_set_lookup_inserts_triesD:
"v ∈ set(lookup_tries (inserts_tries key vs t) xs) ⟹
v ∈ set vs ∪ set(lookup_tries t xs)"
apply(induct vs arbitrary: t)
apply (simp add: inserts_tries_def)
apply (simp add: inserts_tries_def)
apply (fastforce simp add: set_lookup_insert_tries split: if_splits)
done
lemma in_set_lookup_of_listD:
"v ∈ set(lookup_tries (tries_of_list f vs) xs) ⟹ v ∈ set vs"
by(auto simp: tries_of_list_def dest: in_set_lookup_inserts_triesD)
subsection ‹@{const set_tries}›
lemma set_tries_eq_ran: "set_tries t = Union(set ` ran(lookup_trie t))"
apply(auto simp add: set_eq_iff set_tries_def lookup_tries_def ran_def)
apply metis
by (metis option.inject)
lemma set_tries_empty[simp]: "set_tries (Trie None []) = {}"
by(simp add: set_tries_def)
lemma set_tries_insert[simp]:
"set_tries (insert_tries a x t) = Set.insert x (set_tries t)"
apply(auto simp: set_tries_def lookup_update set_lookup_insert_tries)
by (metis insert_iff)
lemma set_insert_tries:
"set_tries (inserts_tries key xs t) =
set xs Un set_tries t"
by(induct xs arbitrary: t) (auto simp: inserts_tries_def)
lemma set_tries_of_list[simp]:
"set_tries(tries_of_list key xs) = set xs"
by(simp add: tries_of_list_def set_insert_tries)
lemma in_set_lookup_set_triesD:
"x∈set (lookup_tries t a) ⟹ x ∈ set_tries t"
by(auto simp: set_tries_def)
end