Section Clight_safety_equivalence.
Context (CPROOF : semax_to_juicy_machine.CSL_proof).
Definition prog:= CPROOF.(CSL_prog).
Definition ge:= Clight.globalenv prog.
Definition init_mem:= proj1_sig (init_mem CPROOF).
(*We should be able to construct a Clight.state from the proof... *)
Definition f_main : {f | Genv.find_funct_ptr (Clight.genv_genv ge) (projT1 (spr CPROOF)) = Some f}.
Inductive match_ctl : ctl -> ctl -> Prop :=
| match_Krun c c' : match_states c (fst (CC'.CC_state_to_CC_core c')) -> match_ctl (Krun c) (Krun c')
| match_Kblocked c c' : match_states c (fst (CC'.CC_state_to_CC_core c')) -> match_ctl (Kblocked c) (Kblocked c')
| match_Kresume c c' v : match_states c (fst (CC'.CC_state_to_CC_core c')) -> match_ctl (Kresume c v) (Kresume c' v)
| match_Kinit v v' : match_ctl (Kinit v v') (Kinit v v').
(* This should essentially reproduce Clight_sim at the hybrid machine level. *)
Inductive match_st (tp : ThreadPool.t(resources := dryResources)(ThreadPool:= threadPool.OrdinalPool.OrdinalThreadPool(Sem:=Clight_newSem ge)))
(tp' : ThreadPool.t(resources := dryResources)(ThreadPool:= threadPool.OrdinalPool.OrdinalThreadPool(Sem:=ClightSem ge))) : Prop :=
MATCH_ST: forall (mtch_cnt: forall {tid},  containsThread tp tid -> containsThread tp' tid)
(mtch_cnt': forall {tid}, containsThread tp' tid -> containsThread tp tid)
(mtch_gtc: forall {tid} (Htid:containsThread tp tid)(Htid':containsThread tp' tid),
match_ctl (getThreadC Htid) (getThreadC Htid'))
(mtch_gtr1: forall {tid} (Htid:containsThread tp tid)(Htid':containsThread tp' tid)
b ofs,
(fst (getThreadR Htid)) !! b ofs = (fst (getThreadR Htid')) !! b ofs)
(mtch_gtr2: forall {tid} (Htid:containsThread tp tid)(Htid':containsThread tp' tid),
snd (getThreadR Htid) = snd (getThreadR Htid'))
(mtch_locks: forall a, lockRes tp a = lockRes tp' a)
(mtch_latest: latestThread tp = latestThread tp'),
match_st tp tp'.
Existing Instance scheduler.
Existing Instance DilMem.
Instance ClightAxioms : @CoreLanguage.SemAxioms (ClightSem ge).
Opaque updThread updThreadC containsThread getThreadC getThreadR lockRes.
Definition MachStateDry := @MachState dryResources (Clight_newSem ge)
(@OrdinalPool.OrdinalThreadPool dryResources (Clight_newSem ge)).
(* SearchHead (MachState -> _). Print Val.inject. Definition flat_inject (v: memval) *)
Definition threadpool_of (st: MachStateDry) :=    match st with (_, _, tp) => tp end.
Definition dryThreadPool := @ThreadPool.t dryResources (Clight_newSem ge)
(@OrdinalPool.OrdinalThreadPool dryResources (Clight_newSem ge)).
Definition ctl_ok nextb (c: @ctl Clight_new.corestate) : Prop :=
match c with
| Krun q => corestate_ok nextb q
| Kblocked q => corestate_ok nextb q
| Kresume q v => corestate_ok nextb q /\ val_ok nextb v
| Kinit v1 v2 => val_ok nextb v1 /\ val_ok nextb v2
end.
Definition mem_ok (tp: dryThreadPool) m :=
Smallstep.globals_not_fresh (Clight.genv_genv ge) m /\
mem_wd2 m /\
(forall i (CT: containsThread tp i),
ctl_ok (Mem.nextblock m) (getThreadC CT)).
(* spawn handler *)
Notation tvoidptr := (Tpointer Tvoid noattr).
Notation tvoidfun := (Tfunction (Tcons tvoidptr Tnil) tvoidptr AST.cc_default).
Definition f_wrapper : Clight.function :=
{| Clight.fn_return := Tvoid; Clight.fn_callconv := AST.cc_default;
Clight.fn_params := [(1%positive, tvoidfun); (2%positive, tvoidptr)];
Clight.fn_vars := []; Clight.fn_temps := [];
Clight.fn_body := Clight.Scall None (Clight.Etempvar 1%positive tvoidfun) [Clight.Etempvar 2%positive tvoidptr] |}.
(*Todo Explain the following definition *)
Class spawn_wrapper := { lookup_wrapper: exists b_wrapper, Genv.find_funct_ptr (Clight.genv_genv ge) b_wrapper = Some (Ctypes.Internal f_wrapper)}.
Context {SW : spawn_wrapper}.

Lemma match_body: forall body f te,
match_cont
(Clight_new.strip_skip
[Clight_new.Kseq body; Clight_new.Kseq (Clight.Sreturn None);
Clight_new.Kcall None f Clight.empty_env te;
Clight_new.Kseq (Clight.Sloop Clight.Sskip Clight.Sskip)])
(strip_skip'
(CC.Kseq body
(Clight.Kcall None f_wrapper Clight.empty_env te (Clight.Kseq (Clight.Sloop Clight.Sskip Clight.Sskip) Clight.Kstop)))).