Section GENERIC_INJECTION.
Variable f: meminj.
Variables m m': mem.
Hypothesis valid_pointer_inj:
forall b1 ofs b2 delta,
f b1 = Some(b2, delta) ->
Mem.valid_pointer m b1 (Ptrofs.unsigned ofs) = true ->
Mem.valid_pointer m' b2 (Ptrofs.unsigned (Ptrofs.add ofs (Ptrofs.repr delta))) = true.
Hypothesis weak_valid_pointer_inj:
forall b1 ofs b2 delta,
f b1 = Some(b2, delta) ->
Mem.weak_valid_pointer m b1 (Ptrofs.unsigned ofs) = true ->
Mem.weak_valid_pointer m' b2 (Ptrofs.unsigned (Ptrofs.add ofs (Ptrofs.repr delta))) = true.
Hypothesis weak_valid_pointer_no_overflow:
forall b1 ofs b2 delta,
f b1 = Some(b2, delta) ->
Mem.weak_valid_pointer m b1 (Ptrofs.unsigned ofs) = true ->
0 <= Ptrofs.unsigned ofs + Ptrofs.unsigned (Ptrofs.repr delta) <= Ptrofs.max_unsigned.
Hypothesis valid_different_pointers_inj:
forall b1 ofs1 b2 ofs2 b1' delta1 b2' delta2,
b1 <> b2 ->
Mem.valid_pointer m b1 (Ptrofs.unsigned ofs1) = true ->
Mem.valid_pointer m b2 (Ptrofs.unsigned ofs2) = true ->
f b1 = Some (b1', delta1) ->
f b2 = Some (b2', delta2) ->
b1' <> b2' \/
Ptrofs.unsigned (Ptrofs.add ofs1 (Ptrofs.repr delta1)) <> Ptrofs.unsigned (Ptrofs.add ofs2 (Ptrofs.repr delta2)).
Remark val_inject_vtrue: forall f, Val.inject f Vtrue Vtrue.
Remark val_inject_vptrofs: forall n, Val.inject f (Vptrofs n) (Vptrofs n).
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.
End GENERIC_INJECTION.
(** * Some properties of operator semantics *)
(** This section collects some common-sense properties about the type classification and semantic functions above.  Some properties are used in the CompCert semantics preservation proofs.  Others are not, but increase confidence in the specification and its relation with the ISO C99 standard. *)
(** Relation between Boolean value and casting to [_Bool] type. *)
intros.
assert (A: classify_bool t =
match t with
| Tint _ _ _ => bool_case_i
| Tpointer _ _ | Tarray _ _ _ | Tfunction _ _ _ => if Archi.ptr64 then bool_case_l else bool_case_i
| Tfloat F64 _ => bool_case_f
| Tfloat F32 _ => bool_case_s
| Tlong _ _ => bool_case_l
| _ => bool_default
end).
{
unfold classify_bool; destruct t; simpl; auto. destruct i; auto.
}
unfold bool_val. rewrite A.
unfold sem_cast, classify_cast; remember Archi.ptr64 as ptr64; destruct t; simpl; auto; destruct v; auto.
destruct (Int.eq i0 Int.zero); auto.
destruct ptr64; auto. destruct (Mem.weak_valid_pointer m b (Ptrofs.unsigned i0)); auto.
destruct (Int64.eq i Int64.zero); auto.
destruct (negb ptr64); auto. destruct (Mem.weak_valid_pointer m b (Ptrofs.unsigned i)); auto.
destruct f; auto.
destruct f; auto.
destruct f; auto.
destruct f; auto.
destruct (Float.cmp Ceq f0 Float.zero); auto.
destruct f; auto.
destruct (Float32.cmp Ceq f0 Float32.zero); auto.
destruct f; auto.
destruct ptr64; auto.
destruct (Int.eq i Int.zero); auto.
destruct ptr64; auto.
destruct ptr64; auto.
destruct ptr64; auto. destruct (Int64.eq i Int64.zero); auto.
destruct ptr64; auto.
destruct ptr64; auto.
destruct ptr64; auto. destruct (Mem.weak_valid_pointer m b (Ptrofs.unsigned i)); auto.
destruct (Mem.weak_valid_pointer m b (Ptrofs.unsigned i)); auto.
destruct ptr64; auto.
destruct ptr64; auto. destruct (Int.eq i Int.zero); auto.
destruct ptr64; auto. destruct (Int64.eq i Int64.zero); auto.
destruct ptr64; auto.
destruct ptr64; auto.
destruct ptr64; auto. destruct (Mem.weak_valid_pointer m b (Ptrofs.unsigned i)); auto.
destruct (Mem.weak_valid_pointer m b (Ptrofs.unsigned i)); auto.
destruct ptr64; auto.
destruct ptr64; auto. destruct (Int.eq i Int.zero); auto.
destruct ptr64; auto. destruct (Int64.eq i Int64.zero); auto.
destruct ptr64; auto.
destruct ptr64; auto.
destruct ptr64; auto. destruct (Mem.weak_valid_pointer m b (Ptrofs.unsigned i)); auto.
destruct (Mem.weak_valid_pointer m b (Ptrofs.unsigned i)); auto.
Qed.
(** Relation between Boolean value and Boolean negation. *)

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.