Section function_entry_locals.
Variable vals:list val.
Variable fd:fun_decl.
Let actuals := combine (fnd_formals fd) vals.
Definition make_locals := ShareMap.build_map _ _ _ (actuals ++ fnd_locals fd).
End function_entry_locals.
(* unwind_return drops all the leading kseq constructions to finde the correct function return position *)
Fixpoint unwind_return (k:ctl) : option (ident * locals * ctl):=
match k with
| kseq _ k' => unwind_return k'
| kcall i rho k => Some (i,rho,k)
| kext _ _ _ _ => None
| knil => None
end.
(* Main small step semantics definition. We send state (k,rho,m) to state (k',rho',m') when we execute command c (in program p). *)
Inductive step (pu:program_unit) :
forall (k:ctl) (rho:locals) (m:mem)
(c:cmd)
(k':ctl) (rho':locals) (m':mem), Prop :=
| step_skip : forall k rho m,
step pu  k rho m
skip
k rho m
| step_seq : forall k rho m c1 c2,
step pu k rho m
(seq c1 c2)
(kseq c1 (kseq c2 k)) rho m
| step_if_false : forall k rho m e c1 c2,
proj1_sig e rho = Some (int_val 0) ->
step pu k rho m
(cif e c1 c2)
(kseq c2 k) rho m
| step_if_true : forall k rho m x e c1 c2,
x <> 0 ->
proj1_sig e rho = Some (int_val x) ->
step pu k rho m
(cif e c1 c2)
(kseq c1 k) rho m
| step_while_false : forall k rho m e c,
proj1_sig e rho = Some (int_val 0) ->
step pu k rho m
(while e c)
k rho m
| step_while_true : forall k rho m e c x,
x <> 0 ->
proj1_sig e rho = Some (int_val x) ->
step pu k rho m
(while e c)
(kseq c (kseq (while e c) k)) rho m
| step_ret : forall k rho m e v i rho' k' rho'',
proj1_sig e rho = Some v ->
unwind_return k = (Some (i,rho',k')) ->
ShareMap.map_upd _ _ _ i v rho' = Some rho'' ->
step pu k rho m
(ret e)
k' rho''  m
| step_call_internal : forall k rho m x f exps vals fd,
evaluate_exprs rho exps vals ->
pu f = Some fd ->
step pu k rho m
(call x f exps)
(kseq (fnd_cmd fd) (kcall x rho k))
(make_locals vals fd) m
| step_call_external : forall k rho m x f exps vals,
pu f = None ->
evaluate_exprs rho exps vals ->
step pu k rho m
(call x f exps)
(kext x f vals k) rho m
| step_assign : forall k rho rho' m i e v,
proj1_sig e rho = Some v ->
ShareMap.map_upd _ _ _ i v rho = Some rho' ->
step pu k rho m
(assign i e)
k rho' m
| step_load : forall k rho rho' m i e a v,
proj1_sig e rho = Some (ptr_val a) ->
ShareMap.map_val _ _ a m = Some v ->
ShareMap.map_upd _ _ _ i v rho = Some rho' ->
step pu k rho m
(load i e)
k rho' m
| step_store : forall k rho m e1 a e2 v m',
proj1_sig e1 rho = Some (ptr_val a) ->
proj1_sig e2 rho = Some v ->
ShareMap.map_upd _ _ _ a v m = Some m' ->
step pu k rho m
(store e1 e2)
k rho m'.
(* Pull off the outermost command and execute it *)
Inductive step' (pu:program_unit) :
forall (st st':state), Prop :=
| step'_step : forall c k rho m k' rho' m',
step  pu k rho m c k' rho' m' ->
step' pu (kseq c k,rho,m) (k',rho',m').

(* The small step semantics is functional (deterministic) *)
Lemma step_fun : forall pu k rho m c k1 rho1 m1 k2 rho2 m2,
step pu k rho m c k1 rho1 m1 ->
step pu k rho m c k2 rho2 m2 ->
(k1,rho1,m1) = (k2,rho2,m2).