| author | wenzelm | 
| Fri, 29 Oct 2010 11:49:56 +0200 | |
| changeset 40255 | 9ffbc25e1606 | 
| parent 39246 | 9e58f0499f57 | 
| child 41141 | ad923cdd4a5d | 
| permissions | -rw-r--r-- | 
| 23449 | 1 | (* Title: HOL/MetisTest/BT.thy | 
| 2 | Author: Lawrence C Paulson, Cambridge University Computer Laboratory | |
| 36487 
50fd056cc3ce
insert a nice proof found by Vampire, which demonstrates the use of "let" in Isar proofs
 blanchet parents: 
36484diff
changeset | 3 | Author: Jasmin Blanchette, TU Muenchen | 
| 23449 | 4 | |
| 5 | Testing the metis method | |
| 6 | *) | |
| 7 | ||
| 8 | header {* Binary trees *}
 | |
| 9 | ||
| 27104 
791607529f6d
rep_datatype command now takes list of constructors as input arguments
 haftmann parents: 
26312diff
changeset | 10 | theory BT | 
| 
791607529f6d
rep_datatype command now takes list of constructors as input arguments
 haftmann parents: 
26312diff
changeset | 11 | imports Main | 
| 
791607529f6d
rep_datatype command now takes list of constructors as input arguments
 haftmann parents: 
26312diff
changeset | 12 | begin | 
| 23449 | 13 | |
| 14 | datatype 'a bt = | |
| 15 | Lf | |
| 16 | | Br 'a "'a bt" "'a bt" | |
| 17 | ||
| 39246 | 18 | primrec n_nodes :: "'a bt => nat" where | 
| 19 | "n_nodes Lf = 0" | |
| 20 | | "n_nodes (Br a t1 t2) = Suc (n_nodes t1 + n_nodes t2)" | |
| 21 | ||
| 22 | primrec n_leaves :: "'a bt => nat" where | |
| 23 | "n_leaves Lf = Suc 0" | |
| 24 | | "n_leaves (Br a t1 t2) = n_leaves t1 + n_leaves t2" | |
| 23449 | 25 | |
| 39246 | 26 | primrec depth :: "'a bt => nat" where | 
| 27 | "depth Lf = 0" | |
| 28 | | "depth (Br a t1 t2) = Suc (max (depth t1) (depth t2))" | |
| 23449 | 29 | |
| 39246 | 30 | primrec reflect :: "'a bt => 'a bt" where | 
| 31 | "reflect Lf = Lf" | |
| 32 | | "reflect (Br a t1 t2) = Br a (reflect t2) (reflect t1)" | |
| 23449 | 33 | |
| 39246 | 34 | primrec bt_map :: "('a => 'b) => ('a bt => 'b bt)" where
 | 
| 23449 | 35 | "bt_map f Lf = Lf" | 
| 39246 | 36 | | "bt_map f (Br a t1 t2) = Br (f a) (bt_map f t1) (bt_map f t2)" | 
| 23449 | 37 | |
| 39246 | 38 | primrec preorder :: "'a bt => 'a list" where | 
| 23449 | 39 | "preorder Lf = []" | 
| 39246 | 40 | | "preorder (Br a t1 t2) = [a] @ (preorder t1) @ (preorder t2)" | 
| 23449 | 41 | |
| 39246 | 42 | primrec inorder :: "'a bt => 'a list" where | 
| 23449 | 43 | "inorder Lf = []" | 
| 39246 | 44 | | "inorder (Br a t1 t2) = (inorder t1) @ [a] @ (inorder t2)" | 
| 23449 | 45 | |
| 39246 | 46 | primrec postorder :: "'a bt => 'a list" where | 
| 23449 | 47 | "postorder Lf = []" | 
| 39246 | 48 | | "postorder (Br a t1 t2) = (postorder t1) @ (postorder t2) @ [a]" | 
| 23449 | 49 | |
| 39246 | 50 | primrec append :: "'a bt => 'a bt => 'a bt" where | 
| 51 | "append Lf t = t" | |
| 52 | | "append (Br a t1 t2) t = Br a (append t1 t) (append t2 t)" | |
| 23449 | 53 | |
| 54 | text {* \medskip BT simplification *}
 | |
