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 _ (Vsingle _) _ |- _ ] =>
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_condition_inj:
forall cond vl1 vl2 b,
Val.inject_list f vl1 vl2 ->
eval_condition cond vl1 m1 = Some b ->
eval_condition cond vl2 m2 = Some b.