104 fun invc :: "'a rbt \<Rightarrow> bool" where |
104 fun invc :: "'a rbt \<Rightarrow> bool" where |
105 "invc Leaf = True" | |
105 "invc Leaf = True" | |
106 "invc (Node c l a r) = |
106 "invc (Node c l a r) = |
107 (invc l \<and> invc r \<and> (c = Red \<longrightarrow> color l = Black \<and> color r = Black))" |
107 (invc l \<and> invc r \<and> (c = Red \<longrightarrow> color l = Black \<and> color r = Black))" |
108 |
108 |
109 fun invc_sons :: "'a rbt \<Rightarrow> bool" \<comment> \<open>Weaker version\<close> where |
109 fun invc2 :: "'a rbt \<Rightarrow> bool" \<comment> \<open>Weaker version\<close> where |
110 "invc_sons Leaf = True" | |
110 "invc2 Leaf = True" | |
111 "invc_sons (Node c l a r) = (invc l \<and> invc r)" |
111 "invc2 (Node c l a r) = (invc l \<and> invc r)" |
112 |
112 |
113 fun invh :: "'a rbt \<Rightarrow> bool" where |
113 fun invh :: "'a rbt \<Rightarrow> bool" where |
114 "invh Leaf = True" | |
114 "invh Leaf = True" | |
115 "invh (Node c l x r) = (invh l \<and> invh r \<and> bheight l = bheight r)" |
115 "invh (Node c l x r) = (invh l \<and> invh r \<and> bheight l = bheight r)" |
116 |
116 |
117 lemma invc_sonsI: "invc t \<Longrightarrow> invc_sons t" |
117 lemma invc2I: "invc t \<Longrightarrow> invc2 t" |
118 by (cases t) simp+ |
118 by (cases t) simp+ |
119 |
119 |
120 definition rbt :: "'a rbt \<Rightarrow> bool" where |
120 definition rbt :: "'a rbt \<Rightarrow> bool" where |
121 "rbt t = (invc t \<and> invh t \<and> color t = Black)" |
121 "rbt t = (invc t \<and> invh t \<and> color t = Black)" |
122 |
122 |
124 by (cases t) auto |
124 by (cases t) auto |
125 |
125 |
126 theorem rbt_Leaf: "rbt Leaf" |
126 theorem rbt_Leaf: "rbt Leaf" |
127 by (simp add: rbt_def) |
127 by (simp add: rbt_def) |
128 |
128 |
129 lemma paint_invc_sons: "invc_sons t \<Longrightarrow> invc_sons (paint c t)" |
129 lemma paint_invc2: "invc2 t \<Longrightarrow> invc2 (paint c t)" |
130 by (cases t) auto |
130 by (cases t) auto |
131 |
131 |
132 lemma invc_paint_Black: "invc_sons t \<Longrightarrow> invc (paint Black t)" |
132 lemma invc_paint_Black: "invc2 t \<Longrightarrow> invc (paint Black t)" |
133 by (cases t) auto |
133 by (cases t) auto |
134 |
134 |
135 lemma invh_paint: "invh t \<Longrightarrow> invh (paint c t)" |
135 lemma invh_paint: "invh t \<Longrightarrow> invh (paint c t)" |
136 by (cases t) auto |
136 by (cases t) auto |
137 |
137 |
138 lemma invc_bal: |
138 lemma invc_bal: |
139 "\<lbrakk>invc l \<and> invc_sons r \<or> invc_sons l \<and> invc r\<rbrakk> \<Longrightarrow> invc (bal l a r)" |
139 "\<lbrakk>invc l \<and> invc2 r \<or> invc2 l \<and> invc r\<rbrakk> \<Longrightarrow> invc (bal l a r)" |
140 by (induct l a r rule: bal.induct) auto |
140 by (induct l a r rule: bal.induct) auto |
141 |
141 |
142 lemma bheight_bal: |
142 lemma bheight_bal: |
143 "bheight l = bheight r \<Longrightarrow> bheight (bal l a r) = Suc (bheight l)" |
143 "bheight l = bheight r \<Longrightarrow> bheight (bal l a r) = Suc (bheight l)" |
144 by (induct l a r rule: bal.induct) auto |
144 by (induct l a r rule: bal.induct) auto |
183 shows "invh (balL lt a rt)" |
183 shows "invh (balL lt a rt)" |
184 "bheight (balL lt a rt) = bheight rt" |
184 "bheight (balL lt a rt) = bheight rt" |
185 using assms |
185 using assms |
186 by (induct lt a rt rule: balL.induct) (auto simp add: invh_bal bheight_bal) |
186 by (induct lt a rt rule: balL.induct) (auto simp add: invh_bal bheight_bal) |
187 |
187 |
188 lemma balL_invc: "\<lbrakk>invc_sons l; invc r; color r = Black\<rbrakk> \<Longrightarrow> invc (balL l a r)" |
188 lemma balL_invc: "\<lbrakk>invc2 l; invc r; color r = Black\<rbrakk> \<Longrightarrow> invc (balL l a r)" |
189 by (induct l a r rule: balL.induct) (simp_all add: invc_bal) |
189 by (induct l a r rule: balL.induct) (simp_all add: invc_bal) |
190 |
190 |
191 lemma balL_invc_sons: "\<lbrakk> invc_sons lt; invc rt \<rbrakk> \<Longrightarrow> invc_sons (balL lt a rt)" |
191 lemma balL_invc2: "\<lbrakk> invc2 lt; invc rt \<rbrakk> \<Longrightarrow> invc2 (balL lt a rt)" |
192 by (induct lt a rt rule: balL.induct) (auto simp: invc_bal paint_invc_sons invc_sonsI) |
192 by (induct lt a rt rule: balL.induct) (auto simp: invc_bal paint_invc2 invc2I) |
193 |
193 |
194 lemma balR_invh_with_invc: |
194 lemma balR_invh_with_invc: |
195 assumes "invh lt" "invh rt" "bheight lt = bheight rt + 1" "invc lt" |
195 assumes "invh lt" "invh rt" "bheight lt = bheight rt + 1" "invc lt" |
196 shows "invh (balR lt a rt) \<and> bheight (balR lt a rt) = bheight lt" |
196 shows "invh (balR lt a rt) \<and> bheight (balR lt a rt) = bheight lt" |
197 using assms |
197 using assms |
198 by(induct lt a rt rule: balR.induct) |
198 by(induct lt a rt rule: balR.induct) |
199 (auto simp: invh_bal bheight_bal invh_paint bheight_paint_Red) |
199 (auto simp: invh_bal bheight_bal invh_paint bheight_paint_Red) |
200 |
200 |
201 lemma invc_balR: "\<lbrakk>invc a; invc_sons b; color a = Black\<rbrakk> \<Longrightarrow> invc (balR a x b)" |
201 lemma invc_balR: "\<lbrakk>invc a; invc2 b; color a = Black\<rbrakk> \<Longrightarrow> invc (balR a x b)" |
202 by (induct a x b rule: balR.induct) (simp_all add: invc_bal) |
202 by (induct a x b rule: balR.induct) (simp_all add: invc_bal) |
203 |
203 |
204 lemma invc_sons_balR: "\<lbrakk> invc lt; invc_sons rt \<rbrakk> \<Longrightarrow>invc_sons (balR lt x rt)" |
204 lemma invc2_balR: "\<lbrakk> invc lt; invc2 rt \<rbrakk> \<Longrightarrow>invc2 (balR lt x rt)" |
205 by (induct lt x rt rule: balR.induct) (auto simp: invc_bal paint_invc_sons invc_sonsI) |
205 by (induct lt x rt rule: balR.induct) (auto simp: invc_bal paint_invc2 invc2I) |
206 |
206 |
207 lemma invh_combine: |
207 lemma invh_combine: |
208 assumes "invh lt" "invh rt" "bheight lt = bheight rt" |
208 assumes "invh lt" "invh rt" "bheight lt = bheight rt" |
209 shows "bheight (combine lt rt) = bheight lt" "invh (combine lt rt)" |
209 shows "bheight (combine lt rt) = bheight lt" "invh (combine lt rt)" |
210 using assms |
210 using assms |
212 (auto simp: balL_invh_app split: tree.splits color.splits) |
212 (auto simp: balL_invh_app split: tree.splits color.splits) |
213 |
213 |
214 lemma invc_combine: |
214 lemma invc_combine: |
215 assumes "invc lt" "invc rt" |
215 assumes "invc lt" "invc rt" |
216 shows "color lt = Black \<Longrightarrow> color rt = Black \<Longrightarrow> invc (combine lt rt)" |
216 shows "color lt = Black \<Longrightarrow> color rt = Black \<Longrightarrow> invc (combine lt rt)" |
217 "invc_sons (combine lt rt)" |
217 "invc2 (combine lt rt)" |
218 using assms |
218 using assms |
219 by (induct lt rt rule: combine.induct) |
219 by (induct lt rt rule: combine.induct) |
220 (auto simp: balL_invc invc_sonsI split: tree.splits color.splits) |
220 (auto simp: balL_invc invc2I split: tree.splits color.splits) |
221 |
221 |
222 |
222 |
223 lemma assumes "invh lt" "invc lt" |
223 lemma assumes "invh lt" "invc lt" |
224 shows |
224 shows |
225 del_invc_invh: "invh (del x lt) \<and> (color lt = Red \<and> bheight (del x lt) = bheight lt \<and> invc (del x lt) |
225 del_invc_invh: "invh (del x lt) \<and> (color lt = Red \<and> bheight (del x lt) = bheight lt \<and> invc (del x lt) |
226 \<or> color lt = Black \<and> bheight (del x lt) = bheight lt - 1 \<and> invc_sons (del x lt))" |
226 \<or> color lt = Black \<and> bheight (del x lt) = bheight lt - 1 \<and> invc2 (del x lt))" |
227 and "\<lbrakk>invh rt; bheight lt = bheight rt; invc rt\<rbrakk> \<Longrightarrow> |
227 and "\<lbrakk>invh rt; bheight lt = bheight rt; invc rt\<rbrakk> \<Longrightarrow> |
228 invh (delL x lt k rt) \<and> |
228 invh (delL x lt k rt) \<and> |
229 bheight (delL x lt k rt) = bheight lt \<and> |
229 bheight (delL x lt k rt) = bheight lt \<and> |
230 (color lt = Black \<and> color rt = Black \<and> invc (delL x lt k rt) \<or> |
230 (color lt = Black \<and> color rt = Black \<and> invc (delL x lt k rt) \<or> |
231 (color lt \<noteq> Black \<or> color rt \<noteq> Black) \<and> invc_sons (delL x lt k rt))" |
231 (color lt \<noteq> Black \<or> color rt \<noteq> Black) \<and> invc2 (delL x lt k rt))" |
232 and "\<lbrakk>invh rt; bheight lt = bheight rt; invc rt\<rbrakk> \<Longrightarrow> |
232 and "\<lbrakk>invh rt; bheight lt = bheight rt; invc rt\<rbrakk> \<Longrightarrow> |
233 invh (delR x lt k rt) \<and> |
233 invh (delR x lt k rt) \<and> |
234 bheight (delR x lt k rt) = bheight lt \<and> |
234 bheight (delR x lt k rt) = bheight lt \<and> |
235 (color lt = Black \<and> color rt = Black \<and> invc (delR x lt k rt) \<or> |
235 (color lt = Black \<and> color rt = Black \<and> invc (delR x lt k rt) \<or> |
236 (color lt \<noteq> Black \<or> color rt \<noteq> Black) \<and> invc_sons (delR x lt k rt))" |
236 (color lt \<noteq> Black \<or> color rt \<noteq> Black) \<and> invc2 (delR x lt k rt))" |
237 using assms |
237 using assms |
238 proof (induct x lt and x lt k rt and x lt k rt rule: del_delL_delR.induct) |
238 proof (induct x lt and x lt k rt and x lt k rt rule: del_delL_delR.induct) |
239 case (2 y c _ y') |
239 case (2 y c _ y') |
240 have "y = y' \<or> y < y' \<or> y > y'" by auto |
240 have "y = y' \<or> y < y' \<or> y > y'" by auto |
241 thus ?case proof (elim disjE) |
241 thus ?case proof (elim disjE) |
242 assume "y = y'" |
242 assume "y = y'" |
243 with 2 show ?thesis |
243 with 2 show ?thesis |
244 by (cases c) (simp_all add: invh_combine invc_combine) |
244 by (cases c) (simp_all add: invh_combine invc_combine) |
245 next |
245 next |
246 assume "y < y'" |
246 assume "y < y'" |
247 with 2 show ?thesis by (cases c) (auto simp: invc_sonsI) |
247 with 2 show ?thesis by (cases c) (auto simp: invc2I) |
248 next |
248 next |
249 assume "y' < y" |
249 assume "y' < y" |
250 with 2 show ?thesis by (cases c) (auto simp: invc_sonsI) |
250 with 2 show ?thesis by (cases c) (auto simp: invc2I) |
251 qed |
251 qed |
252 next |
252 next |
253 case (3 y lt z rta y' bb) |
253 case (3 y lt z rta y' bb) |
254 thus ?case by (cases "color (Node Black lt z rta) = Black \<and> color bb = Black") (simp add: balL_invh_with_invc balL_invc balL_invc_sons)+ |
254 thus ?case by (cases "color (Node Black lt z rta) = Black \<and> color bb = Black") (simp add: balL_invh_with_invc balL_invc balL_invc2)+ |
255 next |
255 next |
256 case (5 y a y' lt z rta) |
256 case (5 y a y' lt z rta) |
257 thus ?case by (cases "color a = Black \<and> color (Node Black lt z rta) = Black") (simp add: balR_invh_with_invc invc_balR invc_sons_balR)+ |
257 thus ?case by (cases "color a = Black \<and> color (Node Black lt z rta) = Black") (simp add: balR_invh_with_invc invc_balR invc2_balR)+ |
258 next |
258 next |
259 case ("6_1" y a y') thus ?case by (cases "color a = Black \<and> color Leaf = Black") simp+ |
259 case ("6_1" y a y') thus ?case by (cases "color a = Black \<and> color Leaf = Black") simp+ |
260 qed auto |
260 qed auto |
261 |
261 |
262 theorem rbt_delete: "rbt t \<Longrightarrow> rbt (delete k t)" |
262 theorem rbt_delete: "rbt t \<Longrightarrow> rbt (delete k t)" |
263 by (metis delete_def rbt_def color_paint_Black del_invc_invh invc_paint_Black invc_sonsI invh_paint) |
263 by (metis delete_def rbt_def color_paint_Black del_invc_invh invc_paint_Black invc2I invh_paint) |
264 |
264 |
265 text \<open>Overall correctness:\<close> |
265 text \<open>Overall correctness:\<close> |
266 |
266 |
267 interpretation Set_by_Ordered |
267 interpretation Set_by_Ordered |
268 where empty = Leaf and isin = isin and insert = insert and delete = delete |
268 where empty = Leaf and isin = isin and insert = insert and delete = delete |