(* Simultaneous evaluation of a list of expressions *)
Fixpoint list_eval (es:list expr) (vs:list val) : pred world :=
match es, vs with
| e::es', v::vs' => eval e v && list_eval es' vs'
| nil, nil => TT
| _, _ => FF
end.

(* Specifications: *)
(* List evaluation likewise passes into larger worlds. *)
Lemma list_eval_up : forall es vals P Q,
(P && list_eval es vals) * Q |--
(P * Q) && list_eval es vals.
(* The make_locals function actually satisfies the func_start_locals predicate. *)
Lemma make_locals_func_start_locals : forall fd vs n m,
identity m ->
func_start_locals fd vs (n,(make_locals vs fd,m)).
(* The 'defined' predicate is sufficent to successfully perform a local variable update. *)
Lemma defined_update : forall i P n rho m v,
(defined i * P)%pred (n,(rho,m)) ->
exists rho',
LocalsMap.map_upd i v rho = Some rho' /\
(hasval i v * P)%pred (n,(rho',m)).
(* mapsto imp the ability to read from memory *)
Lemma mapsto_val : forall a sh v P n rho m,
(mapsto a sh v * P )%pred(n,(rho,m)) ->
MemMap.map_val a m = Some v.
(* mapsto with the full share imp that memory stores will succeed. *)
Lemma mapsto_update : forall a v v' P n rho m,
(mapsto a Share.top v * P)%pred (n,(rho,m)) ->
exists m',
MemMap.map_upd a v' m = Some m' /\
(mapsto a Share.top v' * P)%pred (n,(rho,m')).
(* rguards is insensitive to 'kseq' constructors on the top of the stack. *)
Lemma rguards_unwind : forall pu R F k1 k2 w1 w2,
unwind_return k1 = unwind_return k2 ->
necR w1 w2 ->
rguards pu R F k1 w1 -> rguards pu R F k2 w2.
(* Some additional facts about evaluation *)
Lemma list_eval_join_sub : forall es vs w1 w2,
join_sub w1 w2 ->
list_eval es vs w1 ->
list_eval es vs w2.
Lemma list_eval_evaluate_exprs : forall es vs w,
list_eval es vs w ->
evaluate_exprs (fst (snd w)) es vs.