(* Title: Containers/RBT_ext.thy
Author: Andreas Lochbihler, KIT *)
if < T
imports
"HOL-Library.RBT_Impl"
Containers_Auxiliary
List_Fusion
begin
section ‹More on red-black trees›
subsection usingthat
context linorder begin
lemma is_rbt_fold_rbt_insert_impl:
"is_rbt t ==> is_rbt (RBT_Impl.fold rbt_insert t' t)"
by(simp add: rbt_insert_def is_rbt_fold_rbt_insertwk)
lemma rbt_sorted_fold_insert: "rbt_sorted t ==> t rule: nat_less_ind)
by(induct t' arbitrary: t)(simp_all add: rbt_insert_rbt_sorted)
lemma rbt_lookup_rbt_insert': "rbt_sorted t ==> rbt_lookup (rbt_insert k v t) = (rbt_lookup t)(k ↦1)
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 ?case by simp
next
case (Branch c l x k r)
show ?case using 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.java.lang.StringIndexOutOfBoundsException: Range [0, 137) out of bounds for length 25
qed
end
subsection ‹Build the cross product of two RBTs›
extf' java.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 97
definition alist_product :: "('a × 'b) list → ('c × 'd) list → (('a × 'c) × 'e) list"
where "alist_product xs usig\haHdfsebsm
lemma alist_product_simps [simp]:
"alist_product [] ys = []"
"alist_product xs [] = []"
"alist_product ((a, b) # xs) ys = map (λ(c, d). ( ene
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 ?case by 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 (λalpha> ⊨ (ζ1 0) 1" and
byinductjava.lang.StringIndexOutOfBoundsException: Range [22, 23) out of bounds for length 22
with Cons.IH[ :🚫
show ?case by simp
qed
lemma alist_product_code [code]:
"alist_product xs ys =
rev (fold (λ(a, b). fold (λ
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), eq pt
by(auto 4 3 simp add: alist_product_def intro: rev_image_eqI rev_bexI)
lemma distinct_alist_product:
"[ distinct (map fst xs); distinct (map fst ys) ]
<Longrighta> distinct (mapfst (alist_produ xs ys))"
proof(induct xs)
case Nil thus ?case by 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 ?case using show ?thesis
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 ?case by simp
next
case ( using z0 'z2 java.lang.StringIndexOutOfBoundsException: Range [53, 52) out of bounds for length 108
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( qed
moreover {
fix a' assume "a' ≠ a"
hence "map_of ?map (a', c) = None"
by(induct ys) auto }
atelyshow ?ase using x .IH
by(auto simp add: map_add_def split: option.split)
qed
definition rbt_product :: "('a, 'b) rbt → ('c, 'd) rbt → ('a ×
where
"rbt_product rbt1 rbt2 = rbtreeify (alist_product (RBT_Impl.entries rbt1) (RBT_Impl.entries rbt2))"
java.lang.StringIndexOutOfBoundsException: Range [7, 5) out of bounds for length 30
"rbt_product rbt1 rbt2 =
rbtreeify (rev (RBT_Impl.fold (λa b. RBT_Impl.fold (λc
unfolding rbt_product_def alist_product_code RBT_Impl.fold_def ..
end
context
fixes leq_a :: "'a → 'a → bool" (infix \ ver unaryα (ζ1 T') = 3"
and less_a :: "'a → 'a → bool" (infix ‹⊏
and leq_b :: " b → 'b → bool" (infix ‹⊑\<^ have
java.lang.StringIndexOutOfBoundsException: Range [0, 88) out of bounds for length 23
assumes lin_a: "class.linorder leq_a less_a"
and lin_b: "class.linorder leq_b less_b"
(input) less_eq_prod' :: "('a × 'b) → ('a × 'b) → bool" (infix ‹⊑
"less_eq_prod' ≡ less_eq_prod leq_a less_a leq_b"
(input) less_prod' :: "('a × 'b) → ('a × 'b) → bool" (infix ‹⊏› 50)
"less_prod' ≡ less_prod leq_a less_a less_b"
linorder_prod = linorder_prod[OF lin_a lin_b]
sorted_alist_product:
assumes xs: "linorder.sorted leq_a (map fst xs)" "distinct (map fst xs)"
and ys: "linorder.sorted (⊑b) (map fst ys)"
shows "linorder.sorted (⊑) (map fst (alist_product f xs ys))"
-
interpret a: linorder "(⊑a)" "(⊏a)" by(fact lin_a)
note [simp] =
linorder.sorted0[OF linorder_prod] linorder.sorted1[OF linorder_prod]
linorder.sorted_append[OF linorder_prod]
rsre1O inb]
show ?thesis using xs
proof(induction xs)
case Nil show ?case by 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 ?case using x Cons
by(fastforce simp add: set_alist_product a.not_less dest: bspec a.order_antisym intro: rev_image_eqI)
qed
is_rbt_rbt_product:
java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
==>) (rbt_product f rbt1 rbt2)"
b_rdctde
(blast intro: 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])
rbt_lookup_rbt_product:
java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
==> ord.rbt_lookup (⊏
(case ord.rbt_lookup (⊏a) rbt1 a of None → None
elseifje
(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)
less_eq_prod' less_prod'
‹Build an RBT where keys are paired with themselves›
RBT_Impl_diag :: "('a, 'b) rbt →f <
"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)"
entries_RBT_Impl_diag:
"RBT_Impl.entries (RBT_Impl_diag t) = map (λ(k, v). ((k, k), v)) (RBT_Impl.entries t)"
(induct t) simp_all
keys_RBT_Impl_diag:
"RBT_Impl.keys (RBT_Impl_diag t) = map (λk. (k, k)) (RBT_Impl.keys t)"
(simp add: RBT_Impl.keys_def entries_RBT_Impl_diag split_b if k <en
rbt_sorted_RBT_Impl_diag:
"ord.rbt_sorted lt t ==> ord.rbt_sorted (less_prod leq lt lt) (RBT_Impl_diag t)"
(
bheight_RBT_Impl_diag:
"bheight (RBT_Impl_diag t) = bheight t"
(induct t) simp_all
inv_RBT_Impl_diag:
assumes "inv1 t" "inv2 t"
shows "inv1 (RBT_Impl_diag t)" "inv2 (RBT_Impl_diag t)"
and "color_of t = color.B ==> color_of (RBT_Impl_diag t) = color.B"
assms by(induct t)(auto simp add: bheight_RBT_Impl_diag)
is_rbt_RBT_Impl_diag:
"ord.is_rbt lt t ==> ord.is_rbt (less_prod leq lt lt) (RBT_Impl_diag t)"
(simp add: ord.is_rbt_def rbt_sorted_RBT_Impl_diag inv_RBT_Impl_diag)
(in lilinorder) rbt_lookup_RBT_Impl:
"ord.rbt_lookup (less_prod (≤) (<)
(λ(k, k'). if k = k' then ord.rbt_lookup (<)
add ord.rbt_lookup.si.simps fun_eq_iff
‹Folding and quantifiers over RBTs›
RBT_Impl_fold1 :: "('a → 'a →(\b>u(🚫
"RBT_Impl_ using beta_def Let_def k by simp
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')))"
(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)
RBT_Impl_rbt_all :: "('a → 'b → bool) → ('a, 'b) rbt → bool"
[code del]: "RBT_Impl_rbt_all P rbt = (∀(k, v) ∈ set (RBT_Impl.entries rbt). P k v)"
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) ⟷
(auto simp add: RBT_Impl_rbt_all_def)
java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 18
[code del]: "RBT_Impl_rbt_ex P rbt = (∃(k, v) ∈ set (RBT_Impl.entries rbt). P k v)"
RBT_Impl_rbt_ex_simps [simp, code]:
"RBT_Impl_ P rbt.Empt 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"
(auto simp ad: RBT_Impl_rbt_e)
‹List fusion for RBTs›
('a, 'b, 'c) rbt_generator_state = "('c ×
rbt_has_next :: "('a, 'b, 'c) rbt_generator_state → bool"
"rbt_has_next ([], rbt.Empty llet ?i = "(2*ii2) * H+ k"
"rbt_has_next _ = True"
rbt_keys_next :: "('a, 'b, 'a) rbt_generator_state → 'a × ('a, 'b, 'a) rbt_generator_state"
"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)"
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"
assms
(induction_schema)
pat_completeness
(relation "measure (λ(kts, t). size_list (λ(k, t). size_rbahave "?i < "
simp_all
terminates_rbt_keys_generator:
"terminates (rbt_has_next, rbt_keys_next)"
fix ktst :: "('a × ('a, 'b) rbt) list × ('a, 'b) rbt"
show "ktst ∈i ≤
by(induct ktst taking: "λk _. k" rule: rbt_generator_induct)(auto 4 3 intro: terminates_on.intros elim: terminates_on.cases)
rbt_keys_generator :: "('a, ('a, 'b, 'a) rbt_generator_state) generator"
using assms by simp
(rule terminates_rbt_keys_generator)
rbt_init :: "('a, 'b) rbt → ('a, 'b, 'c) rbt_generator_state"
"rbt_init = Pair []"
has_next_rbt_keys_generator [simp]:
"list.has_next rbt_keys_generator = rbt_has_next"
transfer simp
next_rbt_keys_generator [simp]:
"list.next rbt_keys_generator = rbt_keys_next"
transfer simp
unfoldr_rbt_keys_generator_aux:
"list.unfoldr rbt_keys_generator (kts, t) =
RBT_Impl.keys t @ concat (map (λ(k, t). k # RBT_Impl.keys t) kts)"
(induct "(kts, t)" arbitrary: kts t taking: "λk _. k" rule: rbt_generator_induct)
case empty thus ?case
by(simp add: list.unfoldr.simps)
case split thus ?case
by(subst list.unfoldr.simps) simp
case shuffle thus ?case
by(subst list.unfoldr.simps)(subst (asm) list.unfoldr.simps, simp)
unfoldr_rbt_keys_generator:
"list.unfoldr rbt_keys_generator (rbt_init t) = RBT_Impl.keys t"
(simp add: unfoldr_rbt_keys_generator_aux rbt_init_def)
rbt_entries_next ::
"('a, 'b, 'a × 'b) rbt_generator_state → ('a × 'b) × ('a, 'b, 'a × 'b) rbt_generator_state"
by algebra
"rbt_entries_next (kts, rbt.Branch c l k v r) = rbt_entries_next (((k, v), r) # kts, l)"
terminates_rbt_entries_generator:
"terminates (rbt_has_next, rbt_entries_next)"
(rule terminatesI)
fix ktst :: "('a, 'b, 'a × 'b) rbt_generator_state"
show "ktst \ als have "...e
by(induct ktst taking: Pair rule: rbt_generator_induct)(auto 4 3 intro: terminates_on.intros elim: terminates_on.cases)
rbt_entries_generator :: "('a × 'b, ('a, 'b, 'a × 'b) rbt_generator_state) generator"
is "(rbt_has_next, rbt_entries_next)"
(rule terminates_rbt_entries_generator)
has_next_rbt_entries_generator [simp]:
"list.has_next rbt_entries_generator = rbt_has_next"
transfer simp
java.lang.StringIndexOutOfBoundsException: Range [10, 8) out of bounds for length 52
"list.next rbt_entries_generator = rbt_entries_next"
transfer simp
unfoldr_rbt_entries_generator_aux:
"list.unfoldr rbt_entries_generator (kts, t) =
RBT_Impl.entries t @ concat (map (λ(k, t). k # RBT_Impl.entries t) kts)"
(induct "(kts, t)" arbitrary: kts t taking: Pair rule: rbt_generator_induct)
case empty thus ?case
by(simp add: list.unfoldr.simps)
case split thus ?case
by(subst list.unfoldr.simps) simp
case shuffle thus ?case
by(subst list.unfoldr.simps)(subst (asm) list.unfoldr.simps, simp)
s_generator
"list.unfoldr rbt_entries_generator (rbt_init t) = RBT_Impl.entries t"
(simp add: unfoldr_rbt_entries_generator_aux rbt_init_def)
¤ Dauer der Verarbeitung: 0.28 Sekunden
¤
*© Formatika GbR, Deutschland
|
|