Definition restrict (j: meminj) (X:block -> bool) : meminj :=
  fun b => if X b then j b else None.

(* Specifications: *)
Lemma restrictD_Some: forall j X b1 b2 d (R:restrict j X b1 = Some(b2,d)), j b1 = Some(b2,d) /\ X b1 = true.
Lemma restrictI_Some: forall j X b b2 d (J:j b = Some(b2,d)) (Hb: X b = true), restrict j X b = Some(b2,d).
Lemma restrictD_None: forall j X b1 b2 d (R:restrict j X b1 = None) (J: j b1 = Some(b2,d)), X b1 = false.
Lemma restrictD_None': forall j X b1 (R:restrict j X b1 = None), j b1 = None \/ (exists b2 d, j b1 =Some(b2,d) /\ X b1 = false).
Lemma restrictI_None: forall j X b (Hb: j b = None \/ X b = false), restrict j X b = None.
Lemma join_restrict: forall j k X, join (restrict j X) (restrict k X) = restrict (join j k) X.
Lemma restrict_outside: forall j X (HX: forall b1 b2 d, j b1 = Some(b2, d) -> X b1 = true), restrict j X = j.
Lemma restrict_incr: forall j X, inject_incr (restrict j X) j.
Lemma restrict_com: forall j X Y, restrict (restrict j X) Y = restrict (restrict j Y) X.
Lemma restrict_nest: forall j X Y (HXY: forall b, Y b = true -> X b = true), restrict (restrict j X) Y = restrict j Y.
Lemma restrict_nest': forall j X Y (HXY: forall b, Y b = true -> X b = true), restrict (restrict j Y) X = restrict j Y.
Lemma val_inject_restrictD: forall j v v' X (V: val_inject (restrict j X) v v'), val_inject j v v'.
Lemma forall_vals_inject_restrictD: forall j vals1 vals2 X (Inj : Forall2 (val_inject (restrict j X)) vals1 vals2), Forall2 (val_inject j) vals1 vals2.
Lemma restrictD_Some: forall j X b1 b2 d (R:restrict j X b1 = Some(b2,d)), j b1 = Some(b2,d) /\ X b1 = true.
Lemma restrictI_Some: forall j X b b2 d (J:j b = Some(b2,d)) (Hb: X b = true), restrict j X b = Some(b2,d).
Lemma restrictD_None: forall j X b1 b2 d (R:restrict j X b1 = None) (J: j b1 = Some(b2,d)), X b1 = false.
Lemma restrictD_None': forall j X b1 (R:restrict j X b1 = None), j b1 = None \/ (exists b2 d, j b1 =Some(b2,d) /\ X b1 = false).
Lemma restrictI_None: forall j X b (Hb: j b = None \/ X b = false), restrict j X b = None.
Lemma join_restrict: forall j k X, join (restrict j X) (restrict k X) = restrict (join j k) X.
Lemma restrict_outside: forall j X (HX: forall b1 b2 d, j b1 = Some(b2, d) -> X b1 = true), restrict j X = j.
Lemma restrict_incr: forall j X, inject_incr (restrict j X) j.
Lemma restrict_com: forall j X Y, restrict (restrict j X) Y = restrict (restrict j Y) X.
Lemma restrict_nest: forall j X Y (HXY: forall b, Y b = true -> X b = true), restrict (restrict j X) Y = restrict j Y.
Lemma restrict_nest': forall j X Y (HXY: forall b, Y b = true -> X b = true), restrict (restrict j Y) X = restrict j Y.
Lemma val_inject_restrictD: forall j v v' X (V: val_inject (restrict j X) v v'), val_inject j v v'.
Lemma forall_vals_inject_restrictD: forall j vals1 vals2 X (Inj : Forall2 (val_inject (restrict j X)) vals1 vals2), Forall2 (val_inject j) vals1 vals2.