Definition AccessMap_EI_Property (j:meminj) (m1 m1' m2 : mem)
(AM:ZMap.t (Z -> perm_kind -> option permission)):Prop :=
forall b2,
(Mem.valid_block m2 b2 -> forall k ofs2,
match j b2 with
None => PMap.get b2 AM ofs2 k  =
PMap.get b2 m2.(Mem.mem_access) ofs2 k
| Some (b3,d3) =>
(Mem.perm m1 b2 ofs2 Max Nonempty ->
PMap.get b2 AM ofs2 k = PMap.get b2 m1'.(Mem.mem_access) ofs2 k)
/\ (~Mem.perm m1 b2 ofs2 Max Nonempty ->
PMap.get b2 AM ofs2 k  = PMap.get b2 m2.(Mem.mem_access) ofs2 k)
end)
/\ (~ Mem.valid_block m2 b2 -> forall k ofs2,
(Mem.perm m1' b2 ofs2 Max Nonempty ->
PMap.get b2 AM ofs2 k = PMap.get b2 m1'.(Mem.mem_access) ofs2 k)
/\ (~Mem.perm m1' b2 ofs2 Max Nonempty -> PMap.get b2 AM ofs2 k = None)).
Definition Content_EI_Property (j:meminj) (m1 m1' m2:Mem.mem)
(CM:ZMap.t (ZMap.t memval)):=
forall b2,
(Mem.valid_block m2 b2 -> forall ofs2,
match j b2 with
None =>  ZMap.get ofs2 (PMap.get b2 CM) =
ZMap.get ofs2 (PMap.get b2 m2.(Mem.mem_contents))
| Some (b3,delta3) =>
(Mem.perm m1 b2 ofs2 Max Nonempty ->
ZMap.get ofs2 (PMap.get b2 CM) =
ZMap.get ofs2 (PMap.get b2 m1'.(Mem.mem_contents)))
/\ (~Mem.perm m1 b2 ofs2 Max Nonempty ->
ZMap.get ofs2 (PMap.get b2 CM) =
ZMap.get ofs2 (PMap.get b2 m2.(Mem.mem_contents)))
end)
/\ (~ Mem.valid_block m2 b2 -> forall (HM1': Mem.valid_block m1' b2) ofs2,
(Mem.perm m1' b2 ofs2 Cur Readable ->
ZMap.get ofs2 (PMap.get b2 CM) =
ZMap.get ofs2 (PMap.get b2 m1'.(Mem.mem_contents)))
/\ (~Mem.perm m1' b2 ofs2 Cur Readable ->
ZMap.get ofs2 (PMap.get b2 CM) =Undef))
/\ fst CM !! b2 = Undef.

Lemma EI_ok: forall (m1 m2 m1':mem)
(Ext12: Mem.extends m1 m2)
(Fwd1: mem_forward m1 m1') m3 j
(Inj23: Mem.inject j m2 m3)
m3' (Fwd3: mem_forward m3 m3') j'
(Inj13': Mem.inject j' m1' m3')
(UnchOn3: Mem.unchanged_on (loc_out_of_reach j m1) m3 m3')
(InjInc: inject_incr j j') (injSep: inject_separated j j' m1 m3)
(UnchOn1: Mem.unchanged_on (loc_unmapped j) m1 m1') m2'
(NB: m2'.(Mem.nextblock)=m1'.(Mem.nextblock))
(CONT: Content_EI_Property j m1 m1' m2 (m2'.(Mem.mem_contents)))
(ACCESS: AccessMap_EI_Property j m1 m1' m2 (m2'.(Mem.mem_access))),
mem_forward m2 m2' /\
Mem.extends m1' m2' /\
Mem.inject j' m2' m3' /\
Mem.unchanged_on (loc_out_of_bounds m1) m2 m2' /\
Mem.unchanged_on (loc_unmapped j) m2 m2'.