src/HOL/Library/Nat_Bijection.thy
 author haftmann Fri Mar 22 19:18:08 2019 +0000 (3 months ago) changeset 69946 494934c30f38 parent 69593 3dda49e08b9d permissions -rw-r--r--
improved code equations taken over from AFP
 wenzelm@41959 ` 1` ```(* Title: HOL/Library/Nat_Bijection.thy ``` huffman@35700 ` 2` ``` Author: Brian Huffman ``` huffman@35700 ` 3` ``` Author: Florian Haftmann ``` huffman@35700 ` 4` ``` Author: Stefan Richter ``` huffman@35700 ` 5` ``` Author: Tobias Nipkow ``` huffman@35700 ` 6` ``` Author: Alexander Krauss ``` huffman@35700 ` 7` ```*) ``` huffman@35700 ` 8` wenzelm@60500 ` 9` ```section \Bijections between natural numbers and other types\ ``` huffman@35700 ` 10` huffman@35700 ` 11` ```theory Nat_Bijection ``` wenzelm@63625 ` 12` ``` imports Main ``` huffman@35700 ` 13` ```begin ``` huffman@35700 ` 14` wenzelm@69593 ` 15` ```subsection \Type \<^typ>\nat \ nat\\ ``` huffman@35700 ` 16` wenzelm@63625 ` 17` ```text \Triangle numbers: 0, 1, 3, 6, 10, 15, ...\ ``` huffman@35700 ` 18` wenzelm@62046 ` 19` ```definition triangle :: "nat \ nat" ``` wenzelm@62046 ` 20` ``` where "triangle n = (n * Suc n) div 2" ``` huffman@35700 ` 21` huffman@35700 ` 22` ```lemma triangle_0 [simp]: "triangle 0 = 0" ``` wenzelm@63625 ` 23` ``` by (simp add: triangle_def) ``` huffman@35700 ` 24` huffman@35700 ` 25` ```lemma triangle_Suc [simp]: "triangle (Suc n) = triangle n + Suc n" ``` wenzelm@63625 ` 26` ``` by (simp add: triangle_def) ``` huffman@35700 ` 27` wenzelm@62046 ` 28` ```definition prod_encode :: "nat \ nat \ nat" ``` wenzelm@62046 ` 29` ``` where "prod_encode = (\(m, n). triangle (m + n) + m)" ``` huffman@35700 ` 30` wenzelm@69593 ` 31` ```text \In this auxiliary function, \<^term>\triangle k + m\ is an invariant.\ ``` huffman@35700 ` 32` wenzelm@62046 ` 33` ```fun prod_decode_aux :: "nat \ nat \ nat \ nat" ``` wenzelm@63625 ` 34` ``` where "prod_decode_aux k m = ``` huffman@35700 ` 35` ``` (if m \ k then (m, k - m) else prod_decode_aux (Suc k) (m - Suc k))" ``` huffman@35700 ` 36` huffman@35700 ` 37` ```declare prod_decode_aux.simps [simp del] ``` huffman@35700 ` 38` wenzelm@62046 ` 39` ```definition prod_decode :: "nat \ nat \ nat" ``` wenzelm@62046 ` 40` ``` where "prod_decode = prod_decode_aux 0" ``` huffman@35700 ` 41` wenzelm@63625 ` 42` ```lemma prod_encode_prod_decode_aux: "prod_encode (prod_decode_aux k m) = triangle k + m" ``` wenzelm@63625 ` 43` ``` apply (induct k m rule: prod_decode_aux.induct) ``` wenzelm@63625 ` 44` ``` apply (subst prod_decode_aux.simps) ``` wenzelm@63625 ` 45` ``` apply (simp add: prod_encode_def) ``` wenzelm@63625 ` 46` ``` done ``` huffman@35700 ` 47` huffman@35700 ` 48` ```lemma prod_decode_inverse [simp]: "prod_encode (prod_decode n) = n" ``` wenzelm@63625 ` 49` ``` by (simp add: prod_decode_def prod_encode_prod_decode_aux) ``` huffman@35700 ` 50` wenzelm@62046 ` 51` ```lemma prod_decode_triangle_add: "prod_decode (triangle k + m) = prod_decode_aux k m" ``` wenzelm@63625 ` 52` ``` apply (induct k arbitrary: m) ``` wenzelm@63625 ` 53` ``` apply (simp add: prod_decode_def) ``` wenzelm@63625 ` 54` ``` apply (simp only: triangle_Suc add.assoc) ``` wenzelm@63625 ` 55` ``` apply (subst prod_decode_aux.simps) ``` wenzelm@63625 ` 56` ``` apply simp ``` wenzelm@63625 ` 57` ``` done ``` huffman@35700 ` 58` huffman@35700 ` 59` ```lemma prod_encode_inverse [simp]: "prod_decode (prod_encode x) = x" ``` wenzelm@63625 ` 60` ``` unfolding prod_encode_def ``` wenzelm@63625 ` 61` ``` apply (induct x) ``` wenzelm@63625 ` 62` ``` apply (simp add: prod_decode_triangle_add) ``` wenzelm@63625 ` 63` ``` apply (subst prod_decode_aux.simps) ``` wenzelm@63625 ` 64` ``` apply simp ``` wenzelm@63625 ` 65` ``` done ``` huffman@35700 ` 66` huffman@35700 ` 67` ```lemma inj_prod_encode: "inj_on prod_encode A" ``` wenzelm@63625 ` 68` ``` by (rule inj_on_inverseI) (rule prod_encode_inverse) ``` huffman@35700 ` 69` huffman@35700 ` 70` ```lemma inj_prod_decode: "inj_on prod_decode A" ``` wenzelm@63625 ` 71` ``` by (rule inj_on_inverseI) (rule prod_decode_inverse) ``` huffman@35700 ` 72` huffman@35700 ` 73` ```lemma surj_prod_encode: "surj prod_encode" ``` wenzelm@63625 ` 74` ``` by (rule surjI) (rule prod_decode_inverse) ``` huffman@35700 ` 75` huffman@35700 ` 76` ```lemma surj_prod_decode: "surj prod_decode" ``` wenzelm@63625 ` 77` ``` by (rule surjI) (rule prod_encode_inverse) ``` huffman@35700 ` 78` huffman@35700 ` 79` ```lemma bij_prod_encode: "bij prod_encode" ``` wenzelm@63625 ` 80` ``` by (rule bijI [OF inj_prod_encode surj_prod_encode]) ``` huffman@35700 ` 81` huffman@35700 ` 82` ```lemma bij_prod_decode: "bij prod_decode" ``` wenzelm@63625 ` 83` ``` by (rule bijI [OF inj_prod_decode surj_prod_decode]) ``` huffman@35700 ` 84` huffman@35700 ` 85` ```lemma prod_encode_eq: "prod_encode x = prod_encode y \ x = y" ``` wenzelm@63625 ` 86` ``` by (rule inj_prod_encode [THEN inj_eq]) ``` huffman@35700 ` 87` huffman@35700 ` 88` ```lemma prod_decode_eq: "prod_decode x = prod_decode y \ x = y" ``` wenzelm@63625 ` 89` ``` by (rule inj_prod_decode [THEN inj_eq]) ``` huffman@35700 ` 90` wenzelm@62046 ` 91` wenzelm@60500 ` 92` ```text \Ordering properties\ ``` huffman@35700 ` 93` huffman@35700 ` 94` ```lemma le_prod_encode_1: "a \ prod_encode (a, b)" ``` wenzelm@63625 ` 95` ``` by (simp add: prod_encode_def) ``` huffman@35700 ` 96` huffman@35700 ` 97` ```lemma le_prod_encode_2: "b \ prod_encode (a, b)" ``` wenzelm@63625 ` 98` ``` by (induct b) (simp_all add: prod_encode_def) ``` huffman@35700 ` 99` huffman@35700 ` 100` wenzelm@69593 ` 101` ```subsection \Type \<^typ>\nat + nat\\ ``` huffman@35700 ` 102` wenzelm@62046 ` 103` ```definition sum_encode :: "nat + nat \ nat" ``` wenzelm@63625 ` 104` ``` where "sum_encode x = (case x of Inl a \ 2 * a | Inr b \ Suc (2 * b))" ``` huffman@35700 ` 105` wenzelm@62046 ` 106` ```definition sum_decode :: "nat \ nat + nat" ``` wenzelm@63625 ` 107` ``` where "sum_decode n = (if even n then Inl (n div 2) else Inr (n div 2))" ``` huffman@35700 ` 108` huffman@35700 ` 109` ```lemma sum_encode_inverse [simp]: "sum_decode (sum_encode x) = x" ``` wenzelm@63625 ` 110` ``` by (induct x) (simp_all add: sum_decode_def sum_encode_def) ``` huffman@35700 ` 111` huffman@35700 ` 112` ```lemma sum_decode_inverse [simp]: "sum_encode (sum_decode n) = n" ``` haftmann@58834 ` 113` ``` by (simp add: even_two_times_div_two sum_decode_def sum_encode_def) ``` huffman@35700 ` 114` huffman@35700 ` 115` ```lemma inj_sum_encode: "inj_on sum_encode A" ``` wenzelm@63625 ` 116` ``` by (rule inj_on_inverseI) (rule sum_encode_inverse) ``` huffman@35700 ` 117` huffman@35700 ` 118` ```lemma inj_sum_decode: "inj_on sum_decode A" ``` wenzelm@63625 ` 119` ``` by (rule inj_on_inverseI) (rule sum_decode_inverse) ``` huffman@35700 ` 120` huffman@35700 ` 121` ```lemma surj_sum_encode: "surj sum_encode" ``` wenzelm@63625 ` 122` ``` by (rule surjI) (rule sum_decode_inverse) ``` huffman@35700 ` 123` huffman@35700 ` 124` ```lemma surj_sum_decode: "surj sum_decode" ``` wenzelm@63625 ` 125` ``` by (rule surjI) (rule sum_encode_inverse) ``` huffman@35700 ` 126` huffman@35700 ` 127` ```lemma bij_sum_encode: "bij sum_encode" ``` wenzelm@63625 ` 128` ``` by (rule bijI [OF inj_sum_encode surj_sum_encode]) ``` huffman@35700 ` 129` huffman@35700 ` 130` ```lemma bij_sum_decode: "bij sum_decode" ``` wenzelm@63625 ` 131` ``` by (rule bijI [OF inj_sum_decode surj_sum_decode]) ``` huffman@35700 ` 132` huffman@35700 ` 133` ```lemma sum_encode_eq: "sum_encode x = sum_encode y \ x = y" ``` wenzelm@63625 ` 134` ``` by (rule inj_sum_encode [THEN inj_eq]) ``` huffman@35700 ` 135` huffman@35700 ` 136` ```lemma sum_decode_eq: "sum_decode x = sum_decode y \ x = y" ``` wenzelm@63625 ` 137` ``` by (rule inj_sum_decode [THEN inj_eq]) ``` huffman@35700 ` 138` huffman@35700 ` 139` wenzelm@69593 ` 140` ```subsection \Type \<^typ>\int\\ ``` huffman@35700 ` 141` wenzelm@62046 ` 142` ```definition int_encode :: "int \ nat" ``` wenzelm@63625 ` 143` ``` where "int_encode i = sum_encode (if 0 \ i then Inl (nat i) else Inr (nat (- i - 1)))" ``` huffman@35700 ` 144` wenzelm@62046 ` 145` ```definition int_decode :: "nat \ int" ``` wenzelm@63625 ` 146` ``` where "int_decode n = (case sum_decode n of Inl a \ int a | Inr b \ - int b - 1)" ``` huffman@35700 ` 147` huffman@35700 ` 148` ```lemma int_encode_inverse [simp]: "int_decode (int_encode x) = x" ``` wenzelm@63625 ` 149` ``` by (simp add: int_decode_def int_encode_def) ``` huffman@35700 ` 150` huffman@35700 ` 151` ```lemma int_decode_inverse [simp]: "int_encode (int_decode n) = n" ``` wenzelm@63625 ` 152` ``` unfolding int_decode_def int_encode_def ``` wenzelm@63625 ` 153` ``` using sum_decode_inverse [of n] by (cases "sum_decode n") simp_all ``` huffman@35700 ` 154` huffman@35700 ` 155` ```lemma inj_int_encode: "inj_on int_encode A" ``` wenzelm@63625 ` 156` ``` by (rule inj_on_inverseI) (rule int_encode_inverse) ``` huffman@35700 ` 157` huffman@35700 ` 158` ```lemma inj_int_decode: "inj_on int_decode A" ``` wenzelm@63625 ` 159` ``` by (rule inj_on_inverseI) (rule int_decode_inverse) ``` huffman@35700 ` 160` huffman@35700 ` 161` ```lemma surj_int_encode: "surj int_encode" ``` wenzelm@63625 ` 162` ``` by (rule surjI) (rule int_decode_inverse) ``` huffman@35700 ` 163` huffman@35700 ` 164` ```lemma surj_int_decode: "surj int_decode" ``` wenzelm@63625 ` 165` ``` by (rule surjI) (rule int_encode_inverse) ``` huffman@35700 ` 166` huffman@35700 ` 167` ```lemma bij_int_encode: "bij int_encode" ``` wenzelm@63625 ` 168` ``` by (rule bijI [OF inj_int_encode surj_int_encode]) ``` huffman@35700 ` 169` huffman@35700 ` 170` ```lemma bij_int_decode: "bij int_decode" ``` wenzelm@63625 ` 171` ``` by (rule bijI [OF inj_int_decode surj_int_decode]) ``` huffman@35700 ` 172` huffman@35700 ` 173` ```lemma int_encode_eq: "int_encode x = int_encode y \ x = y" ``` wenzelm@63625 ` 174` ``` by (rule inj_int_encode [THEN inj_eq]) ``` huffman@35700 ` 175` huffman@35700 ` 176` ```lemma int_decode_eq: "int_decode x = int_decode y \ x = y" ``` wenzelm@63625 ` 177` ``` by (rule inj_int_decode [THEN inj_eq]) ``` huffman@35700 ` 178` huffman@35700 ` 179` wenzelm@69593 ` 180` ```subsection \Type \<^typ>\nat list\\ ``` huffman@35700 ` 181` wenzelm@62046 ` 182` ```fun list_encode :: "nat list \ nat" ``` wenzelm@63625 ` 183` ``` where ``` wenzelm@63625 ` 184` ``` "list_encode [] = 0" ``` wenzelm@63625 ` 185` ``` | "list_encode (x # xs) = Suc (prod_encode (x, list_encode xs))" ``` huffman@35700 ` 186` wenzelm@62046 ` 187` ```function list_decode :: "nat \ nat list" ``` wenzelm@63625 ` 188` ``` where ``` wenzelm@63625 ` 189` ``` "list_decode 0 = []" ``` wenzelm@63625 ` 190` ``` | "list_decode (Suc n) = (case prod_decode n of (x, y) \ x # list_decode y)" ``` wenzelm@63625 ` 191` ``` by pat_completeness auto ``` huffman@35700 ` 192` huffman@35700 ` 193` ```termination list_decode ``` wenzelm@63625 ` 194` ``` apply (relation "measure id") ``` wenzelm@63625 ` 195` ``` apply simp_all ``` wenzelm@63625 ` 196` ``` apply (drule arg_cong [where f="prod_encode"]) ``` wenzelm@63625 ` 197` ``` apply (drule sym) ``` wenzelm@63625 ` 198` ``` apply (simp add: le_imp_less_Suc le_prod_encode_2) ``` wenzelm@63625 ` 199` ``` done ``` huffman@35700 ` 200` huffman@35700 ` 201` ```lemma list_encode_inverse [simp]: "list_decode (list_encode x) = x" ``` wenzelm@63625 ` 202` ``` by (induct x rule: list_encode.induct) simp_all ``` huffman@35700 ` 203` huffman@35700 ` 204` ```lemma list_decode_inverse [simp]: "list_encode (list_decode n) = n" ``` wenzelm@63625 ` 205` ``` apply (induct n rule: list_decode.induct) ``` wenzelm@63625 ` 206` ``` apply simp ``` wenzelm@63625 ` 207` ``` apply (simp split: prod.split) ``` wenzelm@63625 ` 208` ``` apply (simp add: prod_decode_eq [symmetric]) ``` wenzelm@63625 ` 209` ``` done ``` huffman@35700 ` 210` huffman@35700 ` 211` ```lemma inj_list_encode: "inj_on list_encode A" ``` wenzelm@63625 ` 212` ``` by (rule inj_on_inverseI) (rule list_encode_inverse) ``` huffman@35700 ` 213` huffman@35700 ` 214` ```lemma inj_list_decode: "inj_on list_decode A" ``` wenzelm@63625 ` 215` ``` by (rule inj_on_inverseI) (rule list_decode_inverse) ``` huffman@35700 ` 216` huffman@35700 ` 217` ```lemma surj_list_encode: "surj list_encode" ``` wenzelm@63625 ` 218` ``` by (rule surjI) (rule list_decode_inverse) ``` huffman@35700 ` 219` huffman@35700 ` 220` ```lemma surj_list_decode: "surj list_decode" ``` wenzelm@63625 ` 221` ``` by (rule surjI) (rule list_encode_inverse) ``` huffman@35700 ` 222` huffman@35700 ` 223` ```lemma bij_list_encode: "bij list_encode" ``` wenzelm@63625 ` 224` ``` by (rule bijI [OF inj_list_encode surj_list_encode]) ``` huffman@35700 ` 225` huffman@35700 ` 226` ```lemma bij_list_decode: "bij list_decode" ``` wenzelm@63625 ` 227` ``` by (rule bijI [OF inj_list_decode surj_list_decode]) ``` huffman@35700 ` 228` huffman@35700 ` 229` ```lemma list_encode_eq: "list_encode x = list_encode y \ x = y" ``` wenzelm@63625 ` 230` ``` by (rule inj_list_encode [THEN inj_eq]) ``` huffman@35700 ` 231` huffman@35700 ` 232` ```lemma list_decode_eq: "list_decode x = list_decode y \ x = y" ``` wenzelm@63625 ` 233` ``` by (rule inj_list_decode [THEN inj_eq]) ``` huffman@35700 ` 234` huffman@35700 ` 235` wenzelm@60500 ` 236` ```subsection \Finite sets of naturals\ ``` huffman@35700 ` 237` wenzelm@60500 ` 238` ```subsubsection \Preliminaries\ ``` huffman@35700 ` 239` huffman@35700 ` 240` ```lemma finite_vimage_Suc_iff: "finite (Suc -` F) \ finite F" ``` wenzelm@63625 ` 241` ``` apply (safe intro!: finite_vimageI inj_Suc) ``` wenzelm@63625 ` 242` ``` apply (rule finite_subset [where B="insert 0 (Suc ` Suc -` F)"]) ``` wenzelm@63625 ` 243` ``` apply (rule subsetI) ``` wenzelm@63625 ` 244` ``` apply (case_tac x) ``` wenzelm@63625 ` 245` ``` apply simp ``` wenzelm@63625 ` 246` ``` apply simp ``` wenzelm@63625 ` 247` ``` apply (rule finite_insert [THEN iffD2]) ``` wenzelm@63625 ` 248` ``` apply (erule finite_imageI) ``` wenzelm@63625 ` 249` ``` done ``` huffman@35700 ` 250` huffman@35700 ` 251` ```lemma vimage_Suc_insert_0: "Suc -` insert 0 A = Suc -` A" ``` wenzelm@63625 ` 252` ``` by auto ``` huffman@35700 ` 253` wenzelm@63625 ` 254` ```lemma vimage_Suc_insert_Suc: "Suc -` insert (Suc n) A = insert n (Suc -` A)" ``` wenzelm@63625 ` 255` ``` by auto ``` huffman@35700 ` 256` huffman@35700 ` 257` ```lemma div2_even_ext_nat: ``` haftmann@58834 ` 258` ``` fixes x y :: nat ``` haftmann@58834 ` 259` ``` assumes "x div 2 = y div 2" ``` wenzelm@63625 ` 260` ``` and "even x \ even y" ``` haftmann@58834 ` 261` ``` shows "x = y" ``` haftmann@58834 ` 262` ```proof - ``` wenzelm@60500 ` 263` ``` from \even x \ even y\ have "x mod 2 = y mod 2" ``` haftmann@58834 ` 264` ``` by (simp only: even_iff_mod_2_eq_zero) auto ``` haftmann@58834 ` 265` ``` with assms have "x div 2 * 2 + x mod 2 = y div 2 * 2 + y mod 2" ``` haftmann@58834 ` 266` ``` by simp ``` haftmann@58834 ` 267` ``` then show ?thesis ``` haftmann@58834 ` 268` ``` by simp ``` haftmann@58834 ` 269` ```qed ``` huffman@35700 ` 270` haftmann@58710 ` 271` wenzelm@60500 ` 272` ```subsubsection \From sets to naturals\ ``` huffman@35700 ` 273` wenzelm@62046 ` 274` ```definition set_encode :: "nat set \ nat" ``` nipkow@67399 ` 275` ``` where "set_encode = sum ((^) 2)" ``` huffman@35700 ` 276` huffman@35700 ` 277` ```lemma set_encode_empty [simp]: "set_encode {} = 0" ``` lp15@59506 ` 278` ``` by (simp add: set_encode_def) ``` lp15@59506 ` 279` wenzelm@63625 ` 280` ```lemma set_encode_inf: "\ finite A \ set_encode A = 0" ``` wenzelm@63625 ` 281` ``` by (simp add: set_encode_def) ``` wenzelm@63625 ` 282` wenzelm@63625 ` 283` ```lemma set_encode_insert [simp]: "finite A \ n \ A \ set_encode (insert n A) = 2^n + set_encode A" ``` wenzelm@63625 ` 284` ``` by (simp add: set_encode_def) ``` huffman@35700 ` 285` huffman@35700 ` 286` ```lemma even_set_encode_iff: "finite A \ even (set_encode A) \ 0 \ A" ``` wenzelm@63625 ` 287` ``` by (induct set: finite) (auto simp: set_encode_def) ``` huffman@35700 ` 288` huffman@35700 ` 289` ```lemma set_encode_vimage_Suc: "set_encode (Suc -` A) = set_encode A div 2" ``` wenzelm@63625 ` 290` ``` apply (cases "finite A") ``` wenzelm@63625 ` 291` ``` apply (erule finite_induct) ``` wenzelm@63625 ` 292` ``` apply simp ``` wenzelm@63625 ` 293` ``` apply (case_tac x) ``` wenzelm@63625 ` 294` ``` apply (simp add: even_set_encode_iff vimage_Suc_insert_0) ``` wenzelm@63625 ` 295` ``` apply (simp add: finite_vimageI add.commute vimage_Suc_insert_Suc) ``` wenzelm@63625 ` 296` ``` apply (simp add: set_encode_def finite_vimage_Suc_iff) ``` wenzelm@63625 ` 297` ``` done ``` huffman@35700 ` 298` huffman@35700 ` 299` ```lemmas set_encode_div_2 = set_encode_vimage_Suc [symmetric] ``` huffman@35700 ` 300` wenzelm@62046 ` 301` wenzelm@60500 ` 302` ```subsubsection \From naturals to sets\ ``` huffman@35700 ` 303` wenzelm@62046 ` 304` ```definition set_decode :: "nat \ nat set" ``` wenzelm@62046 ` 305` ``` where "set_decode x = {n. odd (x div 2 ^ n)}" ``` huffman@35700 ` 306` huffman@35700 ` 307` ```lemma set_decode_0 [simp]: "0 \ set_decode x \ odd x" ``` wenzelm@63625 ` 308` ``` by (simp add: set_decode_def) ``` huffman@35700 ` 309` wenzelm@63625 ` 310` ```lemma set_decode_Suc [simp]: "Suc n \ set_decode x \ n \ set_decode (x div 2)" ``` wenzelm@63625 ` 311` ``` by (simp add: set_decode_def div_mult2_eq) ``` huffman@35700 ` 312` huffman@35700 ` 313` ```lemma set_decode_zero [simp]: "set_decode 0 = {}" ``` wenzelm@63625 ` 314` ``` by (simp add: set_decode_def) ``` huffman@35700 ` 315` huffman@35700 ` 316` ```lemma set_decode_div_2: "set_decode (x div 2) = Suc -` set_decode x" ``` wenzelm@63625 ` 317` ``` by auto ``` huffman@35700 ` 318` huffman@35700 ` 319` ```lemma set_decode_plus_power_2: ``` huffman@35700 ` 320` ``` "n \ set_decode z \ set_decode (2 ^ n + z) = insert n (set_decode z)" ``` haftmann@60352 ` 321` ```proof (induct n arbitrary: z) ``` wenzelm@63625 ` 322` ``` case 0 ``` wenzelm@63625 ` 323` ``` show ?case ``` haftmann@60352 ` 324` ``` proof (rule set_eqI) ``` wenzelm@63625 ` 325` ``` show "q \ set_decode (2 ^ 0 + z) \ q \ insert 0 (set_decode z)" for q ``` wenzelm@63625 ` 326` ``` by (induct q) (use 0 in simp_all) ``` haftmann@60352 ` 327` ``` qed ``` haftmann@60352 ` 328` ```next ``` wenzelm@63625 ` 329` ``` case (Suc n) ``` wenzelm@63625 ` 330` ``` show ?case ``` haftmann@60352 ` 331` ``` proof (rule set_eqI) ``` wenzelm@63625 ` 332` ``` show "q \ set_decode (2 ^ Suc n + z) \ q \ insert (Suc n) (set_decode z)" for q ``` wenzelm@63625 ` 333` ``` by (induct q) (use Suc in simp_all) ``` haftmann@60352 ` 334` ``` qed ``` haftmann@60352 ` 335` ```qed ``` huffman@35700 ` 336` huffman@35700 ` 337` ```lemma finite_set_decode [simp]: "finite (set_decode n)" ``` wenzelm@63625 ` 338` ``` apply (induct n rule: nat_less_induct) ``` wenzelm@63625 ` 339` ``` apply (case_tac "n = 0") ``` wenzelm@63625 ` 340` ``` apply simp ``` wenzelm@63625 ` 341` ``` apply (drule_tac x="n div 2" in spec) ``` wenzelm@63625 ` 342` ``` apply simp ``` wenzelm@63625 ` 343` ``` apply (simp add: set_decode_div_2) ``` wenzelm@63625 ` 344` ``` apply (simp add: finite_vimage_Suc_iff) ``` wenzelm@63625 ` 345` ``` done ``` huffman@35700 ` 346` wenzelm@62046 ` 347` wenzelm@60500 ` 348` ```subsubsection \Proof of isomorphism\ ``` huffman@35700 ` 349` huffman@35700 ` 350` ```lemma set_decode_inverse [simp]: "set_encode (set_decode n) = n" ``` wenzelm@63625 ` 351` ``` apply (induct n rule: nat_less_induct) ``` wenzelm@63625 ` 352` ``` apply (case_tac "n = 0") ``` wenzelm@63625 ` 353` ``` apply simp ``` wenzelm@63625 ` 354` ``` apply (drule_tac x="n div 2" in spec) ``` wenzelm@63625 ` 355` ``` apply simp ``` wenzelm@63625 ` 356` ``` apply (simp add: set_decode_div_2 set_encode_vimage_Suc) ``` wenzelm@63625 ` 357` ``` apply (erule div2_even_ext_nat) ``` wenzelm@63625 ` 358` ``` apply (simp add: even_set_encode_iff) ``` wenzelm@63625 ` 359` ``` done ``` huffman@35700 ` 360` huffman@35700 ` 361` ```lemma set_encode_inverse [simp]: "finite A \ set_decode (set_encode A) = A" ``` wenzelm@63625 ` 362` ``` apply (erule finite_induct) ``` wenzelm@63625 ` 363` ``` apply simp_all ``` wenzelm@63625 ` 364` ``` apply (simp add: set_decode_plus_power_2) ``` wenzelm@63625 ` 365` ``` done ``` huffman@35700 ` 366` huffman@35700 ` 367` ```lemma inj_on_set_encode: "inj_on set_encode (Collect finite)" ``` wenzelm@63625 ` 368` ``` by (rule inj_on_inverseI [where g = "set_decode"]) simp ``` huffman@35700 ` 369` wenzelm@63625 ` 370` ```lemma set_encode_eq: "finite A \ finite B \ set_encode A = set_encode B \ A = B" ``` wenzelm@63625 ` 371` ``` by (rule iffI) (simp_all add: inj_onD [OF inj_on_set_encode]) ``` huffman@35700 ` 372` wenzelm@62046 ` 373` ```lemma subset_decode_imp_le: ``` wenzelm@62046 ` 374` ``` assumes "set_decode m \ set_decode n" ``` wenzelm@62046 ` 375` ``` shows "m \ n" ``` paulson@51414 ` 376` ```proof - ``` paulson@51414 ` 377` ``` have "n = m + set_encode (set_decode n - set_decode m)" ``` paulson@51414 ` 378` ``` proof - ``` wenzelm@63625 ` 379` ``` obtain A B where ``` wenzelm@63625 ` 380` ``` "m = set_encode A" "finite A" ``` wenzelm@63625 ` 381` ``` "n = set_encode B" "finite B" ``` paulson@51414 ` 382` ``` by (metis finite_set_decode set_decode_inverse) ``` wenzelm@63625 ` 383` ``` with assms show ?thesis ``` nipkow@64267 ` 384` ``` by auto (simp add: set_encode_def add.commute sum.subset_diff) ``` paulson@51414 ` 385` ``` qed ``` wenzelm@63625 ` 386` ``` then show ?thesis ``` paulson@51414 ` 387` ``` by (metis le_add1) ``` paulson@51414 ` 388` ```qed ``` paulson@51414 ` 389` huffman@35700 ` 390` ```end ```