Section SUBJECT_REDUCTION.
Variable p: program.
Hypothesis wt_p: wt_program p.
Let ge := Genv.globalenv p.
Ltac VHT :=
match goal with
| [ |- Val.has_type (if Archi.ptr64 then _ else _) _] => unfold Val.has_type; destruct Archi.ptr64 eqn:?; VHT
| [ |- Val.has_type (match ?v with _ => _ end) _] => destruct v; VHT
| [ |- Val.has_type (Vptr _ _) Tptr ] => apply Val.Vptr_has_type
| [ |- Val.has_type _ _ ] => exact I
| [ |- Val.has_type (?f _ _ _ _ _) _ ] => unfold f; VHT
| [ |- Val.has_type (?f _ _ _ _) _ ] => unfold f; VHT
| [ |- Val.has_type (?f _ _) _ ] => unfold f; VHT
| [ |- Val.has_type (?f _ _ _) _ ] => unfold f; VHT
| [ |- Val.has_type (?f _) _ ] => unfold f; VHT
| [ |- True ] => exact I
| [ |- ?x = ?x ] => reflexivity
| _ => idtac
end.
Ltac VHT' :=
match goal with
| [ H: None = Some _ |- _ ] => discriminate
| [ H: Some _ = Some _ |- _ ] => inv H; VHT
| [ H: match ?x with _ => _ end = Some _ |- _ ] => destruct x; VHT'
| [ H: ?f _ _ _ _ = Some _ |- _ ] => unfold f in H; VHT'
| [ H: ?f _ _ _ = Some _ |- _ ] => unfold f in H; VHT'
| [ H: ?f _ _ = Some _ |- _ ] => unfold f in H; VHT'
| [ H: ?f _ = Some _ |- _ ] => unfold f in H; VHT'
| _ => idtac
end.

Lemma type_binop_sound: forall op v1 v2 m v,
eval_binop op v1 v2 m = Some v -> Val.has_type v (snd (type_binop op)).