lemma rbt_lookup_rbt_insert': "rbt_sorted t ==> rbt_lookup (rbt_insert k v t) = (rbt_lookup t)(k ↦ v)" by(simp add: rbt_insert_def rbt_lookup_rbt_insertwk fun_eq_iff split: option.split)
lemma rbt_lookup_fold_rbt_insert_impl: "rbt_sorted t2 ==> rbt_lookup (RBT_Impl.fold rbt_insert t1 t2) = rbt_lookup t2 ++ map_of (rev (RBT_Impl.entries t1))" proof(induction t1 arbitrary: t2) case Empty thus ?caseby simp next case (Branch c l x k r) show ?caseusing Branch.prems by(simp add: map_add_def Branch.IH rbt_insert_rbt_sorted rbt_sorted_fold_insert rbt_lookup_rbt_insert' fun_eq_iff split: option.split) qed
end
subsection‹Build the cross product of two RBTs›
contextfixes f :: "'a ==> 'b ==> 'c ==> 'd ==> 'e"begin
definition alist_product :: "('a × 'b) list ==> ('c × 'd) list ==> (('a × 'c) × 'e) list" where"alist_product xs ys = concat (map (λ(a, b). map (λ(c, d). ((a, c), f a b c d)) ys) xs)"
lemma alist_product_simps [simp]: "alist_product [] ys = []" "alist_product xs [] = []" "alist_product ((a, b) # xs) ys = map (λ(c, d). ((a, c), f a b c d)) ys @ alist_product xs ys" by(simp_all add: alist_product_def)
lemma append_alist_product_conv_fold: "zs @ alist_product xs ys = rev (fold (λ(a, b). fold (λ(c, d) rest. ((a, c), f a b c d) # rest) ys) xs (rev zs))" proof(induction xs arbitrary: zs) case Nil thus ?caseby simp next case (Cons x xs) obtain a b where x: "x = (a, b)"by(cases x) have"∧zs. fold (λ(c, d). (#) ((a, c), f a b c d)) ys zs = rev (map (λ(c, d). ((a, c), f a b c d)) ys) @ zs" by(induct ys) auto with Cons.IH[of "zs @ map (λ(c, d). ((a, c), f a b c d)) ys"] x show ?caseby simp qed
lemma alist_product_code [code]: "alist_product xs ys = rev (fold (λ(a, b). fold (λ(c, d) rest. ((a, c), f a b c d) # rest) ys) xs [])" using append_alist_product_conv_fold[of "[]" xs ys] by simp
lemma set_alist_product: "set (alist_product xs ys) = (λ((a, b), (c, d)). ((a, c), f a b c d)) ` (set xs × set ys)" by(auto 43 simp add: alist_product_def intro: rev_image_eqI rev_bexI)
lemma distinct_alist_product: "[ distinct (map fst xs); distinct (map fst ys) ] ==> distinct (map fst (alist_product xs ys))" proof(induct xs) case Nil thus ?caseby simp next case (Cons x xs) obtain a b where x: "x = (a, b)"by(cases x) have"distinct (map (fst ∘ (λ(c, d). ((a, c), f a b c d))) ys)" using‹distinct (map fst ys)›by(induct ys)(auto intro: rev_image_eqI) thus ?caseusing Cons x by(auto simp add: set_alist_product intro: rev_image_eqI) qed
lemma map_of_alist_product: "map_of (alist_product xs ys) (a, c) = (case map_of xs a of None ==> None | Some b ==> map_option (f a b c) (map_of ys c))" proof(induction xs) case Nil thus ?caseby simp next case (Cons x xs) obtain a b where x: "x = (a, b)"by (cases x) let ?map = "map (λ(c, d). ((a, c), f a b c d)) ys" have"map_of ?map (a, c) = map_option (f a b c) (map_of ys c)" by(induct ys) auto moreover { fix a' assume"a' ≠ a" hence"map_of ?map (a', c) = None" by(induct ys) auto } ultimatelyshow ?caseusing x Cons.IH by(auto simp add: map_add_def split: option.split) qed
show ?thesis using xs proof(induction xs) case Nil show ?caseby simp next case (Cons x xs) obtain a b where x: "x = (a, b)"by(cases x) have"linorder.sorted (⊑) (map fst (map (λ(c, d). ((a, c), f a b c d)) ys))" using ys by(induct ys) auto thus ?caseusing x Cons by(fastforce simp add: set_alist_product a.not_less dest: bspec a.order_antisym intro: rev_image_eqI) qed qed
lemma rbt_lookup_rbt_product: "[ ord.is_rbt (⊏a) rbt1; ord.is_rbt (⊏b) rbt2 ] ==> ord.rbt_lookup (⊏) (rbt_product f rbt1 rbt2) (a, c) = (case ord.rbt_lookup (⊏a) rbt1 a of None ==> None | Some b ==> map_option (f a b c) (ord.rbt_lookup (⊏b) rbt2 c))" by(simp add: rbt_product_def linorder.rbt_lookup_rbtreeify[OF linorder_prod] linorder.is_rbt_rbtreeify[OF linorder_prod] sorted_alist_product linorder.rbt_sorted_entries[OF lin_a] ord.is_rbt_rbt_sorted linorder.distinct_entries[OF lin_a] linorder.rbt_sorted_entries[OF lin_b] distinct_alist_product linorder.distinct_entries[OF lin_b] map_of_alist_product linorder.map_of_entries[OF lin_a] linorder.map_of_entries[OF lin_b] cong: option.case_cong)
end
hide_const less_eq_prod' less_prod'
subsection‹Build an RBT where keys are paired with themselves›
primrec RBT_Impl_diag :: "('a, 'b) rbt ==> ('a × 'a, 'b) rbt" where "RBT_Impl_diag rbt.Empty = rbt.Empty"
| "RBT_Impl_diag (rbt.Branch c l k v r) = rbt.Branch c (RBT_Impl_diag l) (k, k) v (RBT_Impl_diag r)"
lemma (in linorder) rbt_lookup_RBT_Impl_diag: "ord.rbt_lookup (less_prod (≤) (<) (<)) (RBT_Impl_diag t) = (λ(k, k'). if k = k' then ord.rbt_lookup (<) t k else None)" by(induct t)(auto simp add: ord.rbt_lookup.simps fun_eq_iff)
subsection‹Folding and quantifiers over RBTs›
definition RBT_Impl_fold1 :: "('a ==> 'a ==> 'a) ==> ('a, unit) RBT_Impl.rbt ==> 'a" where"RBT_Impl_fold1 f rbt = fold f (tl (RBT_Impl.keys rbt)) (hd (RBT_Impl.keys rbt))"
lemma RBT_Impl_fold1_simps [simp, code]: "RBT_Impl_fold1 f rbt.Empty = undefined" "RBT_Impl_fold1 f (Branch c rbt.Empty k v r) = RBT_Impl.fold (λk v. f k) r k" "RBT_Impl_fold1 f (Branch c (Branch c' l' k' v' r') k v r) = RBT_Impl.fold (λk v. f k) r (f k (RBT_Impl_fold1 f (Branch c' l' k' v' r')))" by(simp_all add: RBT_Impl_fold1_def RBT_Impl.keys_def fold_map RBT_Impl.fold_def split_def o_def tl_append hd_def split: list.split)
definition RBT_Impl_rbt_all :: "('a ==> 'b ==> bool) ==> ('a, 'b) rbt ==> bool" where [code del]: "RBT_Impl_rbt_all P rbt = (∀(k, v) ∈ set (RBT_Impl.entries rbt). P k v)"
lemma RBT_Impl_rbt_all_simps [simp, code]: "RBT_Impl_rbt_all P rbt.Empty ⟷ True" "RBT_Impl_rbt_all P (Branch c l k v r) ⟷ P k v ∧ RBT_Impl_rbt_all P l ∧ RBT_Impl_rbt_all P r" by(auto simp add: RBT_Impl_rbt_all_def)
definition RBT_Impl_rbt_ex :: "('a ==> 'b ==> bool) ==> ('a, 'b) rbt ==> bool" where [code del]: "RBT_Impl_rbt_ex P rbt = (∃(k, v) ∈ set (RBT_Impl.entries rbt). P k v)"
lemma RBT_Impl_rbt_ex_simps [simp, code]: "RBT_Impl_rbt_ex P rbt.Empty ⟷ False" "RBT_Impl_rbt_ex P (Branch c l k v r) ⟷ P k v ∨ RBT_Impl_rbt_ex P l ∨ RBT_Impl_rbt_ex P r" by(auto simp add: RBT_Impl_rbt_ex_def)
fun rbt_has_next :: "('a, 'b, 'c) rbt_generator_state ==> bool" where "rbt_has_next ([], rbt.Empty) = False"
| "rbt_has_next _ = True"
fun rbt_keys_next :: "('a, 'b, 'a) rbt_generator_state ==> 'a × ('a, 'b, 'a) rbt_generator_state" where "rbt_keys_next ((k, t) # kts, rbt.Empty) = (k, kts, t)"
| "rbt_keys_next (kts, rbt.Branch c l k v r) = rbt_keys_next ((k, r) # kts, l)"
lemma rbt_generator_induct [case_names empty split shuffle]: assumes"P ([], rbt.Empty)" and"∧k t kts. P (kts, t) ==> P ((k, t) # kts, rbt.Empty)" and"∧kts c l k v r. P ((f k v, r) # kts, l) ==> P (kts, Branch c l k v r)" shows"P ktst" using assms apply(induction_schema) apply pat_completeness apply(relation "measure (λ(kts, t). size_list (λ(k, t). size_rbt (λ_. 1) (λ_. 1) t) kts + size_rbt (λ_. 1) (λ_. 1) t)") apply simp_all done
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 und die Messung sind noch experimentell.