| 55 | ||
| 38991 | 56 | declare [[ sledgehammer_problem_prefix = "BT__n_leaves_reflect" ]] | 
| 36484 | 57 | |
| 23449 | 58 | lemma n_leaves_reflect: "n_leaves (reflect t) = n_leaves t" | 
| 36484 | 59 | proof (induct t) | 
| 36487 
50fd056cc3ce
insert a nice proof found by Vampire, which demonstrates the use of "let" in Isar proofs
 blanchet parents: 
36484diff
changeset | 60 | case Lf thus ?case | 
| 
50fd056cc3ce
insert a nice proof found by Vampire, which demonstrates the use of "let" in Isar proofs
 blanchet parents: 
36484diff
changeset | 61 | proof - | 
| 
50fd056cc3ce
insert a nice proof found by Vampire, which demonstrates the use of "let" in Isar proofs
 blanchet parents: 
36484diff
changeset | 62 | let "?p\<^isub>1 x\<^isub>1" = "x\<^isub>1 \<noteq> n_leaves (reflect (Lf::'a bt))" | 
| 
50fd056cc3ce
insert a nice proof found by Vampire, which demonstrates the use of "let" in Isar proofs
 blanchet parents: 
36484diff
changeset | 63 | have "\<not> ?p\<^isub>1 (Suc 0)" by (metis reflect.simps(1) n_leaves.simps(1)) | 
| 
50fd056cc3ce
insert a nice proof found by Vampire, which demonstrates the use of "let" in Isar proofs
 blanchet parents: 
36484diff
changeset | 64 | hence "\<not> ?p\<^isub>1 (n_leaves (Lf::'a bt))" by (metis n_leaves.simps(1)) | 
| 
50fd056cc3ce
insert a nice proof found by Vampire, which demonstrates the use of "let" in Isar proofs
 blanchet parents: 
36484diff
changeset | 65 | thus "n_leaves (reflect (Lf::'a bt)) = n_leaves (Lf::'a bt)" by metis | 
| 
50fd056cc3ce
insert a nice proof found by Vampire, which demonstrates the use of "let" in Isar proofs
 blanchet parents: 
36484diff
changeset | 66 | qed | 
| 36484 | 67 | next | 
| 68 | case (Br a t1 t2) thus ?case | |
| 36487 
50fd056cc3ce
insert a nice proof found by Vampire, which demonstrates the use of "let" in Isar proofs
 blanchet parents: 
