Definition  source j m (b2:block) (ofs2:Z) : option(block * Z) :=
if plt 1%positive (Mem.nextblock m)
then sourceN (Pos.pred (Mem.nextblock m)) j m b2 ofs2
else None.

(* Specifications: *)
Lemma perm_nextblock_gt_1: forall m b ofs k p (P: Mem.perm m b ofs k p),
Plt 1 (Mem.nextblock m).
Lemma source_SomeE: forall j m (b2:block) (ofs2:Z) p,
Some p = source j m b2 ofs2 ->
exists b1, exists delta, exists ofs1,
p = (b1,ofs1) /\
(b1 < Mem.nextblock m)%positive /\ j b1 = Some(b2,delta) /\
Mem.perm m b1 ofs1 Max Nonempty /\ ofs2=ofs1+delta.
Lemma source_NoneE: forall j m b2 ofs2,
None = source j m b2 ofs2 ->
forall b1 delta, (b1 < Mem.nextblock m)%positive -> j b1 = Some(b2,delta) ->
~ Mem.perm m b1 (ofs2-delta) Max Nonempty.
Lemma source_SomeI: forall j m b2 b1 ofs1 delta (OV:Mem.meminj_no_overlap j m),
j b1 = Some(b2,delta) -> Mem.perm m b1 ofs1 Max Nonempty ->
source j m b2 (ofs1+delta) = Some(b1,ofs1).
Lemma sourceNone_LOOR: forall j m1 b2 ofs2 (N: None = source j m1 b2 ofs2) m2
(Inj12: Mem.inject j m1 m2), loc_out_of_reach j m1 b2 ofs2.
Lemma memvalUnchOnR: forall m1 m2 m3 m3' b ofs
(n : ~ Mem.perm m1 b ofs Max Nonempty)
(UnchOn13 : Mem.unchanged_on (loc_out_of_bounds m1) m3 m3')
(MV : memval_inject inject_id
(ZMap.get ofs (PMap.get b (Mem.mem_contents m2)))
(ZMap.get ofs (PMap.get b (Mem.mem_contents m3))))
(Rd: Mem.perm m3 b ofs Cur Readable),
memval_inject inject_id (ZMap.get ofs (PMap.get b (Mem.mem_contents m2)))
(ZMap.get ofs (PMap.get b (Mem.mem_contents m3'))).
Lemma perm_order_total: forall p1 p2, perm_order p1 p2 \/ perm_order p2 p1.
Lemma perm_order_antisym: forall p1 p2, perm_order p1 p2 -> perm_order p2 p1 -> p1=p2.
Lemma perm_splitA: forall m b ofs k' p m2' m2 m3' k b3 ofs3
(SPLIT: (Mem.perm m b ofs k' p-> PMap.get b (Mem.mem_access m2') ofs k = PMap.get b (Mem.mem_access m2) ofs k) /\
(~Mem.perm m b ofs k' p -> PMap.get b (Mem.mem_access m2') ofs k = PMap.get b3 (Mem.mem_access m3') ofs3 k))
(P:Prop)
(HA: Mem.perm m b ofs k' p -> Mem.perm m2' b ofs k = Mem.perm m2 b ofs k -> P)
(HB: ~Mem.perm m b ofs k' p -> Mem.perm m2' b ofs k = Mem.perm m3' b3 ofs3 k  -> P), P.
Lemma valid_splitA: forall (m m2' m2 m1':mem) (b:block) ofs k
(SPLIT: if plt b (Mem.nextblock m)
then PMap.get b (Mem.mem_access m2') ofs k = PMap.get b (Mem.mem_access m2) ofs k
else PMap.get b (Mem.mem_access m2') ofs k = PMap.get b (Mem.mem_access m1') ofs k)
P
(HA: Mem.valid_block m b -> Mem.perm m2' b ofs k = Mem.perm m2 b ofs k -> P)
(HB: ~Mem.valid_block m b -> Mem.perm m2' b ofs k = Mem.perm m1' b ofs k -> P), P.
Lemma valid_splitC: forall (T:Type)(m:mem) (b:block) X (A B:T)
(SPLIT: if plt b (Mem.nextblock m)
then X = A
else X = B)
P
(HA: Mem.valid_block m b -> X=A -> P)
(HB: ~Mem.valid_block m b -> X=B -> P), P.
Lemma dec_split: forall {C} (dec: C \/ ~ C) (A B: Prop)
(SPLIT: (C -> A) /\ (~C -> B))
(P:Prop)
(HA: C -> A -> P)
(HB: ~C -> B -> P), P.
Lemma valid_split: forall m b (A B: Prop)
(SPLIT: (Mem.valid_block m b  -> A) /\ (~Mem.valid_block m b -> B))
(P:Prop)
(HA: Mem.valid_block m b -> A -> P)
(HB: ~Mem.valid_block m b -> B -> P), P.
Lemma perm_nextblock_gt_1: forall m b ofs k p (P: Mem.perm m b ofs k p),
Plt 1 (Mem.nextblock m).
Lemma source_SomeE: forall j m (b2:block) (ofs2:Z) p,
Some p = source j m b2 ofs2 ->
exists b1, exists delta, exists ofs1,
p = (b1,ofs1) /\
(b1 < Mem.nextblock m)%positive /\ j b1 = Some(b2,delta) /\
Mem.perm m b1 ofs1 Max Nonempty /\ ofs2=ofs1+delta.
Lemma source_NoneE: forall j m b2 ofs2,
None = source j m b2 ofs2 ->
forall b1 delta, (b1 < Mem.nextblock m)%positive -> j b1 = Some(b2,delta) ->
~ Mem.perm m b1 (ofs2-delta) Max Nonempty.
Lemma source_SomeI: forall j m b2 b1 ofs1 delta (OV:Mem.meminj_no_overlap j m),
j b1 = Some(b2,delta) -> Mem.perm m b1 ofs1 Max Nonempty ->
source j m b2 (ofs1+delta) = Some(b1,ofs1).
Lemma sourceNone_LOOR: forall j m1 b2 ofs2 (N: None = source j m1 b2 ofs2) m2
(Inj12: Mem.inject j m1 m2), loc_out_of_reach j m1 b2 ofs2.
Lemma memvalUnchOnR: forall m1 m2 m3 m3' b ofs
(n : ~ Mem.perm m1 b ofs Max Nonempty)
(UnchOn13 : Mem.unchanged_on (loc_out_of_bounds m1) m3 m3')
(MV : memval_inject inject_id
(ZMap.get ofs (PMap.get b (Mem.mem_contents m2)))
(ZMap.get ofs (PMap.get b (Mem.mem_contents m3))))
(Rd: Mem.perm m3 b ofs Cur Readable),
memval_inject inject_id (ZMap.get ofs (PMap.get b (Mem.mem_contents m2)))
(ZMap.get ofs (PMap.get b (Mem.mem_contents m3'))).
Lemma perm_order_total: forall p1 p2, perm_order p1 p2 \/ perm_order p2 p1.
Lemma perm_order_antisym: forall p1 p2, perm_order p1 p2 -> perm_order p2 p1 -> p1=p2.
Lemma perm_splitA: forall m b ofs k' p m2' m2 m3' k b3 ofs3
(SPLIT: (Mem.perm m b ofs k' p-> PMap.get b (Mem.mem_access m2') ofs k = PMap.get b (Mem.mem_access m2) ofs k) /\
(~Mem.perm m b ofs k' p -> PMap.get b (Mem.mem_access m2') ofs k = PMap.get b3 (Mem.mem_access m3') ofs3 k))
(P:Prop)
(HA: Mem.perm m b ofs k' p -> Mem.perm m2' b ofs k = Mem.perm m2 b ofs k -> P)
(HB: ~Mem.perm m b ofs k' p -> Mem.perm m2' b ofs k = Mem.perm m3' b3 ofs3 k  -> P), P.
Lemma valid_splitA: forall (m m2' m2 m1':mem) (b:block) ofs k
(SPLIT: if plt b (Mem.nextblock m)
then PMap.get b (Mem.mem_access m2') ofs k = PMap.get b (Mem.mem_access m2) ofs k
else PMap.get b (Mem.mem_access m2') ofs k = PMap.get b (Mem.mem_access m1') ofs k)
P
(HA: Mem.valid_block m b -> Mem.perm m2' b ofs k = Mem.perm m2 b ofs k -> P)
(HB: ~Mem.valid_block m b -> Mem.perm m2' b ofs k = Mem.perm m1' b ofs k -> P), P.
Lemma valid_splitC: forall (T:Type)(m:mem) (b:block) X (A B:T)
(SPLIT: if plt b (Mem.nextblock m)
then X = A
else X = B)
P
(HA: Mem.valid_block m b -> X=A -> P)
(HB: ~Mem.valid_block m b -> X=B -> P), P.
Lemma dec_split: forall {C} (dec: C \/ ~ C) (A B: Prop)
(SPLIT: (C -> A) /\ (~C -> B))
(P:Prop)
(HA: C -> A -> P)
(HB: ~C -> B -> P), P.
Lemma valid_split: forall m b (A B: Prop)
(SPLIT: (Mem.valid_block m b  -> A) /\ (~Mem.valid_block m b -> B))
(P:Prop)
(HA: Mem.valid_block m b -> A -> P)
(HB: ~Mem.valid_block m b -> B -> P), P.