fun isin :: "'a::linorder tree23 → 'a → bool"where "isin Leaf x = False" | "isin (Node2 l a r) x = (case cmp x a of LT → isin l x | EQ → True | GT → isin r x)" | "isin (Node3 l a m b r) x = (case cmp x a of LT → isin l x | EQ → True | GT → (case cmp x b of LT → isin m x | EQ → True | GT → isin r x))"
datatype 'a upi = Eqi"'a tree23" | Of "'a tree23" 'a "'a tree23"
fun treei :: "'a upi→ 'a tree23"where "treei (Eqi t) = t" | "treei (Of l a r) = Node2 l a r"
fun ins :: "'a::linorder → 'a tree23 → 'a upi"where "ins x Leaf = Of Leaf x Leaf" | "ins x (Node2 l a r) = (case cmp x a of LT → (case ins x l of Eqi l' => Eqi (Node2 l' a r) | Of l1 b l2 => Eqi (Node3 l1 b l2 a r)) | EQ → Eqi (Node2 l a r) | GT → (case ins x r of Eqi r' => Eqi (Node2 l a r') | Of r1 b r2 => Eqi (Node3 l a r1 b r2)))" | "ins x (Node3 l a m b r) = (case cmp x a of LT → (case ins x l of Eqi l' => Eqi (Node3 l' a m b r) | Of l1 c l2 => Of (Node2 l1 c l2) a (Node2 m b r)) | EQ → Eqi (Node3 l a m b r) | GT → (case cmp x b of GT → (case ins x r of Eqi r' => Eqi (Node3 l a m b r') | Of r1 c r2 => Of (Node2 l a m) b (Node2 r1 c r2)) | EQ → Eqi (Node3 l a m b r) | LT → (case ins x m of Eqi m' => Eqi (Node3 l a m' b r) | Of m1 c m2 => Of (Node2 l a m1) c (Node2 m2 b r))))"
hide_const insert
definition insert :: "'a::linorder → 'a tree23 → 'a tree23"where "insert x t = treei(ins x t)"
datatype 'a upd = Eqd"'a tree23" | Uf "'a tree23"
fun treed :: "'a upd→ 'a tree23"where "treed (Eqd t) = t" | "treed (Uf t) = t"
(* Variation: return None to signal no-change *)
fun node21 :: "'a upd→ 'a → 'a tree23 → 'a upd"where "node21 (Eqd t1) a t2 = Eqd(Node2 t1 a t2)" | "node21 (Uf t1) a (Node2 t2 b t3) = Uf(Node3 t1 a t2 b t3)" | "node21 (Uf t1) a (Node3 t2 b t3 c t4) = Eqd(Node2 (Node2 t1 a t2) b (Node2 t3 c t4))"
fun node22 :: "'a tree23 → 'a → 'a upd→ 'a upd"where "node22 t1 a (Eqd t2) = Eqd(Node2 t1 a t2)" | "node22 (Node2 t1 b t2) a (Uf t3) = Uf(Node3 t1 b t2 a t3)" | "node22 (Node3 t1 b t2 c t3) a (Uf t4) = Eqd(Node2 (Node2 t1 b t2) c (Node2 t3 a t4))"
fun node31 :: "'a upd→ 'a → 'a tree23 → 'a → 'a tree23 → 'a upd"where "node31 (Eqd t1) a t2 b t3 = Eqd(Node3 t1 a t2 b t3)" | "node31 (Uf t1) a (Node2 t2 b t3) c t4 = Eqd(Node2 (Node3 t1 a t2 b t3) c t4)" | "node31 (Uf t1) a (Node3 t2 b t3 c t4) d t5 = Eqd(Node3 (Node2 t1 a t2) b (Node2 t3 c t4) d t5)"
fun node32 :: "'a tree23 → 'a → 'a upd→ 'a → 'a tree23 → 'a upd"where "node32 t1 a (Eqd t2) b t3 = Eqd(Node3 t1 a t2 b t3)" | "node32 t1 a (Uf t2) b (Node2 t3 c t4) = Eqd(Node2 t1 a (Node3 t2 b t3 c t4))" | "node32 t1 a (Uf t2) b (Node3 t3 c t4 d t5) = Eqd(Node3 t1 a (Node2 t2 b t3) c (Node2 t4 d t5))"
fun node33 :: "'a tree23 → 'a → 'a tree23 → 'a → 'a upd→ 'a upd"where "node33 t1 a t2 b (Eqd t3) = Eqd(Node3 t1 a t2 b t3)" | "node33 t1 a (Node2 t2 b t3) c (Uf t4) = Eqd(Node2 t1 a (Node3 t2 b t3 c t4))" | "node33 t1 a (Node3 t2 b t3 c t4) d (Uf t5) = Eqd(Node3 t1 a (Node2 t2 b t3) c (Node2 t4 d t5))"
fun split_min :: "'a tree23 → 'a * 'a upd"where "split_min (Node2 Leaf a Leaf) = (a, Uf Leaf)" | "split_min (Node3 Leaf a Leaf b Leaf) = (a, Eqd(Node2 Leaf b Leaf))" | "split_min (Node2 l a r) = (let (x,l') = split_min l in (x, node21 l' a r))" | "split_min (Node3 l a m b r) = (let (x,l') = split_min l in (x, node31 l' a m b r))"
text‹In the base cases of ‹split_min› and ‹del› it is enough to check if one subtree is a ‹Leaf›,
which case completeness implies that so are the others. Exercise.›
fun del :: "'a::linorder → 'a tree23 → 'a upd"where "del x Leaf = Eqd Leaf" | "del x (Node2 Leaf a Leaf) = (if x = a then Uf Leaf else Eqd(Node2 Leaf a Leaf))" | "del x (Node3 Leaf a Leaf b Leaf) = Eqd(if x = a then Node2 Leaf b Leaf else if x = b then Node2 Leaf a Leaf else Node3 Leaf a Leaf b Leaf)" | "del x (Node2 l a r) = (case cmp x a of LT → node21 (del x l) a r | GT → node22 l a (del x r) | EQ → let (a',r') = split_min r in node22 l a' r')" | "del x (Node3 l a m b r) = (case cmp x a of LT → node31 (del x l) a m b r | EQ → let (a',m') = split_min m in node32 l a' m' b r | GT → (case cmp x b of LT → node32 l a (del x m) b r | EQ → let (b',r') = split_min r in node33 l a m b' r' | GT → node33 l a m b (del x r)))"
definition delete :: "'a::linorder → 'a tree23 → 'a tree23"where "delete x t = treed(del x t)"
subsection"Functional Correctness"
subsubsection"Proofs for isin"
lemma isin_set: "sorted(inorder t) ==> isin t x = (x ∈ set (inorder t))" by (induction t) (auto simp: isin_simps)
subsubsection"Proofs for insert"
lemma inorder_ins: "sorted(inorder t) ==> inorder(treei(ins x t)) = ins_list x (inorder t)" by(induction t) (auto simp: ins_list_simps split: upi.splits)
lemma inorder_insert: "sorted(inorder t) ==> inorder(insert a t) = ins_list a (inorder t)" by(simp add: insert_def inorder_ins)
subsubsection"Proofs for delete"
lemma inorder_node21: "height r > 0 ==> inorder (treed (node21 l' a r)) = inorder (treed l') @ a # inorder r" by(induct l' a r rule: node21.induct) auto
lemma inorder_node22: "height l > 0 ==> inorder (treed (node22 l a r')) = inorder l @ a # inorder (treed r')" by(induct l a r' rule: node22.induct) auto
lemma inorder_node31: "height m > 0 ==> inorder (treed (node31 l' a m b r)) = inorder (treed l') @ a # inorder m @ b # inorder r" by(induct l' a m b r rule: node31.induct) auto
lemma inorder_node32: "height r > 0 ==> inorder (treed (node32 l a m' b r)) = inorder l @ a # inorder (treed m') @ b # inorder r" by(induct l a m' b r rule: node32.induct) auto
lemma inorder_node33: "height m > 0 ==> inorder (treed (node33 l a m b r')) = inorder l @ a # inorder m @ b # inorder (treed r')" by(induct l a m b r' rule: node33.induct) auto
lemma split_minD: "split_min t = (x,t') ==> complete t ==> height t > 0 ==> x # inorder(treed t') = inorder t" by(induction t arbitrary: t' rule: split_min.induct)
(auto simp: inorder_nodes split: prod.splits)
lemma inorder_del: "[ complete t ; sorted(inorder t) ]==> inorder(treed (del x t)) = del_list x (inorder t)" by(induction t rule: del.induct)
(auto simp: del_list_simps inorder_nodes split_minD split!: if_split prod.splits)
lemma inorder_delete: "[ complete t ; sorted(inorder t) ]==> inorder(delete x t) = del_list x (inorder t)" by(simp add: delete_def inorder_del)
subsection‹Completeness›
subsubsection"Proofs for insert"
text‹First a standard proof that const‹ins› preserves const‹complete›.›
fun hi :: "'a upi→ nat"where "hi (Eqi t) = height t" | "hi (Of l a r) = height l"
lemma complete_ins: "complete t ==> complete (treei(ins a t)) ∧ hi(ins a t) = height t" by (induct t) (auto split!: if_split upi.split) (* 15 secs in 2015 *)
text‹Now an alternative proof (by Brian Huffman) that runs faster because
properties (completeness and height) are combined in one predicate.›
inductive full :: "nat → 'a tree23 → bool"where "full 0 Leaf" | "[full n l; full n r]==> full (Suc n) (Node2 l p r)" | "[full n l; full n m; full n r]==> full (Suc n) (Node3 l p m q r)"
inductive_cases full_elims: "full n Leaf" "full n (Node2 l p r)" "full n (Node3 l p m q r)"
lemma full_0_iff [simp]: "full 0 t ⟷ t = Leaf" by (auto elim: full_0_elim intro: full.intros)
lemma full_Leaf_iff [simp]: "full n Leaf ⟷ n = 0" by (auto elim: full_elims intro: full.intros)
lemma full_Suc_Node2_iff [simp]: "full (Suc n) (Node2 l p r) ⟷ full n l ∧ full n r" by (auto elim: full_elims intro: full.intros)
lemma full_Suc_Node3_iff [simp]: "full (Suc n) (Node3 l p m q r) ⟷ full n l ∧ full n m ∧ full n r" by (auto elim: full_elims intro: full.intros)
lemma full_imp_height: "full n t ==> height t = n" by (induct set: full, simp_all)
lemma full_imp_complete: "full n t ==> complete t" by (induct set: full, auto dest: full_imp_height)
lemma complete_imp_full: "complete t ==> full (height t) t" by (induct t, simp_all)
lemma complete_iff_full: "complete t ⟷ (∃n. full n t)" by (auto elim!: complete_imp_full full_imp_complete)
text‹The const‹insert› function either preserves the height of the
, or increases it by one. The constructor returned by the term‹insert› function determines which: A return value of the form term‹Eqi t› indicates that the height will be the same. A value of the term‹Of l p r› indicates an increase in height.›
fun fulli :: "nat → 'a upi→ bool"where "fulli n (Eqi t) ⟷ full n t" | "fulli n (Of l p r) ⟷ full n l ∧ full n r"
lemma fulli_ins: "full n t ==> fulli n (ins a t)" by (induct rule: full.induct) (auto split: upi.split)
fun hd :: "'a upd→ nat"where "hd (Eqd t) = height t" | "hd (Uf t) = height t + 1"
lemma complete_treed_node21: "[complete r; complete (treed l'); height r = hd l' ]==> complete (treed (node21 l' a r))" by(induct l' a r rule: node21.induct) auto
lemma complete_treed_node22: "[complete(treed r'); complete l; hd r' = height l ]==> complete (treed (node22 l a r'))" by(induct l a r' rule: node22.induct) auto
lemma complete_treed_node31: "[ complete (treed l'); complete m; complete r; hd l' = height r; height m = height r ] ==> complete (treed (node31 l' a m b r))" by(induct l' a m b r rule: node31.induct) auto
lemma complete_treed_node32: "[ complete l; complete (treed m'); complete r; height l = height r; hd m' = height r ] ==> complete (treed (node32 l a m' b r))" by(induct l a m' b r rule: node32.induct) auto
lemma complete_treed_node33: "[ complete l; complete m; complete(treed r'); height l = hd r'; height m = hd r' ] ==> complete (treed (node33 l a m b r'))" by(induct l a m b r' rule: node33.induct) auto
lemma height'_node21: "height r > 0 ==> hd(node21 l' a r) = max (hd l') (height r) + 1" by(induct l' a r rule: node21.induct)(simp_all)
lemma height'_node22: "height l > 0 ==> hd(node22 l a r') = max (height l) (hd r') + 1" by(induct l a r' rule: node22.induct)(simp_all)
lemma height'_node31: "height m > 0 ==> hd(node31 l a m b r) = max (hd l) (max (height m) (height r)) + 1" by(induct l a m b r rule: node31.induct)(simp_all add: max_def)
lemma height'_node32: "height r > 0 ==> hd(node32 l a m b r) = max (height l) (max (hd m) (height r)) + 1" by(induct l a m b r rule: node32.induct)(simp_all add: max_def)
lemma height'_node33: "height m > 0 ==> hd(node33 l a m b r) = max (height l) (max (height m) (hd r)) + 1" by(induct l a m b r rule: node33.induct)(simp_all add: max_def)
lemma height_split_min: "split_min t = (x, t') ==> height t > 0 ==> complete t ==> hd t' = height t" by(induct t arbitrary: x t' rule: split_min.induct)
(auto simp: heights split: prod.splits)
lemma height_del: "complete t ==> hd(del x t) = height t" by(induction x t rule: del.induct)
(auto simp: heights max_def height_split_min split: prod.splits)
lemma complete_split_min: "[ split_min t = (x, t'); complete t; height t > 0 ]==> complete (treed t')" by(induct t arbitrary: x t' rule: split_min.induct)
(auto simp: heights height_split_min completes split: prod.splits)
lemma complete_treed_del: "complete t ==> complete(treed(del x t))" by(induction x t rule: del.induct)
(auto simp: completes complete_split_min height_del height_split_min split: prod.splits)
corollary complete_delete: "complete t ==> complete(delete x t)" by(simp add: delete_def complete_treed_del)
subsection‹Overall Correctness›
interpretation S: Set_by_Ordered where empty = empty and isin = isin and insert = insert and delete = delete and inorder = inorder and inv = complete proof (standard, goal_cases) case2thus ?caseby(simp add: isin_set) next case3thus ?caseby(simp add: inorder_insert) next case4thus ?caseby(simp add: inorder_delete) next case6thus ?caseby(simp add: complete_insert) next case7thus ?caseby(simp add: complete_delete) qed (simp add: empty_def)+
end
Messung V0.5 in Prozent
¤ 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.0.1Bemerkung:
(vorverarbeitet am 2026-06-30)
¤
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.