(** * Abstracting memory states *)

Record amem : Type := AMem {
  am_stack: ablock;
  am_glob: PTree.t ablock;
  am_nonstack: aptr;
  am_top: aptr
}.(** * Abstracting memory states *)

Record amem : Type := AMem {
  am_stack: ablock;
  am_glob: PTree.t ablock;
  am_nonstack: aptr;
  am_top: aptr
}.(** * Abstracting memory states *)

Record amem : Type := AMem {
  am_stack: ablock;
  am_glob: PTree.t ablock;
  am_nonstack: aptr;
  am_top: aptr
}.(** * Abstracting memory states *)

Record amem : Type := AMem {
  am_stack: ablock;
  am_glob: PTree.t ablock;
  am_nonstack: aptr;
  am_top: aptr
}.(** * Abstracting memory states *)

Record amem : Type := AMem {
  am_stack: ablock;
  am_glob: PTree.t ablock;
  am_nonstack: aptr;
  am_top: aptr
}.(** * Abstracting memory states *)

Record amem : Type := AMem {
  am_stack: ablock;
  am_glob: PTree.t ablock;
  am_nonstack: aptr;
  am_top: aptr
}.Definition minit (p: aptr) :=
  {| am_stack := ablock_init p;
     am_glob := PTree.empty _;
     am_nonstack := p;
     am_top := p |}.Definition mbot := minit Pbot.Definition mtop := minit Ptop.Definition loadv (chunk: memory_chunk) (rm: romem) (m: amem) (addr: aval) : aval :=
  load chunk rm m (aptr_of_aval addr).Definition storev (chunk: memory_chunk) (m: amem) (addr: aval) (v: aval): amem :=
  store chunk m (aptr_of_aval addr) v.

(* Specifications: *)
Theorem load_sound: forall chunk m b ofs v rm am p, Mem.load chunk m b (Ptrofs.unsigned ofs) = Some v -> romatch m rm -> mmatch m am -> pmatch b ofs p -> vmatch v (load chunk rm am p).
Theorem loadv_sound: forall chunk m addr v rm am aaddr, Mem.loadv chunk m addr = Some v -> romatch m rm -> mmatch m am -> vmatch addr aaddr -> vmatch v (loadv chunk rm am aaddr).
Theorem store_sound: forall chunk m b ofs v m' am p av, Mem.store chunk m b (Ptrofs.unsigned ofs) v = Some m' -> mmatch m am -> pmatch b ofs p -> vmatch v av -> mmatch m' (store chunk am p av).
Theorem storev_sound: forall chunk m addr v m' am aaddr av, Mem.storev chunk m addr v = Some m' -> mmatch m am -> vmatch addr aaddr -> vmatch v av -> mmatch m' (storev chunk am aaddr av).
Theorem loadbytes_sound: forall m b ofs sz bytes am rm p, Mem.loadbytes m b (Ptrofs.unsigned ofs) sz = Some bytes -> romatch m rm -> mmatch m am -> pmatch b ofs p -> forall b' ofs' q i, In (Fragment (Vptr b' ofs') q i) bytes -> pmatch b' ofs' (loadbytes am rm p).
Theorem storebytes_sound: forall m b ofs bytes m' am p sz q, Mem.storebytes m b (Ptrofs.unsigned ofs) bytes = Some m' -> mmatch m am -> pmatch b ofs p -> length bytes = nat_of_Z sz -> (forall b' ofs' qt i, In (Fragment (Vptr b' ofs') qt i) bytes -> pmatch b' ofs' q) -> mmatch m' (storebytes am p sz q).
Lemma mmatch_ext: forall m am m', mmatch m am -> (forall b ofs n bytes, bc b <> BCinvalid -> n >= 0 -> Mem.loadbytes m' b ofs n = Some bytes -> Mem.loadbytes m b ofs n = Some bytes) -> Ple (Mem.nextblock m) (Mem.nextblock m') -> mmatch m' am.
Lemma mmatch_free: forall m b lo hi m' am, Mem.free m b lo hi = Some m' -> mmatch m am -> mmatch m' am.
Lemma mmatch_top': forall m am, mmatch m am -> mmatch m mtop.