Parameter REACH : mem -> (block -> bool) -> block -> bool.

(* Specifications: *)
Axiom REACHAX : (* Constructible via FiniteMaps.v, relying on finiteness of memories *)
forall m B b, REACH m B b = true
<-> exists L, reach m (fun bb => B bb = true) L b.
Lemma REACH_nil: forall m B b, B b = true -> REACH m B b = true.
Lemma REACH_cons: forall m B b b' z off n q,
REACH m B b' = true ->
Mem.perm m b' z Cur Readable ->
ZMap.get z (PMap.get b' (Mem.mem_contents m)) =
Fragment (Vptr b off) q  n ->
REACH m B b = true.
Lemma REACH_inject: forall m1 m2 j (J: Mem.inject j m1 m2) B1 B2
(HB: forall b, B1 b = true -> exists jb d, j b = Some(jb,d) /\ B2 jb = true)
b1 (R: REACH m1 B1 b1 = true),
exists b2 d, j b1 = Some(b2,d) /\ REACH m2 B2 b2 = true.
Lemma REACH_mono: forall B1 B2 (HB: forall b, B1 b = true -> B2 b = true) m b
(R: REACH m B1 b = true), REACH m B2 b = true.
Axiom REACHAX : (* Constructible via FiniteMaps.v, relying on finiteness of memories *)
forall m B b, REACH m B b = true
<-> exists L, reach m (fun bb => B bb = true) L b.
Lemma REACH_nil: forall m B b, B b = true -> REACH m B b = true.
Lemma REACH_cons: forall m B b b' z off n,
REACH m B b' = true ->
Mem.perm m b' z Cur Readable ->
ZMap.get z (PMap.get b' (Mem.mem_contents m)) =
Pointer b off n ->
REACH m B b = true.
Lemma REACH_inject: forall m1 m2 j (J: Mem.inject j m1 m2) B1 B2
(HB: forall b, B1 b = true -> exists jb d, j b = Some(jb,d) /\ B2 jb = true)
b1 (R: REACH m1 B1 b1 = true),
exists b2 d, j b1 = Some(b2,d) /\ REACH m2 B2 b2 = true.
Lemma REACH_mono: forall B1 B2 (HB: forall b, B1 b = true -> B2 b = true) m b
(R: REACH m B1 b = true), REACH m B2 b = true.