Section CMCONSTR.
Variable ge: genv.
Variable sp: val.
Variable e: env.
Variable m: mem.
(** We now show that the code generated by "smart constructor" functions such as [Selection.notint] behaves as expected.  Continuing the [notint] example, we show that if the expression [e] evaluates to some integer value [Vint n], then [Selection.notint e] evaluates to a value [Vint (Int.not n)] which is indeed the integer negation of the value of [e].  All proofs follow a common pattern: - Reasoning by case over the result of the classification functions (such as [add_match] for integer addition), gathering additional information on the shape of the argument expressions in the non-default cases. - Inversion of the evaluations of the arguments, exploiting the additional information thus gathered. - Equational reasoning over the arithmetic operations performed, using the lemmas from the [Int] and [Float] modules. - Construction of an evaluation derivation for the expression returned by the smart constructor. *)
Definition unary_constructor_sound (cstr: expr -> expr) (sem: val -> val) : Prop :=
forall le a x,
eval_expr ge sp e m le a x ->
exists v, eval_expr ge sp e m le (cstr a) v /\ Val.lessdef (sem x) v.
Definition binary_constructor_sound (cstr: expr -> expr -> expr) (sem: val -> val -> val) : Prop :=
forall le a x b y,
eval_expr ge sp e m le a x ->
eval_expr ge sp e m le b y ->
exists v, eval_expr ge sp e m le (cstr a b) v /\ Val.lessdef (sem x y) v.
(** ** Constants *)
(** ** Addition, opposite, subtraction *)
(** ** Immediate shifts *)
Remark eval_shlimm_base: forall le a n x,
eval_expr ge sp e m le a x ->
Int.ltu n Int.iwordsize = true ->
eval_expr ge sp e m le (shlimm_base a n) (Val.shl x (Vint n)).
Remark eval_shruimm_base: forall le a n x,
eval_expr ge sp e m le a x ->
Int.ltu n Int.iwordsize = true ->
eval_expr ge sp e m le (shruimm_base a n) (Val.shru x (Vint n)).
Remark sub_shift_amount:
forall y z,
Int.ltu y Int.iwordsize = true -> Int.ltu z Int.iwordsize = true -> Int.unsigned y <= Int.unsigned z ->
Int.ltu (Int.sub z y) Int.iwordsize = true.
Remark eval_shrimm_base: forall le a n x,
eval_expr ge sp e m le a x ->
Int.ltu n Int.iwordsize = true ->
eval_expr ge sp e m le (shrimm_base a n) (Val.shr x (Vint n)).
(** ** Multiplication *)
(** Integer conversions *)
(** Bitwise not, and, or, xor *)
Remark eval_same_expr:
forall a1 a2 le v1 v2,
same_expr_pure a1 a2 = true ->
eval_expr ge sp e m le a1 v1 ->
eval_expr ge sp e m le a2 v2 ->
a1 = a2 /\ v1 = v2.
(** ** Integer division and modulus *)

Theorem eval_shrximm:
forall le a n x z,
eval_expr ge sp e m le a x ->
Val.shrx x (Vint n) = Some z ->
exists v, eval_expr ge sp e m le (shrximm a n) v /\ Val.lessdef z v.