Inductive wt_stackframes: list stackframe -> signature -> Prop :=
| wt_stackframes_nil: forall sg,
sg.(sig_res) = Some Tint ->
wt_stackframes nil sg
| wt_stackframes_cons:
forall s res f sp pc rs env sg,
wt_function f env ->
wt_regset env rs ->
env res = proj_sig_res sg ->
wt_stackframes s (fn_sig f) ->
wt_stackframes (Stackframe res f sp pc rs :: s) sg.
Inductive wt_state: state -> Prop :=
| wt_state_intro:
forall s f sp pc rs m env
(WT_STK: wt_stackframes s (fn_sig f))
(WT_FN: wt_function f env)
(WT_RS: wt_regset env rs),
wt_state (State s f sp pc rs m)
| wt_state_call:
forall s f args m,
wt_stackframes s (funsig f) ->
wt_fundef f ->
Val.has_type_list args (sig_args (funsig f)) ->
wt_state (Callstate s f args m)
| wt_state_return:
forall s v m sg,
wt_stackframes s sg ->
Val.has_type v (proj_sig_res sg) ->
wt_state (Returnstate s v m).
Remark wt_stackframes_change_sig:
forall s sg1 sg2,
sg1.(sig_res) = sg2.(sig_res) -> wt_stackframes s sg1 -> wt_stackframes s sg2.
Section SUBJECT_REDUCTION.
Variable p: program.
Hypothesis wt_p: wt_program p.
Let ge := Genv.globalenv p.

Lemma wt_instr_inv:
forall s f sp pc rs m i,
wt_state (State s f sp pc rs m) ->
f.(fn_code)!pc = Some i ->
exists env, wt_instr f env i /\ wt_regset env rs.