Section MINMAX_EFF.
Variable nu12: SM_Injection.
Variable j12' :meminj.
Variable m1' m2: mem.
Definition MINMAX_Offset (b2:block) : option (Z * Z) :=
if plt b2 (Mem.nextblock m2)
then match (zmap_finite_c _ (PMap.get b2 m2.(Mem.mem_contents)))
with (min2, max2) =>
match minmax m1' (as_inj nu12) b2 with
Some(min1, max1) =>
Some(Z.min min1 min2, Z.max max1 max2)
| None => Some(min2,max2)
end
end
else minmax m1' j12' b2.
Hypothesis inc12: inject_incr (as_inj nu12) j12'.
Hypothesis VBj12'_1: forall b1 b2 delta,
j12' b1 = Some (b2, delta) ->
Mem.valid_block m1' b1.
Hypothesis JJ: forall b1 b2 delta,
j12' b1 = Some (b2, delta) ->
Mem.valid_block m2 b2 ->
as_inj nu12 b1 = Some (b2, delta).
End MINMAX_EFF.

(*The interpolation for the afterExternal rule*)
Lemma EFF_interp_II_strong: forall m1 m2 nu12
(MInj12 : Mem.inject (as_inj nu12) m1 m2) m1'
(Fwd1: mem_forward m1 m1') nu23 m3
(MInj23 : Mem.inject (as_inj nu23) m2 m3) m3'
(Fwd3: mem_forward m3 m3')
nu' (WDnu' : SM_wd nu')
(SMvalNu' : sm_valid nu' m1' m3')
(MemInjNu' : Mem.inject (as_inj nu') m1' m3')
(ExtIncr: extern_incr (compose_sm nu12 nu23) nu')
(SMInjSep: sm_inject_separated (compose_sm nu12 nu23) nu' m1 m3)
(SMV12: sm_valid nu12 m1 m2)
(SMV23: sm_valid nu23 m2 m3)
(UnchPrivSrc: Mem.unchanged_on (fun b ofs => locBlocksSrc (compose_sm nu12 nu23) b = true /\
pubBlocksSrc (compose_sm nu12 nu23) b = false) m1 m1')
(UnchLOOR13: Mem.unchanged_on (local_out_of_reach (compose_sm nu12 nu23) m1) m3 m3')
(GlueInvNu: SM_wd nu12 /\ SM_wd nu23 /\
locBlocksTgt nu12 = locBlocksSrc nu23 /\
extBlocksTgt nu12 = extBlocksSrc nu23 /\
(forall b, pubBlocksTgt nu12 b = true ->
pubBlocksSrc nu23 b = true) /\
(forall b, frgnBlocksTgt nu12 b = true ->
frgnBlocksSrc nu23 b = true))
(Norm12: forall b1 b2 d1, extern_of nu12 b1 = Some(b2,d1) ->
exists b3 d2, extern_of nu23 b2 = Some(b3, d2)),
exists m2', exists nu12', exists nu23', nu'=compose_sm nu12' nu23' /\
extern_incr nu12 nu12' /\ extern_incr nu23 nu23' /\
Mem.inject (as_inj nu12') m1' m2' /\ mem_forward m2 m2' /\
Mem.inject (as_inj nu23') m2' m3' /\
sm_inject_separated nu12 nu12' m1 m2 /\
sm_inject_separated nu23 nu23' m2 m3 /\
sm_valid nu12' m1' m2' /\ sm_valid nu23' m2' m3' /\
(SM_wd nu12' /\ SM_wd nu23' /\
locBlocksTgt nu12' = locBlocksSrc nu23' /\
extBlocksTgt nu12' = extBlocksSrc nu23' /\
(forall b, pubBlocksTgt nu12' b = true ->
pubBlocksSrc nu23' b = true) /\
(forall b, frgnBlocksTgt nu12' b = true ->
frgnBlocksSrc nu23' b = true)) /\
(forall b1 b2 d1, extern_of nu12' b1 = Some(b2,d1) ->
exists b3 d2, extern_of nu23' b2 = Some(b3, d2)) /\
Mem.unchanged_on (fun b ofs => locBlocksSrc nu23 b = true /\
pubBlocksSrc nu23 b = false) m2 m2' /\
Mem.unchanged_on (local_out_of_reach nu12 m1) m2 m2' /\
(forall b1 b2 d1, as_inj nu12' b1 = Some(b2,d1) ->
as_inj nu12 b1 = Some(b2,d1) \/
exists b3 d, as_inj nu' b1 = Some(b3,d)) /\
(forall b2 b3 d2, as_inj nu23' b2 = Some(b3,d2) ->
as_inj nu23 b2 = Some(b3,d2) \/
exists b1 d, as_inj nu' b1 = Some(b3,d)) /\
(forall b1 b2 ofs2, as_inj nu12' b1 = Some(b2,ofs2) ->
(as_inj nu12 b1 = Some (b2,ofs2)) \/
(b1 = Mem.nextblock m1 /\ b2 = Mem.nextblock m2 /\ ofs2 = 0) \/
(exists m, (b1 = Mem.nextblock m1 + m /\ b2=Mem.nextblock m2 + m)%positive /\ ofs2=0)) /\
(forall b2 b3 ofs3, as_inj nu23' b2 = Some(b3,ofs3) ->
(as_inj nu23 b2 = Some (b3,ofs3)) \/
(b2 = Mem.nextblock m2 /\ as_inj nu' (Mem.nextblock m1) = Some(b3,ofs3)) \/
(exists m, (b2 = Mem.nextblock m2 + m)%positive /\
as_inj nu' ((Mem.nextblock m1+m)%positive) = Some(b3,ofs3))).