Remark var_names_app:
forall vars1 vars2, var_names (vars1 ++ vars2) = var_names vars1 ++ var_names vars2.
Remark filter_app:
forall (A: Type) (f: A -> bool) l1 l2,
List.filter f (l1 ++ l2) = List.filter f l1 ++ List.filter f l2.
Remark filter_charact:
forall (A: Type) (f: A -> bool) x l,
In x (List.filter f l) <-> In x l /\ f x = true.
Remark filter_norepet:
forall (A: Type) (f: A -> bool) l,
list_norepet l -> list_norepet (List.filter f l).
Remark filter_map:
forall (A B: Type) (f: A -> B) (pa: A -> bool) (pb: B -> bool),
(forall a, pb (f a) = pa a) ->
forall l, List.map f (List.filter pa l) = List.filter pb (List.map f l).

(* Specifications: *)
Lemma create_undef_temps_lifted:
forall id f,
~ In id (var_names (fn_params f)) ->
(create_undef_temps (add_lifted (cenv_for f) (fn_vars f) (fn_temps f))) ! id =
(create_undef_temps (add_lifted (cenv_for f) (fn_params f ++ fn_vars f) (fn_temps f))) ! id.
Lemma vars_and_temps_properties:
forall cenv params vars temps,
list_norepet (var_names params ++ var_names vars) ->
list_disjoint (var_names params) (var_names temps) ->
list_norepet (var_names params)
/\ list_norepet (var_names (remove_lifted cenv (params ++ vars)))
/\ list_disjoint (var_names params) (var_names (add_lifted cenv vars temps)).
Theorem match_envs_alloc_variables:
forall cenv m vars e m' temps j tm,
alloc_variables ge empty_env m vars e m' ->
list_norepet (var_names vars) ->
Mem.inject j m tm ->
(forall id ty, In (id, ty) vars -> VSet.mem id cenv = true ->
exists chunk, access_mode ty = By_value chunk) ->
(forall id, VSet.mem id cenv = true -> In id (var_names vars)) ->
exists j', exists te, exists tm',
alloc_variables tge empty_env tm (remove_lifted cenv vars) te tm'
/\ match_envs j' cenv e (create_undef_temps temps) m' (Mem.nextblock m) (Mem.nextblock m')
te (create_undef_temps (add_lifted cenv vars temps)) (Mem.nextblock tm) (Mem.nextblock tm')
/\ Mem.inject j' m' tm'
/\ inject_incr j j'
/\ (forall b, Mem.valid_block m b -> j' b = j b)
/\ (forall b b' delta, j' b = Some(b', delta) -> Mem.valid_block tm b' -> j' b = j b)
/\ (forall id ty, In (id, ty) vars -> VSet.mem id cenv = false -> exists b, te!id = Some(b, ty)).
Lemma assign_loc_inject:
forall f ty m loc ofs v m' tm loc' ofs' v',
assign_loc ge ty m loc ofs v m' ->
Val.inject f (Vptr loc ofs) (Vptr loc' ofs') ->
Val.inject f v v' ->
Mem.inject f m tm ->
exists tm',
assign_loc tge ty tm loc' ofs' v' tm'
/\ Mem.inject f m' tm'
/\ (forall b chunk v,
f b = None -> Mem.load chunk m b 0 = Some v -> Mem.load chunk m' b 0 = Some v).
Lemma assign_loc_nextblock:
forall ge ty m b ofs v m',
assign_loc ge ty m b ofs v m' -> Mem.nextblock m' = Mem.nextblock m.
Theorem store_params_correct:
forall j f k cenv le lo hi te tlo thi e m params args m',
bind_parameters ge e m params args m' ->
forall s tm tle1 tle2 targs,
list_norepet (var_names params) ->
list_forall2 val_casted args (map snd params) ->
Val.inject_list j args targs ->
match_envs j cenv e le m lo hi te tle1 tlo thi ->
Mem.inject j m tm ->
(forall id, ~In id (var_names params) -> tle2!id = tle1!id) ->
(forall id, In id (var_names params) -> le!id = None) ->
exists tle, exists tm',
star step2 tge (State f (store_params cenv params s) k te tle tm)
E0 (State f s k te tle tm')
/\ bind_parameter_temps params targs tle2 = Some tle
/\ Mem.inject j m' tm'
/\ match_envs j cenv e le m' lo hi te tle tlo thi
/\ Mem.nextblock tm' = Mem.nextblock tm.
Lemma bind_parameters_nextblock:
forall ge e m params args m',
bind_parameters ge e m params args m' -> Mem.nextblock m' = Mem.nextblock m.
Lemma bind_parameters_load:
forall ge e chunk b ofs,
(forall id b' ty, e!id = Some(b', ty) -> b <> b') ->
forall m params args m',
bind_parameters ge e m params args m' ->
Mem.load chunk m' b ofs = Mem.load chunk m b ofs.