Hint Resolve leftcontext_context.
(** Strategy for reducing expressions. We reduce the leftmost innermost non-simple subexpression, evaluating its arguments (which are necessarily simple expressions) with the big-step semantics. If there are none, the whole expression is simple and is evaluated in one big step. *)
Inductive estep: state -> trace -> state -> Prop :=
| step_expr: forall f r k e m v ty,
eval_simple_rvalue e m r v ->
match r with Eval _ _ => False | _ => True end ->
ty = typeof r ->
estep (ExprState f r k e m)
E0 (ExprState f (Eval v ty) k e m)
| step_rvalof_volatile: forall f C l ty k e m b ofs t v,
leftcontext RV RV C ->
eval_simple_lvalue e m l b ofs ->
deref_loc ge ty m b ofs t v ->
ty = typeof l -> type_is_volatile ty = true ->
estep (ExprState f (C (Evalof l ty)) k e m)
t (ExprState f (C (Eval v ty)) k e m)
| step_seqand_true: forall f C r1 r2 ty k e m v,
leftcontext RV RV C ->
eval_simple_rvalue e m r1 v ->
bool_val v (typeof r1) m = Some true ->
estep (ExprState f (C (Eseqand r1 r2 ty)) k e m)
E0 (ExprState f (C (Eparen r2 type_bool ty)) k e m)
| step_seqand_false: forall f C r1 r2 ty k e m v,
leftcontext RV RV C ->
eval_simple_rvalue e m r1 v ->
bool_val v (typeof r1) m = Some false ->
estep (ExprState f (C (Eseqand r1 r2 ty)) k e m)
E0 (ExprState f (C (Eval (Vint Int.zero) ty)) k e m)
| step_seqor_true: forall f C r1 r2 ty k e m v,
leftcontext RV RV C ->
eval_simple_rvalue e m r1 v ->
bool_val v (typeof r1) m = Some true ->
estep (ExprState f (C (Eseqor r1 r2 ty)) k e m)
E0 (ExprState f (C (Eval (Vint Int.one) ty)) k e m)
| step_seqor_false: forall f C r1 r2 ty k e m v,
leftcontext RV RV C ->
eval_simple_rvalue e m r1 v ->
bool_val v (typeof r1) m = Some false ->
estep (ExprState f (C (Eseqor r1 r2 ty)) k e m)
E0 (ExprState f (C (Eparen r2 type_bool ty)) k e m)
| step_condition: forall f C r1 r2 r3 ty k e m v b,
leftcontext RV RV C ->
eval_simple_rvalue e m r1 v ->
bool_val v (typeof r1) m = Some b ->
estep (ExprState f (C (Econdition r1 r2 r3 ty)) k e m)
E0 (ExprState f (C (Eparen (if b then r2 else r3) ty ty)) k e m)
| step_assign: forall f C l r ty k e m b ofs v v' t m',
leftcontext RV RV C ->
eval_simple_lvalue e m l b ofs ->
eval_simple_rvalue e m r v ->
sem_cast v (typeof r) (typeof l) m = Some v' ->
assign_loc ge (typeof l) m b ofs v' t m' ->
ty = typeof l ->
estep (ExprState f (C (Eassign l r ty)) k e m)
t (ExprState f (C (Eval v' ty)) k e m')
| step_assignop: forall f C op l r tyres ty k e m b ofs v1 v2 v3 v4 t1 t2 m' t,
leftcontext RV RV C ->
eval_simple_lvalue e m l b ofs ->
deref_loc ge (typeof l) m b ofs t1 v1 ->
eval_simple_rvalue e m r v2 ->
sem_binary_operation ge op v1 (typeof l) v2 (typeof r) m = Some v3 ->
sem_cast v3 tyres (typeof l) m = Some v4 ->
assign_loc ge (typeof l) m b ofs v4 t2 m' ->
ty = typeof l ->
t = t1 ** t2 ->
estep (ExprState f (C (Eassignop op l r tyres ty)) k e m)
t (ExprState f (C (Eval v4 ty)) k e m')
| step_assignop_stuck: forall f C op l r tyres ty k e m b ofs v1 v2 t,
leftcontext RV RV C ->
eval_simple_lvalue e m l b ofs ->
deref_loc ge (typeof l) m b ofs t v1 ->
eval_simple_rvalue e m r v2 ->
match sem_binary_operation ge op v1 (typeof l) v2 (typeof r) m with
| None => True
| Some v3 =>
match sem_cast v3 tyres (typeof l) m with
| None => True
| Some v4 => forall t2 m', ~(assign_loc ge (typeof l) m b ofs v4 t2 m')
end
end ->
ty = typeof l ->
estep (ExprState f (C (Eassignop op l r tyres ty)) k e m)
t Stuckstate
| step_postincr: forall f C id l ty k e m b ofs v1 v2 v3 t1 t2 m' t,
leftcontext RV RV C ->
eval_simple_lvalue e m l b ofs ->
deref_loc ge ty m b ofs t1 v1 ->
sem_incrdecr ge id v1 ty m = Some v2 ->
sem_cast v2 (incrdecr_type ty) ty m = Some v3 ->
assign_loc ge ty m b ofs v3 t2 m' ->
ty = typeof l ->
t = t1 ** t2 ->
estep (ExprState f (C (Epostincr id l ty)) k e m)
t (ExprState f (C (Eval v1 ty)) k e m')
| step_postincr_stuck: forall f C id l ty k e m b ofs v1 t,
leftcontext RV RV C ->
eval_simple_lvalue e m l b ofs ->
deref_loc ge ty m b ofs t v1 ->
match sem_incrdecr ge id v1 ty m with
| None => True
| Some v2 =>
match sem_cast v2 (incrdecr_type ty) ty m with
| None => True
| Some v3 => forall t2 m', ~(assign_loc ge (typeof l) m b ofs v3 t2 m')
end
end ->
ty = typeof l ->
estep (ExprState f (C (Epostincr id l ty)) k e m)
t Stuckstate
| step_comma: forall f C r1 r2 ty k e m v,
leftcontext RV RV C ->
eval_simple_rvalue e m r1 v ->
ty = typeof r2 ->
estep (ExprState f (C (Ecomma r1 r2 ty)) k e m)
E0 (ExprState f (C r2) k e m)
| step_paren: forall f C r tycast ty k e m v1 v,
leftcontext RV RV C ->
eval_simple_rvalue e m r v1 ->
sem_cast v1 (typeof r) tycast m = Some v ->
estep (ExprState f (C (Eparen r tycast ty)) k e m)
E0 (ExprState f (C (Eval v ty)) k e m)
| step_call: forall f C rf rargs ty k e m targs tres cconv vf vargs fd,
leftcontext RV RV C ->
classify_fun (typeof rf) = fun_case_f targs tres cconv ->
eval_simple_rvalue e m rf vf ->
eval_simple_list e m rargs targs vargs ->
Genv.find_funct ge vf = Some fd ->
type_of_fundef fd = Tfunction targs tres cconv ->
estep (ExprState f (C (Ecall rf rargs ty)) k e m)
E0 (Callstate fd vargs (Kcall f e C ty k) m)
| step_builtin: forall f C ef tyargs rargs ty k e m vargs t vres m',
leftcontext RV RV C ->
eval_simple_list e m rargs tyargs vargs ->
external_call ef ge vargs m t vres m' ->
estep (ExprState f (C (Ebuiltin ef tyargs rargs ty)) k e m)
t (ExprState f (C (Eval vres ty)) k e m').
Definition step (S: state) (t: trace) (S': state) : Prop :=
estep S t S' \/ sstep ge S t S'.
(** Properties of contexts *)

Lemma context_compose:
forall k2 k3 C2, context k2 k3 C2 ->
forall k1 C1, context k1 k2 C1 ->
context k1 k3 (fun x => C2(C1 x))
with contextlist_compose:
forall k2 C2, contextlist k2 C2 ->
forall k1 C1, context k1 k2 C1 ->
contextlist k1 (fun x => C2(C1 x)).