+ intros. xomega.
+ induction 1.
- apply Mem.nextblock_storebytes in H;
rewrite H; xomega.
- apply Mem.nextblock_alloc in H.
rewrite H. clear. xomega.
- apply nextblock_freelist in H.
rewrite H; xomega.
- xomega.
Qed.

(* Specifications: *)
Lemma mem_step_nextblock':
forall m m',
mem_step m m' ->
(Mem.nextblock m <= Mem.nextblock m')%positive.
Lemma estep_unch_on_loc_not_writable m m' (E:e_step m m'): Mem.unchanged_on (loc_not_writable m) m m'.
*)
(* Theorem loadbytes_drop m b lo hi p m' (D:Mem.drop_perm m b lo hi p = Some m'): forall b' ofs, b' <> b \/ ofs < lo \/ hi <= ofs \/ perm_order p Readable -> Mem.loadbytes m' b' ofs 1 = Mem.loadbytes m b' ofs 1. *)
Lemma mem_step_obeys_cur_write:
forall m b ofs m',
Mem.valid_block m b ->
~ Mem.perm m b ofs Cur Writable ->
mem_step m m' ->
ZMap.get ofs (PMap.get b (Mem.mem_contents m)) =
ZMap.get ofs (PMap.get b (Mem.mem_contents m')).
Lemma ple_load m ch a v
(LD: Mem.loadv ch m a = Some v)
m1 (PLE: perm_lesseq m m1):
Mem.loadv ch m1 a = Some v.
Lemma ple_store:
forall ch m v1 v2 m' m1
(PLE: perm_lesseq m m1),
Mem.storev ch m v1 v2 = Some m' ->
exists m1', perm_lesseq m' m1' /\ Mem.storev ch m1 v1 v2 = Some m1'.
Lemma free_access_inv m b lo hi m' (FR: Mem.free m b lo hi = Some m') b' ofs k p
(P: (Mem.mem_access m') !! b' ofs k = Some p):  (Mem.mem_access m) !! b' ofs k = Some p.
Lemma free_access_inv_None m b lo hi m' (FR: Mem.free m b lo hi = Some m') b' ofs k
(P: (Mem.mem_access m') !! b' ofs k = None):
(b' = b /\ Z.le lo ofs /\ Z.lt ofs hi /\  (Mem.mem_access m) !! b' ofs k = Some Freeable) \/
((b' <> b \/ Z.lt ofs lo \/ Z.le hi ofs) /\ (Mem.mem_access m) !! b' ofs k = None).
Lemma ple_free: forall m m' b lo hi (FL: Mem.free m b lo hi = Some m') m1 (PLE:perm_lesseq m m1),
exists m1', Mem.free m1 b lo hi = Some m1' /\ perm_lesseq m' m1'.
Lemma ple_freelist: forall l m m' (FL: Mem.free_list m l = Some m') m1 (PLE:perm_lesseq m m1),
exists m1', Mem.free_list m1 l = Some m1' /\ perm_lesseq m' m1'.
Lemma ple_storebytes:
forall m b ofs bytes m' m1
(PLE: perm_lesseq m m1),
Mem.storebytes m b ofs bytes = Some m' ->
exists m1', perm_lesseq m' m1' /\ Mem.storebytes m1 b ofs bytes = Some m1'.
Lemma ple_loadbytes m b ofs n bytes
(LD: Mem.loadbytes m b ofs n = Some bytes)
m1 (PLE: perm_lesseq m m1) (N: 0 <= n):
Mem.loadbytes m1 b ofs n = Some bytes.
Lemma alloc_access_inv m b lo hi m' (ALLOC: Mem.alloc m lo hi = (m', b)) b' ofs k p
(P: (Mem.mem_access m') !! b' ofs k = Some p):
(b'=b /\ Z.le lo ofs /\ Z.lt ofs hi) \/
(b' <> b /\ (Mem.mem_access m) !! b' ofs k = Some p).
Lemma alloc_access_inv_None m b lo hi m' (ALLOC: Mem.alloc m lo hi = (m', b)) b' ofs k
(P: (Mem.mem_access m') !! b' ofs k = None): (Mem.mem_access m) !! b' ofs k = None.
Lemma alloc_inc_perm: forall m lo hi m' b
(M: Mem.alloc m lo hi = (m',b)) m1 (PLE: perm_lesseq m m1),
exists m1' : mem, Mem.alloc m1 lo hi =(m1',b) /\ perm_lesseq m' m1'.
Lemma perm_lesseq_refl:
forall m, perm_lesseq m m.
Lemma mem_step_nextblock':
forall m m',
mem_step m m' ->
(Mem.nextblock m <= Mem.nextblock m')%positive.
Lemma estep_unch_on_loc_not_writable m m' (E:e_step m m'): Mem.unchanged_on (loc_not_writable m) m m'.
*)
(* Theorem loadbytes_drop m b lo hi p m' (D:Mem.drop_perm m b lo hi p = Some m'): forall b' ofs, b' <> b \/ ofs < lo \/ hi <= ofs \/ perm_order p Readable -> Mem.loadbytes m' b' ofs 1 = Mem.loadbytes m b' ofs 1. *)
Lemma mem_step_obeys_cur_write:
forall m b ofs m',
Mem.valid_block m b ->
~ Mem.perm m b ofs Cur Writable ->
mem_step m m' ->
ZMap.get ofs (PMap.get b (Mem.mem_contents m)) =
ZMap.get ofs (PMap.get b (Mem.mem_contents m')).
Lemma ple_load m ch a v
(LD: Mem.loadv ch m a = Some v)
m1 (PLE: perm_lesseq m m1):
Mem.loadv ch m1 a = Some v.
Lemma ple_store:
forall ch m v1 v2 m' m1
(PLE: perm_lesseq m m1),
Mem.storev ch m v1 v2 = Some m' ->
exists m1', perm_lesseq m' m1' /\ Mem.storev ch m1 v1 v2 = Some m1'.
Lemma free_access_inv m b lo hi m' (FR: Mem.free m b lo hi = Some m') b' ofs k p
(P: (Mem.mem_access m') !! b' ofs k = Some p):  (Mem.mem_access m) !! b' ofs k = Some p.
Lemma free_access_inv_None m b lo hi m' (FR: Mem.free m b lo hi = Some m') b' ofs k
(P: (Mem.mem_access m') !! b' ofs k = None):
(b' = b /\ Z.le lo ofs /\ Z.lt ofs hi /\  (Mem.mem_access m) !! b' ofs k = Some Freeable) \/
((b' <> b \/ Z.lt ofs lo \/ Z.le hi ofs) /\ (Mem.mem_access m) !! b' ofs k = None).
Lemma ple_free: forall m m' b lo hi (FL: Mem.free m b lo hi = Some m') m1 (PLE:perm_lesseq m m1),
exists m1', Mem.free m1 b lo hi = Some m1' /\ perm_lesseq m' m1'.
Lemma ple_freelist: forall l m m' (FL: Mem.free_list m l = Some m') m1 (PLE:perm_lesseq m m1),
exists m1', Mem.free_list m1 l = Some m1' /\ perm_lesseq m' m1'.
Lemma ple_storebytes:
forall m b ofs bytes m' m1
(PLE: perm_lesseq m m1),
Mem.storebytes m b ofs bytes = Some m' ->
exists m1', perm_lesseq m' m1' /\ Mem.storebytes m1 b ofs bytes = Some m1'.
Lemma ple_loadbytes m b ofs n bytes
(LD: Mem.loadbytes m b ofs n = Some bytes)
m1 (PLE: perm_lesseq m m1) (N: 0 <= n):
Mem.loadbytes m1 b ofs n = Some bytes.
Lemma alloc_access_inv m b lo hi m' (ALLOC: Mem.alloc m lo hi = (m', b)) b' ofs k p
(P: (Mem.mem_access m') !! b' ofs k = Some p):
(b'=b /\ Z.le lo ofs /\ Z.lt ofs hi) \/
(b' <> b /\ (Mem.mem_access m) !! b' ofs k = Some p).
Lemma alloc_access_inv_None m b lo hi m' (ALLOC: Mem.alloc m lo hi = (m', b)) b' ofs k
(P: (Mem.mem_access m') !! b' ofs k = None): (Mem.mem_access m) !! b' ofs k = None.
Lemma alloc_inc_perm: forall m lo hi m' b
(M: Mem.alloc m lo hi = (m',b)) m1 (PLE: perm_lesseq m m1),
exists m1' : mem, Mem.alloc m1 lo hi =(m1',b) /\ perm_lesseq m' m1'.
Lemma perm_lesseq_refl:
forall m, perm_lesseq m m.