38 in if rl \<ge> rr then Node (rr+1) l a r else Node (rl+1) r a l)" |
38 in if rl \<ge> rr then Node (rr+1) l a r else Node (rl+1) r a l)" |
39 |
39 |
40 fun get_min :: "'a lheap \<Rightarrow> 'a" where |
40 fun get_min :: "'a lheap \<Rightarrow> 'a" where |
41 "get_min(Node n l a r) = a" |
41 "get_min(Node n l a r) = a" |
42 |
42 |
43 function meld :: "'a::ord lheap \<Rightarrow> 'a lheap \<Rightarrow> 'a lheap" where |
43 function merge :: "'a::ord lheap \<Rightarrow> 'a lheap \<Rightarrow> 'a lheap" where |
44 "meld Leaf t2 = t2" | |
44 "merge Leaf t2 = t2" | |
45 "meld t1 Leaf = t1" | |
45 "merge t1 Leaf = t1" | |
46 "meld (Node n1 l1 a1 r1) (Node n2 l2 a2 r2) = |
46 "merge (Node n1 l1 a1 r1) (Node n2 l2 a2 r2) = |
47 (if a1 \<le> a2 then node l1 a1 (meld r1 (Node n2 l2 a2 r2)) |
47 (if a1 \<le> a2 then node l1 a1 (merge r1 (Node n2 l2 a2 r2)) |
48 else node l2 a2 (meld r2 (Node n1 l1 a1 r1)))" |
48 else node l2 a2 (merge r2 (Node n1 l1 a1 r1)))" |
49 by pat_completeness auto |
49 by pat_completeness auto |
50 termination by (relation "measure (%(t1,t2). rank t1 + rank t2)") auto |
50 termination by (relation "measure (%(t1,t2). rank t1 + rank t2)") auto |
51 |
51 |
52 lemma meld_code: "meld t1 t2 = (case (t1,t2) of |
52 lemma merge_code: "merge t1 t2 = (case (t1,t2) of |
53 (Leaf, _) \<Rightarrow> t2 | |
53 (Leaf, _) \<Rightarrow> t2 | |
54 (_, Leaf) \<Rightarrow> t1 | |
54 (_, Leaf) \<Rightarrow> t1 | |
55 (Node n1 l1 a1 r1, Node n2 l2 a2 r2) \<Rightarrow> |
55 (Node n1 l1 a1 r1, Node n2 l2 a2 r2) \<Rightarrow> |
56 if a1 \<le> a2 then node l1 a1 (meld r1 t2) else node l2 a2 (meld r2 t1))" |
56 if a1 \<le> a2 then node l1 a1 (merge r1 t2) else node l2 a2 (merge r2 t1))" |
57 by(induction t1 t2 rule: meld.induct) (simp_all split: tree.split) |
57 by(induction t1 t2 rule: merge.induct) (simp_all split: tree.split) |
58 |
58 |
59 definition insert :: "'a::ord \<Rightarrow> 'a lheap \<Rightarrow> 'a lheap" where |
59 definition insert :: "'a::ord \<Rightarrow> 'a lheap \<Rightarrow> 'a lheap" where |
60 "insert x t = meld (Node 1 Leaf x Leaf) t" |
60 "insert x t = merge (Node 1 Leaf x Leaf) t" |
61 |
61 |
62 fun del_min :: "'a::ord lheap \<Rightarrow> 'a lheap" where |
62 fun del_min :: "'a::ord lheap \<Rightarrow> 'a lheap" where |
63 "del_min Leaf = Leaf" | |
63 "del_min Leaf = Leaf" | |
64 "del_min (Node n l x r) = meld l r" |
64 "del_min (Node n l x r) = merge l r" |
65 |
65 |
66 |
66 |
67 subsection "Lemmas" |
67 subsection "Lemmas" |
68 |
68 |
69 declare Let_def [simp] |
69 declare Let_def [simp] |
97 get_min q \<in> set_mset(mset q) \<and> (\<forall>x \<in># mset q. get_min q \<le> x)" |
97 get_min q \<in> set_mset(mset q) \<and> (\<forall>x \<in># mset q. get_min q \<le> x)" |
98 and invar_insert: "invar q \<Longrightarrow> invar (insert x q)" |
98 and invar_insert: "invar q \<Longrightarrow> invar (insert x q)" |
99 and invar_del_min: "invar q \<Longrightarrow> invar (del_min q)" |
99 and invar_del_min: "invar q \<Longrightarrow> invar (del_min q)" |
100 |
100 |
101 |
101 |
102 lemma mset_meld: "mset_tree (meld h1 h2) = mset_tree h1 + mset_tree h2" |
102 lemma mset_merge: "mset_tree (merge h1 h2) = mset_tree h1 + mset_tree h2" |
103 by (induction h1 h2 rule: meld.induct) (auto simp add: node_def ac_simps) |
103 by (induction h1 h2 rule: merge.induct) (auto simp add: node_def ac_simps) |
104 |
104 |
105 lemma mset_insert: "mset_tree (insert x t) = mset_tree t + {#x#}" |
105 lemma mset_insert: "mset_tree (insert x t) = mset_tree t + {#x#}" |
106 by (auto simp add: insert_def mset_meld) |
106 by (auto simp add: insert_def mset_merge) |
107 |
107 |
108 lemma get_min: |
108 lemma get_min: |
109 "heap h \<Longrightarrow> h \<noteq> Leaf \<Longrightarrow> |
109 "heap h \<Longrightarrow> h \<noteq> Leaf \<Longrightarrow> |
110 get_min h \<in> set_mset(mset_tree h) \<and> (\<forall>x \<in># mset_tree h. get_min h \<le> x)" |
110 get_min h \<in> set_mset(mset_tree h) \<and> (\<forall>x \<in># mset_tree h. get_min h \<le> x)" |
111 by (induction h) (auto) |
111 by (induction h) (auto) |
112 |
112 |
113 lemma mset_del_min: "mset_tree (del_min h) = mset_tree h - {# get_min h #}" |
113 lemma mset_del_min: "mset_tree (del_min h) = mset_tree h - {# get_min h #}" |
114 by (cases h) (auto simp: mset_meld) |
114 by (cases h) (auto simp: mset_merge) |
115 |
115 |
116 lemma ltree_meld: "\<lbrakk> ltree l; ltree r \<rbrakk> \<Longrightarrow> ltree (meld l r)" |
116 lemma ltree_merge: "\<lbrakk> ltree l; ltree r \<rbrakk> \<Longrightarrow> ltree (merge l r)" |
117 proof(induction l r rule: meld.induct) |
117 proof(induction l r rule: merge.induct) |
118 case (3 n1 l1 a1 r1 n2 l2 a2 r2) |
118 case (3 n1 l1 a1 r1 n2 l2 a2 r2) |
119 show ?case (is "ltree(meld ?t1 ?t2)") |
119 show ?case (is "ltree(merge ?t1 ?t2)") |
120 proof cases |
120 proof cases |
121 assume "a1 \<le> a2" |
121 assume "a1 \<le> a2" |
122 hence "ltree (meld ?t1 ?t2) = ltree (node l1 a1 (meld r1 ?t2))" by simp |
122 hence "ltree (merge ?t1 ?t2) = ltree (node l1 a1 (merge r1 ?t2))" by simp |
123 also have "\<dots> = (ltree l1 \<and> ltree(meld r1 ?t2))" |
123 also have "\<dots> = (ltree l1 \<and> ltree(merge r1 ?t2))" |
124 by(simp add: ltree_node) |
124 by(simp add: ltree_node) |
125 also have "..." using "3.prems" "3.IH"(1)[OF `a1 \<le> a2`] by (simp) |
125 also have "..." using "3.prems" "3.IH"(1)[OF `a1 \<le> a2`] by (simp) |
126 finally show ?thesis . |
126 finally show ?thesis . |
127 next (* analogous but automatic *) |
127 next (* analogous but automatic *) |
128 assume "\<not> a1 \<le> a2" |
128 assume "\<not> a1 \<le> a2" |
129 thus ?thesis using 3 by(simp)(auto simp: ltree_node) |
129 thus ?thesis using 3 by(simp)(auto simp: ltree_node) |
130 qed |
130 qed |
131 qed simp_all |
131 qed simp_all |
132 |
132 |
133 lemma heap_meld: "\<lbrakk> heap l; heap r \<rbrakk> \<Longrightarrow> heap (meld l r)" |
133 lemma heap_merge: "\<lbrakk> heap l; heap r \<rbrakk> \<Longrightarrow> heap (merge l r)" |
134 proof(induction l r rule: meld.induct) |
134 proof(induction l r rule: merge.induct) |
135 case 3 thus ?case by(auto simp: heap_node mset_meld ball_Un) |
135 case 3 thus ?case by(auto simp: heap_node mset_merge ball_Un) |
136 qed simp_all |
136 qed simp_all |
137 |
137 |
138 lemma ltree_insert: "ltree t \<Longrightarrow> ltree(insert x t)" |
138 lemma ltree_insert: "ltree t \<Longrightarrow> ltree(insert x t)" |
139 by(simp add: insert_def ltree_meld del: meld.simps split: tree.split) |
139 by(simp add: insert_def ltree_merge del: merge.simps split: tree.split) |
140 |
140 |
141 lemma heap_insert: "heap t \<Longrightarrow> heap(insert x t)" |
141 lemma heap_insert: "heap t \<Longrightarrow> heap(insert x t)" |
142 by(simp add: insert_def heap_meld del: meld.simps split: tree.split) |
142 by(simp add: insert_def heap_merge del: merge.simps split: tree.split) |
143 |
143 |
144 lemma ltree_del_min: "ltree t \<Longrightarrow> ltree(del_min t)" |
144 lemma ltree_del_min: "ltree t \<Longrightarrow> ltree(del_min t)" |
145 by(cases t)(auto simp add: ltree_meld simp del: meld.simps) |
145 by(cases t)(auto simp add: ltree_merge simp del: merge.simps) |
146 |
146 |
147 lemma heap_del_min: "heap t \<Longrightarrow> heap(del_min t)" |
147 lemma heap_del_min: "heap t \<Longrightarrow> heap(del_min t)" |
148 by(cases t)(auto simp add: heap_meld simp del: meld.simps) |
148 by(cases t)(auto simp add: heap_merge simp del: merge.simps) |
149 |
149 |
150 |
150 |
151 interpretation lheap: Priority_Queue |
151 interpretation lheap: Priority_Queue |
152 where empty = Leaf and is_empty = "\<lambda>h. h = Leaf" |
152 where empty = Leaf and is_empty = "\<lambda>h. h = Leaf" |
153 and insert = insert and del_min = del_min |
153 and insert = insert and del_min = del_min |
185 using Node * by (simp del: power_increasing_iff) |
185 using Node * by (simp del: power_increasing_iff) |
186 also have "\<dots> = size1 \<langle>n, l, a, r\<rangle>" by simp |
186 also have "\<dots> = size1 \<langle>n, l, a, r\<rangle>" by simp |
187 finally show ?case . |
187 finally show ?case . |
188 qed |
188 qed |
189 |
189 |
190 function t_meld :: "'a::ord lheap \<Rightarrow> 'a lheap \<Rightarrow> nat" where |
190 function t_merge :: "'a::ord lheap \<Rightarrow> 'a lheap \<Rightarrow> nat" where |
191 "t_meld Leaf t2 = 1" | |
191 "t_merge Leaf t2 = 1" | |
192 "t_meld t2 Leaf = 1" | |
192 "t_merge t2 Leaf = 1" | |
193 "t_meld (Node n1 l1 a1 r1) (Node n2 l2 a2 r2) = |
193 "t_merge (Node n1 l1 a1 r1) (Node n2 l2 a2 r2) = |
194 (if a1 \<le> a2 then 1 + t_meld r1 (Node n2 l2 a2 r2) |
194 (if a1 \<le> a2 then 1 + t_merge r1 (Node n2 l2 a2 r2) |
195 else 1 + t_meld r2 (Node n1 l1 a1 r1))" |
195 else 1 + t_merge r2 (Node n1 l1 a1 r1))" |
196 by pat_completeness auto |
196 by pat_completeness auto |
197 termination by (relation "measure (%(t1,t2). rank t1 + rank t2)") auto |
197 termination by (relation "measure (%(t1,t2). rank t1 + rank t2)") auto |
198 |
198 |
199 definition t_insert :: "'a::ord \<Rightarrow> 'a lheap \<Rightarrow> nat" where |
199 definition t_insert :: "'a::ord \<Rightarrow> 'a lheap \<Rightarrow> nat" where |
200 "t_insert x t = t_meld (Node 1 Leaf x Leaf) t" |
200 "t_insert x t = t_merge (Node 1 Leaf x Leaf) t" |
201 |
201 |
202 fun t_del_min :: "'a::ord lheap \<Rightarrow> nat" where |
202 fun t_del_min :: "'a::ord lheap \<Rightarrow> nat" where |
203 "t_del_min Leaf = 1" | |
203 "t_del_min Leaf = 1" | |
204 "t_del_min (Node n l a r) = t_meld l r" |
204 "t_del_min (Node n l a r) = t_merge l r" |
205 |
205 |
206 lemma t_meld_rank: "t_meld l r \<le> rank l + rank r + 1" |
206 lemma t_merge_rank: "t_merge l r \<le> rank l + rank r + 1" |
207 proof(induction l r rule: meld.induct) |
207 proof(induction l r rule: merge.induct) |
208 case 3 thus ?case |
208 case 3 thus ?case |
209 by(simp)(fastforce split: tree.splits simp del: t_meld.simps) |
209 by(simp)(fastforce split: tree.splits simp del: t_merge.simps) |
210 qed simp_all |
210 qed simp_all |
211 |
211 |
212 corollary t_meld_log: assumes "ltree l" "ltree r" |
212 corollary t_merge_log: assumes "ltree l" "ltree r" |
213 shows "t_meld l r \<le> log 2 (size1 l) + log 2 (size1 r) + 1" |
213 shows "t_merge l r \<le> log 2 (size1 l) + log 2 (size1 r) + 1" |
214 using le_log2_of_power[OF pow2_rank_size1[OF assms(1)]] |
214 using le_log2_of_power[OF pow2_rank_size1[OF assms(1)]] |
215 le_log2_of_power[OF pow2_rank_size1[OF assms(2)]] t_meld_rank[of l r] |
215 le_log2_of_power[OF pow2_rank_size1[OF assms(2)]] t_merge_rank[of l r] |
216 by linarith |
216 by linarith |
217 |
217 |
218 corollary t_insert_log: "ltree t \<Longrightarrow> t_insert x t \<le> log 2 (size1 t) + 2" |
218 corollary t_insert_log: "ltree t \<Longrightarrow> t_insert x t \<le> log 2 (size1 t) + 2" |
219 using t_meld_log[of "Node 1 Leaf x Leaf" t] |
219 using t_merge_log[of "Node 1 Leaf x Leaf" t] |
220 by(simp add: t_insert_def split: tree.split) |
220 by(simp add: t_insert_def split: tree.split) |
221 |
221 |
222 lemma ld_ld_1_less: |
222 lemma ld_ld_1_less: |
223 assumes "x > 0" "y > 0" shows "1 + log 2 x + log 2 y < 2 * log 2 (x+y)" |
223 assumes "x > 0" "y > 0" shows "1 + log 2 x + log 2 y < 2 * log 2 (x+y)" |
224 proof - |
224 proof - |
234 shows "t_del_min t \<le> 2 * log 2 (size1 t) + 1" |
234 shows "t_del_min t \<le> 2 * log 2 (size1 t) + 1" |
235 proof(cases t) |
235 proof(cases t) |
236 case Leaf thus ?thesis using assms by simp |
236 case Leaf thus ?thesis using assms by simp |
237 next |
237 next |
238 case [simp]: (Node _ t1 _ t2) |
238 case [simp]: (Node _ t1 _ t2) |
239 have "t_del_min t = t_meld t1 t2" by simp |
239 have "t_del_min t = t_merge t1 t2" by simp |
240 also have "\<dots> \<le> log 2 (size1 t1) + log 2 (size1 t2) + 1" |
240 also have "\<dots> \<le> log 2 (size1 t1) + log 2 (size1 t2) + 1" |
241 using \<open>ltree t\<close> by (auto simp: t_meld_log simp del: t_meld.simps) |
241 using \<open>ltree t\<close> by (auto simp: t_merge_log simp del: t_merge.simps) |
242 also have "\<dots> \<le> 2 * log 2 (size1 t) + 1" |
242 also have "\<dots> \<le> 2 * log 2 (size1 t) + 1" |
243 using ld_ld_1_less[of "size1 t1" "size1 t2"] by (simp) |
243 using ld_ld_1_less[of "size1 t1" "size1 t2"] by (simp) |
244 finally show ?thesis . |
244 finally show ?thesis . |
245 qed |
245 qed |
246 |
246 |