src/FOL/ex/Nat_Class.thy
author wenzelm
Tue, 05 Nov 2019 14:16:16 +0100
changeset 71046 b8aeeedf7e68
parent 69866 01732226987a
permissions -rw-r--r--
support for Linux user management;

(*  Title:      FOL/ex/Nat_Class.thy
    Author:     Markus Wenzel, TU Muenchen
*)

section \<open>Theory of the natural numbers: Peano's axioms, primitive recursion\<close>

theory Nat_Class
  imports FOL
begin

text \<open>
  This is an abstract version of \<^file>\<open>Nat.thy\<close>. Instead of axiomatizing a
  single type \<open>nat\<close>, it defines the class of all these types (up to
  isomorphism).

  Note: The \<open>rec\<close> operator has been made \<^emph>\<open>monomorphic\<close>, because class
  axioms cannot contain more than one type variable.
\<close>

class nat =
  fixes Zero :: \<open>'a\<close>  (\<open>0\<close>)
    and Suc :: \<open>'a \<Rightarrow> 'a\<close>
    and rec :: \<open>'a \<Rightarrow> 'a \<Rightarrow> ('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> 'a\<close>
  assumes induct: \<open>P(0) \<Longrightarrow> (\<And>x. P(x) \<Longrightarrow> P(Suc(x))) \<Longrightarrow> P(n)\<close>
    and Suc_inject: \<open>Suc(m) = Suc(n) \<Longrightarrow> m = n\<close>
    and Suc_neq_Zero: \<open>Suc(m) = 0 \<Longrightarrow> R\<close>
    and rec_Zero: \<open>rec(0, a, f) = a\<close>
    and rec_Suc: \<open>rec(Suc(m), a, f) = f(m, rec(m, a, f))\<close>
begin

definition add :: \<open>'a \<Rightarrow> 'a \<Rightarrow> 'a\<close>  (infixl \<open>+\<close> 60)
  where \<open>m + n = rec(m, n, \<lambda>x y. Suc(y))\<close>

lemma Suc_n_not_n: \<open>Suc(k) \<noteq> (k::'a)\<close>
  apply (rule_tac n = \<open>k\<close> in induct)
   apply (rule notI)
   apply (erule Suc_neq_Zero)
  apply (rule notI)
  apply (erule notE)
  apply (erule Suc_inject)
  done

lemma \<open>(k + m) + n = k + (m + n)\<close>
  apply (rule induct)
  back
  back
  back
  back
  back
  oops

lemma add_Zero [simp]: \<open>0 + n = n\<close>
  apply (unfold add_def)
  apply (rule rec_Zero)
  done

lemma add_Suc [simp]: \<open>Suc(m) + n = Suc(m + n)\<close>
  apply (unfold add_def)
  apply (rule rec_Suc)
  done

lemma add_assoc: \<open>(k + m) + n = k + (m + n)\<close>
  apply (rule_tac n = \<open>k\<close> in induct)
   apply simp
  apply simp
  done

lemma add_Zero_right: \<open>m + 0 = m\<close>
  apply (rule_tac n = \<open>m\<close> in induct)
   apply simp
  apply simp
  done

lemma add_Suc_right: \<open>m + Suc(n) = Suc(m + n)\<close>
  apply (rule_tac n = \<open>m\<close> in induct)
   apply simp_all
  done

lemma
  assumes prem: \<open>\<And>n. f(Suc(n)) = Suc(f(n))\<close>
  shows \<open>f(i + j) = i + f(j)\<close>
  apply (rule_tac n = \<open>i\<close> in induct)
   apply simp
  apply (simp add: prem)
  done

end

end