Section EFFSEM.
Variable FE:function -> list val -> mem -> env -> temp_env -> mem -> Prop.
Inductive clight_effstep (ge:genv): (block -> Z -> bool) ->
CL_core -> mem -> CL_core -> mem -> Prop :=
| clight_effstep_assign:   forall f a1 a2 k e le m loc ofs v2 v m',
eval_lvalue ge e le m a1 loc ofs ->
eval_expr ge e le m a2 v2 ->
sem_cast v2 (typeof a2) (typeof a1) = Some v ->
assign_loc (typeof a1) m loc ofs v m' ->
clight_effstep ge (assign_loc_Effect (typeof a1) loc ofs v)
(CL_State f (Sassign a1 a2) k e le) m
(CL_State f Sskip k e le) m'
| clight_effstep_set:   forall f id a k e le m v,
eval_expr ge e le m a v ->
clight_effstep ge EmptyEffect (CL_State f (Sset id a) k e le) m
(CL_State f Sskip k e (PTree.set id v le)) m
| clight_effstep_call:   forall f optid a al k e le m tyargs tyres vf vargs fd,
classify_fun (typeof a) = fun_case_f tyargs tyres ->
eval_expr ge e le m a vf ->
eval_exprlist ge e le m al tyargs vargs ->
Genv.find_funct ge vf = Some fd ->
type_of_fundef fd = Tfunction tyargs tyres ->
clight_effstep ge EmptyEffect (CL_State f (Scall optid a al) k e le) m
(CL_Callstate fd vargs (Kcall optid f e le k)) m
(* WE DO NOT TREAT BUILTINS | clight_effstep_builtin:   forall f optid ef tyargs al k e le m vargs t vres m', eval_exprlist ge e le m al tyargs vargs -> external_call ef ge vargs m t vres m' -> clight_effstep ge (BuiltinEffect ge (ef_sig ef) vargs m) (CL_State f (Sbuiltin optid ef tyargs al) k e le) m (CL_State f Sskip k e (set_opttemp optid vres le)) m' *)
| clight_effstep_seq:  forall f s1 s2 k e le m,
clight_effstep ge EmptyEffect (CL_State f (Ssequence s1 s2) k e le) m
(CL_State f s1 (Kseq s2 k) e le) m
| clight_effstep_skip_seq: forall f s k e le m,
clight_effstep ge EmptyEffect (CL_State f Sskip (Kseq s k) e le) m
(CL_State f s k e le) m
| clight_effstep_continue_seq: forall f s k e le m,
clight_effstep ge EmptyEffect
(CL_State f Scontinue (Kseq s k) e le) m
(CL_State f Scontinue k e le) m
| clight_effstep_break_seq: forall f s k e le m,
clight_effstep ge EmptyEffect (CL_State f Sbreak (Kseq s k) e le) m
(CL_State f Sbreak k e le) m
| clight_effstep_ifthenelse:  forall f a s1 s2 k e le m v1 b,
eval_expr ge e le m a v1 ->
bool_val v1 (typeof a) = Some b ->
clight_effstep ge EmptyEffect
(CL_State f (Sifthenelse a s1 s2) k e le) m
(CL_State f (if b then s1 else s2) k e le) m
| clight_effstep_loop: forall f s1 s2 k e le m,
clight_effstep ge EmptyEffect
(CL_State f (Sloop s1 s2) k e le) m
(CL_State f s1 (Kloop1 s1 s2 k) e le) m
| clight_effstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x,
x = Sskip \/ x = Scontinue ->
clight_effstep ge EmptyEffect
(CL_State f x (Kloop1 s1 s2 k) e le) m
(CL_State f s2 (Kloop2 s1 s2 k) e le) m
| clight_effstep_break_loop1:  forall f s1 s2 k e le m,
clight_effstep ge EmptyEffect
(CL_State f Sbreak (Kloop1 s1 s2 k) e le) m
(CL_State f Sskip k e le) m
| clight_effstep_skip_loop2: forall f s1 s2 k e le m,
clight_effstep ge EmptyEffect
(CL_State f Sskip (Kloop2 s1 s2 k) e le) m
(CL_State f (Sloop s1 s2) k e le) m
| clight_effstep_break_loop2: forall f s1 s2 k e le m,
clight_effstep ge EmptyEffect
(CL_State f Sbreak (Kloop2 s1 s2 k) e le) m
(CL_State f Sskip k e le) m
| clight_effstep_return_0: forall f k e le m m',
Mem.free_list m (blocks_of_env e) = Some m' ->
clight_effstep ge (FreelistEffect m (blocks_of_env e))
(CL_State f (Sreturn None) k e le) m
(CL_Returnstate Vundef (call_cont k)) m'
| clight_effstep_return_1: forall f a k e le m v v' m',
eval_expr ge e le m a v ->
sem_cast v (typeof a) f.(fn_return) = Some v' ->
Mem.free_list m (blocks_of_env e) = Some m' ->
clight_effstep ge (FreelistEffect m (blocks_of_env e))
(CL_State f (Sreturn (Some a)) k e le) m
(CL_Returnstate v' (call_cont k)) m'
| clight_effstep_skip_call: forall f k e le m m',
is_call_cont k ->
Mem.free_list m (blocks_of_env e) = Some m' ->
clight_effstep ge (FreelistEffect m (blocks_of_env e))
(CL_State f Sskip k e le) m
(CL_Returnstate Vundef k) m'
| clight_effstep_switch: forall f a sl k e le m n,
eval_expr ge e le m a (Vint n) ->
clight_effstep ge EmptyEffect
(CL_State f (Sswitch a sl) k e le) m
(CL_State f (seq_of_labeled_statement (select_switch n sl)) (Kswitch k) e le) m
| clight_effstep_skip_break_switch: forall f x k e le m,
x = Sskip \/ x = Sbreak ->
clight_effstep ge EmptyEffect
(CL_State f x (Kswitch k) e le) m
(CL_State f Sskip k e le) m
| clight_effstep_continue_switch: forall f k e le m,
clight_effstep ge EmptyEffect
(CL_State f Scontinue (Kswitch k) e le) m
(CL_State f Scontinue k e le) m
| clight_effstep_label: forall f lbl s k e le m,
clight_effstep ge EmptyEffect
(CL_State f (Slabel lbl s) k e le) m
(CL_State f s k e le) m
| clight_effstep_goto: forall f lbl k e le m s' k',
find_label lbl f.(fn_body) (call_cont k) = Some (s', k') ->
clight_effstep ge EmptyEffect
(CL_State f (Sgoto lbl) k e le) m
(CL_State f s' k' e le) m
| clight_effstep_internal_function: forall f vargs k m e le m',
FE f vargs m e le m' ->
clight_effstep ge EmptyEffect
(CL_Callstate (Internal f) vargs k) m
(CL_State f f.(fn_body) k e le) m'
(*no external step | step_external_function: forall ef targs tres vargs k m vres t m', external_call ef ge vargs m t vres m' -> clight_effstep (CL_Callstate (External ef targs tres) vargs k) m (CL_Returnstate vres k) m' *)
| clight_effstep_returnstate: forall v optid f e le k m,
clight_effstep ge EmptyEffect
(CL_Returnstate v (Kcall optid f e le k)) m
(CL_State f Sskip k e (set_opttemp optid v le)) m
| clight_effstep_sub_val: forall E EE c m c' m',
(forall b ofs, Mem.valid_block m b ->
E b ofs = true -> EE b ofs = true) ->
clight_effstep ge E c m c' m' ->
clight_effstep ge EE c m c' m'.
Variable FE_FWD: forall f vargs m e le m', FE f vargs m e le m' -> mem_forward m m'.
Variable FE_UNCH: forall f vargs m e le m', FE f vargs m e le m'->
Mem.unchanged_on (fun b z => EmptyEffect b z = false) m m'.

Lemma clightstep_effax2: forall ge c m c' m',
corestep (CL_coop_sem FE FE_FWD) ge c m c' m' ->
exists M, clight_effstep ge M c m c' m'.