End INFERENCE.
(** * Type preservation during evaluation *)
(** The type system for RTL is not sound in that it does not guarantee progress: well-typed instructions such as [Icall] can fail because of run-time type tests (such as the equality between callee and caller's signatures).  However, the type system guarantees a type preservation property: if the execution does not fail because of a failed run-time test, the result values and register states match the static typing assumptions.  This preservation property will be useful later for the proof of semantic equivalence between [Linear] and [Mach]. Even though we do not need it for [RTL], we show preservation for [RTL] here, as a warm-up exercise and because some of the lemmas will be useful later. *)
Definition wt_regset (env: regenv) (rs: regset) : Prop :=
forall r, Val.has_type (rs#r) (env r).

(* Specifications: *)
Lemma wt_regset_assign:
forall env rs v r,
wt_regset env rs ->
Val.has_type v (env r) ->
wt_regset env (rs#r <- v).
Lemma wt_regset_list:
forall env rs,
wt_regset env rs ->
forall rl, Val.has_type_list (rs##rl) (List.map env rl).
Lemma wt_regset_setres:
forall env rs v res,
wt_regset env rs ->
Val.has_type v (type_of_builtin_res env res) ->
wt_regset env (regmap_setres res v rs).
Lemma wt_init_regs:
forall env rl args,
Val.has_type_list args (List.map env rl) ->
wt_regset env (init_regs args rl).
Lemma wt_exec_Iop:
forall (ge: genv) env f sp op args res s rs m v,
wt_instr f env (Iop op args res s) ->
eval_operation ge sp op rs##args m = Some v ->
wt_regset env rs ->
wt_regset env (rs#res <- v).
Lemma wt_exec_Iload:
forall env f chunk addr args dst s m a v rs,
wt_instr f env (Iload chunk addr args dst s) ->
Mem.loadv chunk m a = Some v ->
wt_regset env rs ->
wt_regset env (rs#dst <- v).
Lemma wt_exec_Ibuiltin:
forall env f ef (ge: genv) args res s vargs m t vres m' rs,
wt_instr f env (Ibuiltin ef args res s) ->
external_call ef ge vargs m t vres m' ->
wt_regset env rs ->
wt_regset env (regmap_setres res vres rs).
Lemma wt_instr_at:
forall f env pc i,
wt_function f env -> f.(fn_code)!pc = Some i -> wt_instr f env i.