Theory ClosureEx

(*
    Author:      Norbert Schirmer
    Maintainer:  Norbert Schirmer, norbert.schirmer at web de

Copyright (C) 2006-2008 Norbert Schirmer
*)

theory ClosureEx
imports "../Vcg" "../Simpl_Heap" Closure
begin


record globals =
 cnt_' :: "ref  nat"
 alloc_' :: "ref list"
 free_' :: "nat"
record 'g vars = "'g state" +
 p_':: ref
 r_':: nat
 n_':: nat
 m_':: nat
 c_':: "(string × ref) list × string"
 d_':: "(string × ref) list × string"
 e_':: "(string × nat) list × string"


definition "varn = [''n'' (λx. n_'_update (λ_. x)),
                    ''m'' (λx. m_'_update (λ_. x))]"
definition "updn = gen_upd varn"

lemma updn_ap: "updn (fst (ap es (es',p))) = updn es'  updn es"
  by (simp add: updn_def gen_upd_ap)


lemma
"Γ´n=n0  (i j. Γ ´n=i  ´m=j callClosure updn ´e ´r=i + j)
      ´e :== (ap [(''n'',´n)] ´e)
   j. Γ ´m=j callClosure updn ´e ´r=n0 + j"
apply vcg_step
apply clarify
apply (rule ap_closure [where var=varn, folded updn_def])
apply clarsimp
apply (rename_tac s s')
apply (erule_tac x="n_' s" in allE)
apply (erule_tac x="m_' s'" in allE)
apply (rule exI)
apply (rule exI)
apply (rule conjI)
apply (assumption)
apply (simp add: updn_def gen_upd_def varn_def)
done


definition "var = [''p'' (λx. p_'_update (λ_. x))]"
definition "upd = gen_upd var"

procedures Inc(p|r) =
 "´p→´cnt :== ´p→´cnt + 1;;
  ´r :== ´p→´cnt"

lemma (in Inc_impl)
 "i p. Γ ´p´cnt = i ´r :== PROC Inc(´p) ´r=i+1  ´p´cnt = i+1"
  apply vcg
  apply simp
  done

procedures (imports Inc_signature) NewCounter(|c) =
"´p :== NEW 1 [´cnt :== 0];;
 ´c :== ([(''p'',´p)],Inc_'proc)"


locale NewCounter_impl' = NewCounter_impl + Inc_impl
lemma (in NewCounter_impl')
shows
  "alloc. Γ 1  ´free ´c :== PROC NewCounter()
          p. p´cnt = 0 
               (i. Γ p´cnt = i callClosure upd ´c ´r=i+1  p´cnt = i+1)"
apply vcg
apply simp
apply (rule_tac x="new (set alloc)" in exI)
apply simp
apply (simp add: callClosure_def)
apply vcg_step
apply vcg_step
apply vcg_step
apply vcg_step
apply (simp add: upd_def var_def gen_upd_def)
done

lemma (in NewCounter_impl')

shows
  "alloc. Γ 1  ´free ´c :== PROC NewCounter()
          p. p´cnt = 0 
               (i. Γ p´cnt = i callClosure upd ´c ´r=i+1  p´cnt = i+1)"
apply vcg
apply simp
apply (rule_tac x="new (set alloc)" in exI)
apply simp
apply (simp add: callClosure_def)
apply vcg_step
apply vcg_step
apply vcg_step
apply vcg_step
apply (simp add: upd_def var_def gen_upd_def)
done

lemma (in NewCounter_impl')
shows NewCounter_spec:
  "alloc. Γ 1  ´free  ´alloc=alloc ´c :== PROC NewCounter()
          p. p  set alloc  p  set ´alloc  p  Null  p´cnt = 0 
               (i. Γ p´cnt = i callClosure upd ´c ´r=i+1  p´cnt = i+1)"
apply vcg
apply clarsimp
apply (rule_tac x="new (set alloc)" in exI)
apply simp
apply (simp add: callClosure_def)
apply vcg_step
apply vcg_step
apply vcg_step
apply vcg_step
apply (simp add: upd_def var_def gen_upd_def)
done



lemma "Γp. p  Null  p´cnt = i 
              (i. Γ p´cnt = i callClosure upd ´c ´r=i+1  p´cnt = i+1)
           dynCallClosure (λs. s) upd c_' (λs t. sglobals := globals t)
                         (λs t. Basic (λu. ur_' := r_' t))
           ´r=i+1"
apply (rule conseq_extract_pre)
apply clarify
apply (rule dynCallClosureFix)
apply (simp only: Ball_def)
prefer 3
apply (assumption)
prefer 2
apply vcg_step
apply vcg_step
apply (simp only: simp_thms)
apply clarsimp
done

declare [[hoare_trace = 1]]

ML val hoare_tacs = #hoare_tacs (Hoare.get_data @{context});
lemma (in NewCounter_impl')
 shows "Γ 1  ´free
             ´c :== CALL NewCounter ();;
             dynCallClosure (λs. s) upd c_' (λs t. sglobals := globals t)
                         (λs t. Basic (λu. ur_' := r_' t))
           ´r=1"
  apply vcg_step
apply (rule dynCallClosure)
prefer 2
apply vcg_step
apply vcg_step
apply vcg_step
apply clarsimp
apply (erule_tac x=0 in allE)
apply (rule exI)
apply (rule exI)
apply (rule conjI)
apply (assumption)
apply simp
done


lemma (in NewCounter_impl')
 shows "Γ 1  ´free
             ´c :== CALL NewCounter ();;
             dynCallClosure (λs. s) upd c_' (λs t. sglobals := globals t)
                         (λs t. Basic (λu. ur_' := r_' t));;
             dynCallClosure (λs. s) upd c_' (λs t. sglobals := globals t)
                         (λs t. Basic (λu. ur_' := r_' t))
           ´r=2"
apply vcg_step
apply (rule dynCallClosure)
prefer 2
apply vcg_step
apply vcg_step
apply vcg_step
apply (rule dynCallClosure)
apply vcg_step
apply vcg_step
apply vcg_step

apply clarsimp
apply (subgoal_tac "Γ p´cnt = 0 callClosure upd (c_' t) ´r = Suc 0  p´cnt = Suc 0")
apply (rule exI)
apply (rule exI)
apply (rule conjI)
apply assumption
apply clarsimp
apply (erule_tac x=1 in allE)
apply (rule exI)
apply (rule exI)
apply (rule conjI)
apply assumption
apply clarsimp
apply (erule allE)
apply assumption
done


lemma (in NewCounter_impl')
 shows "Γ 1  ´free
             ´c :== CALL NewCounter ();;
             ´d :== ´c;;
             dynCallClosure (λs. s) upd c_' (λs t. sglobals := globals t)
                         (λs t. Basic (λu. un_' := r_' t));;
             dynCallClosure (λs. s) upd d_' (λs t. sglobals := globals t)
                         (λs t. Basic (λu. um_' := r_' t));;
             ´r :== ´n + ´m
           ´r=3"

apply vcg_step
apply vcg_step
apply (rule dynCallClosure)
prefer 2
apply vcg_step
apply vcg_step
apply vcg_step
apply (rule dynCallClosure)
apply vcg_step
apply vcg_step
apply vcg_step
apply vcg_step
apply clarsimp
apply (subgoal_tac "Γ p´cnt = 0 callClosure upd (c_' t) ´r = Suc 0  p´cnt = Suc 0")
apply (rule exI)
apply (rule exI)
apply (rule conjI)
apply assumption
apply clarsimp
apply (erule_tac x=1 in allE)
apply (rule exI)
apply (rule exI)
apply (rule conjI)
apply assumption
apply clarsimp
apply (erule allE)
apply assumption
done

end