Fixpoint set_params' (vl: list val) (il: list ident) (te: Cminor.env) : Cminor.env :=
match il, vl with
| i1 :: is, v1 :: vs => set_params' vs is (PTree.set i1 v1 te)
| i1 :: is, nil => set_params' nil is (PTree.set i1 Vundef te)
| _, _ => te
end.

(* Specifications: *)
Lemma bind_parameters_agree_rec:
forall f vars vals tvals le1 le2 te,
bind_parameters vars vals le1 = Some le2 ->
Val.inject_list f vals tvals ->
match_temps f le1 te ->
match_temps f le2 (set_params' tvals vars te).
Lemma set_params'_outside:
forall id il vl te, ~In id il -> (set_params' vl il te)!id = te!id.
Lemma set_params'_inside:
forall id il vl te1 te2,
In id il ->
(set_params' vl il te1)!id = (set_params' vl il te2)!id.
Lemma set_params_set_params':
forall il vl id,
list_norepet il ->
(set_params vl il)!id = (set_params' vl il (PTree.empty val))!id.
Lemma set_locals_outside:
forall e id il,
~In id il -> (set_locals il e)!id = e!id.
Lemma set_locals_inside:
forall e id il,
In id il -> (set_locals il e)!id = Some Vundef.
Lemma set_locals_set_params':
forall vars vals params id,
list_norepet params ->
list_disjoint params vars ->
(set_locals vars (set_params vals params)) ! id =
(set_params' vals params (set_locals vars (PTree.empty val))) ! id.
Lemma bind_parameters_agree:
forall f params temps vals tvals le,
bind_parameters params vals (create_undef_temps temps) = Some le ->
Val.inject_list f vals tvals ->
list_norepet params ->
list_disjoint params temps ->
match_temps f le (set_locals temps (set_params tvals params)).