src/HOL/Library/Extended_Nat.thy
changeset 43921 e8511be08ddd
parent 43919 a7e4fb1a0502
child 43922 c6f35921056e
equal deleted inserted replaced
43920:cedb5cb948fd 43921:e8511be08ddd
     7 
     7 
     8 theory Extended_Nat
     8 theory Extended_Nat
     9 imports Main
     9 imports Main
    10 begin
    10 begin
    11 
    11 
       
    12 class infinity =
       
    13   fixes infinity :: "'a"
       
    14 
       
    15 notation (xsymbols)
       
    16   infinity  ("\<infinity>")
       
    17 
       
    18 notation (HTML output)
       
    19   infinity  ("\<infinity>")
       
    20 
    12 subsection {* Type definition *}
    21 subsection {* Type definition *}
    13 
    22 
    14 text {*
    23 text {*
    15   We extend the standard natural numbers by a special value indicating
    24   We extend the standard natural numbers by a special value indicating
    16   infinity.
    25   infinity.
    17 *}
    26 *}
    18 
    27 
    19 datatype enat = Fin nat | Infty
    28 typedef (open) enat = "UNIV :: nat option set" ..
    20 
    29  
    21 notation (xsymbols)
    30 definition Fin :: "nat \<Rightarrow> enat" where
    22   Infty  ("\<infinity>")
    31   "Fin n = Abs_enat (Some n)"
    23 
    32  
    24 notation (HTML output)
    33 instantiation enat :: infinity
    25   Infty  ("\<infinity>")
    34 begin
    26 
    35   definition "\<infinity> = Abs_enat None"
    27 
    36   instance proof qed
    28 lemma not_Infty_eq[iff]: "(x ~= Infty) = (EX i. x = Fin i)"
    37 end
       
    38  
       
    39 rep_datatype Fin "\<infinity> :: enat"
       
    40 proof -
       
    41   fix P i assume "\<And>j. P (Fin j)" "P \<infinity>"
       
    42   then show "P i"
       
    43   proof induct
       
    44     case (Abs_enat y) then show ?case
       
    45       by (cases y rule: option.exhaust)
       
    46          (auto simp: Fin_def infinity_enat_def)
       
    47   qed
       
    48 qed (auto simp add: Fin_def infinity_enat_def Abs_enat_inject)
       
    49 
       
    50 declare [[coercion "Fin :: nat \<Rightarrow> enat"]]
       
    51 
       
    52 lemma not_Infty_eq[iff]: "(x \<noteq> \<infinity>) = (EX i. x = Fin i)"
    29 by (cases x) auto
    53 by (cases x) auto
    30 
    54 
    31 lemma not_Fin_eq [iff]: "(ALL y. x ~= Fin y) = (x = Infty)"
    55 lemma not_Fin_eq [iff]: "(ALL y. x ~= Fin y) = (x = \<infinity>)"
    32 by (cases x) auto
    56 by (cases x) auto
    33 
       
    34 
    57 
    35 primrec the_Fin :: "enat \<Rightarrow> nat"
    58 primrec the_Fin :: "enat \<Rightarrow> nat"
    36 where "the_Fin (Fin n) = n"
    59 where "the_Fin (Fin n) = n"
    37 
    60 
    38 
       
    39 subsection {* Constructors and numbers *}
    61 subsection {* Constructors and numbers *}
    40 
    62 
    41 instantiation enat :: "{zero, one, number}"
    63 instantiation enat :: "{zero, one, number}"
    42 begin
    64 begin
    43 
    65 
    67   by (simp add: number_of_enat_def)
    89   by (simp add: number_of_enat_def)
    68 
    90 
    69 lemma one_iSuc: "1 = iSuc 0"
    91 lemma one_iSuc: "1 = iSuc 0"
    70   by (simp add: zero_enat_def one_enat_def iSuc_def)
    92   by (simp add: zero_enat_def one_enat_def iSuc_def)
    71 
    93 
    72 lemma Infty_ne_i0 [simp]: "\<infinity> \<noteq> 0"
    94 lemma Infty_ne_i0 [simp]: "(\<infinity>::enat) \<noteq> 0"
    73   by (simp add: zero_enat_def)
    95   by (simp add: zero_enat_def)
    74 
    96 
    75 lemma i0_ne_Infty [simp]: "0 \<noteq> \<infinity>"
    97 lemma i0_ne_Infty [simp]: "0 \<noteq> (\<infinity>::enat)"
    76   by (simp add: zero_enat_def)
    98   by (simp add: zero_enat_def)
    77 
    99 
    78 lemma zero_enat_eq [simp]:
   100 lemma zero_enat_eq [simp]:
    79   "number_of k = (0\<Colon>enat) \<longleftrightarrow> number_of k = (0\<Colon>nat)"
   101   "number_of k = (0\<Colon>enat) \<longleftrightarrow> number_of k = (0\<Colon>nat)"
    80   "(0\<Colon>enat) = number_of k \<longleftrightarrow> number_of k = (0\<Colon>nat)"
   102   "(0\<Colon>enat) = number_of k \<longleftrightarrow> number_of k = (0\<Colon>nat)"
    88 lemma zero_one_enat_neq [simp]:
   110 lemma zero_one_enat_neq [simp]:
    89   "\<not> 0 = (1\<Colon>enat)"
   111   "\<not> 0 = (1\<Colon>enat)"
    90   "\<not> 1 = (0\<Colon>enat)"
   112   "\<not> 1 = (0\<Colon>enat)"
    91   unfolding zero_enat_def one_enat_def by simp_all
   113   unfolding zero_enat_def one_enat_def by simp_all
    92 
   114 
    93 lemma Infty_ne_i1 [simp]: "\<infinity> \<noteq> 1"
   115 lemma Infty_ne_i1 [simp]: "(\<infinity>::enat) \<noteq> 1"
    94   by (simp add: one_enat_def)
   116   by (simp add: one_enat_def)
    95 
   117 
    96 lemma i1_ne_Infty [simp]: "1 \<noteq> \<infinity>"
   118 lemma i1_ne_Infty [simp]: "1 \<noteq> (\<infinity>::enat)"
    97   by (simp add: one_enat_def)
   119   by (simp add: one_enat_def)
    98 
   120 
    99 lemma Infty_ne_number [simp]: "\<infinity> \<noteq> number_of k"
   121 lemma Infty_ne_number [simp]: "(\<infinity>::enat) \<noteq> number_of k"
   100   by (simp add: number_of_enat_def)
   122   by (simp add: number_of_enat_def)
   101 
   123 
   102 lemma number_ne_Infty [simp]: "number_of k \<noteq> \<infinity>"
   124 lemma number_ne_Infty [simp]: "number_of k \<noteq> (\<infinity>::enat)"
   103   by (simp add: number_of_enat_def)
   125   by (simp add: number_of_enat_def)
   104 
   126 
   105 lemma iSuc_Fin: "iSuc (Fin n) = Fin (Suc n)"
   127 lemma iSuc_Fin: "iSuc (Fin n) = Fin (Suc n)"
   106   by (simp add: iSuc_def)
   128   by (simp add: iSuc_def)
   107 
   129 
   132 
   154 
   133 definition [nitpick_simp]:
   155 definition [nitpick_simp]:
   134   "m + n = (case m of \<infinity> \<Rightarrow> \<infinity> | Fin m \<Rightarrow> (case n of \<infinity> \<Rightarrow> \<infinity> | Fin n \<Rightarrow> Fin (m + n)))"
   156   "m + n = (case m of \<infinity> \<Rightarrow> \<infinity> | Fin m \<Rightarrow> (case n of \<infinity> \<Rightarrow> \<infinity> | Fin n \<Rightarrow> Fin (m + n)))"
   135 
   157 
   136 lemma plus_enat_simps [simp, code]:
   158 lemma plus_enat_simps [simp, code]:
   137   "Fin m + Fin n = Fin (m + n)"
   159   fixes q :: enat
   138   "\<infinity> + q = \<infinity>"
   160   shows "Fin m + Fin n = Fin (m + n)"
   139   "q + \<infinity> = \<infinity>"
   161     and "\<infinity> + q = \<infinity>"
       
   162     and "q + \<infinity> = \<infinity>"
   140   by (simp_all add: plus_enat_def split: enat.splits)
   163   by (simp_all add: plus_enat_def split: enat.splits)
   141 
   164 
   142 instance proof
   165 instance proof
   143   fix n m q :: enat
   166   fix n m q :: enat
   144   show "n + m + q = n + (m + q)"
   167   show "n + m + q = n + (m + q)"
   193   "m * n = (case m of \<infinity> \<Rightarrow> if n = 0 then 0 else \<infinity> | Fin m \<Rightarrow>
   216   "m * n = (case m of \<infinity> \<Rightarrow> if n = 0 then 0 else \<infinity> | Fin m \<Rightarrow>
   194     (case n of \<infinity> \<Rightarrow> if m = 0 then 0 else \<infinity> | Fin n \<Rightarrow> Fin (m * n)))"
   217     (case n of \<infinity> \<Rightarrow> if m = 0 then 0 else \<infinity> | Fin n \<Rightarrow> Fin (m * n)))"
   195 
   218 
   196 lemma times_enat_simps [simp, code]:
   219 lemma times_enat_simps [simp, code]:
   197   "Fin m * Fin n = Fin (m * n)"
   220   "Fin m * Fin n = Fin (m * n)"
   198   "\<infinity> * \<infinity> = \<infinity>"
   221   "\<infinity> * \<infinity> = (\<infinity>::enat)"
   199   "\<infinity> * Fin n = (if n = 0 then 0 else \<infinity>)"
   222   "\<infinity> * Fin n = (if n = 0 then 0 else \<infinity>)"
   200   "Fin m * \<infinity> = (if m = 0 then 0 else \<infinity>)"
   223   "Fin m * \<infinity> = (if m = 0 then 0 else \<infinity>)"
   201   unfolding times_enat_def zero_enat_def
   224   unfolding times_enat_def zero_enat_def
   202   by (simp_all split: enat.split)
   225   by (simp_all split: enat.split)
   203 
   226 
   272 end
   295 end
   273 
   296 
   274 lemma idiff_Fin_Fin[simp,code]: "Fin a - Fin b = Fin (a - b)"
   297 lemma idiff_Fin_Fin[simp,code]: "Fin a - Fin b = Fin (a - b)"
   275 by(simp add: diff_enat_def)
   298 by(simp add: diff_enat_def)
   276 
   299 
   277 lemma idiff_Infty[simp,code]: "\<infinity> - n = \<infinity>"
   300 lemma idiff_Infty[simp,code]: "\<infinity> - n = (\<infinity>::enat)"
   278 by(simp add: diff_enat_def)
   301 by(simp add: diff_enat_def)
   279 
   302 
   280 lemma idiff_Infty_right[simp,code]: "Fin a - \<infinity> = 0"
   303 lemma idiff_Infty_right[simp,code]: "Fin a - \<infinity> = 0"
   281 by(simp add: diff_enat_def)
   304 by(simp add: diff_enat_def)
   282 
   305 
   298 
   321 
   299 lemma iSuc_minus_1 [simp]: "iSuc n - 1 = n"
   322 lemma iSuc_minus_1 [simp]: "iSuc n - 1 = n"
   300 by(simp add: one_enat_def iSuc_Fin[symmetric] zero_enat_def[symmetric])
   323 by(simp add: one_enat_def iSuc_Fin[symmetric] zero_enat_def[symmetric])
   301 
   324 
   302 (*lemmas idiff_self_eq_0_Fin = idiff_self_eq_0[unfolded zero_enat_def]*)
   325 (*lemmas idiff_self_eq_0_Fin = idiff_self_eq_0[unfolded zero_enat_def]*)
   303 
       
   304 
   326 
   305 subsection {* Ordering *}
   327 subsection {* Ordering *}
   306 
   328 
   307 instantiation enat :: linordered_ab_semigroup_add
   329 instantiation enat :: linordered_ab_semigroup_add
   308 begin
   330 begin
   316     | \<infinity> \<Rightarrow> False)"
   338     | \<infinity> \<Rightarrow> False)"
   317 
   339 
   318 lemma enat_ord_simps [simp]:
   340 lemma enat_ord_simps [simp]:
   319   "Fin m \<le> Fin n \<longleftrightarrow> m \<le> n"
   341   "Fin m \<le> Fin n \<longleftrightarrow> m \<le> n"
   320   "Fin m < Fin n \<longleftrightarrow> m < n"
   342   "Fin m < Fin n \<longleftrightarrow> m < n"
   321   "q \<le> \<infinity>"
   343   "q \<le> (\<infinity>::enat)"
   322   "q < \<infinity> \<longleftrightarrow> q \<noteq> \<infinity>"
   344   "q < (\<infinity>::enat) \<longleftrightarrow> q \<noteq> \<infinity>"
   323   "\<infinity> \<le> q \<longleftrightarrow> q = \<infinity>"
   345   "(\<infinity>::enat) \<le> q \<longleftrightarrow> q = \<infinity>"
   324   "\<infinity> < q \<longleftrightarrow> False"
   346   "(\<infinity>::enat) < q \<longleftrightarrow> False"
   325   by (simp_all add: less_eq_enat_def less_enat_def split: enat.splits)
   347   by (simp_all add: less_eq_enat_def less_enat_def split: enat.splits)
   326 
   348 
   327 lemma enat_ord_code [code]:
   349 lemma enat_ord_code [code]:
   328   "Fin m \<le> Fin n \<longleftrightarrow> m \<le> n"
   350   "Fin m \<le> Fin n \<longleftrightarrow> m \<le> n"
   329   "Fin m < Fin n \<longleftrightarrow> m < n"
   351   "Fin m < Fin n \<longleftrightarrow> m < n"
   330   "q \<le> \<infinity> \<longleftrightarrow> True"
   352   "q \<le> (\<infinity>::enat) \<longleftrightarrow> True"
   331   "Fin m < \<infinity> \<longleftrightarrow> True"
   353   "Fin m < \<infinity> \<longleftrightarrow> True"
   332   "\<infinity> \<le> Fin n \<longleftrightarrow> False"
   354   "\<infinity> \<le> Fin n \<longleftrightarrow> False"
   333   "\<infinity> < q \<longleftrightarrow> False"
   355   "(\<infinity>::enat) < q \<longleftrightarrow> False"
   334   by simp_all
   356   by simp_all
   335 
   357 
   336 instance by default
   358 instance by default
   337   (auto simp add: less_eq_enat_def less_enat_def plus_enat_def split: enat.splits)
   359   (auto simp add: less_eq_enat_def less_enat_def plus_enat_def split: enat.splits)
   338 
   360 
   412 
   434 
   413 lemma min_enat_simps [simp]:
   435 lemma min_enat_simps [simp]:
   414   "min (Fin m) (Fin n) = Fin (min m n)"
   436   "min (Fin m) (Fin n) = Fin (min m n)"
   415   "min q 0 = 0"
   437   "min q 0 = 0"
   416   "min 0 q = 0"
   438   "min 0 q = 0"
   417   "min q \<infinity> = q"
   439   "min q (\<infinity>::enat) = q"
   418   "min \<infinity> q = q"
   440   "min (\<infinity>::enat) q = q"
   419   by (auto simp add: min_def)
   441   by (auto simp add: min_def)
   420 
   442 
   421 lemma max_enat_simps [simp]:
   443 lemma max_enat_simps [simp]:
   422   "max (Fin m) (Fin n) = Fin (max m n)"
   444   "max (Fin m) (Fin n) = Fin (max m n)"
   423   "max q 0 = q"
   445   "max q 0 = q"
   424   "max 0 q = q"
   446   "max 0 q = q"
   425   "max q \<infinity> = \<infinity>"
   447   "max q \<infinity> = (\<infinity>::enat)"
   426   "max \<infinity> q = \<infinity>"
   448   "max \<infinity> q = (\<infinity>::enat)"
   427   by (simp_all add: max_def)
   449   by (simp_all add: max_def)
   428 
   450 
   429 lemma Fin_ile: "n \<le> Fin m \<Longrightarrow> \<exists>k. n = Fin k"
   451 lemma Fin_ile: "n \<le> Fin m \<Longrightarrow> \<exists>k. n = Fin k"
   430   by (cases n) simp_all
   452   by (cases n) simp_all
   431 
   453 
   477 lemma less_FinE:
   499 lemma less_FinE:
   478   "[| n < Fin m; !!k. n = Fin k ==> k < m ==> P |] ==> P"
   500   "[| n < Fin m; !!k. n = Fin k ==> k < m ==> P |] ==> P"
   479 by (induct n) auto
   501 by (induct n) auto
   480 
   502 
   481 lemma less_InftyE:
   503 lemma less_InftyE:
   482   "[| n < Infty; !!k. n = Fin k ==> P |] ==> P"
   504   "[| n < \<infinity>; !!k. n = Fin k ==> P |] ==> P"
   483 by (induct n) auto
   505 by (induct n) auto
   484 
   506 
   485 lemma enat_less_induct:
   507 lemma enat_less_induct:
   486   assumes prem: "!!n. \<forall>m::enat. m < n --> P m ==> P n" shows "P n"
   508   assumes prem: "!!n. \<forall>m::enat. m < n --> P m ==> P n" shows "P n"
   487 proof -
   509 proof -
   493   show ?thesis
   515   show ?thesis
   494   proof (induct n)
   516   proof (induct n)
   495     fix nat
   517     fix nat
   496     show "P (Fin nat)" by (rule P_Fin)
   518     show "P (Fin nat)" by (rule P_Fin)
   497   next
   519   next
   498     show "P Infty"
   520     show "P \<infinity>"
   499       apply (rule prem, clarify)
   521       apply (rule prem, clarify)
   500       apply (erule less_InftyE)
   522       apply (erule less_InftyE)
   501       apply (simp add: P_Fin)
   523       apply (simp add: P_Fin)
   502       done
   524       done
   503   qed
   525   qed