Theory CValue

theory CValue
imports C
begin

domain CValue
  = CFn (lazy "(C  CValue)  (C  CValue)")
  | CB (lazy "bool discr")

fixrec CFn_project :: "CValue  (C  CValue)  (C  CValue)"
 where "CFn_project(CFnf)v = f  v"

abbreviation CFn_project_abbr (infix "↓CFn" 55)
  where "f ↓CFn v  CFn_projectfv"

lemma CFn_project_strict[simp]:
  " ↓CFn v = "
  "CBb ↓CFn v = "
  by (fixrec_simp)+

lemma CB_below[simp]: "CBb  v  v = CBb"
  by (cases v) auto

fixrec CB_project :: "CValue  CValue  CValue  CValue" where
  "CB_project(CBdb)v1v2 = (if undiscr db then v1 else v2)"

lemma [simp]:
  "CB_project(CB(Discr b))v1v2 = (if b then v1 else v2)"
  "CB_projectv1v2 = "
  "CB_project(CFnf)v1v2 = "
by fixrec_simp+

lemma CB_project_not_bot:
  "CB_projectscrutv1v2    ( b. scrut = CB(Discr b)  (if b then v1 else v2)  )"
  apply (cases scrut)
  apply simp
  apply simp
  by (metis (poly_guards_query) CB_project.simps CValue.injects(2) discr.exhaust undiscr_Discr)

text ‹HOLCF provides us @{const CValue_take}::›@{typeof CValue_take};
we want a similar function for @{typ "C  CValue"}.›

abbreviation C_to_CValue_take :: "nat  (C  CValue)  (C  CValue)"
   where "C_to_CValue_take n  cfun_mapID(CValue_take n)"

lemma C_to_CValue_chain_take: "chain C_to_CValue_take"
  by (auto intro: chainI cfun_belowI chainE[OF CValue.chain_take] monofun_cfun_fun)

lemma C_to_CValue_reach: "( n. C_to_CValue_take nx) = x"
  by (auto intro:  cfun_eqI simp add: contlub_cfun_fun[OF ch2ch_Rep_cfunL[OF C_to_CValue_chain_take]]  CValue.reach)


end