Definition restrict_sm mu (X:block -> bool) :=
match mu with
  Build_SM_Injection locBSrc locBTgt pSrc pTgt local extBSrc extBTgt fSrc fTgt extern =>
  Build_SM_Injection locBSrc locBTgt pSrc pTgt (restrict local X)
                     extBSrc extBTgt fSrc fTgt (restrict extern X)
end.

(* Specifications: *)
Lemma restrict_sm_com: forall mu X Y, restrict_sm (restrict_sm mu X) Y = restrict_sm (restrict_sm mu Y) X.
Lemma restrict_sm_nest: forall mu X Y (HXY: forall b, Y b = true -> X b = true), restrict_sm (restrict_sm mu X) Y = restrict_sm mu Y.
Lemma restrict_sm_nest': forall mu X Y (HXY: forall b, Y b = true -> X b = true), restrict_sm (restrict_sm mu Y) X = restrict_sm mu Y.
Lemma restrict_sm_local: forall mu X, local_of (restrict_sm mu X) = restrict (local_of mu) X.
Lemma restrict_sm_pub: forall mu X, pub_of (restrict_sm mu X) = restrict (pub_of mu) X.
Lemma restrict_sm_extern: forall mu X, extern_of (restrict_sm mu X) = restrict (extern_of mu) X.
Lemma restrict_sm_foreign: forall mu X, foreign_of (restrict_sm mu X) = restrict (foreign_of mu) X.
Lemma restrict_sm_all: forall mu X, as_inj (restrict_sm mu X) = restrict (as_inj mu) X.
Lemma restrict_sm_local': forall mu (WD: SM_wd mu) X (HX: forall b, vis mu b = true -> X b = true), local_of (restrict_sm mu X) = local_of mu.
Lemma restrict_sm_pub': forall mu (WD: SM_wd mu) X (HX: forall b, vis mu b = true -> X b = true), pub_of (restrict_sm mu X) = pub_of mu.
Lemma restrict_sm_foreign': forall mu (WD: SM_wd mu) X (HX: forall b, vis mu b = true -> X b = true), foreign_of (restrict_sm mu X) = foreign_of mu.
Lemma restrict_sm_locBlocksSrc: forall mu X, locBlocksSrc (restrict_sm mu X) = locBlocksSrc mu.
Lemma restrict_sm_extBlocksSrc: forall mu X, extBlocksSrc (restrict_sm mu X) = extBlocksSrc mu.
Lemma restrict_sm_pubBlocksSrc: forall mu X, pubBlocksSrc (restrict_sm mu X) = pubBlocksSrc mu.
Lemma restrict_sm_frgnBlocksSrc: forall mu X, frgnBlocksSrc (restrict_sm mu X) = frgnBlocksSrc mu.
Lemma restrict_sm_DomSrc: forall mu X, DomSrc (restrict_sm mu X) = DomSrc mu.
Lemma restrict_sm_DOM: forall mu X, DOM (restrict_sm mu X) = DOM mu.
Lemma restrict_sm_locBlocksTgt: forall mu X, locBlocksTgt (restrict_sm mu X) = locBlocksTgt mu.
Lemma restrict_sm_extBlocksTgt: forall mu X, extBlocksTgt (restrict_sm mu X) = extBlocksTgt mu.
Lemma restrict_sm_pubBlocksTgt: forall mu X, pubBlocksTgt (restrict_sm mu X) = pubBlocksTgt mu.
Lemma restrict_sm_frgnBlocksTgt: forall mu X, frgnBlocksTgt (restrict_sm mu X) = frgnBlocksTgt mu.
Lemma restrict_sm_DomTgt: forall mu X, DomTgt (restrict_sm mu X) = DomTgt mu.
Lemma restrict_sm_RNG: forall mu X, RNG (restrict_sm mu X) = RNG mu.
Lemma restrict_sm_visTgt mu X: visTgt (restrict_sm mu X) = visTgt mu.
Lemma replace_locals_exportedTgt: forall (mu : SM_Injection) (pubSrc' pubTgt' : block -> bool) vals, exportedTgt (replace_locals mu pubSrc' pubTgt') vals = (fun b : block => getBlocks vals b || (frgnBlocksTgt mu b || pubTgt' b)).
Lemma restrict_sm_WD: forall mu (WD: SM_wd mu) X (HX: forall b, vis mu b = true -> X b = true), SM_wd (restrict_sm mu X).
Lemma restrict_sm_preserves_globals: forall {F V} (ge:Genv.t F V) mu X (PG : meminj_preserves_globals ge (as_inj mu)) (Glob : forall b, isGlobalBlock ge b = true -> X b = true), meminj_preserves_globals ge (as_inj (restrict_sm mu X)).
Lemma restrict_sm_preserves_globals' F V (ge:Genv.t F V) mu X : Events.meminj_preserves_globals ge (extern_of mu) -> (forall b, isGlobalBlock ge b = true -> X b = true) -> Events.meminj_preserves_globals ge (extern_of (restrict_sm mu X)).
Lemma restrict_sm_com: forall mu X Y, restrict_sm (restrict_sm mu X) Y = restrict_sm (restrict_sm mu Y) X.
Lemma restrict_sm_nest: forall mu X Y (HXY: forall b, Y b = true -> X b = true), restrict_sm (restrict_sm mu X) Y = restrict_sm mu Y.
Lemma restrict_sm_nest': forall mu X Y (HXY: forall b, Y b = true -> X b = true), restrict_sm (restrict_sm mu Y) X = restrict_sm mu Y.
Lemma restrict_sm_local: forall mu X, local_of (restrict_sm mu X) = restrict (local_of mu) X.
Lemma restrict_sm_pub: forall mu X, pub_of (restrict_sm mu X) = restrict (pub_of mu) X.
Lemma restrict_sm_extern: forall mu X, extern_of (restrict_sm mu X) = restrict (extern_of mu) X.
Lemma restrict_sm_foreign: forall mu X, foreign_of (restrict_sm mu X) = restrict (foreign_of mu) X.
Lemma restrict_sm_all: forall mu X, as_inj (restrict_sm mu X) = restrict (as_inj mu) X.
Lemma restrict_sm_local': forall mu (WD: SM_wd mu) X (HX: forall b, vis mu b = true -> X b = true), local_of (restrict_sm mu X) = local_of mu.
Lemma restrict_sm_pub': forall mu (WD: SM_wd mu) X (HX: forall b, vis mu b = true -> X b = true), pub_of (restrict_sm mu X) = pub_of mu.
Lemma restrict_sm_foreign': forall mu (WD: SM_wd mu) X (HX: forall b, vis mu b = true -> X b = true), foreign_of (restrict_sm mu X) = foreign_of mu.
Lemma restrict_sm_locBlocksSrc: forall mu X, locBlocksSrc (restrict_sm mu X) = locBlocksSrc mu.
Lemma restrict_sm_extBlocksSrc: forall mu X, extBlocksSrc (restrict_sm mu X) = extBlocksSrc mu.
Lemma restrict_sm_pubBlocksSrc: forall mu X, pubBlocksSrc (restrict_sm mu X) = pubBlocksSrc mu.
Lemma restrict_sm_frgnBlocksSrc: forall mu X, frgnBlocksSrc (restrict_sm mu X) = frgnBlocksSrc mu.
Lemma restrict_sm_DomSrc: forall mu X, DomSrc (restrict_sm mu X) = DomSrc mu.
Lemma restrict_sm_DOM: forall mu X, DOM (restrict_sm mu X) = DOM mu.
Lemma restrict_sm_locBlocksTgt: forall mu X, locBlocksTgt (restrict_sm mu X) = locBlocksTgt mu.
Lemma restrict_sm_extBlocksTgt: forall mu X, extBlocksTgt (restrict_sm mu X) = extBlocksTgt mu.
Lemma restrict_sm_pubBlocksTgt: forall mu X, pubBlocksTgt (restrict_sm mu X) = pubBlocksTgt mu.
Lemma restrict_sm_frgnBlocksTgt: forall mu X, frgnBlocksTgt (restrict_sm mu X) = frgnBlocksTgt mu.
Lemma restrict_sm_DomTgt: forall mu X, DomTgt (restrict_sm mu X) = DomTgt mu.
Lemma restrict_sm_RNG: forall mu X, RNG (restrict_sm mu X) = RNG mu.
Lemma restrict_sm_WD: forall mu (WD: SM_wd mu) X (HX: forall b, vis mu b = true -> X b = true), SM_wd (restrict_sm mu X).
Lemma restrict_sm_preserves_globals: forall {F V} (ge:Genv.t F V) mu X (PG : meminj_preserves_globals ge (as_inj mu)) (Glob : forall b, isGlobalBlock ge b = true -> X b = true), meminj_preserves_globals ge (as_inj (restrict_sm mu X)).