theory Splay_Heap imports "HOL-Library.Tree_Multiset" begin
text‹Splay heaps were invented by Okasaki~cite‹"Okasaki"›. They represent
queues by splay trees, not by heaps!›
fun get_min :: "('a::linorder) tree ==> 'a"where "get_min(Node l m r) = (if l = Leaf then m else get_min l)"
fun partition :: "'a::linorder ==> 'a tree ==> 'a tree * 'a tree"where "partition p Leaf = (Leaf,Leaf)" | "partition p (Node al a ar) = (if a ≤ p then case ar of Leaf ==> (Node al a ar, Leaf) | Node bl b br ==> if b ≤ p then let (pl,pr) = partition p br in (Node (Node al a bl) b pl, pr) else let (pl,pr) = partition p bl in (Node al a pl, Node pr b br) else case al of Leaf ==> (Leaf, Node al a ar) | Node bl b br ==> if b ≤ p then let (pl,pr) = partition p br in (Node bl b pl, Node pr a ar) else let (pl,pr) = partition p bl in (pl, Node pr b (Node br a ar)))"
definition insert :: "'a::linorder ==> 'a tree ==> 'a tree"where "insert x h = (let (l,r) = partition x h in Node l x r)"
fun del_min :: "'a::linorder tree ==> 'a tree"where "del_min Leaf = Leaf" | "del_min (Node Leaf _ r) = r" | "del_min (Node (Node ll a lr) b r) = (if ll = Leaf then Node lr b r else Node (del_min ll) a (Node lr b r))"
lemma get_min_in: "h ≠ Leaf ==> get_min h ∈ set_tree h" by(induction h) auto
lemma get_min_min: "[ bst_wrt (≤) h; h ≠ Leaf ]==>∀x ∈ set_tree h. get_min h ≤ x" proof(induction h) case (Node l x r) thus ?caseusing get_min_in[of l] get_min_in[of r] by auto (blast intro: order_trans) qed simp
lemma size_partition: "partition p t = (l',r') ==> size t = size l' + size r'" by (induction p t arbitrary: l' r' rule: partition.induct)
(auto split: if_splits tree.splits prod.splits)
lemma mset_partition: "[ bst_wrt (≤) t; partition p t = (l',r') ] ==> mset_tree t = mset_tree l' + mset_tree r'" proof(induction p t arbitrary: l' r' rule: partition.induct) case1thus ?caseby simp next case (2 p l a r) show ?case proof cases assume"a ≤ p" show ?thesis proof (cases r) case Leaf thus ?thesis using‹a ≤ p›"2.prems"by auto next case (Node rl b rr) show ?thesis proof cases assume"b ≤ p" thus ?thesis using Node ‹a ≤ p›"2.prems""2.IH"(1)[OF _ Node] by (auto simp: ac_simps split: prod.splits) next assume"¬ b ≤ p" thus ?thesis using Node ‹a ≤ p›"2.prems""2.IH"(2)[OF _ Node] by (auto simp: ac_simps split: prod.splits) qed qed next assume"¬ a ≤ p" show ?thesis proof (cases l) case Leaf thus ?thesis using‹¬ a ≤ p›"2.prems"by auto next case (Node ll b lr) show ?thesis proof cases assume"b ≤ p" thus ?thesis using Node ‹¬ a ≤ p›"2.prems""2.IH"(3)[OF _ Node] by (auto simp: ac_simps split: prod.splits) next assume"¬ b ≤ p" thus ?thesis using Node ‹¬ a ≤ p›"2.prems""2.IH"(4)[OF _ Node] by (auto simp: ac_simps split: prod.splits) qed qed qed qed
lemma set_partition: "[ bst_wrt (≤) t; partition p t = (l',r') ] ==> set_tree t = set_tree l' ∪ set_tree r'" by (metis mset_partition set_mset_tree set_mset_union)
lemma bst_partition: "partition p t = (l',r') ==> bst_wrt (≤) t ==> bst_wrt (≤) (Node l' p r')" proof(induction p t arbitrary: l' r' rule: partition.induct) case1thus ?caseby simp next case (2 p l a r) show ?case proof cases assume"a ≤ p" show ?thesis proof (cases r) case Leaf thus ?thesis using‹a ≤ p›"2.prems"by fastforce next case (Node rl b rr) show ?thesis proof cases assume"b ≤ p" thus ?thesis using Node ‹a ≤ p›"2.prems""2.IH"(1)[OF _ Node] set_partition[of rr] by (fastforce split: prod.splits) next assume"¬ b ≤ p" thus ?thesis using Node ‹a ≤ p›"2.prems""2.IH"(2)[OF _ Node] set_partition[of rl] by (fastforce split: prod.splits) qed qed next assume"¬ a ≤ p" show ?thesis proof (cases l) case Leaf thus ?thesis using‹¬ a ≤ p›"2.prems"by fastforce next case (Node ll b lr) show ?thesis proof cases assume"b ≤ p" thus ?thesis using Node ‹¬ a ≤ p›"2.prems""2.IH"(3)[OF _ Node] set_partition[of lr] by (fastforce split: prod.splits) next assume"¬ b ≤ p" thus ?thesis using Node ‹¬ a ≤ p›"2.prems""2.IH"(4)[OF _ Node] set_partition[of ll] by (fastforce split: prod.splits) qed qed qed qed
lemma size_del_min[simp]: "size(del_min t) = size t - 1" by(induction t rule: del_min.induct) (auto simp: neq_Leaf_iff)
lemma mset_del_min: "mset_tree (del_min h) = mset_tree h - {# get_min h #}" proof(induction h rule: del_min.induct) case (3 ll) show ?case proof cases assume"ll = Leaf"thus ?thesis using3by (simp add: ac_simps) next assume"ll ≠ Leaf" hence"get_min ll ∈# mset_tree ll" by (simp add: get_min_in) thenobtain A where"mset_tree ll = add_mset (get_min ll) A" by (blast dest: multi_member_split) thenshow ?thesis using3by auto qed qed auto
lemma bst_del_min: "bst_wrt (≤) t ==> bst_wrt (≤) (del_min t)" apply(induction t rule: del_min.induct) apply simp apply simp apply auto by (metis Multiset.diff_subset_eq_self subsetD set_mset_mono set_mset_tree mset_del_min)
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.