# HG changeset patch # User nipkow # Date 1604313950 -3600 # Node ID 8eabaf951e6b8549c2cb3a4a5b0958008d01b09b # Parent 97f12d2c8bf2c735c02f63728855c63e8d12b9ee use min_height as in (much of?) the literature diff -r 97f12d2c8bf2 -r 8eabaf951e6b src/HOL/Data_Structures/Leftist_Heap.thy --- a/src/HOL/Data_Structures/Leftist_Heap.thy Sun Nov 01 18:24:10 2020 +0100 +++ b/src/HOL/Data_Structures/Leftist_Heap.thy Mon Nov 02 11:45:50 2020 +0100 @@ -16,32 +16,28 @@ type_synonym 'a lheap = "('a*nat)tree" -fun rank :: "'a lheap \ nat" where -"rank Leaf = 0" | -"rank (Node _ _ r) = rank r + 1" - -fun rk :: "'a lheap \ nat" where -"rk Leaf = 0" | -"rk (Node _ (_, n) _) = n" +fun mht :: "'a lheap \ nat" where +"mht Leaf = 0" | +"mht (Node _ (_, n) _) = n" text\The invariants:\ fun (in linorder) heap :: "('a*'b) tree \ bool" where "heap Leaf = True" | "heap (Node l (m, _) r) = - (heap l \ heap r \ (\x \ set_tree l \ set_tree r. m \ x))" + ((\x \ set_tree l \ set_tree r. m \ x) \ heap l \ heap r)" fun ltree :: "'a lheap \ bool" where "ltree Leaf = True" | "ltree (Node l (a, n) r) = - (n = rank r + 1 \ rank l \ rank r \ ltree l & ltree r)" + (min_height l \ min_height r \ n = min_height r + 1 \ ltree l & ltree r)" definition empty :: "'a lheap" where "empty = Leaf" definition node :: "'a lheap \ 'a \ 'a lheap \ 'a lheap" where "node l a r = - (let rl = rk l; rr = rk r + (let rl = mht l; rr = mht r in if rl \ rr then Node l (a,rr+1) r else Node r (a,rl+1) l)" fun get_min :: "'a lheap \ 'a" where @@ -82,11 +78,11 @@ lemma mset_tree_empty: "mset_tree t = {#} \ t = Leaf" by(cases t) auto -lemma rk_eq_rank[simp]: "ltree t \ rk t = rank t" +lemma mht_eq_min_height: "ltree t \ mht t = min_height t" by(cases t) auto lemma ltree_node: "ltree (node l a r) \ ltree l \ ltree r" -by(auto simp add: node_def) +by(auto simp add: node_def mht_eq_min_height) lemma heap_node: "heap (node l a r) \ heap l \ heap r \ (\x \ set_tree l \ set_tree r. a \ x)" @@ -162,51 +158,36 @@ subsection "Complexity" -lemma pow2_rank_size1: "ltree t \ 2 ^ rank t \ size1 t" -proof(induction t rule: tree2_induct) - case Leaf show ?case by simp -next - case (Node l a n r) - hence "rank r \ rank l" by simp - hence *: "(2::nat) ^ rank r \ 2 ^ rank l" by simp - have "(2::nat) ^ rank \l, (a, n), r\ = 2 ^ rank r + 2 ^ rank r" - by(simp add: mult_2) - also have "\ \ size1 l + size1 r" - using Node * by (simp del: power_increasing_iff) - also have "\ = size1 \l, (a, n), r\" by simp - finally show ?case . -qed - text\Explicit termination argument: sum of sizes\ -fun t_merge :: "'a::ord lheap \ 'a lheap \ nat" where -"t_merge Leaf t = 1" | -"t_merge t Leaf = 1" | -"t_merge (Node l1 (a1, n1) r1 =: t1) (Node l2 (a2, n2) r2 =: t2) = - (if a1 \ a2 then 1 + t_merge r1 t2 - else 1 + t_merge t1 r2)" +fun T_merge :: "'a::ord lheap \ 'a lheap \ nat" where +"T_merge Leaf t = 1" | +"T_merge t Leaf = 1" | +"T_merge (Node l1 (a1, n1) r1 =: t1) (Node l2 (a2, n2) r2 =: t2) = + (if a1 \ a2 then T_merge r1 t2 + else T_merge t1 r2) + 1" -definition t_insert :: "'a::ord \ 'a lheap \ nat" where -"t_insert x t = t_merge (Node Leaf (x, 1) Leaf) t" +definition T_insert :: "'a::ord \ 'a lheap \ nat" where +"T_insert x t = T_merge (Node Leaf (x, 1) Leaf) t + 1" -fun t_del_min :: "'a::ord lheap \ nat" where -"t_del_min Leaf = 1" | -"t_del_min (Node l _ r) = t_merge l r" +fun T_del_min :: "'a::ord lheap \ nat" where +"T_del_min Leaf = 1" | +"T_del_min (Node l _ r) = T_merge l r + 1" -lemma t_merge_rank: "t_merge l r \ rank l + rank r + 1" +lemma T_merge_min_height: "ltree l \ ltree r \ T_merge l r \ min_height l + min_height r + 1" proof(induction l r rule: merge.induct) - case 3 thus ?case by(simp) + case 3 thus ?case by(auto) qed simp_all -corollary t_merge_log: assumes "ltree l" "ltree r" - shows "t_merge l r \ log 2 (size1 l) + log 2 (size1 r) + 1" -using le_log2_of_power[OF pow2_rank_size1[OF assms(1)]] - le_log2_of_power[OF pow2_rank_size1[OF assms(2)]] t_merge_rank[of l r] +corollary T_merge_log: assumes "ltree l" "ltree r" + shows "T_merge l r \ log 2 (size1 l) + log 2 (size1 r) + 1" +using le_log2_of_power[OF min_height_size1[of l]] + le_log2_of_power[OF min_height_size1[of r]] T_merge_min_height[of l r] assms by linarith -corollary t_insert_log: "ltree t \ t_insert x t \ log 2 (size1 t) + 2" -using t_merge_log[of "Node Leaf (x, 1) Leaf" t] -by(simp add: t_insert_def split: tree.split) +corollary T_insert_log: "ltree t \ T_insert x t \ log 2 (size1 t) + 3" +using T_merge_log[of "Node Leaf (x, 1) Leaf" t] +by(simp add: T_insert_def split: tree.split) (* FIXME mv ? *) lemma ld_ld_1_less: @@ -221,17 +202,17 @@ finally show ?thesis by simp qed -corollary t_del_min_log: assumes "ltree t" - shows "t_del_min t \ 2 * log 2 (size1 t) + 1" +corollary T_del_min_log: assumes "ltree t" + shows "T_del_min t \ 2 * log 2 (size1 t) + 1" proof(cases t rule: tree2_cases) case Leaf thus ?thesis using assms by simp next - case [simp]: (Node t1 _ _ t2) - have "t_del_min t = t_merge t1 t2" by simp - also have "\ \ log 2 (size1 t1) + log 2 (size1 t2) + 1" - using \ltree t\ by (auto simp: t_merge_log simp del: t_merge.simps) + case [simp]: (Node l _ _ r) + have "T_del_min t = T_merge l r + 1" by simp + also have "\ \ log 2 (size1 l) + log 2 (size1 r) + 2" + using \ltree t\ T_merge_log[of l r] by (auto simp del: T_merge.simps) also have "\ \ 2 * log 2 (size1 t) + 1" - using ld_ld_1_less[of "size1 t1" "size1 t2"] by (simp) + using ld_ld_1_less[of "size1 l" "size1 r"] by (simp) finally show ?thesis . qed