(*Inserts the new injection entries into extern component, but not into foreign*)
Definition insert_as_extern (mu: SM_Injection) (j: meminj) (DomJ TgtJ:block->bool)
: SM_Injection:=
match mu with
Build_SM_Injection locBSrc locBTgt pSrc pTgt local extBSrc extBTgt fSrc fTgt extern =>
Build_SM_Injection locBSrc locBTgt pSrc pTgt local
(fun b => orb (extBSrc b) (DomJ b))
(fun b => orb (extBTgt b) (TgtJ b))
fSrc
fTgt
(join extern (fun b => match local b with Some _ => None
| None => j b end))
end.
Definition convertL (nu12: SM_Injection) (j12':meminj) FreshSrc FreshMid:=
insert_as_extern nu12 j12' FreshSrc FreshMid.
Definition convertR (nu23: SM_Injection) (j23':meminj) FreshMid FreshTgt:=
insert_as_extern nu23 j23' FreshMid FreshTgt.
Definition AccessEffProperty nu23 nu12 (j12' :meminj) (m1 m1' m2 : mem)
(AM:ZMap.t (Z -> perm_kind -> option permission)):Prop :=
forall b2,
(Mem.valid_block m2 b2 -> forall k ofs2,
if (locBlocksSrc nu23 b2)
then if (pubBlocksSrc nu23 b2)
then match source (local_of nu12) m1 b2 ofs2 with
Some(b1,ofs1) => if pubBlocksSrc nu12 b1
then PMap.get b2 AM ofs2 k =
PMap.get b1 m1'.(Mem.mem_access) ofs1 k
else PMap.get b2 AM ofs2 k =
PMap.get b2 m2.(Mem.mem_access) ofs2 k
| None =>  PMap.get b2 AM ofs2 k =
PMap.get b2 m2.(Mem.mem_access) ofs2 k
end
else PMap.get b2 AM ofs2 k =
PMap.get b2 m2.(Mem.mem_access) ofs2 k
else match source (as_inj nu12) m1 b2 ofs2 with
Some(b1,ofs1) =>  PMap.get b2 AM ofs2 k =
PMap.get b1 m1'.(Mem.mem_access) ofs1 k
| None => match (*j23*) (as_inj nu23) b2 with
None => PMap.get b2 AM ofs2 k  = PMap.get b2 m2.(Mem.mem_access) ofs2 k
| Some (b3,d3) =>  PMap.get b2 AM ofs2 k = None (* mem_interpolation_II.v has PMap.get b2 m2.(Mem.mem_access) ofs2 k here
-- see the comment in the proof script below to see where None is needed*)
end
end)
/\ (~ Mem.valid_block m2 b2 -> forall k ofs2,
match source j12' m1' b2 ofs2 with
Some(b1,ofs1) => PMap.get b2 AM ofs2 k =
PMap.get b1 m1'.(Mem.mem_access) ofs1 k
| None =>  PMap.get b2 AM ofs2 k = None
end).
Definition ContentEffProperty nu23 nu12 (j12':meminj) (m1 m1' m2:Mem.mem)
(CM:ZMap.t (ZMap.t memval)):=
forall b2,
(Mem.valid_block m2 b2 -> forall ofs2,
if locBlocksSrc nu23 b2
then if (pubBlocksSrc nu23 b2)
then match source (local_of nu12) m1 b2 ofs2 with
Some(b1,ofs1) =>
if pubBlocksSrc nu12 b1
then ZMap.get ofs2 (PMap.get b2 CM) =
inject_memval j12'
(ZMap.get ofs1 (PMap.get b1 m1'.(Mem.mem_contents)))
else ZMap.get ofs2 (PMap.get b2 CM) =
ZMap.get ofs2 (PMap.get b2 m2.(Mem.mem_contents))
| None => ZMap.get ofs2 (PMap.get b2 CM) =
ZMap.get ofs2 (PMap.get b2 m2.(Mem.mem_contents))
end
else ZMap.get ofs2 (PMap.get b2 CM) =
ZMap.get ofs2 (PMap.get b2 m2.(Mem.mem_contents))
else match source (as_inj nu12) m1 b2 ofs2 with
Some(b1,ofs1) => ZMap.get ofs2 (PMap.get b2 CM) =
inject_memval j12'
(ZMap.get ofs1 (PMap.get b1 m1'.(Mem.mem_contents)))
| None => ZMap.get ofs2 (PMap.get b2 CM) =
ZMap.get ofs2 (PMap.get b2 m2.(Mem.mem_contents))
end)
/\ (~ Mem.valid_block m2 b2 -> forall ofs2,
match source j12' m1' b2 ofs2 with
None => ZMap.get ofs2 (PMap.get b2 CM) = Undef
| Some(b1,ofs1) =>
ZMap.get ofs2 (PMap.get b2 CM) =
inject_memval j12'
(ZMap.get ofs1 (PMap.get b1 m1'.(Mem.mem_contents)))
end)
/\ fst CM !! b2 = Undef.
(*     Mem.unchanged_on (local_out_of_reach nu23 m2) m3 m3' /\*)
(*FreshSrc:*) (fun b => andb (DomSrc nu' b) (negb (DomSrc nu12 b))) (*FreshMid:*) (FreshDom (as_inj nu23) j23')) /\ nu23' = (convertR nu23 j23' (*FreshMid:*) (FreshDom (as_inj nu23) j23') (*FreshTgt:*) (fun b => andb (DomTgt nu' b) (negb (DomTgt nu23 b)))) /\ nu'=compose_sm nu12' nu23' /\ extern_incr nu12 nu12' /\ extern_incr nu23 nu23' /\ 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_forward m2 m2' /\ Mem.inject (as_inj nu12') m1' m2' /\ Mem.inject (as_inj nu23') m2' m3'.  Section MEMORY_CONSTRUCTION_EFF. Variable nu23 nu12 : SM_Injection. Variable j23 j12':meminj. Variable m1 m1' m2 : mem.  Definition AccessMap_EFF_FUN (b2:block): Z -> perm_kind -> option permission := if plt b2 (Mem.nextblock m2) then fun ofs2 k => if (locBlocksSrc nu23 b2) then if (pubBlocksSrc nu23 b2) then match source (local_of nu12) m1 b2 ofs2 with Some(b1,ofs1) => if pubBlocksSrc nu12 b1 then PMap.get b1 m1'.(Mem.mem_access) ofs1 k else PMap.get b2 m2.(Mem.mem_access) ofs2 k | None => PMap.get b2 m2.(Mem.mem_access) ofs2 k end else PMap.get b2 m2.(Mem.mem_access) ofs2 k else match source (as_inj nu12) m1 b2 ofs2 with Some(b1,ofs1) => PMap.get b1 m1'.(Mem.mem_access) ofs1 k | None => match j23 b2 with None => PMap.get b2 m2.(Mem.mem_access) ofs2 k | Some (b3,d3) => None end (*Was:                            PMap.get b2 m2.(Mem.mem_access) ofs2 k*)
Definition ContentMap_EFF_ValidBlock_FUN b2 ofs2: memval :=
if locBlocksSrc nu23 b2
then if (pubBlocksSrc nu23 b2)
then match source (local_of nu12) m1 b2 ofs2 with
Some(b1,ofs1) =>
if pubBlocksSrc nu12 b1
then inject_memval j12'
(ZMap.get ofs1 (PMap.get b1 m1'.(Mem.mem_contents)))
else ZMap.get ofs2 (PMap.get b2 m2.(Mem.mem_contents))
| None => ZMap.get ofs2 (PMap.get b2 m2.(Mem.mem_contents))
end
else ZMap.get ofs2 (PMap.get b2 m2.(Mem.mem_contents))
else match source (as_inj nu12) m1 b2 ofs2 with
Some(b1,ofs1) => inject_memval j12'
(ZMap.get ofs1 (PMap.get b1 m1'.(Mem.mem_contents)))
| None => ZMap.get ofs2 (PMap.get b2 m2.(Mem.mem_contents))
end.
Definition ContentMap_EFF_InvalidBlock_FUN b2 ofs2: memval :=
match source j12' m1' b2 ofs2 with
None => Undef
| Some(b1,ofs1) => inject_memval j12'
(ZMap.get ofs1 (PMap.get b1 m1'.(Mem.mem_contents)))
end.
Definition ContentMap_EFF_Block_FUN b ofs : memval:=
if plt b (Mem.nextblock m2)
then ContentMap_EFF_ValidBlock_FUN b ofs
else ContentMap_EFF_InvalidBlock_FUN b ofs.
Variable MINMAX_Offset: block -> option (Z * Z).
Hypothesis MINMAX: forall b2 ,
match MINMAX_Offset b2 with
Some(mn,mx) =>
(forall ofs, ofs < mn \/ ofs > mx ->
Plt b2 (Mem.nextblock m2) ->
ZMap.get ofs (Mem.mem_contents m2)!!b2 = Undef) /\
forall b1 delta, as_inj nu12 b1 = Some(b2,delta) \/ j12' b1 = Some(b2,delta)->
forall z, z + delta < mn \/ z + delta > mx ->
ZMap.get z (Mem.mem_contents m1')!!b1 = Undef
| None =>
(Plt b2 (Mem.nextblock m2) ->
forall ofs, ZMap.get ofs (Mem.mem_contents m2)!!b2 = Undef)
/\
forall b1 delta, as_inj nu12 b1 = Some(b2,delta) \/ j12' b1 = Some(b2,delta)->
forall z, ZMap.get z (Mem.mem_contents m1')!!b1 = Undef
end.
Variable WDnu12: SM_wd nu12.
Definition ContentsMap_EFF_FUN  (NB2' b:block) : ZMap.t memval.
destruct (plt b NB2').
apply (CM_block_EFF_existsT b).
apply (ZMap.init Undef).
Defined.
Definition mkEFF
(NB2':block)
(Hyp1: (Mem.nextblock m2 <= NB2')%positive)
(Hyp2: forall (b1 b2 : block) (delta : Z),
j12' b1 = Some (b2, delta) -> (b2 < NB2')%positive)
: Mem.mem'.
destruct (mkAccessMap_EFF_existsT NB2' Hyp1 Hyp2) as [AM [ADefault PAM]].
destruct (ContentsMap_EFF_existsT NB2') as [CM [CDefault PCM]].
eapply Mem.mkmem with (nextblock:=NB2')
(mem_access:=AM)
(mem_contents:=CM).
(*access_max*)
intros. rewrite PAM. unfold AccessMap_EFF_FUN.
destruct (plt b (Mem.nextblock m2)).
(*valid_block m2 b*)
destruct (locBlocksSrc nu23 b).
destruct (pubBlocksSrc nu23 b).
destruct (source (local_of nu12) m1 b ofs).
destruct p0.
destruct (pubBlocksSrc nu12 b0). apply m1'. apply m2.
apply m2.
apply m2.
destruct (source (as_inj nu12) m1 b ofs).
destruct p0. apply m1'.
destruct (j23 b). destruct p0. reflexivity. apply m2.
(*invalid_block m2 b*)
destruct (source j12' m1' b ofs).
destruct p. apply m1'.
reflexivity.
(*nextblock_noaccess*)
intros. rewrite PAM.
unfold AccessMap_EFF_FUN.
destruct (plt b (Mem.nextblock m2)).
exfalso. apply H; clear - Hyp1 p. xomega.
remember (source j12' m1' b ofs) as src.
destruct src; trivial.
destruct p.
exfalso. apply H. clear - Heqsrc Hyp2.
apply source_SomeE in Heqsrc.
destruct Heqsrc as [b1 [delta [ofs1
[PBO [Bounds [J1 [P1 Off2]]]]]]]; subst.
apply (Hyp2 _ _ _ J1).
(*contents_default*)
intros.
rewrite PCM; clear PCM.
unfold ContentsMap_EFF_FUN.
destruct (plt b NB2').
remember (CM_block_EFF_existsT b).
destruct s. apply a.
reflexivity.
Defined.

Lemma mkEff_nextblock: forall N Hyp1 Hyp2,
Mem.nextblock (mkEFF N Hyp1 Hyp2) = N.