Definition FLIP mu :=
  match mu with
    Build_SM_Injection locBSrc locBTgt pSrc pTgt local extBSrc extBTgt fSrc fTgt extern =>
    Build_SM_Injection extBSrc extBTgt fSrc fTgt extern locBSrc locBTgt pSrc pTgt local
  end.

(* Specifications: *)
Lemma SAWP_wd: forall mu (WD: SM_wd mu), SM_wd (FLIP mu).
Lemma FLIPlocBlocksSrc: forall mu, locBlocksSrc (FLIP mu) = extBlocksSrc mu.
Lemma FLIPlocBlocksTgt: forall mu, locBlocksTgt (FLIP mu) = extBlocksTgt mu.
Lemma FLIPextBlocksSrc: forall mu, extBlocksSrc (FLIP mu) = locBlocksSrc mu.
Lemma FLIPextBlocksTgt: forall mu, extBlocksTgt (FLIP mu) = locBlocksTgt mu.
Lemma FLIPpubBlocksSrc: forall mu, pubBlocksSrc (FLIP mu) = frgnBlocksSrc mu.
Lemma FLIPpubBlocksTgt: forall mu, pubBlocksTgt (FLIP mu) = frgnBlocksTgt mu.
Lemma FLIPfrgnBlocksSrc: forall mu, frgnBlocksSrc (FLIP mu) = pubBlocksSrc mu.
Lemma FLIPfrgnBlocksTgt: forall mu, frgnBlocksTgt (FLIP mu) = pubBlocksTgt mu.
Lemma FLIPlocal: forall mu, local_of (FLIP mu) = extern_of mu.
Lemma FLIPextern: forall mu, extern_of (FLIP mu) = local_of mu.
Lemma RelyGuaranteeSrc: forall mu (WD: SM_wd mu) Esrc m m' (SrcHyp: forall b ofs, Esrc b ofs = true -> vis mu b = true) (Unch: Mem.unchanged_on (fun b z => Esrc b z = false) m m'), Mem.unchanged_on (fun b ofs => locBlocksSrc (FLIP mu) b = true /\ pubBlocksSrc (FLIP mu) b = false) m m'.
Lemma unchanged_on_perm: forall (P:block -> Z -> Prop) m m' (Unch: Mem.unchanged_on P m m'), Mem.unchanged_on (fun b z => P b z /\ Mem.perm m b z Max Nonempty) m m'.
Lemma unchanged_on_perm': forall (P:block -> Z -> Prop) m m' (Unch: Mem.unchanged_on (fun b z => P b z \/ ~ Mem.perm m b z Max Nonempty) m m'), Mem.unchanged_on P m m'.
Lemma RelyGuaranteeTgtPerm: forall mu Etgt Esrc m2 m2' (WD: SM_wd mu) m1 (TgtHyp: forall b ofs, Etgt b ofs = true -> (Mem.valid_block m2 b /\ (locBlocksTgt mu b = false -> exists b1 delta1, foreign_of mu b1 = Some(b,delta1) /\ Esrc b1 (ofs-delta1) = true /\ Mem.perm m1 b1 (ofs-delta1) Max Nonempty))) (Unch2: Mem.unchanged_on (fun b z => Etgt b z = false) m2 m2') (SrcHyp: forall b ofs, Esrc b ofs = true -> vis mu b = true) (*m1 (SrcPerm: forall b1 z, Esrc b1 z = true -> Mem.perm m1 b1 z Max Nonempty)*), Mem.unchanged_on (local_out_of_reach (FLIP mu) m1) m2 m2'.
Lemma RelyGuaranteeTgt: forall mu Etgt Esrc m2 m2' (WD: SM_wd mu) (TgtHyp: forall b ofs, Etgt b ofs = true -> (Mem.valid_block m2 b /\ (locBlocksTgt mu b = false -> exists b1 delta1, foreign_of mu b1 = Some(b,delta1) /\ Esrc b1 (ofs-delta1) = true))) (Unch2: Mem.unchanged_on (fun b z => Etgt b z = false) m2 m2') (SrcHyp: forall b ofs, Esrc b ofs = true -> vis mu b = true) m1 (SrcPerm: forall b1 z, Esrc b1 z = true -> Mem.perm m1 b1 z Max Nonempty), Mem.unchanged_on (local_out_of_reach (FLIP mu) m1) m2 m2'.
Lemma RGSrc_multicoreLICSpaper: forall mu (WDmu: SM_wd mu) Esrc m m' (SrcHyp: forall b ofs, Esrc b ofs = true -> vis mu b = true) (Unch: Mem.unchanged_on (fun b z => Esrc b z = false) m m') nu (WDnu: SM_wd nu) (LB: forall b, locBlocksSrc nu b = true -> locBlocksSrc mu b = true -> False) (X2: forall b1 b2 d, foreign_of mu b1 = Some(b2, d) -> locBlocksSrc nu b1 || locBlocksTgt nu b2 = true -> pub_of nu b1 = Some(b2,d)), Mem.unchanged_on (fun b ofs => locBlocksSrc nu b = true /\ pubBlocksSrc nu b = false) m m'.
Lemma RGTgt_multicoreLICSpaper: forall mu Etgt Esrc m2 m2' (WD: SM_wd mu) m1 (TgtHyp: forall b ofs, Etgt b ofs = true -> (Mem.valid_block m2 b /\ (locBlocksTgt mu b = false -> exists b1 delta1, foreign_of mu b1 = Some(b,delta1) /\ Esrc b1 (ofs-delta1) = true /\ Mem.perm m1 b1 (ofs-delta1) Max Nonempty))) (Unch2: Mem.unchanged_on (fun b z => Etgt b z = false) m2 m2') nu (X1: forall b, locBlocksTgt nu b = true -> locBlocksTgt mu b = false) (X2: forall b1 b2 d, foreign_of mu b1 = Some(b2, d) -> locBlocksSrc nu b1 || locBlocksTgt nu b2 = true -> pub_of nu b1 = Some(b2,d)), Mem.unchanged_on (local_out_of_reach nu m1) m2 m2'.