# HG changeset patch # User haftmann # Date 1213104662 -7200 # Node ID 194aa674c2a168a63e2a899c367afb0f253e91a2 # Parent 779e73b02ccad7a214358dacd1b7118d978e5ff0 refactoring; addition, numerals diff -r 779e73b02cca -r 194aa674c2a1 src/HOL/Library/Nat_Infinity.thy --- a/src/HOL/Library/Nat_Infinity.thy Tue Jun 10 15:31:01 2008 +0200 +++ b/src/HOL/Library/Nat_Infinity.thy Tue Jun 10 15:31:02 2008 +0200 @@ -1,6 +1,6 @@ (* Title: HOL/Library/Nat_Infinity.thy ID: $Id$ - Author: David von Oheimb, TU Muenchen + Author: David von Oheimb, TU Muenchen; Florian Haftmann, TU Muenchen *) header {* Natural numbers with infinity *} @@ -9,12 +9,11 @@ imports ATP_Linkup begin -subsection "Definitions" +subsection {* Type definition *} text {* We extend the standard natural numbers by a special value indicating - infinity. This includes extending the ordering relations @{term "op - <"} and @{term "op \"}. + infinity. *} datatype inat = Fin nat | Infty @@ -25,196 +24,267 @@ notation (HTML output) Infty ("\") -definition - iSuc :: "inat => inat" where - "iSuc i = (case i of Fin n => Fin (Suc n) | \ => \)" -instantiation inat :: "{ord, zero}" +subsection {* Constructors and numbers *} + +instantiation inat :: "{zero, one, number}" begin definition - Zero_inat_def: "0 == Fin 0" + "0 = Fin 0" definition - iless_def: "m < n == - case m of Fin m1 => (case n of Fin n1 => m1 < n1 | \ => True) - | \ => False" + [code inline]: "1 = Fin 1" definition - ile_def: "m \ n == - case n of Fin n1 => (case m of Fin m1 => m1 \ n1 | \ => False) - | \ => True" + [code inline, code func del]: "number_of k = Fin (number_of k)" instance .. end -lemmas inat_defs = Zero_inat_def iSuc_def iless_def ile_def -lemmas inat_splits = inat.split inat.split_asm - -text {* - Below is a not quite complete set of theorems. Use the method - @{text "(simp add: inat_defs split:inat_splits, arith?)"} to prove - new theorems or solve arithmetic subgoals involving @{typ inat} on - the fly. -*} - -subsection "Constructors" +definition iSuc :: "inat \ inat" where + "iSuc i = (case i of Fin n \ Fin (Suc n) | \ \ \)" lemma Fin_0: "Fin 0 = 0" -by (simp add: inat_defs split:inat_splits) + by (simp add: zero_inat_def) + +lemma Fin_1: "Fin 1 = 1" + by (simp add: one_inat_def) + +lemma Fin_number: "Fin (number_of k) = number_of k" + by (simp add: number_of_inat_def) + +lemma one_iSuc: "1 = iSuc 0" + by (simp add: zero_inat_def one_inat_def iSuc_def) lemma Infty_ne_i0 [simp]: "\ \ 0" -by (simp add: inat_defs split:inat_splits) + by (simp add: zero_inat_def) lemma i0_ne_Infty [simp]: "0 \ \" -by (simp add: inat_defs split:inat_splits) + by (simp add: zero_inat_def) + +lemma zero_inat_eq [simp]: + "number_of k = (0\inat) \ number_of k = (0\nat)" + "(0\inat) = number_of k \ number_of k = (0\nat)" + unfolding zero_inat_def number_of_inat_def by simp_all + +lemma one_inat_eq [simp]: + "number_of k = (1\inat) \ number_of k = (1\nat)" + "(1\inat) = number_of k \ number_of k = (1\nat)" + unfolding one_inat_def number_of_inat_def by simp_all + +lemma zero_one_inat_neq [simp]: + "\ 0 = (1\inat)" + "\ 1 = (0\inat)" + unfolding zero_inat_def one_inat_def by simp_all -lemma iSuc_Fin [simp]: "iSuc (Fin n) = Fin (Suc n)" -by (simp add: inat_defs split:inat_splits) +lemma Infty_ne_i1 [simp]: "\ \ 1" + by (simp add: one_inat_def) + +lemma i1_ne_Infty [simp]: "1 \ \" + by (simp add: one_inat_def) + +lemma Infty_ne_number [simp]: "\ \ number_of k" + by (simp add: number_of_inat_def) + +lemma number_ne_Infty [simp]: "number_of k \ \" + by (simp add: number_of_inat_def) + +lemma iSuc_Fin: "iSuc (Fin n) = Fin (Suc n)" + by (simp add: iSuc_def) + +lemma iSuc_number_of: "iSuc (number_of k) = Fin (Suc (number_of k))" + by (simp add: iSuc_Fin number_of_inat_def) lemma iSuc_Infty [simp]: "iSuc \ = \" -by (simp add: inat_defs split:inat_splits) + by (simp add: iSuc_def) lemma iSuc_ne_0 [simp]: "iSuc n \ 0" -by (simp add: inat_defs split:inat_splits) + by (simp add: iSuc_def zero_inat_def split: inat.splits) + +lemma zero_ne_iSuc [simp]: "0 \ iSuc n" + by (rule iSuc_ne_0 [symmetric]) -lemma iSuc_inject [simp]: "(iSuc x = iSuc y) = (x = y)" -by (simp add: inat_defs split:inat_splits) +lemma iSuc_inject [simp]: "iSuc m = iSuc n \ m = n" + by (simp add: iSuc_def split: inat.splits) + +lemma number_of_inat_inject [simp]: + "(number_of k \ inat) = number_of l \ (number_of k \ nat) = number_of l" + by (simp add: number_of_inat_def) -subsection "Ordering relations" +subsection {* Addition *} + +instantiation inat :: comm_monoid_add +begin + +definition + [code del]: "m + n = (case m of \ \ \ | Fin m \ (case n of \ \ \ | Fin n \ Fin (m + n)))" -instance inat :: linorder -proof - fix x :: inat - show "x \ x" - by (simp add: inat_defs split: inat_splits) -next - fix x y :: inat - assume "x \ y" and "y \ x" thus "x = y" - by (simp add: inat_defs split: inat_splits) -next - fix x y z :: inat - assume "x \ y" and "y \ z" thus "x \ z" - by (simp add: inat_defs split: inat_splits) -next - fix x y :: inat - show "(x < y) = (x \ y \ x \ y)" - by (simp add: inat_defs order_less_le split: inat_splits) -next - fix x y :: inat - show "x \ y \ y \ x" - by (simp add: inat_defs linorder_linear split: inat_splits) +lemma plus_inat_simps [simp, code]: + "Fin m + Fin n = Fin (m + n)" + "\ + q = \" + "q + \ = \" + by (simp_all add: plus_inat_def split: inat.splits) + +instance proof + fix n m q :: inat + show "n + m + q = n + (m + q)" + by (cases n, auto, cases m, auto, cases q, auto) + show "n + m = m + n" + by (cases n, auto, cases m, auto) + show "0 + n = n" + by (cases n) (simp_all add: zero_inat_def) qed -lemma Infty_ilessE [elim!]: "\ < Fin m ==> R" -by (simp add: inat_defs split:inat_splits) - -lemma iless_linear: "m < n \ m = n \ n < (m::inat)" -by (rule linorder_less_linear) - -lemma iless_not_refl: "\ n < (n::inat)" -by (rule order_less_irrefl) +end -lemma iless_trans: "i < j ==> j < k ==> i < (k::inat)" -by (rule order_less_trans) +lemma plus_inat_0 [simp]: + "0 + (q\inat) = q" + "(q\inat) + 0 = q" + by (simp_all add: plus_inat_def zero_inat_def split: inat.splits) -lemma iless_not_sym: "n < m ==> \ m < (n::inat)" -by (rule order_less_not_sym) - -lemma Fin_iless_mono [simp]: "(Fin n < Fin m) = (n < m)" -by (simp add: inat_defs split:inat_splits) +lemma plus_inat_number [simp]: + "(number_of k \ inat) + number_of l = (if neg (number_of k \ int) then number_of l + else if neg (number_of l \ int) then number_of k else number_of (k + l))" + unfolding number_of_inat_def plus_inat_simps nat_arith(1) if_distrib [symmetric, of _ Fin] .. -lemma Fin_iless_Infty [simp]: "Fin n < \" -by (simp add: inat_defs split:inat_splits) - -lemma Infty_eq [simp]: "(n < \) = (n \ \)" -by (simp add: inat_defs split:inat_splits) - -lemma i0_eq [simp]: "((0::inat) < n) = (n \ 0)" -by (fastsimp simp: inat_defs split:inat_splits) +lemma iSuc_number [simp]: + "iSuc (number_of k) = (if neg (number_of k \ int) then 1 else number_of (Int.succ k))" + unfolding iSuc_number_of + unfolding one_inat_def number_of_inat_def Suc_nat_number_of if_distrib [symmetric] .. -lemma i0_iless_iSuc [simp]: "0 < iSuc n" -by (simp add: inat_defs split:inat_splits) - -lemma not_ilessi0 [simp]: "\ n < (0::inat)" -by (simp add: inat_defs split:inat_splits) - -lemma Fin_iless: "n < Fin m ==> \k. n = Fin k" -by (simp add: inat_defs split:inat_splits) - -lemma iSuc_mono [simp]: "(iSuc n < iSuc m) = (n < m)" -by (simp add: inat_defs split:inat_splits) - +lemma iSuc_plus_1: + "iSuc n = n + 1" + by (cases n) (simp_all add: iSuc_Fin one_inat_def) + +lemma plus_1_iSuc: + "1 + q = iSuc q" + "q + 1 = iSuc q" + unfolding iSuc_plus_1 by (simp_all add: add_ac) -lemma ile_def2: "(m \ n) = (m < n \ m = (n::inat))" -by (rule order_le_less) +subsection {* Ordering *} + +instantiation inat :: ordered_ab_semigroup_add +begin -lemma ile_refl [simp]: "n \ (n::inat)" -by (rule order_refl) +definition + [code del]: "m \ n = (case n of Fin n1 \ (case m of Fin m1 \ m1 \ n1 | \ \ False) + | \ \ True)" -lemma ile_trans: "i \ j ==> j \ k ==> i \ (k::inat)" -by (rule order_trans) +definition + [code del]: "m < n = (case m of Fin m1 \ (case n of Fin n1 \ m1 < n1 | \ \ True) + | \ \ False)" -lemma ile_iless_trans: "i \ j ==> j < k ==> i < (k::inat)" -by (rule order_le_less_trans) - -lemma iless_ile_trans: "i < j ==> j \ k ==> i < (k::inat)" -by (rule order_less_le_trans) +lemma inat_ord_simps [simp]: + "Fin m \ Fin n \ m \ n" + "Fin m < Fin n \ m < n" + "q \ \" + "q < \ \ q \ \" + "\ \ q \ q = \" + "\ < q \ False" + by (simp_all add: less_eq_inat_def less_inat_def split: inat.splits) -lemma Infty_ub [simp]: "n \ \" -by (simp add: inat_defs split:inat_splits) +lemma inat_ord_code [code]: + "Fin m \ Fin n \ m \ n" + "Fin m < Fin n \ m < n" + "q \ \ \ True" + "Fin m < \ \ True" + "\ \ Fin n \ False" + "\ < q \ False" + by simp_all -lemma i0_lb [simp]: "(0::inat) \ n" -by (simp add: inat_defs split:inat_splits) +instance by default + (auto simp add: less_eq_inat_def less_inat_def plus_inat_def split: inat.splits) -lemma Infty_ileE [elim!]: "\ \ Fin m ==> R" -by (simp add: inat_defs split:inat_splits) +end + +lemma inat_ord_number [simp]: + "(number_of m \ inat) \ number_of n \ (number_of m \ nat) \ number_of n" + "(number_of m \ inat) < number_of n \ (number_of m \ nat) < number_of n" + by (simp_all add: number_of_inat_def) -lemma Fin_ile_mono [simp]: "(Fin n \ Fin m) = (n \ m)" -by (simp add: inat_defs split:inat_splits) +lemma i0_lb [simp]: "(0\inat) \ n" + by (simp add: zero_inat_def less_eq_inat_def split: inat.splits) -lemma ilessI1: "n \ m ==> n \ m ==> n < (m::inat)" -by (rule order_le_neq_trans) +lemma i0_neq [simp]: "n \ (0\inat) \ n = 0" + by (simp add: zero_inat_def less_eq_inat_def split: inat.splits) + +lemma Infty_ileE [elim!]: "\ \ Fin m \ R" + by (simp add: zero_inat_def less_eq_inat_def split: inat.splits) -lemma ileI1: "m < n ==> iSuc m \ n" -by (simp add: inat_defs split:inat_splits) +lemma Infty_ilessE [elim!]: "\ < Fin m \ R" + by simp -lemma Suc_ile_eq: "(Fin (Suc m) \ n) = (Fin m < n)" -by (simp add: inat_defs split:inat_splits, arith) +lemma not_ilessi0 [simp]: "\ n < (0\inat)" + by (simp add: zero_inat_def less_inat_def split: inat.splits) + +lemma i0_eq [simp]: "(0\inat) < n \ n \ 0" + by (simp add: zero_inat_def less_inat_def split: inat.splits) -lemma iSuc_ile_mono [simp]: "(iSuc n \ iSuc m) = (n \ m)" -by (simp add: inat_defs split:inat_splits) +lemma iSuc_ile_mono [simp]: "iSuc n \ iSuc m \ n \ m" + by (simp add: iSuc_def less_eq_inat_def split: inat.splits) + +lemma iSuc_mono [simp]: "iSuc n < iSuc m \ n < m" + by (simp add: iSuc_def less_inat_def split: inat.splits) -lemma iless_Suc_eq [simp]: "(Fin m < iSuc n) = (Fin m \ n)" -by (simp add: inat_defs split:inat_splits, arith) +lemma ile_iSuc [simp]: "n \ iSuc n" + by (simp add: iSuc_def less_eq_inat_def split: inat.splits) lemma not_iSuc_ilei0 [simp]: "\ iSuc n \ 0" -by (simp add: inat_defs split:inat_splits) + by (simp add: zero_inat_def iSuc_def less_eq_inat_def split: inat.splits) + +lemma i0_iless_iSuc [simp]: "0 < iSuc n" + by (simp add: zero_inat_def iSuc_def less_inat_def split: inat.splits) + +lemma ileI1: "m < n \ iSuc m \ n" + by (simp add: iSuc_def less_eq_inat_def less_inat_def split: inat.splits) + +lemma Suc_ile_eq: "Fin (Suc m) \ n \ Fin m < n" + by (cases n) auto + +lemma iless_Suc_eq [simp]: "Fin m < iSuc n \ Fin m \ n" + by (auto simp add: iSuc_def less_inat_def split: inat.splits) -lemma ile_iSuc [simp]: "n \ iSuc n" -by (simp add: inat_defs split:inat_splits) +lemma min_inat_simps [simp]: + "min (Fin m) (Fin n) = Fin (min m n)" + "min q 0 = 0" + "min 0 q = 0" + "min q \ = q" + "min \ q = q" + by (auto simp add: min_def) -lemma Fin_ile: "n \ Fin m ==> \k. n = Fin k" -by (simp add: inat_defs split:inat_splits) +lemma max_inat_simps [simp]: + "max (Fin m) (Fin n) = Fin (max m n)" + "max q 0 = q" + "max 0 q = q" + "max q \ = \" + "max \ q = \" + by (simp_all add: max_def) + +lemma Fin_ile: "n \ Fin m \ \k. n = Fin k" + by (cases n) simp_all + +lemma Fin_iless: "n < Fin m \ \k. n = Fin k" + by (cases n) simp_all lemma chain_incr: "\i. \j. Y i < Y j ==> \j. Fin k < Y j" apply (induct_tac k) apply (simp (no_asm) only: Fin_0) - apply (fast intro: ile_iless_trans [OF i0_lb]) + apply (fast intro: le_less_trans [OF i0_lb]) apply (erule exE) apply (drule spec) apply (erule exE) apply (drule ileI1) apply (rule iSuc_Fin [THEN subst]) apply (rule exI) -apply (erule (1) ile_iless_trans) +apply (erule (1) le_less_trans) done -subsection "Well-ordering" +subsection {* Well-ordering *} lemma less_FinE: "[| n < Fin m; !!k. n = Fin k ==> k < m ==> P |] ==> P" @@ -256,4 +326,12 @@ qed qed + +subsection {* Traditional theorem names *} + +lemmas inat_defs = zero_inat_def one_inat_def number_of_inat_def iSuc_def + plus_inat_def less_eq_inat_def less_inat_def + +lemmas inat_splits = inat.splits + end