Section VAL_INJ_OPS.
Variable f: meminj.
Remark add_inject:
forall v1 v1' v2 v2',
inject f v1 v1' ->
inject f v2 v2' ->
inject f (Val.add v1 v2) (Val.add v1' v2').
Remark sub_inject:
forall v1 v1' v2 v2',
inject f v1 v1' ->
inject f v2 v2' ->
inject f (Val.sub v1 v2) (Val.sub v1' v2').
Remark addl_inject:
forall v1 v1' v2 v2',
inject f v1 v1' ->
inject f v2 v2' ->
inject f (Val.addl v1 v2) (Val.addl v1' v2').
Remark subl_inject:
forall v1 v1' v2 v2',
inject f v1 v1' ->
inject f v2 v2' ->
inject f (Val.subl v1 v2) (Val.subl v1' v2').
Variable (valid_ptr1 valid_ptr2 : block -> Z -> bool).
Let weak_valid_ptr1 b ofs := valid_ptr1 b ofs || valid_ptr1 b (ofs - 1).
Let weak_valid_ptr2 b ofs := valid_ptr2 b ofs || valid_ptr2 b (ofs - 1).
Hypothesis valid_ptr_inj:
forall b1 ofs b2 delta,
f b1 = Some(b2, delta) ->
valid_ptr1 b1 (Ptrofs.unsigned ofs) = true ->
valid_ptr2 b2 (Ptrofs.unsigned (Ptrofs.add ofs (Ptrofs.repr delta))) = true.
Hypothesis weak_valid_ptr_inj:
forall b1 ofs b2 delta,
f b1 = Some(b2, delta) ->
weak_valid_ptr1 b1 (Ptrofs.unsigned ofs) = true ->
weak_valid_ptr2 b2 (Ptrofs.unsigned (Ptrofs.add ofs (Ptrofs.repr delta))) = true.
Hypothesis weak_valid_ptr_no_overflow:
forall b1 ofs b2 delta,
f b1 = Some(b2, delta) ->
weak_valid_ptr1 b1 (Ptrofs.unsigned ofs) = true ->
0 <= Ptrofs.unsigned ofs + Ptrofs.unsigned (Ptrofs.repr delta) <= Ptrofs.max_unsigned.
Hypothesis valid_different_ptrs_inj:
forall b1 ofs1 b2 ofs2 b1' delta1 b2' delta2,
b1 <> b2 ->
valid_ptr1 b1 (Ptrofs.unsigned ofs1) = true ->
valid_ptr1 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)).
End VAL_INJ_OPS.
End Val.
Notation meminj := Val.meminj.
(** Monotone evolution of a memory injection. *)
Definition inject_incr (f1 f2: meminj) : Prop :=
forall b b' delta, f1 b = Some(b', delta) -> f2 b = Some(b', delta).
Hint Resolve inject_incr_refl val_inject_incr val_inject_list_incr.
(** The identity injection gives rise to the "less defined than" relation. *)
Definition inject_id : meminj := fun b => Some(b, 0).
(** Composing two memory injections *)
Definition compose_meminj (f f': meminj) : meminj :=
fun b =>
match f b with
| None => None
| Some(b', delta) =>
match f' b' with
| None => None
| Some(b'', delta') => Some(b'', delta + delta')
end
end.

Lemma val_inject_compose:
forall f f' v1 v2 v3,
Val.inject f v1 v2 -> Val.inject f' v2 v3 ->
Val.inject (compose_meminj f f') v1 v3.