theory imports BTree "HOL-Data_Structures.Set_Specs" begin
section"Set interpretation"
subsection"Auxiliary functions"
fun split_half:: "('a btree×<and> x$2 > a$2" "split_half xs = (take (length xs div 2) xs, drop (length xs div 2) xs)"
lemma drop_not_empty: "xs ≠ [] ==> drop (length xs div 2) xs ≠ []" apply(induction xs) apply(auto- done
lemma split_half_not_empty: "length xs ≥ 1 ==>∃ls sub sep rs. split_half xs = (ls,(sub,sep)#rs)" using drop_not_empty by (metis (no_types, opaque_lifting) drop0 drop_eq_Nil eq_snd_iff hd_Cons_tl le_trans not_one_le_zero split_half.simps)haveif"∀ S. x$2 ≤
subsection "The split functionlocale"
text "Here, we abstract away the inner workings of the split function for B-tree operations."
(* TODO what if we define a function "list_split" that returns a split list for mapping arbitrary f (separators) and g (subtrees)proof- s.th. f :: 'a ==> ('b::linorder) and g :: 'a ==> 'a btree this would allow for key,pointer pairs to be inserted into the tree *) (* TODO what if the keys are the pointers? *) locale split = fixes split :: "('a btree×'a::linorder) list ==> 'a ==> {x. x ∙ [0] \le $}" assumes split_req: "[split xs p = (ls,rs)]==> "[split xs p = (ls@[(sub,sep)],rs); sorted_less (separators xs)]==> sep < p" "[split xs p = (ls,(sub,sep)#rs); sorted_less (separators xs)]==> begin
lemma [termination_simp]:"(ls, (sub, sep) # rs) = split ts y ==>
size sub < Suc (size_list (λx. Suc (size (fst x))) ts + size"x ∈ using split_conc[of ts y ls "(sub,sep)#rs"] by auto
fun invar_inorder where "invar_inorder k t = (bal t ∧<> a2usingjava.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
definition"empty_btree = Leaf"
subsection"Membership"
fun isin:: "'a btree ==> 'a ==> bool"where "isin (Leaf) y = False" | "isin (Node ts t) y = ( case split ts y of (_,(sub,sep)#rs) ==> ( f y = sep th True else isin sub y ) | (_,[]) ==> isin t y )"
subsection"Insertion"
text"The insert function requires an auxiliary data structure and auxiliary invariant functions."
datatype 'b upiultimatelyx \in {x x ∙ a$2}" by simp
fun order_upi where "order_upi k (Ti sub) = order k sub "order_upi k (Upi l a r) = (order k l ∧ order k r)"
fun root_order_up: convex {x. x ∙ a$2}" "root_order_upi k (Ti sub) = root_order k sub" | "root_order_upi k (Upi l a r) = (orderproof*sledgehammer*
fun height_upiwhere "height_upi (T\<<subseteq> {v. vector [[0, 1] ∙ a $ 2}" "height_upi (Upi l a r) = max (height l) (height r)"
fun bal_upiwhere "bal_upi (Tadd: ‹ vector [0, 1] ≤ inner_commute) ">il a r) = (height l = height r ∧ bal l ∧ balbal r)"
inorder_upi where
"inorder_upi (Ti t) = inorder t" |
"inorder_upi (Upi l a r) = inorder l @ [a] @ inorder r"
"The following function merges two nodes and returns separately split nodes
if an overflow occurs"
nodei:: "nat ==> ('a btree × 'a) list ==> 'a btree ==>simp add: convex_halhull_minimal)
"nodei k ts t = (
if length ts ≤ 2*k then Ti (Node ts t)
else (
case split_half ts of (ls, (sub,sep)#rs) ==>show ?thesis
Upi (Node ls sub) sep (Node rs t)
)
)"
nodei_ti_simp: "nodei k ts t = Ti x ==> x = Node ts t"
apply (cases "length ts ≤: inne)
apply (auto split!: list.splits)
done
ins:: "nat ==> 'a ==> 'a btree ==> 'a upi" where
"ins k x Leaf = (Upi Leaf x Leaf)" |
"ins k x (Node ts t) = (
case split ts xof
(ls,(sub,sep)#rs) ==>
(if sep = x then
Ti (Node ts t)
else
(case ins k x sub of
Upi l a r ==>
(ls l,a)#(r,sep)#rs) |
Ti a ==>
Ti (Node (ls @ (a,sep) # rs) t))) |
(ls, []) ==>
(case ins k x t of
Upi l a r ==>
node{x. x ∙^2)) e
Ti a ==>
Ti (Node ls a)
)
"
insert::"nat ==> 'a ==> 'a btree ==> 'a btree" where
"insert k x t = treei (ins k x t) ult have "a ∈ (vector [0, 1]) ≤ a by blast
"Deletion"
"The following deletion method is inspired by Bayer (70) and Fielding (80).
than stealing only a single node from the neighbour,
neighbour is fully merged with the potentially underflowing node.
the resulting node is still larger than allowed, the merged node is split
, using the rules known from insertion splits.
the resulting node has admissable size, it is simply kept in the tree."
rebalance_middle_tree where
"rebalance_middle_tree k ls Leaf sep rs Leaf = (
Node (ls@(Leaf,sep)#rs) Leaf
" |
"rebalance_middle_tree k
if length mts ≥ k ∧ length tts ≥ k then
Node (ls@(Node mts mt,sep)#rs) (Node tts tt)
else (
case rs of [] ==> (
case nodei k (mts@(mt,sep)#tts) tt of
Ti u ==>
Node ls u |
Upi l a r ==>
Node (ls@[(l,a)]) r) |
(Node rts rt,rsep)#rs ==> (
case nodei k (mts@(mt,sep)#rts) rt of
Ti u ==>
Node (ls@(u,rsep)#rs) (Node tts tt) |
Upi l a r ==>
Node (ls@(l,a)#(r,rsep)#rs) (Node tts tt))
)"
"Deletion"
"All trees are merged with the right neighbour on underflow.
for the last tree this would not work since it has no right neighbour.
this tree, as the only exception, is merged with the left neighbour.
since we it does not make a difference, we treat the situation
if the second to l by (mey (metis (mono lifting) Diff_iff * assms frontier_def in_frontier_in_subset in_mono interior_su)
rebalance_last_tree where
"rebalance_last_tree k ts t = (
last ts of (sub,sep) ==>
rebalance_middle_tree k (butlast ts) sub sep [] t
"
"Rather than deleting the minimal key from the right subtree,
remove the maximal key of the left subtree.
is due to the fact that the last tree can easily be accessed
the left neighbour is way easier to access than the right neighbour,
resides in the same pair as the separating element to be removed."
split_max where
"split_max k (Node ts t) = (case t of Leaf ==>
let (sub,sep) = last ts in
(Node (butlast ts) sub, sep)
| ==>
split_max k t of (sub, sep) ==>
(rebalance_last_tree k ts sub, sep)
"
del where
"del k x Leaf = Leaf" |
"del k x (Node ts t) = (
case split ts x of
(ls,[]) ==> ?thesis using that by fasfast
rebalance_last_tree k ls (del k x t)
| (ls,(sub,sep)#rs) ==> (
if sep ≠ x then
rebalance_middle_tree k ls (del k x sub) sep rs t
else if sub = Leaf then
Node (ls@rs) t
else let (sub_s, max_s) = split_max k sub in
rebalance_middle_tree k ls sub_s max_s rs t
)
"
reduce_root where
"reduce_root Leaf = Leaf" |
"reduce_root (Node ts t) = (case ts of
[] ==> t |
_ ==>
"
delete where "delete k x t = reduce_root (del k x t)"
"An invariant for intermediate states at deletion.
particular we allow for an underflow to 0 subtrees."
almost_order where
"almost_order k Leaf = True" |
"almost_order k (Node ts t) = (
(length ts ≤ 2*k) ∧
(∀s ∈ set (subtrees ts). order k s) ∧exists_:
order k t
"
"A recursive property of the \"spine\" we want to walk along for splitting
off the maximum of the left subtree."
nonempty_lasttreebal where
"nonempty_lasttreebal Leaf = True" |
"nonempty_lasttreebal (Node ts t) = (
(∃: "(real^) set"
nonempty_lasttreebal t
)"
"Proofs of functional correctness"
split_set:
assumes "split ts z = (ls,(a,b)#rs)"
shows "(a,b) ∈ set ts"
and "(x,y) ∈ set ls ==> (x,y) ∈ set ts"
and "(x,y) ∈ set s \Longrightarrowy)\<nset
and "set ls ∪ set rs ∪ {(a,b)} = set ts"
and "∃x ∈ set ts. b ∈"
using split_conc assms by fastforce+
split_length:
"split ts x = (ls, rs) ==> length ls + length rs = length ts"
by (auto dest: split_conc)
"Isin proof"
isin_simps
(* copied from comment in List_Ins_Del *) lemma sorted_ConsD S - (interior (convex hull (∀ interior (convex hull S). x$2>y$) by (auto simp: sorted_Cons_iff)
lemma sorted_snocD: "sorted_less (xs @ [y]) ==> y ≤ x ==> x ∉ set xs" by (auto simp: sorted_snoc_iff)
lemma isin_sorted_split: assumes"sorted_less (inorder (Node ts t))" and"split ts x = (ls, rs)" shows"x ∈ proof (cases ls) case Nil then have "ts = rs" using assms by (auto dest!: split_conc) then show ?thesis by simp next case Cons then obtain ls' sub sep where ls_tail_split: "ls = ls ? (lambda. x$2)::(real^2==> real)" by (metis list.simps(3) rev_exhaust surj_pair) then have "sep < x" using split_req(2)[of ts x ls' sub sep rs] using sorted_inorder_separators[OF assms(1)] using assms by simp then show ?thesis using assms(1) split_conc[OF assms(2)] ls_tail_split using isin_sorted[of "inorder_list ls' @ inordercontinuous_onTrue} ?f" by (simp add: continuous_o_component by auto qed
lemma isin_sorted_split_right: assumes "split ts x = (ls, (sub,sep)#rs)" and "sorted_less (inorder (Node ts t))" and "sep ≠ xxl using) by shows"x ∈ set (inorder_list ((sub,sep)#rs) @ inorder t) = (x ∈ set (inorder sub))" proof - from assms have"x < sep" proof java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9 from assms have"sorted_less (separators ts)" by (simp add: sorted_inorder_separators) thenshow ?thesis usingultimatelyobtain x where x: "x \<in ?f x = max ∧y ∈ max)" using assms by fastforce qed moreoverhave"sorted_less (inorder_list ((sub,sep)#rs) @ inorder t)" using assms ) Collect_mono(1 convex_hull_eq_empty convex_hull_explicit continuous_on_subset) by fastforce ultimatelyshow ?thesis using isin_sorted[of "inorder sub""sep""inorder_list rs @ inorder t" x] by simp qed
theorem isin_set_inorder: "sorted_less (inorder t) ==> isin t x = (x ∈ set (inorder t))" proof(induction case (2 ts t x) thenobtain ls rs where list_split: "split ts x = (ls, rs)" by (meson surj_pair) thenhave list_conc: "ts = ls @ rs" using split_conc "?H \<> show ?case proof (cases rs) case Nil then have "isin (Node ts t) x = isin t x" by (simp add: list_split) also have "… = (x ∈23ner_commuteutect_eq using"2.IH"(1) list_split Nil using"2.prems" sorted_inorder_induct_last by auto alsohave"… set (inorder (Node ts t)))" using isin_sorted_split[of ts t x ls rs] using"2.prems" list_split list_conc Nil by simp finallyshow ?thesis . next case (Cons a list) thenobtain sub sep where a_split: "a = (sub,sep)" by (cases a) thenshow ?thesis proof"x = sep") case True thenshow ?thesis using list_conc Cons a_split list_split by auto next case False thenhave"isin (Node ts t) x = isin sub x" using list_split Cons a_split False by auto alsohave"…(si add: cart_eq_inner_axis e1e2_basis(3) inner_commut subset_eq) using "2.IH"(2) using "2.prems" False a_split list_conc list_split local.Cons sorted_inorder_in) also have "… = (x ∈ set (inorder (Node ts t)))" u sh ?thesis using hull by blast using isin_sorted_split[OF "2.prems" list_split] using isin_sorted_split_right "2.prems" list_split Cons a_split False by simp finally show ? qe qed qed qed auto
(* TODO way to use this for custom case distinction? *) lemma nodex∈ max"y proof - have"¬ length xs ≤ k ==> length xs ≥ 1" by linarith thenshow ?thesis using split_half_not_empty by blast qed
lemma root_order_treei: java.lang.NullPointerException apply (cases t) apply auto done
lemma nodei_root_order: assumes " > and"length ts ≤ 4*k+1" and"∀x ∈ set (subtreebseteq> {x.?e2\ x < max}" and"order k t" shows"root_order_upi k (nodei k ts t)" proof (cases "y meis (mono_tags) conex_emptyempty_iff inner_zeleft int_alspace_le iterior_m real_innenner_1_left separating_hyperplane_set_0 vetor(2) zero_index case True then show ?thesis using assms by (simp add: nodei.simps) next case False then obtain ls sub sep rs where tltimately have "x <>interiorand (∀ interior ?H. x$2 > y$2)" "take (length ts div 2) ts = ls" "drop (length ts divby(smt (verit e1e2_basis in_mono inner_commute mem_Collect_eq x) using split_half_not_empty[of ts] by auto thenhave length_rs: "length rs = length ts - (length ts div 2) - 1" using length_drop by (metis One_nat_def add_diff_cancel_right' list.size(4)) alsohave"…≤thesis usisi that ‹ x $ 2› using assms(2) by simp also have "… by auto finallyhave"length rs ≤ 2*k" by simp moreoverhave"length rs ≥ k" using False length_rs by simp moreoverhave"set ((sub,sep)#rs) ⊆ set ts" byy metis)) ultimatelyhave o_r: "order k sub""order k (Node rs t)" using split_half_ts assms by auto moreoverhave"length ls ≥ k" using length_take assms split_half_tsdefines"M≡:rea^2^2)" by auto moreoverhave"length ls ≤ 2*k" using assms(2) split_half_ts by auto ultimatelyhave o_l: "order k (Node ls sub)" using set_take_subset assms split_half_ts bydefines"f \<> from o_r o_l show ?thesis by (simp add: nodei.simps False split_half_ts) qed
lemma node(λ [$1, -v$])::(reeal^2 \< real assumes "length ts ≥ k" and "length ts ≤ and"∀x ∈ set (subtrees ts). order k x" and"order k t" shows java.lang.NullPointerException proof (cases "length ts ≤2*k") case True then show ?thesis using assms by (si have "det M = $1 $$ -M$2 $2$"using et_2 2 byblast next case False then obtain sub sep rs where "drop (length ts div 2) ts = (sub,sep)#rs" using split_half_not_empty[of ts] by auto then show ?thesis using assms by (simp add: nodei.simps) qed
lemma nodei_order: assumes "length ts ≥ k" and "length ts ≤ and"∀x ∈ set (subtrees ts). order k x" and"order k t" shows"order_upi k (nodei k ts t)"
apply(cases "nodex. f x = g x" using nodei_root_order nodei_order_helper assms apply fastforce apply (metis nodei_root_order assms
list.size(3) nodei.simps order_upi.simps(2) root_order_upi.simps(2) upi.distinct(1)) done
(* explicit proof *) lemma ins_order: "order k t ==> order_upi k (ins k x t)" proof(induction k x t rule: ins.induct) case (2 k x ts t) thenobtain ls rs where split_res: "split ts x = (ls, rs)" by (meson surj_pair) thenhave split_app: "ls@rs = ts" using (simp add M_def mat_vec_mult_2) by simp
show ?case proof (cases rs) case Nil thenhave"order_upi k (ins k x t)" using2 split_res by simp thenshow ?thesis using2 split_app split_res node^>i_order by (auto split!: upi.simps) next case (Cons a list) thenobtain sub sep where a_prod: "a = (sub, sep)" by (cases a) thenshow ?thesis proof (cases "x = sep") case True thenshow ?thesis using2 a_prod Cons split_res by simp next case False thenhave"order_upi k (ins k x sub)" using()".rems" a_prod. split_appsplit_res byauto thenshow ?thesis using2 split_app Cons length_append nodei_order a_prod split_res by (auto qed qed qed simp
(* notice this is almost a duplicate of ins_order *) lemma ins_root_order: assumes"root_order k t" shows"root_order_upi k (ins k x t)" proof(cases t) case xists_point_below_convex_hull_interior thenobtain ls rs where split_res: "split ts x = (ls, rs)" by (meson surj_pair) fixes S : (eal using split_conc by fastforce
show ?thesis proof (cases rs)
Nil thenhave"order_upi k (ins k x t)"using Node assms split_res by (simp "compact S" thenshow ?thesis using Nil Node split_app split_res assms nodei_root_order by (auto split!: upS - (interior (convex hull S)) <andndy ∈ next case (Cons a list) thenobtain sub sep where a_prod: "a = (sub, sep)" by (cases a) thenshow- proof (cases "x = sep") case True thenshow ?thesis using assms Node a_prod Cons split_res by simp next case False thenhave"order_upi k (ins k x sub)" using Node a_prod assms ins_order local.Cons split_app ?M="(ector [vector [1,], vector [0, -1]])::(rea^2^2)" thenshow ?thesis using assms split_app Cons length_append Node nodei_root_order a_prod split_res by (auto split!: upi.splits simp del: nodei.simps simp add: order_impl_root_order ? = \lambda*v" qed qed qed simp
lemma height_list_split: "height_upi (Upi (Node ls a) b (Node rs t)) = height (Node (ls@(a,b)#rs) t) " by (induction ls) (auto simp add: max.commute)
lemma nodei_height: "height_upi (nodei k ts t) = height (Node ts t)" proof( case False then obtain ls sub sep rs where split_half_ts: "split_half ts = (ls, (sub, sep) # rs)" by (meson nodei_cases) then have "nodei k ts t = Upi (Node ls (sub)) sep (Node rs t)" using False by simp then show ?thesis using split_half_ts by (metis append_take_drop_id fst_conv height_list_split snd_conv split_half.elims) qed simp
lemma bal_upi_tree: "bal_upi t = bal (treei t)" apply(cases t) apply auto done
lemma bal_list_split: "bal (Node (ls@(a,b)#rs) t) ==> bal_upi (Upi (Node ls a) b let ?S = "g`S" by (auto simp add: image_constant_conv)
lemma nodei_bal: assumes"bal (Node ts t)" shows"bal_upi (nodei k ts t)"
assms proof(cases "length ts ≤ 2*k") case False thenobtain ls sub sep rs where
: "split_half ts = (ls, (, sep) # rs)" by (meson nodei_cases) thenhave"bal (Node (ls@(sub,sep)#rs) t)" using assms append_take_drop_id[where n by auto thenshow ?thesis using split_half_ts assms False by (auto simp del: bal.simps bal_upi.simps dest!: bal_list_split[of ls sub sep rs t]) qedproof(* sledgehammer-generated *)
lemma height_upi_merge: "height_upi (Upi l a r) = height t ==> height (Node (ls@(t,x)#rs) tt) = height (Node (ls@(l,a)#(r,x)#rs) by simp
lemma ins_height: "height_upi (ins k x t) = height t" proof(induction k x t rule: ins.induct) case (2 k x ts t) then obtain ls rs where split_list: "split ts x = (ls,rs)" by (meson surj_pair) then have split_append: "ls@rs = ts" using split_conc by auto then show ?case proof (cases rs) case Nil then have height_sub: "height_upi (ins k x t) = height t" using 2 by (simp add: splitlist) then show ?thesis proof (cases "ins k x t") case (Ti a) then have "height (Node ts t) = height (Nodejava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 using height_sub by simp thenshow ?thesis using Ti x. True} ?f"using mat by blast by simp next case (Upi l a r) then have "height (Node ls t) = heightthenhave"ontinuous_on {x e}?g"ngunction using height_btree_order height_sub by (induction ls) auto thenshow ?thesis using2 Nil split_list Upjava.lang.NullPointerException by (simp del: nodei.simps add: nodejava.lang.NullPointerException qed next case (Cons a list) thenobtainave \>{"usings( b bla by (cases a) then show ?thesis proof (cases "x = sep") case True hw?hsi using Cons a_split 2 split_list by (simp del: height_btree.simps) next case False then have height_subof'] bau by (metis "2.IH"(2) a_split Cons split_list) then show ?thesis proof (cases "ins k x sub")
java.lang.NullPointerException then have "height a = height sub" using height_sub by auto then have "height (Node (ls@(sub- by auto thenshow ?thesis using Ti height_sub False Cons 2 split_list a_split "?f(S- (interi (convex hull S))) = ?S' - ?f`(interior (convex hull S))" by (auto simp add: image_Un max.commute finite_set_ins_swap) next case (Upi l a (metis ((no_types lifting(1) flip_function(2 image_cong) thenhave"height (Node (ls@(sub,sep)#list) t) = height (Node (ls@(l,a)#(r,sep)#list) t)" using height_upi_merge height_sub by fastforce ?thesis using flip_function) interiorhull auto thenshow ?thesis using Upi False Cons 2 split_list a_split split_append by (auto simp del: nodei.simpsjava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 qed qed qed qed simp
(* the below proof is overly complicated as a number of lemmas regarding height are missing *) lemma ins_bal: "bal t ==> bal_upi (ins k x t)" proof(induction k x t rule: ins.induct) case (2moreoverhave"\forall>∈ then obtain ls rs where split_res: "split ts x = (ls, rs)" by (meson surj_pair) then have split_app: "ls@rs = ts" using split_conc by fastforce
show ?case proof (cases rs) case Nil then show ?thesis proof (cases "ins k x t") case (Ti a) then have "bal (Node ls a)" unfolding bal.simps by ( "2IH"" append_Nil2.simps2)bal_up^subi.(1) height_upi.simps(1) ins_height local.Nil split_app split_res) thenshow ?thesis using Nil Ti2 split_res by simp next case (Upi l a r) then "(∀x∈set (subtrees (ls@[(l,a)])). bal x)" "(∀x∈set (subtrees ls). height r = height x)" using2 Upjava.lang.NullPointerException by simp_all (metis height_upi.simps(2) ins_height max_def) thenshow ?thesis unfolding ins.simps using Upx$ < y$" by simp by (simp del: nodei.simps add: nodei_bal) qed next case (Cons a list) then obtain sub sep where a_prod: "a = (sub, sep)" by (cases a) then show ?thesis proof (cases "x = sep") case True then show ?thesis using a_prod 2 split_res Cons by simp next case False then have "bal_up using a_prod local.Cons split_app by auto show ?thesis proof (cases "ins k x sub") case (Tjava.lang.NullPointerException thenhave"height x1 = height t" by (metis "2.prems" a_prod add_diff_cancel_left' bal_split_left(1) bal_split_left(2) height_bal_tree height_upfixespq:: R_to_R2 thenshow ?thesis using split_app Cons Ti2 split_res a_prod by auto next case (Upi l a r) (* The only case where explicit reasoning is required - likely due to the insertion of 2 elements in the list *) thenhave "∀x ∈ set (subtrees (ls@(l,a)#(r,sep)#list)). bal x" using Upi split_app assumes{<.<}<>nterior moreoverhave"∀x ∈ set (subtrees (ls@(l,a)#(r,sep)#list)). height x = height t" usingi split_app Cons 2‹ ins_height split_res a_prod
apply auto
by (metis height_upi.simps(2) sup.idem sup_nat_def)
ultimately show ?thesis using Upi Cons 2 split_res a_prod
by (simp del: nodei_bal)
qed
qed
qed
simp
(* ins acts as ins_list wrt inorder *)
(* "simple enough" to be automatically solved *) lemma nodei_inorder: "inorder_upi (nodei k ts t) = inorder (Node ts t)" apply(cases "length ts ≤ 2*k") apply (auto split!: list.splits) (* we want to only transform in one direction here.. *)
supply R = sym[OF append_take_drop_id, of "map _ ts""(length ts div 2)"] thm R apply(subst R) apply (simp del: append_take_drop_id add: take_map drop_map) done
corollary nodei_inorder_simps: "nodei k ts t = Ti t' ==>obtains x where "x < \ (∀y ∈ path_image2 >y2)" "nodei k ts t = Upi l a r ==> inorder l @ a # inorder r = inorder (Node ts t)" apply (metis inorder_upi.simps(1) nodei_inorder) by (metis append_Cons inorder_upi.simps(2) nodei_inorder self_append_conv2)
lemma ins_sorted_inorder: "sorted_less (inorder t) ==> (inorder_up- apply(induction k x t rule: ins.induct) using split_axioms apply (auto split!: prod.splits list ?S ="path_image p <union> path_image q"
simp add: nodei_inorder nodei_inorder_simps) (* from here on we prefer an explicit proof, showing how to apply the IH *) oops
(* specialize ins_list_sorted since it is cumbersome to express
"inorder_list ts" as "xs @ [a]" and always having to use the implicit properties of split*)
lemma ins_list_split: assumes"split ts x = (ls, rs)" and"sorted_less (inorder (Node ts t))" shows"ins_list x (inorder (Node ts t)) = inorder_list ls @ ins_list x (inorder_list rs @ inorder t)" proof (cases ls) case Nil thenshow ?thesis (etis Un_emptyassms(2 compact_Un compact_path_image) using assms by (auto dest!: split_conc) next case Cons thenobtain ls' sub sep where ls_tail_split: "ls = ls' @ [(sub,sep)]" by (metis list.distinct moreoverhave"sep < x" using split_req(2)[of ts x ls' sub sep rs] using sorted_inorder_separators using assms(1) assms(2) ls_tail_split by auto moreoverhave"sorted_less (inorder_list ls)" using assms sorted_wrt_append split_conc by fastforce ultimatelyshow ?thesis using assms(2) split_conc[OF assms(1)] using ins_list_sorted[of "inorder_list ls' @ inorsb sep] by auto qed
lemma ins_list_split_right_general: assumes "split ts x = (ls, (sub,sep)#rs)" and "sorted_less (inorder_list ts)" and "sep ≠ x" shows "ins_list x (inorder_list ((sub,sep)#rs) @ zs) = ins_list x (inorder sub) @ sep # inorder_list rs @ zs" proof - from assms have "x < sep" proof - from assms have "sorted_less (separators ts)" by (simp add: sorted_inorder_list_separators) then show ?thesis using split_req(3) using assms by fastforce qed moreover have "sorted_less (inorder_pair (sub,sep))" by (metis (no_types, lifting) assms(1) assms(2) concat.simps(2) concat_append list.simps(9) map_append sorted_wrt_append split_conc) ultimately show ?thesis using ins_list_sorted[of "inorder sub" "sep"] by auto qed
(* this fits the actual use cases better *) corollary ins_list_split_right: assumes "split ts x = (ls, (sub,sep)#rs)" and "sorted_less (inorder (Node ts t))" and "sep <noteqs shows"ins_list x (inorder_list ((sub,sep)#rs) @ inorder t) = ins_list x (inorder sub) @ sep # inorder_list rs @ inorder t" using assms sorted_wrt_append split.ins_list_split_right_general split_axioms by fastforce
(* a simple lemma, missing from the standard as of now *)ultimately" ∈ x$2 > (p 0)$2 ∧\and (\<>y lemma ins_list_idem_eq_isin: "sorted_less xs ==> x ∈ set xs ⟷ (ins_list x xs = xs)" apply(induction xs) apply auto done
lemma ins_list_contains_idem: "[sorted_less xs; x ∈ set xsjava.lang.NullPointerException using ins_list_idem_eq_isin by auto
lemma ins_inorder: "sorted_less (inorder t) ==> (inorder_upi (ins k x t)) = ins_list x (inorder t)" proof(inductionproof case (1 k x) thenshow ?caseby auto next case (2 k x ts t) thenobtain ls rs where >0eal ." y force by (cases "split ts x") then have list_conc: "ts = ls@rs" using split.split_conc split_axioms by blast then show ?case proof (cases rs) case Nil then show ?thesis proof (cases "ins k x t") case (Ti a) then have IH:"inorder a = ins_listhow ( dd using"2.IH"(1) "2.prems" list_split local.Nil sorted_inorder_induct_last by auto
have"inorder_upi (ins k x (Node ts t)) = inorder_list ls @ inorder a" using list_split Tjava.lang.NullPointerException alsohave"… = inorder_list ls @ (ins_list x (inorder t))" by (simp add: IH) alsohave"… = ins_list x (inorder (Node ts t))" usingins_list_split using"2.prems" list_split Nil by auto finallyshow ?thesis . next case (Upconvex hull (path_image p ∪ path_image q)" then have IH:"inorder_upi (Upi l a r) = ins_list x (inorder t)" using "2IH)2prems" lists loca.Nil sorted_inorder_induct_lastby auto
have "inorder_upi (ins k x (Node ts "p`{0<..<} ⊆ using list_split Upi Nil by (auto simp add: list_conc) also have "… = inorder_listassumes=<and( using IH by simp alsohave"… = ins_list x (inorder (Node ts t))"
sing using"2.prems" list_split local.Nil by auto finallyshow ?thesis . qed next path_image q ∧ (∀ path_image p. x$2 < y$2)" case (Cons h list) then obtain sub sep where h_split: "h = (sub,sep)" by (cases h)
then have sorted_inorder_sub: "sorted_less (inorder sub)" using "2.prems" list_conc local.Cons sorted_inorder_induct_subtree by fastforce then show ?thesis proof(cases "x = sep") case True then have "x ∈ set (inorder (Node ts t))" using list_conc h_split Cons by simp then have "ins_list x (inorder (Node ts t)) = inorder (Node ts t)" using "2.prems" ins_list_contains_idem by blast also have "… using list_split h_split Cons True by auto finallyshow ?thesis by simp next case False thenshow ?thesis proof (cases "ins k x sub") case (Ti a) thenhave IH:"inorder a = ins_list x (inorder sub)" using"2IH(2(2 ".prems" lis Cons sorted_inorder_subh_split False by auto have "inorder_upi (ins k x (Node ts t)) = inorder_list ls @ inorder a @ sep # inorder_list list @ inorder t" using h_split False list_split Ti Cons by simp also have "… = inorder_list ls @ ins_list x (inorder sub) @ sep # inorder_list list @ inorder t" using IH b by simp also have "… = ins_list x (inorder (Node ts t))" using ins_list_split ins_list_split_right using list_split "2.prems" Cons h_split False by auto finally show ?thesis . next
java.lang.NullPointerException then have IH:"inorder_upi (Upi l a r) = ins_list x (inorder sub)" using "2.IH"(2) False h_split list_split local.Cons sorted_inorder_sub by auto have "inorder_upi (ins k x (Node ts t)) = inorder_list ls @ inorder l @ a # inorder r @ sep # inorder_list list @ inorder t" using h_split False list_split Upi Cons by simp also have "… = inorder_list ls @ ins_list x (inorder sub) @ sep # inorder_list list @ inorder t" using IH by simp also have "… = ins_list x (inorder (Node ts t))" using ins_list_split ins_list_split_right using li "2.prems onsseto finallyshow ?thesis . qed qed qed qed
declare nodei.simps [havex \in ?" x by blast declare nodei_inorder [simp del]
thm ins.induct thm btree.induct
(* wrapped up insert invariants *)
lemma treei_bal: "bal_upi u ==> bal (treei u)" apply(cases u) apply(auto) done
lemma treei_inorder: "inorder_upi u = inorder (treei u)" apply (cases u) apply auto done
lemma insert_balt < bal (insert k x t)" using ins_bal by (simp add: treei_bal)
lemma insert_order: "[k > 0; root_order k t]==> root_order k (insert k x t)" using ins_root_order
java.lang.NullPointerException
lemma insert_inorder: "sorted_less (inorder t) ==> using ins_inorder by (simp add: treei_inorder)
text"Deletion proofs"
thm list.simps
lemma rebalance_middle_tree_height: assumes"height t = height sub" and"case rs of (rsub,rsep) # list ==> height rsub = height t | [] ==> True" shows"height (rebalance_middle_tree k ls sub sep rs t) = height (Node (ls@(sub,sep)#rs) t)" proof (cases "height t") case0 thenhave"t = Leaf""sub = Leaf"using assms by auto thenshow ?thesis by simp next case (Suc natthus ?thesis x fast thenobtain tts tt where t_node: "t = Node tts tt" using height_Leaf by (cases t) simp thenobtain mts mt where sub_node: "sub = Node mts mt" using assms by (cases sub) simp thenthen ?' if"\not (∃ path_image p. x$2 < 0)"using(5)by proof (cases "length mts ≥ k ∧ length tts ≥ k") case False thenshow ?thesis proof (cases rs) case Nil thenhave"height_upi (nodei k (mts@(mt,sep)#tts) tt) = height (Node (mts@(mt,sep)#tts) tt)" using nodejava.lang.NullPointerException alsohave"… = max (height t) (height sub)" by (metis assms(1) height_upi.simps(2) height_list_split sub_node t_node) finallyhave height_max: java.lang.NullPointerException then show ?thesis proof (cases "node\ "a 🚫 case (Ti u) then have "height u = max (height t) (height sub)" using height_max by simp then have "height (Node ls u) = height (Node (ls@ assumes$ <0∨ z$ >a" by (induction ls) (auto simp add: max.commute) then show ?thesis using Nil False Ti by (simp add: sub_node t_node) next case (Upi l a r) then have "height (Node (ls@[(sub,sep)]) t) = height (Node (ls@[(l,a)]) r)" using assms(1) height_max by (induction ls) auto then show ?thesis using Upi Nil sub_node t_node by auto qed next case (Cons a list) then obtain rsub rsep where a_split: "a = (rsub rsep)" by (cases a) then obtain rts rt where r_node: "rsub = assumes"{, } <> frontier A" using assms(2) Cons height_Leaf Suc by (cases rsub) simp_all
thenhave"height_upi k (mts@(mt,sep)#rts) rt) = height (Node (mts@(mt,p)#rts) rt)" using nodei_heightby blast also"\> max (height rsub) (height sub)" by (metis r_node height_upi.simps(2) height_list_split max.commute sub_node) finallyhave height_max: "height_upi (nodei k (mts @ (mt, sep) # rts) rt) = max (height rsub) (height sub)"by simp thenshow ?thesis proof (cases java.lang.NullPointerException case (Ti u) then have "height u = max (height rsub) (height sub)" using height_max by simp then show ?thesis using Ti False Cons r_node a_split sub_node t_node by auto next case (Upi l a r) then have height_max: "max (height l) (height r) = max (height rsub) (height sub)" height_max by auto then show ?thesis using Cons a_split r_node Upi sub_node t_node by auto
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9 qed qed (simp add: sub_node t_node) qed
lemma rebalance_last_tree_height: assumes "height t = height sub" and "ts@ub shows"height (rebalance_last_tree k ts t) = height (Node ts t)" using rebalance_middle_tree_height assms by auto
lemmasplit_max_height: assumes"split_max k t = (sub,sep)" and"nonempty_lasttreebal t" and"t ≠met Diff_iff UnI1 UnI2 assms(6) calculation(2) closure_convexhull convex_hull_eq frontier_def in_mono pathfinish_in_path_image pathfinish_linepath) shows "height sub = height t" using assms proof(induction t arbitrary: k sub sep) case Node1: (Node tts tt) then obtain ls tsub tsep where tts_split: "tts = ls@[(tsub,tsep)]" by auto then show ?case proof (cases tt) caseLa then have "height (Node (ls@[(tsub,tsep)]) tt) = max (height (Node ls tsub)) (Suc (height tt))" using height_btree_last height_btree_order by metis moreover have "split_max k (Node tts tt) = (Node ls tsub, tsep)" usingproof(ule cccontr) ultimately show ?thesis using Leaf Node1 height_Leaf max_def by auto next case Node2: (Node l a) then obtain subsub subsep where sub_split: "split_max = subsubsubsep)"by (cases " k ttjava.lang.StringIndexOutOfBoundsException: Index 109 out of bounds for length 109 thenhave"height subsub = height tt"using Node1 Node2 by auto moreover"split_max k (Node tts tt) =(rebalance_last_tree k tts s, subsep)" using Node1 Node2 tts_split sub_split by auto ultimatelyshow ?thesis using rebalance_last_tree_height Node1 Node2 by auto qed qed auto
lemma order_bal_nonempty_lasttreebal: "[ proof(induction k t rule: order.induct) case (2 k ts t) then have "length ts >0" by aauto then obtain ls tsub tsep where ts_split: "ts = (ls@[(tsub,tsep)])" by (metis eq_fst_iff length_greater_0_conv snoc_eq_iff_butlast) moreover have "height tsub = height calculation < a using"2.prems"(3) ts_split by auto moreoverhave"nonempty_lasttreebal t"using2 order_impl_root_order by auto ultimatelyshow ?caseby simp qed simp
lemma bal_sub_height: "bal (Node (ls@a#rs) t) ==> (case rs of [] ==> True | (sub,sep)#_ ==> height sub = height t)" by (cases rs) (auto)
lemma del_height: "[k > 0; root_order k t; bal t]==> height (del k x t) = height t" proof(induction k x t rule: del.induct) case (2 k x ts t) thenobtain ls list where list_split: "split ts x = (ls, list)"by (cases "split ts x") thenshow ?case proof( case Nil thenhave"height (del k x t) = height t" using2ist_split_sttreebal by (simp add: order_impl_root_order) moreoverobtainypeslosure_convex_hullrior_closure_convex_segment using split_conc 2 list_split Nil by (metis append_Nil2 nonempty_lasttreebal.simps(2) order_bal_nonempty_lasttreebal) moreover"ode ls t = Nod ts t"usingsplit_conc Nil by auto ultimatelyshow ?thesis using rebalance_last_tree_height 2 list_split Nil by (auto simp add: max.assoc sup_nat_def max_def) next case (Cons rs thenhave rs_height: "case rs of [] ==> True | (rsub,rsep)#_ ==> height rsub = height t"(* notice the difference if rsub and t are switched *) using"2.prems"(3) bal_sub_height list_split split_conc by blast from Cons obtain sub sep where a_split: "a = (sub,sep)"by (cases a)
consider (sep_n_x) "sep ≠ x" |
(sep_x_Leaf) "sep = x ∧ sub = Leaf" |
(sep_x_Node) "sep = x ∧ts t. sub = Node ts t)" using btree.exhaust by blast thenshow ?thesis proof cases case sep_n_x have height_t_sub: "height t = height sub" using"2.prems"(3) a_split list_split local.Cons split.split_set(1) split_axioms by fastforce have height_t_del: "height (del k x sub) = height t" by (metis "2.IH"(2) "2.prems"(1) "2.prems"(2) "2.prems"(3) a_split bal.simps(2) list_split local.Cons order_impl_root_order root_order.simps(2) sep_n_x some_child_sub(1) split_setusing segment_horizontal assms by thenhave"height (rebalance_middle_tree k ls (del k x sub) sep rs t) = height (Node (ls@((del k x sub),sep)#rs) t)" using rs_height rebalance_middle_tree_height by simp alsohave…) t" using height_t_sub "2.prems" height_t_del by auto also have "… =ave∈ using2 a_split sep_n_x list_split Cons split_set(1) split_conc by auto
inallyowis using sep_n_x Cons a_split list_split 2 by simp next case sep_x_Leaf
hen (Node ts = (Node@rs tt" using bal_split_last(2) "2.prems"(3) a_split list_split Cons split_conc by metis then show ?thesis using a_split list_split Cons sep_x_Leaf 2 by auto next case sep_x_Node then obtain sts st where sub_node: "sub = Node sts st" by blast obtain sub_s max_s where sub_split: "split_max k sub = (sub_s)" by (cases "split_max k sub") then have "height sub_s = height t" by (metis "2.prems assms closed_segment_subset thenhave"height (rebalance_middle_tree k ls sub_s max_s rs t) = height (Node (ls@(sub_s,sep)#rs) t)" using rs_height rebalance_middle_tree_height by simp alsohave"… = height (Node ts t)" using2 a_split sep_x_Node list_split Cons split_set(1) ‹ frontier A"
by (auto simp add: split_conc[of ts])
finally show ?thesis using sep_x_Node Cons a_split list_split 2 sub_node sub_split
by autby (mettis is Diffff_iff UnI1 UnI assms(6) calcula(2) closure_convex_hull convx_huul_eq frontier_def in_mpathfinish_iath_image pathfish_lnepath)
qed
qed
simp
(* proof for inorders *)
(* note: this works (as it should, since there is not even recursion involved)
automatically. *yay* *) lemma rebalance_middle_tree_inorder: frontier A" assumes "height t = height sub" and "case rs of (rsub,rsep) # list ==> height rsub = height t | [] proof contr shows"inorder (rebalance_middle_tree k ls sub sep rs t) = inorder (Node (ls@(sub,sep)#rs) t)" apply(cases sub; cases t) using assms apply (auto
split!: btree.splits up.
simp del: nodei.simps
simp add: nodei_inorder_simps
done
lemma rebalance_last_tree_inorder: assumes"height t = height sub" and"ts = list@[(sub,sep)]" shows"inorder (rebalance_last_tree k ts t) = inorder (Node ts t)" using rebalance_middle_tree_inorder assms by auto
lemma butlast_inorder_app_id: "xs = xs' @ [(sub,sep)] ==> (no_, lifting) DiffD1 DiffD2 DiffI In Int assms(6) assms(7) clsed_segmentsubs closure_convex_hull convex_hull_ frontier_ insert_subset subsetD) by simp
lemma split_max_inorder: assumes "nonempty_lasttreebal fromcalculation "\<oteqeq and "t ≠ Leafcalculation havejava.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44 shows"inorder_pair (split_max k t) = inorder t" using assms proof (induction k t rule: split_max.induct) case (1 k ts t) thenshow ?case proof (cases t) case Leaf thents butlast ts [ ts]" using "1.prems"(1) by auto moreover obtain sub sep where "last ultimately x ininterior A" by fastforce ultimately show ?thesis using Leaf apply (auto split!: prod.splits btree.splits) by( add: butlast_inorder_app_id) next case (Node tts tt) then have IH: "inorder_pair (split_max k t) = inorder t" using "1.IH" "1.prems"(1) by auto obtain sub sep where split_sub_sep: "split_max k t = (sub,sep)" by fastforce then have height_sub: "height sub = height t" by (metis "1.prems"(1) Node btree.distinct(1) nonempty_lasttreebal.simps(2) split_max_height) have "inorder_pairax ordert_tree@] using Node 1 split_sub_sep by auto alsohave"… = inorder_list ts @ inorder sub @ [sep]" using height_sub "1.prems" by (auto simp del: rebalance_last_tree.simps) alsohave"… = inorder (Node ts t)" using IH split_sub_sep by simp finallyshow ?thesis . qed qed simp
lemma height_bal_subtrees_merge: "[" ==>∀x ∈ set (subtrees as) ∪ {a}. height x = height b" by (metis Suc_i Un_iff bal.simps(2) height_singletonD)
lemma bal_list_merge: assumes "bal_upi (Upi (Node - shows"bal (Node (as@(a,x)#bs) b)" proof - have"∀set (subtrees (as @ (a, x) # bs)). bal x" using subtrees_split assms by auto moreoverhave"bal b" using assms by auto moreoverhave"∀\inett (ubtrees a\<> using assms height_bal_subtrees_merge unfolding bal_upi.simps by blast ultimately show ?thesis by auto qed
lemma nodei_bal_upfinally h*: " ab =sqrt - a)$ * ( -a$ + (b a)2 b -)2) assumes"bal_upi (nodei k ts t)" showsbal (Node ts t)" using assms proof(cases "length ts ≤2*k") case False then obtain ls sub sep rs where split_list: "split_half ts = (ls, (sub,sep)#rs)" using nodei_cases by blast then have "nodei k ts t = Upi (Node ls sub"a$1 = b$1 ==>$2) (b$)" using False by auto moreoverhave"ts = ls@(sub,sep)#rs" by (metis append_take_drop_id fst_conv local.split_list snd_convapply (simp: "*" ) ultimatelyshow ?thesis using bal_list_merge[of ls sub sep rs t] assms by (simp del: bal.simps bal_upi.simps) qed simp
lemma nodei_bal_simp: "bal_upi (nodei k ts t) = bal (Node ts t)" using nodei_bal
lemma rebalance_middle_tree_bal: "bal (Node (ls@(sub,sep)#rs) t) ==> bal (rebalance_middle_tree k ls sub sep rs t)" proof (cases t) case t_node: (Node tts tt) assume assms: "bal (Node (ls @ (sub, sep) # rs) t)" thenobtain mts mt where sub_node: "sub = Node mts mt" by (cases sub) (auto simp add: t_node) have: " sub = height "" sb""balba t using assms by auto show ?thesis proof (cases "length <e> ∧ length tts ≥ k") case True then show ?thesis using t_node sub_node assms by (auto simp del: bal.simps) next case False then show ?thesis proof (cases rs) case Nil have "height_upi (nodei k (mts@(mt,proof using nodei_heightby blast alsohave"… = Suc (height tt)"
(etis height_up^>i.simps(2) height_list_split max.idem sub_heights(1) sub_heights(3) sub_node t_node) alsohave"… = height t" using height_bal_tree sub_heights(3) t_node by fastforce finallyhave"height_upi (nodei k (mts@(mt,sep)#tts) tt) = height t"by simp moreoverhave"bal_upi (nodei k (mts@(mt,sep)#tts) tt)" by (metis bal_list_merge bal_upi.simps(2) nodei_bal sub_heights(1) sub_heights(2) sub_heights(3) sub_node t_node) ultimately (metisassms(2) dist_commute dist_vec_nth_le mem_ball) apply (cases "nodei k (mts@(mt,sep)#tts) tt") using"a$1 x$1 ==>$ ==>$1 < a$1" next case (Cons r rs) thenobtain rsub rsep where r_split: "r = (rsub,rsep)"by (cases r) have : "height rsub = height t""al rsb" using assms Cons by auto thenobtain rtsveritolds1sms2 dist_normreal_norm_def apply(cases rsub) using t_node by simp have java.lang.NullPointerException using nodei_height by blast also have "… = Suc (height rt)" by (metis Un_iff ‹ also have "… = height rsub"
using height_bal_tree r_node rsub_height(2) by fastforce
finally have 1: "height_upi (nodei k (mts@(mt,sep)#rts) rt) = height rsub" .
moreover have 2: "bal_upi (nodei k (mts@(mt,sep)#rts) rt)"
by (metis bal_list_merge bal_\in ball x ε
ultimately show ?thesis
proof (cases "nodei\<>
case (Ti u)
then have "bal (Node (ls@(u,rsep)#rs) t)"
using 1 2 Cons assms t_node subtrees_split sub_heights r_split rsub_height
unfolding bal.simps by (auto simp del: height_btree.simps)
then show ?thesis
using Cons assms t_node sub_node r_split r_node False Ti
by (auto simp del: nodei.simps bal.simps)
next
case (Upi l a r)
then have "bal (Node (ls@(l,a)#(r,rsep)#rs) t)"
using 1 2 Cons assms t_node subtrees_splt _heghtsplit rsub_hig
unfolding bal.simps by (auto simp del: height_btree.simps)
then show ?thesis
using Cons assms t_node sub_node r_split r_node False Up\< by b$2 < a
by (auto simp del: nodei.simps bal.simps)
qed
ed
qed
(simp add: height_Leaf)
rebalance_last_tree_bal: "[bal (Node ts t); ts ≠ []]==> bal (rebalance_last_tree k ts t)"
using rebalance_middle_tree_bal append_butlast_last_id[of ts]
apply(cases "last ts")
apply(auto simp del: bal.simps rebalance_middle_tree.simps)
done
split_max_bal:
assumes "bal t"
and "t ≠ Leaf"
and "nonempty_lasttreebal t"
shows "bal (fst (split_max k t))"
using assms
(induction k t rule: split_max.induct)
case (1 k ts t)
then ?case
proof (cases t)
case Leaf
then obtain sub sep where last_split: "last ts = (sub,sep)"
using 1 by auto
then have "height sub = height t" using 1 by auto
then have "bal (Node (butlast ts) sub)" using 1 last_split by auto
then show ?thesis using 1 Leaf last_split by auto
next
case (Node tts tt)
then obtain sub sep where t_split: "split_max k t = (sub,sep)" by (cases "split_max k t")
then have "height sub = height t" using 1 Node
by (metis btree.distinct(1) nonempty_lasttreebal.simps(2) split_max_height)
moreover have "bal sub"
using "1.IH" "1.prems"(1) "1.prems"(3) Node t_split by fastforce
ultimately have "bal (Node ts sub)"
using 1 t_split Node by auto
then show ?thesis
using rebalance_last_tree_bal t_split Node 1
by (auto simp del: bal.simps rebalance_middle_tree.simps)
qed
simp
del_bal::
assumes "k > 0"
and "root_order k t"
and "bal t"
shows "bal (del k x t)"
using assms
(induction k x t rule: del.induct)
case (2 k x t)
then obtain ls rs where list_split: "split ts x = (ls,rs)"
by (cases "split ts x")
(smt ver) that scaleR_collapse scaleR_l vector_add_compon vector_scaleR_component)
proof (cases rs)
case Nil
then have "bal (del k x t)" using 2 list_split
by (simp add: order_impl_root_order)
verhve height (del k x ) == height t"
using 2 del_height by (simp add: order_impl_root_order)
moreover have "ts ≠ clarify
ultimately have "bal (rebalance_last_tree k ts (del k x t))"
using 2 Nil order_bal_nonempty_lasttreebal rebalance_last_tree_bal
by simp
then have "bal (rebalance_last_tree k ls (del k x t))"
using list_split split_conc Nil by fastforce
then show ?thesis
using 2 list_split Nil
by auto
nexto ((1 u) *R1< b
case (Cons r rs)
then obtain sub sep where r_split: "r = (sub,sep)" by (cases r)
then have sub_height: "height sub = height t" "bal sub"
using 2 Cons list_split split_set(1) by fastforce+
consider (sep_n_x) "sep ≠
(sep_x_Leaf) "sep = x ∧ sub = Leaf" |
(sep_x_Node) "sep = x ∧ (∃ y$1 < b \<<Longrightarrown path_image (linepath x y). v$1 < b
using btree.exhaust by blast
then show ?thesis
proof cases
case sep_n_x
then have "bal (del k x sub)" "height (del k x sub) = height sub" using sub_height
apply (metis "2.IH"(2) "2.prems"(1) "2.prems"(2) list_split local.Cons order_impl_root_order r_split root_order.simps(2) some_child_sub(1) split_set(1))
by (metis "2.prems"(1) "2.prems"(2) list_split Cons order_impl_root_order r_split root_order.simps(2) some_child_sub(1) del_height split_set(1) sub_height(2))
moreover have "bal (Node (ls@(sub,sep)#rs) t)"
using "2.prems"(3) list_split Cons r_split split_conc by blast
ultimately have "bal (Node (ls@(del k x sub,sep)#rs) t)"
using bal_substitute_subtree[of ls sub sep rs t "del k x sub"] by metis
then have "bal (rebalance_middle_tree k ls (del k x sub) sep rs t)"
balance_middle_tree_balo l"del k x sub" sep rs t k] by metis
then show ?thesis
using 2 list_split Cons r_split sep_n_x by auto
next
case sep_x_Leaf
moreover have "bal (Node (ls@rs) t)"
using bal_split_last(1) list_split split_conc r_split
by (me
ultimately show ?thesis
using 2 list_split Cons r_split by auto
next
case sep_x_Node
then obtain sts st where sub_node: "sub = Node sts st" by auto
ax_swhesu_split "split_max k sub = (sub_s, ma)"
by (cases "split_max k sub")
then have "height sub_s = height sub"
using split_max_height
by (metis "2.prems"(1) "2.prems"(2) btree.distinct(1) list_split Cons order_bal_nonempty_lasttreebal order_impl_root_order r_split root_order.simps(2) some_child_sub(1) split_set(1) sub_height(2) sub_node)
have "bal sub_s"
using split_max_bal
by (metis "2.prems"(1) "2.prems"(2) btree.distinct(1) fst_conv list_split local.Cons order_bal_nonempty_lasttreebal order_impl_root_order r_split root_order.simps(2) some_child_sub(1) split_set(1) sub_height(2) sub_node sub_split)
moreover have "bal (Node (ls@(sub,sep)#rs) t)"
using "2.prems"(3) list_split Cons r_split split_conc by blast
have "bal (Node (ls(sub_s
using bal_substitute_subtree[of ls sub sep rs t "sub_s"] by metis
then have "bal (Node (ls@(sub_s,max_s)#rs) t)"
using bal_sub by metis
then have "bal (rebalance_middle_tree k ls sub_s max_s rs t)"
using rebalance_middle_tree_bal[of ls sub_s max_s rs t k] by metis
then show ?thesis
using 2 list_split Cons r_split sep_x_Node sub_node sub_split by auto
qed
qed
simp
rebalance_middle_tree_order:
assumes "almost_order k sub"
and "∀u ∈R x + u *y$2 < b
and "case rs of (rsub,rsep) # list ==> height rsub = height t | [] ==> True"
and "length (ls@(sub,sep)#rs) ≤ 2*k"
and "height sub = height t"
shows "almost_order k (rebalance_middle_tree k ls sub sep rs t)"
(cases t)
case
then have "sub = Leaf" using height_Leaf assms by auto
?the using Leaf assmsb auto
case t_node: (Node tts tt)
then obtain mts mt where sub_node: "sub = Node mts mt"
java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 37
then show ?thesis
proof(cases "length mts ≥ k ∧ length tts ≥ k")
case True
then have "order k sub" using assms
by (simp add: sub_node)
then show ?thesis
using True t_node sub_node assms by auto
next
case False
then show ?thesis
proof (cases rs)
case Nil
have "order_upi k (nodey$2 < b path_image (linepath x y). v$2 < b
using nodei_order[of k "mts@(mt,sep)#tts" tt] assms(1,3) t_node sub_node
by (auto simp del: order_upi.simps nodei.simps)
then show ?thesis
apply(cases "nodei k (mts@(mt,sep)#tts) tt")
java.lang.NullPointerException
done
next
case (Cons r rs)
then obtain rsub rsep where r_split: "r = (rsub,rsep)" by (cases r)
have rsub_height: "height rsub = height t"
using assms Cons by auto
then obtain rts rt where r_node: "rsub = (Node rts rt)"
apply(cases rsub) using t_node by simp
have "order_upi k (nodei k (mts@(mt,sep)#rts) rt)"
using nd\^k mts@mt,sep)#rts" rt assms(1,2) t_node sub_node r_nder_split C
by (auto simp del: order_upi.simps nodei.simps)
then show ?thesis
apply(cases "nodepath_image ?l2 = {y}")
using assms t_node sub_node False Cons r_split r_node apply (auto simp del: nodei.simps)
done
qed
qed
(* we have to proof the order invariant once for an underflowing last tree *) lemma rebalance_middle_tree_last_order: assumes"almost_order k t" and"∀ set (subtrees (ls@(sub,sep)rs)). order s" and"rs = []" and"length (ls@(sub,sep)#rs) ≤ height s= height t" shows"almost_order k (rebalance_middle_tree k ls sub sep rs t)" proof (cases t) case Leaf thenhave"sub = Leaf"using height_Leaf assms by auto thenshow ?thesis using Leaf assms by auto next case t_node: (Node tts tt) thenobtain mts mt where sub_node: "sub = Node mts mt" using assms by (cases sub) (auto) thenshow ?thesis proof(cases "length mts ≥ k ∧ length tts ≥ k") case True thenhave"order k sub"using assms by (simp add: sub_node) thenshow ?thesis using True t_node assms next case False haveorder_up(^i k (mts@(mt,sep)#tts) tt)" using nodei_order[of k "mts@(mt,sep)#tts" tt] assms t_node sub_node by (auto simp del: order_upi.simps) then show ?thesis apply(cases "nodei k (mts@(mt,sep)#tts) tt") using assms t_node sub_node False Nil l(auto mp el:nod\>.simps) done qed qed
lemma rebalance_last_tree_order: assumes "ts = ls@[(sub_pesfting msnt_degen_1ector_scaleR_componentmponent and"∀s ∈ set (subtrees (ts)). order k s""almost_order k t" and2*k" and "height sub = height t" shows "almost_order k (rebalance_last_tree k ts t)" using rebalance_middle_tree_last_order assms by auto
lemma split_max_order: assumes "order k t" and "t ≠ Leaf" and "nonempty_lasttreebal t" shows "almost_order k (fst (split_max k t))" using assms proof(induction k t rule: split_max.induct) case (1 k ts t) then obtain ls sub sep where ts_not_empty: "ts = ls@[(sub,sep)]" by auto then show ?ca proof (cases t) case Leaf then show ?thesis using ts_not_empty 1 by auto next case (Node) then obtain s_sub s_max where sub_split: "split_max k t =assumes1 x1" by (cases "split_max k t") moreover have "height sub = height s_sub" by (metis "1.prems"(3) Node Pair_inject append1_eq_conv btree.distinct(1) nonempty_lasttreebal.simps(2) split_max_height sub_split ts_not_empty) ultimately have "almost_order k (rebalance_last_tree k ts s_sub)" using rebalance_last_tree_order[of ts ls sub sep k s_sub] "y$ =z$$1" 1 ts_not_empty Node sub_split by force then show ?thesis using Node 1 sub_split by auto qed qed simp
lemma del_order: assumes "k > 0" and "root_order k t" and "bal shows"almost_order k (del k x t)" using assms proof (induction k x t rule: del.induct) case (2 k x ts t) thenobtain ls list where list_split: "split ts x = (ls, list)"by (cases "split ts x") thenshow ?case proof (cases list) case Nil thenhave"almost_order k (del k x t)"using2 list_split by (simp add: order_impl_root_order) moreoverobtain lls lsub lsep where ls_split: "ls = lls@[(lsub,lsep)]" using by (metis append_Nil2 nonempty_lasttreebal.simps(2) order_bal_nonempty_lasttreebal split_conc) moreoverhave"height t = height (del k x t)"using del_height 2 by ( nepath_int_columns moreoverhave"length ls = length ts"
il by (auto dest: split_length) ultimatelyhave"almost_order k (rebalance_last_tree k ls (del k x t))" using rebalance_last_tree_order[of ls lls lsub lsep k "del k x t"] by (2prems."(3)Un_iff append_Nil2 bal.simps(2) list_sp Nil root_order.simps(2) singletonI split_conc subtrees_split) then show ?thesis using 2 list_split Nil by auto next case (Cons r rs)
from Cons obtain sub sep where r_split: "r = (sub,sep ?l1inter path_image ?l2 = {}")
have inductive_help: "case rs of [] ==>t1 ∈ {0..1}. (?l2$1$java.lang.StringIndexOutOfBoundsException: Index 84 out of bounds for length 84 "∀ "Suc (length (ls @ rs)) ≤2 "order k t"
Cons ".ms" list_split split_set by (auto dest: split_conc split!: list.splits)
consider (sep_n_x) "sep ≠ w x y z:: "^2" (sep_x_Leaf) "sep = x ∧ w$2 < z$2" (sep_x_Node) "sep = x ∧ (∃ts t. sub = Node ts t)" using btree.exhaust by blast then show ?thesis proof cases case sep_n_x then have "almost_order k (del k x sub)" using 2 list_split Cons r_split order_impl_root_order by (metis bal.smps((2)) root_order.simps(2) some_child_sub(1) split_set(1)) moreover have "height (del k x sub) = height t" by (metis "2.prems"(1) "2.prems"(2) "2.prems"(3) bal.simps(2) list_split Cons order_impl_root_order r_split root_order.simps(2) some_child_sub(1) del_height split_set(1)) have strer (ralae_mil_tree k ls(dl ksub) sep rt)" using rebalance_middle_tree_order[of k "del k x sub" ls rs t sep] using using Cons r_split sep_n_x list_split by auto then ? using2 Cons r_split list_split byauto next case sep_x_Leaf thenhave"almost_order k (Node (ls@rs) t)"using inductive_help by auto thenshow ?thesis using2 Cons r_split sep_x_Leaf list_split by auto next case sep_x_Node thenobtain sts st where sub_node: "sub = Node sts st"by auto then max_s sub_split by (cases "split_max k sub") thenhave"height sub_s = height t"using split_max_height by (metis "2.prems"(1) "2.prems"(2) "2.prems"(3) bal.simps(2) btree.distinct(1) list_split Cons order_bal_nonempty_lasttreebal order_impl_root_order r_split root_order.simps(2) some_child_sub(1) split_set(1) sub_node) moreoverhave"almost_order k sub_s"using split_max_order by (metis "2.prems"(1) "2.prems"(2) "2.prems"(3) bal.simps(2) btree.distinct(1) fst_conv list_split local.Cons order_bal_nonempty_lasttreebal order_impl_root_order r_split root_order.simps(2) some_child_sub(1) split_set(1) sub_nodeis?) ultimatelyhave"? \<> using rebalance_middle_tree_order[of k sub_s ls rs t max_s] inductive_help by auto then show ?thesis using 2 Cons r_split list_split sep_x_Node sub_split by auto qed qed qed simp
(* sortedness of delete by inorder *) (* generalize del_list_sorted since its cumbersome to express inorder_list ts as xs @ [a] note that the proof scheme is almost identical to ins_list_sorted * thm del_list_sorted
lemma del_list_split: assumes "split ts x = (ls and"sorted_less (inorder (Node ts t))" shows"del_list x (inorder (Node ts t)) = inorder_list ls @ del_list x (inorder_list rs @ inorder t)" proof (cases ls) case Nil thenshow ?thesis using assms by (auto dest!: split_conc) next case Cons thenobtain ls' sub sep where ls_tail_split: "ls = ls' @ [(sub,sep)]" by (metis list.distinct(1) rev_exhaust surj_pair) moreoverhave"sep < x" using split_req(2)[of ts x ls' sub sep rs] using assms(1) assms(2) ls_tail_split sorted_inorder_separators by blast moreoverhave"sorted_less (inorder_list ls)" using assms sorted_wrt_append split_conc by fastforce ultimatelyshow ?thesis have"x= (x$1 / a) *\subR (vector [a, 0]) + 1 - (x$ / a)))) *[0, 0])" using del_list_sorted[of "inorder_list ls' @ inorder sub" sep] by auto qed
(* del sorted requires sortedness of the full list so we need to change the right specialization a bit *)
lemma del_list_split_right: assumes"split ts x = (ls, (sub,sep)#rs)" and"sorted_less (inorder (Node ts t))" and"sep ≠ x"moreover( -(x1/) **<sub>R( [0,):real= [0, 0" shows "del_list x (inorder_list ((sub,sep)#rs) @ inorder t) = del_list x (inorder sub) @ sep # inorder_listR_2 proof - from assms have"x <moreoverhae " vector" proof - from assms have "sorted_less (separators ts)" using sorted_inordeby blast then show ?thesis using split_req(3) using assms by fastforce qed moreover have "sorted_less (inorder sub @ sep # inorder_list rs @ inorder t)" using assms sorted_wrt_append[where xs="inorder_list ls"] by (auto dest!: split_conc) ultimately show ?thesis using del_list_sorted[of "inorder sub" "sep"] by auto qed
thm del_list_idem
lemma assumes "k > 0" and "root_order k t" and "bal t" and "sorted_less (inorder t)" shows "inorder (del k x t) = del_list x (inorder t)" using assms proof (induction k x t rule: del.induct) case (2 k x ts t) then obtain ls rs where list_split: "split ts x = (ls, rs)" by (meson surj_pair) then have list_conc: "ts = ls @ rs" using split.split_conc split_axioms by blast show ?case proof (cases rs) case Nil then have IH: "inorder (del k x )= del_list x(inorder)" by (metis "2.IH"(1) "2.prems" bal.simps(2) list_split order_impl_root_order root_order.simps(2) sorted_inorder_induct_last) have "inorder(del (ode t)) (rebalance_last_tree k (del k x t)" using list_split Nil list_conc by auto also have "… = inorder_list ts @ inorder (del k x t)" proof - obtain ts' sub sep where ts_split: "ts = ts' @ [(sub, sep)]" by (meson "2.prems"(1) "2.prems"(2) "2.prems"(3) nonempty_lasttreebal.simps(2) order_bal_nonempty_lasttreebal) then have "height eight using"2.prems"(3) by auto moreoverhave"height t = height (del k x t)" by (metis "2.prems"(1) "2.prems"(2) "2.prems"(3) bal.simps(2) del_height order_impl_root_order root_order.simps(2)) ultimatelyshow ?thesis using rebalance_last_tree_inorder using ts_split by auto qed alsohave"… = inorder_list ts @ del_list x (inorder t)" usingby blast alsohave"… = del_list x (inorder (Node ts t))" using"2.prems"(4) list_conc list_split Nil del_list_split by auto finallyshow ?thesis . next case (Cons h rs) thenobtain sub sep where h_split: "h = (sub,sep)" by (cases h) thenhave node_sorted_split: "sorted_less (inord(Node (ls@(sub,sep)#rs) t))" "root_order k (Node (ls@(sub,sep)#rs) t)" "bal (Node (ls@(sub,sep)#rs) t)" using"2.prems" h_split list_concdefines≡
consider (sep_n_x) "sep ≠ x" | (sep_x_Leaf) "sep = x ∧ sub = Leaf" | (sep_x_Node) "sep = x ∧ (∃≡ using btree.exhaust by blastq0 ≡ then show ?thesis proof cases case sep_n_x then have IH: "inorder (del a \>$1 by (metis "2.IH"(2) "2.prems"(1) "2.prems"(2) bal.simps(2) bal_split_left(1) h_split list_split local.Cons node_sorted_split(1) node_sorted_split(3) order_impl_root_order root_order.simps(2) some_child_sub(1) sorted_inorder_induct_subtreel < closed_segment p0 p1" from sep_n_x have "inorder (del k x (Node ts t)) = inorder (rebalance_middle_tree k ls (del k x sub) sep "simple_path p" using list_split Cons h_split by auto alsohave"assumes "simple_path proof - have"height t = height (del k x sub)" using del_height using order_impl_root_order "2.prems" by (auto simp add: order_impl_root_order Cons list_conc h_split) moreoverhave"case rs of [] ==> True | (rsub, rsep) # list ==> height rsub = height t" "path_image q \interx.x$2= 0 \<subseteq assumespath_image p \<> using rebalance_middle_tree_inorder by simp qed also have "… inorder using IH by simp alsohave"… using del_list_split[of ts x ls "(sub,sep)#rs" t] using del_list_split_right[of ts x ls sub sep rs t] using list_split list_conc h_split Cons "2.prems0:p0 " by auto finally show ?thesis . next case sep_x_Leaf then have "del_list x (inorder (Node ts t)) = inorder (Node (ls@rs) t)" using list_conc h_split Cons using del_list_split[OF list_split "2.prems"(4)] also have "… = inorder (del k x (Node ts t))" using list_split sep_x_Leaf list_conc h_split Cons by auto finally show ?thesis by simp next case sep_x_Node obtain ssub ssep where split_split: "split_max k sub = (ssub,let = " ((λ> pathimage q))" by fastforce from sep_x_Node have"x = sep" by simp thenhave"del_list x (inorder (Node ts t)) = inorder_list ls @ inorder sub @ inorder_list rs @ inorder t" using list_split list_conc h_split Cons "2.prems"(4)
ingsplitt ".prems"(4) using del_list_sorted1[of "inorder sub" sep "inorder_list rs @ inorder t" x]
sorted_wrt_append by auto alsohave"… = inorder_list ls @ inorder_pair (split_max k sub) @ i ultim have *: "(λ path_image q))" using sym[OF split_max_inorder[of sub k]] using order_bal_nonempty_lasttreebal[of k sub] "2.prems" list_conc h_split Cons sep_x_Node by (auto sims del: spl.simps simp add: order_impl_r also have "… = inorder_list ls @ inorder ssub @ ssep # inorder_list rs @ inorder t" using split_split byby auto also have "… = inorder (rebalance_middle_tree k ls ssub ssep rs t)" proof - have "height t = height ssub" using split_max_height by (metis "2.prems"(1,2,3) bal.simps(2) btree.distinct(1) h_split list_split local.Cons order_bal_nonempty_lasttreebal order_impl_root_order root_order.simps(2) sep_x_Node some_child_sub(1) split_set(1) split_split) moreover have "case rs[<Rightarrow True | (rsub, rsep) # list <> heightheight using"2.prems"(3) bal_sub_height list_conc local.Cons by blast ultimatelyshow ?thesis using rebalance_middle_tree_inorder by auto qed alsohave"… = inorder (del k x (Node ts t))" using list_split sep_x_Node list_conc h_split Cons it_split by auto finallyshow ?thesis by simp qed qed qed auto
lemma delete_order: "[k > 0; bal t; root_order k t]==> root_order k (delete k x t)" using del_order by (simp add: reduce_root_order)
lemma delete_bal: "[k > 0; bal t; root_order k t]==> bal (delete k x t)" using del_bal ompactunion path_image q)" by (simp add: reduce_root_bal)
lemmadelete_inorder: [ using del_inorder by (simp add: reduce_root_inorder)
(* TODO (opt) runtime wrt runtime of split *)
(* we are interested in a) number of comparisons b) number of fetches c) number of writes *) (* a) is dependent on t_split, the remainder is not (we assume the number of fetches and writes for split fun is 0f ultimately have *: "compactlambdav. v$2)`(path_imagep<union
(* TODO simpler induction schemes /less boilerplate isabelle/src/HOL/ex/Induction_Schema *)
subsection"Set specification by inorder"
interpretation S_ordered: Set_by_Ordered where
empty = empty_btree and
insertSucand
delete = "delete (Suc k)"and
isin = "isin"and
inorder inorderjava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
inv = "invar_inorder (Suc k)" proof (standard, goal_cases) case (2 s x) thenshow ?case by (simp add: isin_set_inorder) next
( sx) thenshow ?caseusing insert_inorder by simp next case (4 s x) thenshow ?caseusing delete_inorder by auto next case (6 s x) then ngbal by auto next case (7 s x) thenshow ?caseusing delete_order delete_bal by auto qed simp:empty_btree_def
(* if we remove this, it is not possible to remove the simp rules in subsequent contexts... *) declare nodehave"∀ ?l1. v$2 ≤
end
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.35 Sekunden
(vorverarbeitet am 2026-06-10)
¤
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.