(** In addition to type preservation during evaluation, we also show properties of the environment [ls] at call points and at return points. These properties are used in the proof of the [Stacking] pass. For call points, we have that the current environment [ls] and the one from the top call stack agree on the [Outgoing] locations used for parameter passing. *)
Definition agree_outgoing_arguments (sg: signature) (ls pls: locset) : Prop :=
forall ty ofs,
In (S Outgoing ofs ty) (regs_of_rpairs (loc_arguments sg)) ->
ls (S Outgoing ofs ty) = pls (S Outgoing ofs ty).
(** For return points, we have that all [Outgoing] stack locations have been set to [Vundef]. *)
Definition outgoing_undef (ls: locset) : Prop :=
forall ty ofs, ls (S Outgoing ofs ty) = Vundef.
(** Soundness of the type system *)
Definition wt_fundef (fd: fundef) :=
match fd with
| Internal f => wt_function f = true
| External ef => True
end.
Inductive wt_callstack: list stackframe -> Prop :=
| wt_callstack_nil:
wt_callstack nil
| wt_callstack_cons: forall f sp rs c s
(WTSTK: wt_callstack s)
(WTF: wt_function f = true)
(WTC: wt_code f c = true)
(WTRS: wt_locset rs),
wt_callstack (Stackframe f sp rs c :: s).

Lemma wt_parent_locset:
forall s, wt_callstack s -> wt_locset (parent_locset s).