36484diff
changeset | 69 | by (metis n_leaves.simps(2) nat_add_commute reflect.simps(2)) | 
| 36484 | 70 | qed | 
| 23449 | 71 | |
| 38991 | 72 | declare [[ sledgehammer_problem_prefix = "BT__n_nodes_reflect" ]] | 
| 36484 | 73 | |
| 23449 | 74 | lemma n_nodes_reflect: "n_nodes (reflect t) = n_nodes t" | 
| 36484 | 75 | proof (induct t) | 
| 76 | case Lf thus ?case by (metis reflect.simps(1)) | |
| 77 | next | |
| 78 | case (Br a t1 t2) thus ?case | |
| 36844 | 79 | by (metis add_commute n_nodes.simps(2) reflect.simps(2)) | 
| 36484 | 80 | qed | 
| 23449 | 81 | |
| 38991 | 82 | declare [[ sledgehammer_problem_prefix = "BT__depth_reflect" ]] | 
| 36484 | 83 | |
| 23449 | 84 | lemma depth_reflect: "depth (reflect t) = depth t" | 
| 36484 | 85 | apply (induct t) | 
| 86 | apply (metis depth.simps(1) reflect.simps(1)) | |
| 87 | by (metis depth.simps(2) min_max.inf_sup_aci(5) reflect.simps(2)) | |
| 23449 | 88 | |
| 89 | text {*
 | |
| 36484 | 90 | The famous relationship between the numbers of leaves and nodes. | 
| 23449 | 91 | *} | 
| 92 | ||
| 38991 | 93 | declare [[ sledgehammer_problem_prefix = "BT__n_leaves_nodes" ]] | 
| 36484 | 94 | |
| 23449 | 95 | lemma n_leaves_nodes: "n_leaves t = Suc (n_nodes t)" | 
| 36484 | 96 | apply (induct t) | 
| 97 | apply (metis n_leaves.simps(1) n_nodes.simps(1)) | |
| 98 | by auto | |
| 23449 | 99 | |
| 38991 | 100 | declare [[ sledgehammer_problem_prefix = "BT__reflect_reflect_ident" ]] | 
| 36484 | 101 | |
| 23449 | 102 | lemma reflect_reflect_ident: "reflect (reflect t) = t" | 
| 36484 | 103 | apply (induct t) | 
| 104 | apply (metis reflect.simps(1)) | |
| 105 | proof - | |
| 106 | fix a :: 'a and t1 :: "'a bt" and t2 :: "'a bt" | |
| 107 | assume A1: "reflect (reflect t1) = t1" | |
| 108 | assume A2: "reflect (reflect t2) = t2" | |
| 109 | have "\<And>V U. reflect (Br U V (reflect t1)) = Br U t1 (reflect V)" | |
| 110 | using A1 by (metis reflect.simps(2)) | |
| 111 | hence "\<And>V U. Br U t1 (reflect (reflect V)) = reflect (reflect (Br U t1 V))" | |
| 112 | by (metis reflect.simps(2)) | |
| 113 | hence "\<And>U. reflect (reflect (Br U t1 t2)) = Br U t1 t2" | |
| 114 | using A2 by metis | |
| 115 | thus "reflect (reflect (Br a t1 t2)) = Br a t1 t2" by blast | |
| 116 | qed | |
| 23449 | 117 | |
| 38991 | 118 | declare [[ sledgehammer_problem_prefix = "BT__bt_map_ident" ]] | 
| 36484 | 119 | |
| 23449 | 120 | lemma bt_map_ident: "bt_map (%x. x) = (%y. y)" | 
| 121 | apply (rule ext) | |
| 122 | apply (induct_tac y) | |
| 36484 | 123 | apply (metis bt_map.simps(1)) | 
| 36571 | 124 | by (metis bt_map.simps(2)) | 
| 23449 | 125 | |
| 39246 | 126 | declare [[ sledgehammer_problem_prefix = "BT__bt_map_append" ]] | 
| 36484 | 127 | |
| 39246 | 128 | lemma bt_map_append: "bt_map f (append t u) = append (bt_map f t) (bt_map f u)" | 
| 23449 | 129 | apply (induct t) | 
| 39246 | 130 | apply (metis append.simps(1) bt_map.simps(1)) | 
| 131 | by (metis append.simps(2) bt_map.simps(2)) | |
| 23449 | 132 | |
| 38991 | 133 | declare [[ sledgehammer_problem_prefix = "BT__bt_map_compose" ]] | 
| 36484 | 134 | |
| 23449 | 135 | lemma bt_map_compose: "bt_map (f o g) t = bt_map f (bt_map g t)" | 
| 36484 | 136 | apply (induct t) | 
| 137 | apply (metis bt_map.simps(1)) | |
| 138 | by (metis bt_map.simps(2) o_eq_dest_lhs) | |
| 23449 | 139 | |
| 38991 | 140 | declare [[ sledgehammer_problem_prefix = "BT__bt_map_reflect" ]] | 
| 36484 | 141 | |
| 23449 | 142 | lemma bt_map_reflect: "bt_map f (reflect t) = reflect (bt_map f t)" | 
| 36484 | 143 | apply (induct t) | 
| 144 | apply (metis bt_map.simps(1) reflect.simps(1)) | |
| 145 | by (metis bt_map.simps(2) reflect.simps(2)) | |
| 23449 | 146 | |
| 38991 | 147 | declare [[ sledgehammer_problem_prefix = "BT__preorder_bt_map" ]] | 
| 36484 | 148 | |
| 23449 | 149 | lemma preorder_bt_map: "preorder (bt_map f t) = map f (preorder t)" | 
| 36484 | 150 | apply (induct t) | 
| 151 | apply (metis bt_map.simps(1) map.simps(1) preorder.simps(1)) | |
| 152 | by simp | |
| 23449 | 153 | |
| 38991 | 154 | declare [[ sledgehammer_problem_prefix = "BT__inorder_bt_map" ]] | 
| 36484 | 155 | |
| 23449 | 156 | lemma inorder_bt_map: "inorder (bt_map f t) = map f (inorder t)" | 
| 36484 | 157 | proof (induct t) | 
| 158 | case Lf thus ?case | |
| 159 | proof - | |
| 160 | have "map f [] = []" by (metis map.simps(1)) | |
| 161 | hence "map f [] = inorder Lf" by (metis inorder.simps(1)) | |
| 162 | hence "inorder (bt_map f Lf) = map f []" by (metis bt_map.simps(1)) | |
| 163 | thus "inorder (bt_map f Lf) = map f (inorder Lf)" by (metis inorder.simps(1)) | |
| 164 | qed | |
| 165 | next | |
| 166 | case (Br a t1 t2) thus ?case by simp | |
| 167 | qed | |
| 23449 | 168 | |
| 38991 | 169 | declare [[ sledgehammer_problem_prefix = "BT__postorder_bt_map" ]] | 
| 36484 | 170 | |
| 23449 | 171 | lemma postorder_bt_map: "postorder (bt_map f t) = map f (postorder t)" | 
| 36484 | 172 | apply (induct t) | 
| 173 | apply (metis Nil_is_map_conv bt_map.simps(1) postorder.simps(1)) | |
| 174 | by simp | |
| 23449 | 175 | |
| 38991 | 176 | declare [[ sledgehammer_problem_prefix = "BT__depth_bt_map" ]] | 
| 36484 | 177 | |
| 23449 | 178 | lemma depth_bt_map [simp]: "depth (bt_map f t) = depth t" | 
| 36484 | 179 | apply (induct t) | 
| 180 | apply (metis bt_map.simps(1) depth.simps(1)) | |
| 181 | by simp | |
| 23449 | 182 | |
| 38991 | 183 | declare [[ sledgehammer_problem_prefix = "BT__n_leaves_bt_map" ]] | 
| 36484 | 184 | |
| 23449 | 185 | lemma n_leaves_bt_map [simp]: "n_leaves (bt_map f t) = n_leaves t" | 
| 36484 | 186 | apply (induct t) | 
| 187 | apply (metis bt_map.simps(1) n_leaves.simps(1)) | |
| 188 | proof - | |
| 189 | fix a :: 'b and t1 :: "'b bt" and t2 :: "'b bt" | |
| 190 | assume A1: "n_leaves (bt_map f t1) = n_leaves t1" | |
| 191 | assume A2: "n_leaves (bt_map f t2) = n_leaves t2" | |
| 192 | have "\<And>V U. n_leaves (Br U (bt_map f t1) V) = n_leaves t1 + n_leaves V" | |
| 193 | using A1 by (metis n_leaves.simps(2)) | |
| 194 | hence "\<And>V U. n_leaves (bt_map f (Br U t1 V)) = n_leaves t1 + n_leaves (bt_map f V)" | |
| 195 | by (metis bt_map.simps(2)) | |
| 196 | hence F1: "\<And>U. n_leaves (bt_map f (Br U t1 t2)) = n_leaves t1 + n_leaves t2" | |
| 197 | using A2 by metis | |
| 198 | have "n_leaves t1 + n_leaves t2 = n_leaves (Br a t1 t2)" | |
| 199 | by (metis n_leaves.simps(2)) | |
| 200 | thus "n_leaves (bt_map f (Br a t1 t2)) = n_leaves (Br a t1 t2)" | |
| 201 | using F1 by metis | |
| 202 | qed | |
| 23449 | 203 | |
| 38991 | 204 | declare [[ sledgehammer_problem_prefix = "BT__preorder_reflect" ]] | 
| 36484 | 205 | |
| 23449 | 206 | lemma preorder_reflect: "preorder (reflect t) = rev (postorder t)" | 
| 36484 | 207 | apply (induct t) | 
| 208 | apply (metis Nil_is_rev_conv postorder.simps(1) preorder.simps(1) | |
| 209 | reflect.simps(1)) | |
| 39246 | 210 | apply simp | 
| 211 | done | |
| 23449 | 212 | |
| 38991 | 213 | declare [[ sledgehammer_problem_prefix = "BT__inorder_reflect" ]] | 
| 36484 | 214 | |
| 23449 | 215 | lemma inorder_reflect: "inorder (reflect t) = rev (inorder t)" | 
| 36484 | 216 | apply (induct t) | 
| 217 | apply (metis Nil_is_rev_conv inorder.simps(1) reflect.simps(1)) | |
| 218 | by simp | |
| 219 | (* Slow: | |
| 220 | by (metis append.simps(1) append_eq_append_conv2 inorder.simps(2) | |
| 221 | reflect.simps(2) rev.simps(2) rev_append) | |
| 222 | *) | |
| 23449 | 223 | |
| 38991 | 224 | declare [[ sledgehammer_problem_prefix = "BT__postorder_reflect" ]] | 
| 36484 | 225 | |
| 23449 | 226 | lemma postorder_reflect: "postorder (reflect t) = rev (preorder t)" | 
| 36484 | 227 | apply (induct t) | 
| 228 | apply (metis Nil_is_rev_conv postorder.simps(1) preorder.simps(1) | |
| 229 | reflect.simps(1)) | |
| 230 | by (metis preorder_reflect reflect_reflect_ident rev_swap) | |
| 23449 | 231 | |
| 232 | text {*
 | |
| 36484 | 233 | Analogues of the standard properties of the append function for lists. | 
| 23449 | 234 | *} | 
| 235 | ||
| 39246 | 236 | declare [[ sledgehammer_problem_prefix = "BT__append_assoc" ]] | 
| 36484 | 237 | |
| 39246 | 238 | lemma append_assoc [simp]: "append (append t1 t2) t3 = append t1 (append t2 t3)" | 
| 36484 | 239 | apply (induct t1) | 
| 39246 | 240 | apply (metis append.simps(1)) | 
| 241 | by (metis append.simps(2)) | |
| 23449 | 242 | |
| 39246 | 243 | declare [[ sledgehammer_problem_prefix = "BT__append_Lf2" ]] | 
| 36484 | 244 | |
| 39246 | 245 | lemma append_Lf2 [simp]: "append t Lf = t" | 
| 36484 | 246 | apply (induct t) | 
| 39246 | 247 | apply (metis append.simps(1)) | 
| 248 | by (metis append.simps(2)) | |
| 36484 | 249 | |
| 250 | declare max_add_distrib_left [simp] | |
| 23449 | 251 | |
| 39246 | 252 | declare [[ sledgehammer_problem_prefix = "BT__depth_append" ]] | 
| 36484 | 253 | |
| 39246 | 254 | lemma depth_append [simp]: "depth (append t1 t2) = depth t1 + depth t2" | 
| 36484 | 255 | apply (induct t1) | 
| 39246 | 256 | apply (metis append.simps(1) depth.simps(1) plus_nat.simps(1)) | 
| 36484 | 257 | by simp | 
| 23449 | 258 | |
| 39246 | 259 | declare [[ sledgehammer_problem_prefix = "BT__n_leaves_append" ]] | 
| 36484 | 260 | |
| 39246 | 261 | lemma n_leaves_append [simp]: | 
| 262 | "n_leaves (append t1 t2) = n_leaves t1 * n_leaves t2" | |
| 36484 | 263 | apply (induct t1) | 
| 39246 | 264 | apply (metis append.simps(1) n_leaves.simps(1) nat_mult_1 plus_nat.simps(1) | 
| 36484 | 265 | semiring_norm(111)) | 
| 266 | by (simp add: left_distrib) | |
| 23449 | 267 | |
| 39246 | 268 | declare [[ sledgehammer_problem_prefix = "BT__bt_map_append" ]] | 
| 36484 | 269 | |
| 39246 | 270 | lemma (*bt_map_append:*) | 
| 271 | "bt_map f (append t1 t2) = append (bt_map f t1) (bt_map f t2)" | |
| 36484 | 272 | apply (induct t1) | 
| 39246 | 273 | apply (metis append.simps(1) bt_map.simps(1)) | 
| 274 | by (metis bt_map_append) | |
| 23449 | 275 | |
| 276 | end |