Theory C

theory C
imports HOLCF "Mono-Nat-Fun"
begin

default_sort cpo

text ‹
The initial solution to the domain equation $C = C_\bot$, i.e. the completion of the natural numbers.
›

domain C = C (lazy "C")

lemma below_C: "x  Cx"
  by (induct x) auto

definition Cinf ("C") where "C = fixC"

lemma C_Cinf[simp]: "CC = C" unfolding Cinf_def by (rule fix_eq[symmetric])

abbreviation Cpow ("C⇗_") where "C⇗n iterate nC"

lemma C_below_C[simp]: "(C⇗i C⇗j)  i  j"
  apply (induction i arbitrary: j)
  apply simp
  apply (case_tac j, auto)
  done

lemma below_Cinf[simp]: "r  C"
  apply (induct r)
  apply simp_all[2]
  apply (metis (full_types) C_Cinf monofun_cfun_arg)
  done

lemma C_eq_Cinf[simp]: "C⇗i C"
  by (metis C_below_C Suc_n_not_le_n below_Cinf)

lemma Cinf_eq_C[simp]: "C = C  r  C = r"
  by (metis C.injects C_Cinf)

lemma C_eq_C[simp]: "(C⇗i= C⇗j)  i = j"
  by (metis C_below_C le_antisym le_refl)

lemma case_of_C_below: "(case r of Cy  x)  x"
  by (cases r) auto

lemma C_case_below: "C_case  f  f"
  by (metis cfun_belowI C.case_rews(2) below_C monofun_cfun_arg)

lemma C_case_bot[simp]: "C_case   = "
  apply (subst eq_bottom_iff)
  apply (rule C_case_below)
  done

lemma C_case_cong:
  assumes " r'. r = Cr'  fr' = gr'"
  shows "C_casefr = C_casegr"
using assms by (cases r) auto


lemma C_cases:
  obtains n where "r = C⇗n⇖" | "r = C"
proof-
  { fix m
    have " n. C_take m  r = C⇗n⇖ "
    proof (rule C.finite_induct)
      have " = C⇗0⇖" by simp
      thus "n.  = C⇗n⇖"..
    next
      fix r
      show "n. r = C⇗n n. Cr = C⇗n⇖"
        by (auto simp del: iterate_Suc simp add: iterate_Suc[symmetric])
    qed
  }
  then obtain f where take: " m. C_take m  r = C⇗f m⇖" by metis
  have "chain (λ m. C⇗f m)" using ch2ch_Rep_cfunL[OF C.chain_take, where x=r, unfolded take].
  hence "mono f" by (auto simp add: mono_iff_le_Suc chain_def elim!:chainE)
  have r: "r = ( m. C⇗f m)"  by (metis (lifting) take C.reach lub_eq)
  from mono f
  show thesis
  proof(rule nat_mono_characterization)
    fix n
    assume n: " m. n  m ==> f n = f m"
    have "max_in_chain n (λ m. C⇗f m)"
      apply (rule max_in_chainI)
      apply simp
      apply (erule n)
      done
    hence "( m. C⇗f m) = C⇗f n⇖" unfolding  maxinch_is_thelub[OF chain _].
    thus ?thesis using that unfolding r by blast
  next
    assume "m. n. m  f n"
    hence " n. C⇗n r" unfolding r by (fastforce intro: below_lub[OF chain _])
    hence "( n. C⇗n)  r" 
      by (rule lub_below[OF chain_iterate])
    hence "C  r" unfolding Cinf_def fix_def2.
    hence "C = r" using below_Cinf by (metis below_antisym)
    thus thesis using that by blast
  qed
qed


lemma C_case_Cinf[simp]: "C_case  f  C = f  C"
  unfolding Cinf_def
  by (subst fix_eq) simp

end