Definition optval_self_injects (ov: option val) : Prop :=
  match ov with
  | Some (Vptr b ofs) => False
  | _ => True
  end.Remark sem_binarith_inject:
  forall sem_int sem_long sem_float sem_single v1 t1 v2 t2 v v1' v2',
  sem_binarith sem_int sem_long sem_float sem_single v1 t1 v2 t2 m = Some v ->
  Val.inject f v1 v1' -> Val.inject f v2 v2' ->
  (forall sg n1 n2, optval_self_injects (sem_int sg n1 n2)) ->
  (forall sg n1 n2, optval_self_injects (sem_long sg n1 n2)) ->
  (forall n1 n2, optval_self_injects (sem_float n1 n2)) ->
  (forall n1 n2, optval_self_injects (sem_single n1 n2)) ->
  exists v', sem_binarith sem_int sem_long sem_float sem_single v1' t1 v2' t2 m' = Some v' /\ Val.inject f v v'.Remark sem_shift_inject:
  forall sem_int sem_long v1 t1 v2 t2 v v1' v2',
  sem_shift sem_int sem_long v1 t1 v2 t2 = Some v ->
  Val.inject f v1 v1' -> Val.inject f v2 v2' ->
  exists v', sem_shift sem_int sem_long v1' t1 v2' t2 = Some v' /\ Val.inject f v v'.Remark sem_cmp_ptr_inj:
  forall c v1 v2 v tv1 tv2,
  cmp_ptr m c v1 v2 = Some v ->
  Val.inject f v1 tv1 ->
  Val.inject f v2 tv2 ->
  exists tv, cmp_ptr m' c tv1 tv2 = Some tv /\ Val.inject f v tv.Remark sem_cmp_inj:
  forall cmp v1 tv1 ty1 v2 tv2 ty2 v,
  sem_cmp cmp v1 ty1 v2 ty2 m = Some v ->
  Val.inject f v1 tv1 ->
  Val.inject f v2 tv2 ->
  exists tv, sem_cmp cmp tv1 ty1 tv2 ty2 m' = Some tv /\ Val.inject f v tv.

(* Specifications: *)
Lemma sem_binary_operation_inj: forall cenv op v1 ty1 v2 ty2 v tv1 tv2, sem_binary_operation cenv op v1 ty1 v2 ty2 m = Some v -> Val.inject f v1 tv1 -> Val.inject f v2 tv2 -> exists tv, sem_binary_operation cenv op tv1 ty1 tv2 ty2 m' = Some tv /\ Val.inject f v tv.
Lemma sem_cast_inject: forall f v1 ty1 ty m v tv1 tm, sem_cast v1 ty1 ty m = Some v -> Val.inject f v1 tv1 -> Mem.inject f m tm -> exists tv, sem_cast tv1 ty1 ty tm = Some tv /\ Val.inject f v tv.
Lemma sem_unary_operation_inject: forall f m m' op v1 ty1 v tv1, sem_unary_operation op v1 ty1 m = Some v -> Val.inject f v1 tv1 -> Mem.inject f m m' -> exists tv, sem_unary_operation op tv1 ty1 m' = Some tv /\ Val.inject f v tv.
Lemma sem_binary_operation_inject: forall f m m' cenv op v1 ty1 v2 ty2 v tv1 tv2, sem_binary_operation cenv op v1 ty1 v2 ty2 m = Some v -> Val.inject f v1 tv1 -> Val.inject f v2 tv2 -> Mem.inject f m m' -> exists tv, sem_binary_operation cenv op tv1 ty1 tv2 ty2 m' = Some tv /\ Val.inject f v tv.
Lemma bool_val_inject: forall f m m' v ty b tv, bool_val v ty m = Some b -> Val.inject f v tv -> Mem.inject f m m' -> bool_val tv ty m' = Some b.
Lemma cast_bool_bool_val: forall v t m, sem_cast v t (Tint IBool Signed noattr) m = match bool_val v t m with None => None | Some b => Some(Val.of_bool b) end.
Lemma notbool_bool_val: forall v t m, sem_notbool v t m = match bool_val v t m with None => None | Some b => Some(Val.of_bool (negb b)) end.
Lemma sem_binary_operation_inj: forall cenv op v1 ty1 v2 ty2 v tv1 tv2, sem_binary_operation cenv op v1 ty1 v2 ty2 m = Some v -> Val.inject f v1 tv1 -> Val.inject f v2 tv2 -> exists tv, sem_binary_operation cenv op tv1 ty1 tv2 ty2 m' = Some tv /\ Val.inject f v tv.
Lemma sem_cast_inject: forall f v1 ty1 ty m v tv1 tm, sem_cast v1 ty1 ty m = Some v -> Val.inject f v1 tv1 -> Mem.inject f m tm -> exists tv, sem_cast tv1 ty1 ty tm = Some tv /\ Val.inject f v tv.
Lemma sem_unary_operation_inject: forall f m m' op v1 ty1 v tv1, sem_unary_operation op v1 ty1 m = Some v -> Val.inject f v1 tv1 -> Mem.inject f m m' -> exists tv, sem_unary_operation op tv1 ty1 m' = Some tv /\ Val.inject f v tv.
Lemma sem_binary_operation_inject: forall f m m' cenv op v1 ty1 v2 ty2 v tv1 tv2, sem_binary_operation cenv op v1 ty1 v2 ty2 m = Some v -> Val.inject f v1 tv1 -> Val.inject f v2 tv2 -> Mem.inject f m m' -> exists tv, sem_binary_operation cenv op tv1 ty1 tv2 ty2 m' = Some tv /\ Val.inject f v tv.
Lemma bool_val_inject: forall f m m' v ty b tv, bool_val v ty m = Some b -> Val.inject f v tv -> Mem.inject f m m' -> bool_val tv ty m' = Some b.
Lemma cast_bool_bool_val: forall v t m, sem_cast v t (Tint IBool Signed noattr) m = match bool_val v t m with None => None | Some b => Some(Val.of_bool b) end.
Lemma notbool_bool_val: forall v t m, sem_notbool v t m = match bool_val v t m with None => None | Some b => Some(Val.of_bool (negb b)) end.