Section EVAL_COMPAT.
Variable F1 F2 V1 V2: Type.
Variable ge1: Genv.t F1 V1.
Variable ge2: Genv.t F2 V2.
Variable f: meminj.
Variable m1: mem.
Variable m2: mem.
Hypothesis valid_pointer_inj:
forall b1 ofs b2 delta,
f b1 = Some(b2, delta) ->
Mem.valid_pointer m1 b1 (Ptrofs.unsigned ofs) = true ->
Mem.valid_pointer m2 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 m1 b1 (Ptrofs.unsigned ofs) = true ->
Mem.weak_valid_pointer m2 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 m1 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 m1 b1 (Ptrofs.unsigned ofs1) = true ->
Mem.valid_pointer m1 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)).
Ltac InvInject :=
match goal with
| [ H: Val.inject _ (Vint _) _ |- _ ] =>
inv H; InvInject
| [ H: Val.inject _ (Vfloat _) _ |- _ ] =>
inv H; InvInject
| [ H: Val.inject _ (Vptr _ _) _ |- _ ] =>
inv H; InvInject
| [ H: Val.inject_list _ nil _ |- _ ] =>
inv H; InvInject
| [ H: Val.inject_list _ (_ :: _) _ |- _ ] =>
inv H; InvInject
| _ => idtac
end.

Lemma eval_shiftl_inject:
forall v1 v2 s a,
Val.inject f v1 v2 -> Val.inject f (eval_shiftl s v1 a) (eval_shiftl s v2 a).