hoelzl@43919: (* Title: HOL/Library/Extended_Nat.thy haftmann@27110: Author: David von Oheimb, TU Muenchen; Florian Haftmann, TU Muenchen nipkow@41853: Contributions: David Trachtenherz, TU Muenchen oheimb@11351: *) oheimb@11351: hoelzl@43919: header {* Extended natural numbers (i.e. with infinity) *} oheimb@11351: hoelzl@43919: theory Extended_Nat haftmann@30663: imports Main nipkow@15131: begin oheimb@11351: haftmann@27110: subsection {* Type definition *} oheimb@11351: oheimb@11351: text {* wenzelm@11355: We extend the standard natural numbers by a special value indicating haftmann@27110: infinity. oheimb@11351: *} oheimb@11351: hoelzl@43919: datatype enat = Fin nat | Infty oheimb@11351: wenzelm@21210: notation (xsymbols) wenzelm@19736: Infty ("\") wenzelm@19736: wenzelm@21210: notation (HTML output) wenzelm@19736: Infty ("\") wenzelm@19736: oheimb@11351: nipkow@31084: lemma not_Infty_eq[iff]: "(x ~= Infty) = (EX i. x = Fin i)" nipkow@31084: by (cases x) auto nipkow@31084: nipkow@31084: lemma not_Fin_eq [iff]: "(ALL y. x ~= Fin y) = (x = Infty)" nipkow@31077: by (cases x) auto nipkow@31077: nipkow@31077: hoelzl@43919: primrec the_Fin :: "enat \ nat" nipkow@41855: where "the_Fin (Fin n) = n" nipkow@41855: nipkow@41855: haftmann@27110: subsection {* Constructors and numbers *} haftmann@27110: hoelzl@43919: instantiation enat :: "{zero, one, number}" haftmann@25594: begin haftmann@25594: haftmann@25594: definition haftmann@27110: "0 = Fin 0" haftmann@25594: haftmann@25594: definition haftmann@32069: [code_unfold]: "1 = Fin 1" haftmann@25594: haftmann@25594: definition haftmann@32069: [code_unfold, code del]: "number_of k = Fin (number_of k)" oheimb@11351: haftmann@25594: instance .. haftmann@25594: haftmann@25594: end haftmann@25594: hoelzl@43919: definition iSuc :: "enat \ enat" where haftmann@27110: "iSuc i = (case i of Fin n \ Fin (Suc n) | \ \ \)" oheimb@11351: oheimb@11351: lemma Fin_0: "Fin 0 = 0" hoelzl@43919: by (simp add: zero_enat_def) haftmann@27110: haftmann@27110: lemma Fin_1: "Fin 1 = 1" hoelzl@43919: by (simp add: one_enat_def) haftmann@27110: haftmann@27110: lemma Fin_number: "Fin (number_of k) = number_of k" hoelzl@43919: by (simp add: number_of_enat_def) haftmann@27110: haftmann@27110: lemma one_iSuc: "1 = iSuc 0" hoelzl@43919: by (simp add: zero_enat_def one_enat_def iSuc_def) oheimb@11351: oheimb@11351: lemma Infty_ne_i0 [simp]: "\ \ 0" hoelzl@43919: by (simp add: zero_enat_def) oheimb@11351: oheimb@11351: lemma i0_ne_Infty [simp]: "0 \ \" hoelzl@43919: by (simp add: zero_enat_def) haftmann@27110: hoelzl@43919: lemma zero_enat_eq [simp]: hoelzl@43919: "number_of k = (0\enat) \ number_of k = (0\nat)" hoelzl@43919: "(0\enat) = number_of k \ number_of k = (0\nat)" hoelzl@43919: unfolding zero_enat_def number_of_enat_def by simp_all haftmann@27110: hoelzl@43919: lemma one_enat_eq [simp]: hoelzl@43919: "number_of k = (1\enat) \ number_of k = (1\nat)" hoelzl@43919: "(1\enat) = number_of k \ number_of k = (1\nat)" hoelzl@43919: unfolding one_enat_def number_of_enat_def by simp_all haftmann@27110: hoelzl@43919: lemma zero_one_enat_neq [simp]: hoelzl@43919: "\ 0 = (1\enat)" hoelzl@43919: "\ 1 = (0\enat)" hoelzl@43919: unfolding zero_enat_def one_enat_def by simp_all oheimb@11351: haftmann@27110: lemma Infty_ne_i1 [simp]: "\ \ 1" hoelzl@43919: by (simp add: one_enat_def) haftmann@27110: haftmann@27110: lemma i1_ne_Infty [simp]: "1 \ \" hoelzl@43919: by (simp add: one_enat_def) haftmann@27110: haftmann@27110: lemma Infty_ne_number [simp]: "\ \ number_of k" hoelzl@43919: by (simp add: number_of_enat_def) haftmann@27110: haftmann@27110: lemma number_ne_Infty [simp]: "number_of k \ \" hoelzl@43919: by (simp add: number_of_enat_def) haftmann@27110: haftmann@27110: lemma iSuc_Fin: "iSuc (Fin n) = Fin (Suc n)" haftmann@27110: by (simp add: iSuc_def) haftmann@27110: haftmann@27110: lemma iSuc_number_of: "iSuc (number_of k) = Fin (Suc (number_of k))" hoelzl@43919: by (simp add: iSuc_Fin number_of_enat_def) oheimb@11351: oheimb@11351: lemma iSuc_Infty [simp]: "iSuc \ = \" haftmann@27110: by (simp add: iSuc_def) oheimb@11351: oheimb@11351: lemma iSuc_ne_0 [simp]: "iSuc n \ 0" hoelzl@43919: by (simp add: iSuc_def zero_enat_def split: enat.splits) haftmann@27110: haftmann@27110: lemma zero_ne_iSuc [simp]: "0 \ iSuc n" haftmann@27110: by (rule iSuc_ne_0 [symmetric]) oheimb@11351: haftmann@27110: lemma iSuc_inject [simp]: "iSuc m = iSuc n \ m = n" hoelzl@43919: by (simp add: iSuc_def split: enat.splits) haftmann@27110: hoelzl@43919: lemma number_of_enat_inject [simp]: hoelzl@43919: "(number_of k \ enat) = number_of l \ (number_of k \ nat) = number_of l" hoelzl@43919: by (simp add: number_of_enat_def) oheimb@11351: oheimb@11351: haftmann@27110: subsection {* Addition *} haftmann@27110: hoelzl@43919: instantiation enat :: comm_monoid_add haftmann@27110: begin haftmann@27110: blanchet@38167: definition [nitpick_simp]: haftmann@37765: "m + n = (case m of \ \ \ | Fin m \ (case n of \ \ \ | Fin n \ Fin (m + n)))" oheimb@11351: hoelzl@43919: lemma plus_enat_simps [simp, code]: haftmann@27110: "Fin m + Fin n = Fin (m + n)" haftmann@27110: "\ + q = \" haftmann@27110: "q + \ = \" hoelzl@43919: by (simp_all add: plus_enat_def split: enat.splits) haftmann@27110: haftmann@27110: instance proof hoelzl@43919: fix n m q :: enat haftmann@27110: show "n + m + q = n + (m + q)" haftmann@27110: by (cases n, auto, cases m, auto, cases q, auto) haftmann@27110: show "n + m = m + n" haftmann@27110: by (cases n, auto, cases m, auto) haftmann@27110: show "0 + n = n" hoelzl@43919: by (cases n) (simp_all add: zero_enat_def) huffman@26089: qed huffman@26089: haftmann@27110: end oheimb@11351: hoelzl@43919: lemma plus_enat_0 [simp]: hoelzl@43919: "0 + (q\enat) = q" hoelzl@43919: "(q\enat) + 0 = q" hoelzl@43919: by (simp_all add: plus_enat_def zero_enat_def split: enat.splits) oheimb@11351: hoelzl@43919: lemma plus_enat_number [simp]: hoelzl@43919: "(number_of k \ enat) + number_of l = (if k < Int.Pls then number_of l huffman@29012: else if l < Int.Pls then number_of k else number_of (k + l))" hoelzl@43919: unfolding number_of_enat_def plus_enat_simps nat_arith(1) if_distrib [symmetric, of _ Fin] .. oheimb@11351: haftmann@27110: lemma iSuc_number [simp]: haftmann@27110: "iSuc (number_of k) = (if neg (number_of k \ int) then 1 else number_of (Int.succ k))" haftmann@27110: unfolding iSuc_number_of hoelzl@43919: unfolding one_enat_def number_of_enat_def Suc_nat_number_of if_distrib [symmetric] .. oheimb@11351: haftmann@27110: lemma iSuc_plus_1: haftmann@27110: "iSuc n = n + 1" hoelzl@43919: by (cases n) (simp_all add: iSuc_Fin one_enat_def) haftmann@27110: haftmann@27110: lemma plus_1_iSuc: haftmann@27110: "1 + q = iSuc q" haftmann@27110: "q + 1 = iSuc q" nipkow@41853: by (simp_all add: iSuc_plus_1 add_ac) nipkow@41853: nipkow@41853: lemma iadd_Suc: "iSuc m + n = iSuc (m + n)" nipkow@41853: by (simp_all add: iSuc_plus_1 add_ac) oheimb@11351: nipkow@41853: lemma iadd_Suc_right: "m + iSuc n = iSuc (m + n)" nipkow@41853: by (simp only: add_commute[of m] iadd_Suc) nipkow@41853: hoelzl@43919: lemma iadd_is_0: "(m + n = (0::enat)) = (m = 0 \ n = 0)" hoelzl@43919: by (cases m, cases n, simp_all add: zero_enat_def) oheimb@11351: huffman@29014: subsection {* Multiplication *} huffman@29014: hoelzl@43919: instantiation enat :: comm_semiring_1 huffman@29014: begin huffman@29014: hoelzl@43919: definition times_enat_def [nitpick_simp]: huffman@29014: "m * n = (case m of \ \ if n = 0 then 0 else \ | Fin m \ huffman@29014: (case n of \ \ if m = 0 then 0 else \ | Fin n \ Fin (m * n)))" huffman@29014: hoelzl@43919: lemma times_enat_simps [simp, code]: huffman@29014: "Fin m * Fin n = Fin (m * n)" huffman@29014: "\ * \ = \" huffman@29014: "\ * Fin n = (if n = 0 then 0 else \)" huffman@29014: "Fin m * \ = (if m = 0 then 0 else \)" hoelzl@43919: unfolding times_enat_def zero_enat_def hoelzl@43919: by (simp_all split: enat.split) huffman@29014: huffman@29014: instance proof hoelzl@43919: fix a b c :: enat huffman@29014: show "(a * b) * c = a * (b * c)" hoelzl@43919: unfolding times_enat_def zero_enat_def hoelzl@43919: by (simp split: enat.split) huffman@29014: show "a * b = b * a" hoelzl@43919: unfolding times_enat_def zero_enat_def hoelzl@43919: by (simp split: enat.split) huffman@29014: show "1 * a = a" hoelzl@43919: unfolding times_enat_def zero_enat_def one_enat_def hoelzl@43919: by (simp split: enat.split) huffman@29014: show "(a + b) * c = a * c + b * c" hoelzl@43919: unfolding times_enat_def zero_enat_def hoelzl@43919: by (simp split: enat.split add: left_distrib) huffman@29014: show "0 * a = 0" hoelzl@43919: unfolding times_enat_def zero_enat_def hoelzl@43919: by (simp split: enat.split) huffman@29014: show "a * 0 = 0" hoelzl@43919: unfolding times_enat_def zero_enat_def hoelzl@43919: by (simp split: enat.split) hoelzl@43919: show "(0::enat) \ 1" hoelzl@43919: unfolding zero_enat_def one_enat_def huffman@29014: by simp huffman@29014: qed huffman@29014: huffman@29014: end huffman@29014: huffman@29014: lemma mult_iSuc: "iSuc m * n = n + m * n" nipkow@29667: unfolding iSuc_plus_1 by (simp add: algebra_simps) huffman@29014: huffman@29014: lemma mult_iSuc_right: "m * iSuc n = m + m * n" nipkow@29667: unfolding iSuc_plus_1 by (simp add: algebra_simps) huffman@29014: huffman@29023: lemma of_nat_eq_Fin: "of_nat n = Fin n" huffman@29023: apply (induct n) huffman@29023: apply (simp add: Fin_0) huffman@29023: apply (simp add: plus_1_iSuc iSuc_Fin) huffman@29023: done huffman@29023: hoelzl@43919: instance enat :: number_semiring huffman@43532: proof hoelzl@43919: fix n show "number_of (int n) = (of_nat n :: enat)" hoelzl@43919: unfolding number_of_enat_def number_of_int of_nat_id of_nat_eq_Fin .. huffman@43532: qed huffman@43532: hoelzl@43919: instance enat :: semiring_char_0 proof haftmann@38621: have "inj Fin" by (rule injI) simp hoelzl@43919: then show "inj (\n. of_nat n :: enat)" by (simp add: of_nat_eq_Fin) haftmann@38621: qed huffman@29023: hoelzl@43919: lemma imult_is_0[simp]: "((m::enat) * n = 0) = (m = 0 \ n = 0)" hoelzl@43919: by(auto simp add: times_enat_def zero_enat_def split: enat.split) nipkow@41853: hoelzl@43919: lemma imult_is_Infty: "((a::enat) * b = \) = (a = \ \ b \ 0 \ b = \ \ a \ 0)" hoelzl@43919: by(auto simp add: times_enat_def zero_enat_def split: enat.split) nipkow@41853: nipkow@41853: nipkow@41853: subsection {* Subtraction *} nipkow@41853: hoelzl@43919: instantiation enat :: minus nipkow@41853: begin nipkow@41853: hoelzl@43919: definition diff_enat_def: nipkow@41853: "a - b = (case a of (Fin x) \ (case b of (Fin y) \ Fin (x - y) | \ \ 0) nipkow@41853: | \ \ \)" nipkow@41853: nipkow@41853: instance .. nipkow@41853: nipkow@41853: end nipkow@41853: nipkow@41853: lemma idiff_Fin_Fin[simp,code]: "Fin a - Fin b = Fin (a - b)" hoelzl@43919: by(simp add: diff_enat_def) nipkow@41853: nipkow@41853: lemma idiff_Infty[simp,code]: "\ - n = \" hoelzl@43919: by(simp add: diff_enat_def) nipkow@41853: nipkow@41853: lemma idiff_Infty_right[simp,code]: "Fin a - \ = 0" hoelzl@43919: by(simp add: diff_enat_def) nipkow@41853: hoelzl@43919: lemma idiff_0[simp]: "(0::enat) - n = 0" hoelzl@43919: by (cases n, simp_all add: zero_enat_def) nipkow@41853: hoelzl@43919: lemmas idiff_Fin_0[simp] = idiff_0[unfolded zero_enat_def] nipkow@41853: hoelzl@43919: lemma idiff_0_right[simp]: "(n::enat) - 0 = n" hoelzl@43919: by (cases n) (simp_all add: zero_enat_def) nipkow@41853: hoelzl@43919: lemmas idiff_Fin_0_right[simp] = idiff_0_right[unfolded zero_enat_def] nipkow@41853: hoelzl@43919: lemma idiff_self[simp]: "n \ \ \ (n::enat) - n = 0" hoelzl@43919: by(auto simp: zero_enat_def) nipkow@41853: nipkow@41855: lemma iSuc_minus_iSuc [simp]: "iSuc n - iSuc m = n - m" hoelzl@43919: by(simp add: iSuc_def split: enat.split) nipkow@41855: nipkow@41855: lemma iSuc_minus_1 [simp]: "iSuc n - 1 = n" hoelzl@43919: by(simp add: one_enat_def iSuc_Fin[symmetric] zero_enat_def[symmetric]) nipkow@41855: hoelzl@43919: (*lemmas idiff_self_eq_0_Fin = idiff_self_eq_0[unfolded zero_enat_def]*) nipkow@41853: huffman@29014: haftmann@27110: subsection {* Ordering *} haftmann@27110: hoelzl@43919: instantiation enat :: linordered_ab_semigroup_add haftmann@27110: begin oheimb@11351: blanchet@38167: definition [nitpick_simp]: haftmann@37765: "m \ n = (case n of Fin n1 \ (case m of Fin m1 \ m1 \ n1 | \ \ False) haftmann@27110: | \ \ True)" oheimb@11351: blanchet@38167: definition [nitpick_simp]: haftmann@37765: "m < n = (case m of Fin m1 \ (case n of Fin n1 \ m1 < n1 | \ \ True) haftmann@27110: | \ \ False)" oheimb@11351: hoelzl@43919: lemma enat_ord_simps [simp]: haftmann@27110: "Fin m \ Fin n \ m \ n" haftmann@27110: "Fin m < Fin n \ m < n" haftmann@27110: "q \ \" haftmann@27110: "q < \ \ q \ \" haftmann@27110: "\ \ q \ q = \" haftmann@27110: "\ < q \ False" hoelzl@43919: by (simp_all add: less_eq_enat_def less_enat_def split: enat.splits) oheimb@11351: hoelzl@43919: lemma enat_ord_code [code]: haftmann@27110: "Fin m \ Fin n \ m \ n" haftmann@27110: "Fin m < Fin n \ m < n" haftmann@27110: "q \ \ \ True" haftmann@27110: "Fin m < \ \ True" haftmann@27110: "\ \ Fin n \ False" haftmann@27110: "\ < q \ False" haftmann@27110: by simp_all oheimb@11351: haftmann@27110: instance by default hoelzl@43919: (auto simp add: less_eq_enat_def less_enat_def plus_enat_def split: enat.splits) oheimb@11351: haftmann@27110: end haftmann@27110: hoelzl@43919: instance enat :: ordered_comm_semiring huffman@29014: proof hoelzl@43919: fix a b c :: enat huffman@29014: assume "a \ b" and "0 \ c" huffman@29014: thus "c * a \ c * b" hoelzl@43919: unfolding times_enat_def less_eq_enat_def zero_enat_def hoelzl@43919: by (simp split: enat.splits) huffman@29014: qed huffman@29014: hoelzl@43919: lemma enat_ord_number [simp]: hoelzl@43919: "(number_of m \ enat) \ number_of n \ (number_of m \ nat) \ number_of n" hoelzl@43919: "(number_of m \ enat) < number_of n \ (number_of m \ nat) < number_of n" hoelzl@43919: by (simp_all add: number_of_enat_def) oheimb@11351: hoelzl@43919: lemma i0_lb [simp]: "(0\enat) \ n" hoelzl@43919: by (simp add: zero_enat_def less_eq_enat_def split: enat.splits) oheimb@11351: hoelzl@43919: lemma ile0_eq [simp]: "n \ (0\enat) \ n = 0" hoelzl@43919: by (simp add: zero_enat_def less_eq_enat_def split: enat.splits) haftmann@27110: haftmann@27110: lemma Infty_ileE [elim!]: "\ \ Fin m \ R" hoelzl@43919: by (simp add: zero_enat_def less_eq_enat_def split: enat.splits) oheimb@11351: haftmann@27110: lemma Infty_ilessE [elim!]: "\ < Fin m \ R" haftmann@27110: by simp oheimb@11351: hoelzl@43919: lemma not_iless0 [simp]: "\ n < (0\enat)" hoelzl@43919: by (simp add: zero_enat_def less_enat_def split: enat.splits) haftmann@27110: hoelzl@43919: lemma i0_less [simp]: "(0\enat) < n \ n \ 0" hoelzl@43919: by (simp add: zero_enat_def less_enat_def split: enat.splits) oheimb@11351: haftmann@27110: lemma iSuc_ile_mono [simp]: "iSuc n \ iSuc m \ n \ m" hoelzl@43919: by (simp add: iSuc_def less_eq_enat_def split: enat.splits) haftmann@27110: haftmann@27110: lemma iSuc_mono [simp]: "iSuc n < iSuc m \ n < m" hoelzl@43919: by (simp add: iSuc_def less_enat_def split: enat.splits) oheimb@11351: haftmann@27110: lemma ile_iSuc [simp]: "n \ iSuc n" hoelzl@43919: by (simp add: iSuc_def less_eq_enat_def split: enat.splits) oheimb@11351: wenzelm@11355: lemma not_iSuc_ilei0 [simp]: "\ iSuc n \ 0" hoelzl@43919: by (simp add: zero_enat_def iSuc_def less_eq_enat_def split: enat.splits) haftmann@27110: haftmann@27110: lemma i0_iless_iSuc [simp]: "0 < iSuc n" hoelzl@43919: by (simp add: zero_enat_def iSuc_def less_enat_def split: enat.splits) haftmann@27110: nipkow@41853: lemma iless_iSuc0[simp]: "(n < iSuc 0) = (n = 0)" hoelzl@43919: by (simp add: zero_enat_def iSuc_def less_enat_def split: enat.split) nipkow@41853: haftmann@27110: lemma ileI1: "m < n \ iSuc m \ n" hoelzl@43919: by (simp add: iSuc_def less_eq_enat_def less_enat_def split: enat.splits) haftmann@27110: haftmann@27110: lemma Suc_ile_eq: "Fin (Suc m) \ n \ Fin m < n" haftmann@27110: by (cases n) auto haftmann@27110: haftmann@27110: lemma iless_Suc_eq [simp]: "Fin m < iSuc n \ Fin m \ n" hoelzl@43919: by (auto simp add: iSuc_def less_enat_def split: enat.splits) oheimb@11351: hoelzl@43919: lemma imult_Infty: "(0::enat) < n \ \ * n = \" hoelzl@43919: by (simp add: zero_enat_def less_enat_def split: enat.splits) nipkow@41853: hoelzl@43919: lemma imult_Infty_right: "(0::enat) < n \ n * \ = \" hoelzl@43919: by (simp add: zero_enat_def less_enat_def split: enat.splits) nipkow@41853: hoelzl@43919: lemma enat_0_less_mult_iff: "(0 < (m::enat) * n) = (0 < m \ 0 < n)" nipkow@41853: by (simp only: i0_less imult_is_0, simp) nipkow@41853: nipkow@41853: lemma mono_iSuc: "mono iSuc" nipkow@41853: by(simp add: mono_def) nipkow@41853: nipkow@41853: hoelzl@43919: lemma min_enat_simps [simp]: haftmann@27110: "min (Fin m) (Fin n) = Fin (min m n)" haftmann@27110: "min q 0 = 0" haftmann@27110: "min 0 q = 0" haftmann@27110: "min q \ = q" haftmann@27110: "min \ q = q" haftmann@27110: by (auto simp add: min_def) oheimb@11351: hoelzl@43919: lemma max_enat_simps [simp]: haftmann@27110: "max (Fin m) (Fin n) = Fin (max m n)" haftmann@27110: "max q 0 = q" haftmann@27110: "max 0 q = q" haftmann@27110: "max q \ = \" haftmann@27110: "max \ q = \" haftmann@27110: by (simp_all add: max_def) haftmann@27110: haftmann@27110: lemma Fin_ile: "n \ Fin m \ \k. n = Fin k" haftmann@27110: by (cases n) simp_all haftmann@27110: haftmann@27110: lemma Fin_iless: "n < Fin m \ \k. n = Fin k" haftmann@27110: by (cases n) simp_all oheimb@11351: oheimb@11351: lemma chain_incr: "\i. \j. Y i < Y j ==> \j. Fin k < Y j" nipkow@25134: apply (induct_tac k) nipkow@25134: apply (simp (no_asm) only: Fin_0) haftmann@27110: apply (fast intro: le_less_trans [OF i0_lb]) nipkow@25134: apply (erule exE) nipkow@25134: apply (drule spec) nipkow@25134: apply (erule exE) nipkow@25134: apply (drule ileI1) nipkow@25134: apply (rule iSuc_Fin [THEN subst]) nipkow@25134: apply (rule exI) haftmann@27110: apply (erule (1) le_less_trans) nipkow@25134: done oheimb@11351: hoelzl@43919: instantiation enat :: "{bot, top}" haftmann@29337: begin haftmann@29337: hoelzl@43919: definition bot_enat :: enat where hoelzl@43919: "bot_enat = 0" haftmann@29337: hoelzl@43919: definition top_enat :: enat where hoelzl@43919: "top_enat = \" haftmann@29337: haftmann@29337: instance proof hoelzl@43919: qed (simp_all add: bot_enat_def top_enat_def) haftmann@29337: haftmann@29337: end haftmann@29337: noschinl@42993: lemma finite_Fin_bounded: noschinl@42993: assumes le_fin: "\y. y \ A \ y \ Fin n" noschinl@42993: shows "finite A" noschinl@42993: proof (rule finite_subset) noschinl@42993: show "finite (Fin ` {..n})" by blast noschinl@42993: noschinl@42993: have "A \ {..Fin n}" using le_fin by fastsimp noschinl@42993: also have "\ \ Fin ` {..n}" noschinl@42993: by (rule subsetI) (case_tac x, auto) noschinl@42993: finally show "A \ Fin ` {..n}" . noschinl@42993: qed noschinl@42993: huffman@26089: haftmann@27110: subsection {* Well-ordering *} huffman@26089: huffman@26089: lemma less_FinE: huffman@26089: "[| n < Fin m; !!k. n = Fin k ==> k < m ==> P |] ==> P" huffman@26089: by (induct n) auto huffman@26089: huffman@26089: lemma less_InftyE: huffman@26089: "[| n < Infty; !!k. n = Fin k ==> P |] ==> P" huffman@26089: by (induct n) auto huffman@26089: hoelzl@43919: lemma enat_less_induct: hoelzl@43919: assumes prem: "!!n. \m::enat. m < n --> P m ==> P n" shows "P n" huffman@26089: proof - huffman@26089: have P_Fin: "!!k. P (Fin k)" huffman@26089: apply (rule nat_less_induct) huffman@26089: apply (rule prem, clarify) huffman@26089: apply (erule less_FinE, simp) huffman@26089: done huffman@26089: show ?thesis huffman@26089: proof (induct n) huffman@26089: fix nat huffman@26089: show "P (Fin nat)" by (rule P_Fin) huffman@26089: next huffman@26089: show "P Infty" huffman@26089: apply (rule prem, clarify) huffman@26089: apply (erule less_InftyE) huffman@26089: apply (simp add: P_Fin) huffman@26089: done huffman@26089: qed huffman@26089: qed huffman@26089: hoelzl@43919: instance enat :: wellorder huffman@26089: proof haftmann@27823: fix P and n hoelzl@43919: assume hyp: "(\n\enat. (\m\enat. m < n \ P m) \ P n)" hoelzl@43919: show "P n" by (blast intro: enat_less_induct hyp) huffman@26089: qed huffman@26089: noschinl@42993: subsection {* Complete Lattice *} noschinl@42993: hoelzl@43919: instantiation enat :: complete_lattice noschinl@42993: begin noschinl@42993: hoelzl@43919: definition inf_enat :: "enat \ enat \ enat" where hoelzl@43919: "inf_enat \ min" noschinl@42993: hoelzl@43919: definition sup_enat :: "enat \ enat \ enat" where hoelzl@43919: "sup_enat \ max" noschinl@42993: hoelzl@43919: definition Inf_enat :: "enat set \ enat" where hoelzl@43919: "Inf_enat A \ if A = {} then \ else (LEAST x. x \ A)" noschinl@42993: hoelzl@43919: definition Sup_enat :: "enat set \ enat" where hoelzl@43919: "Sup_enat A \ if A = {} then 0 noschinl@42993: else if finite A then Max A noschinl@42993: else \" noschinl@42993: instance proof hoelzl@43919: fix x :: "enat" and A :: "enat set" noschinl@42993: { assume "x \ A" then show "Inf A \ x" hoelzl@43919: unfolding Inf_enat_def by (auto intro: Least_le) } noschinl@42993: { assume "\y. y \ A \ x \ y" then show "x \ Inf A" hoelzl@43919: unfolding Inf_enat_def noschinl@42993: by (cases "A = {}") (auto intro: LeastI2_ex) } noschinl@42993: { assume "x \ A" then show "x \ Sup A" hoelzl@43919: unfolding Sup_enat_def by (cases "finite A") auto } noschinl@42993: { assume "\y. y \ A \ y \ x" then show "Sup A \ x" hoelzl@43919: unfolding Sup_enat_def using finite_Fin_bounded by auto } hoelzl@43919: qed (simp_all add: inf_enat_def sup_enat_def) noschinl@42993: end noschinl@42993: haftmann@27110: haftmann@27110: subsection {* Traditional theorem names *} haftmann@27110: hoelzl@43919: lemmas enat_defs = zero_enat_def one_enat_def number_of_enat_def iSuc_def hoelzl@43919: plus_enat_def less_eq_enat_def less_enat_def haftmann@27110: oheimb@11351: end