(** Valid values are the ones that have no pointers outside the domain of f*)
  Definition valid_val (f: memren) (v : val) : Prop :=
    match v with
    | Vptr b _ =>
      exists b', f b = Some b'
    | _ => True
    end.Definition valid_memval (f: memren) (mv : memval) : Prop :=
    match mv with
    | Fragment v _ _ =>
      valid_val f v
    | _ => True
    end.

(* Specifications: *)
Lemma valid_val_incr: forall f f' v (Hvalid: valid_val f v) (Hincr: ren_domain_incr f f'), valid_val f' v.
Lemma valid_val_list_incr: forall f f' vs (Hvalid: valid_val_list f vs) (Hincr: ren_domain_incr f f'), valid_val_list f' vs.
Lemma valid_val_domain: forall f f' m v, valid_val f v -> domain_memren f m -> domain_memren f' m -> valid_val f' v.
Lemma valid_val_list_domain: forall f f' m vs (Hvalid: valid_val_list f vs) (Hdomain: domain_memren f m) (Hdomain': domain_memren f' m), valid_val_list f' vs.
Lemma ofs_val_lt : forall ofs chunk v, ofs < ofs + Z.of_nat (length (encode_val chunk v)).
Lemma valid_val_int: forall f n, valid_val f (Vint n).
Lemma valid_val_long: forall f n, valid_val f (Vlong n).
Lemma valid_val_one: forall f, valid_val f Vone.
Lemma valid_val_single: forall f n, valid_val f (Vsingle n).
Lemma valid_val_float: forall f n, valid_val f (Vfloat n).
Lemma valid_val_hiword: forall f v, valid_val f (Val.hiword v).
Lemma valid_val_loword: forall f v, valid_val f (Val.loword v).
Lemma valid_val_add: forall f v1 v2, valid_val f v1 -> valid_val f v2 -> valid_val f (Val.add v1 v2).
Lemma valid_val_addl: forall f v1 v2, valid_val f v1 -> valid_val f v2 -> valid_val f (Val.addl v1 v2).
Lemma valid_val_offset_ptr: forall f v ofs, valid_val f v -> valid_val f (Val.offset_ptr v ofs).
Lemma valid_val_sub: forall f v1 v2, valid_val f v1 -> valid_val f v2 -> valid_val f (Val.sub v1 v2).
Lemma valid_val_subl: forall f v1 v2, valid_val f v1 -> valid_val f v2 -> valid_val f (Val.subl v1 v2).
Lemma valid_val_mul: forall f v1 v2, valid_val f (Val.mul v1 v2).
Lemma valid_val_mulhu: forall f v1 v2, valid_val f (Val.mulhu v1 v2).
Lemma valid_val_mull: forall f v1 v2, valid_val f (Val.mull v1 v2).
Lemma valid_val_mullhu: forall f v1 v2, valid_val f (Val.mullhu v1 v2).
Lemma valid_val_and: forall f v1 v2, valid_val f (Val.and v1 v2).
Lemma valid_val_or: forall f v1 v2, valid_val f (Val.or v1 v2).
Lemma valid_val_xor: forall f v1 v2, valid_val f (Val.xor v1 v2).
Lemma valid_val_andl: forall f v1 v2, valid_val f (Val.andl v1 v2).
Lemma valid_val_orl: forall f v1 v2, valid_val f (Val.orl v1 v2).
Lemma valid_val_xorl: forall f v1 v2, valid_val f (Val.xorl v1 v2).
Lemma valid_intoffloat: forall f v, valid_val f (Val.maketotal (Val.intoffloat v)).
Lemma valid_intofsingle: forall f v, valid_val f (Val.maketotal (Val.intofsingle v)).
Lemma valid_singleofint: forall f v, valid_val f (Val.maketotal (Val.singleofint v)).
Lemma valid_floatofint: forall f v, valid_val f (Val.maketotal (Val.floatofint v)).
Lemma valid_longoffloat: forall f v, valid_val f (Val.maketotal (Val.longoffloat v)).
Lemma valid_longofsingle: forall f v, valid_val f (Val.maketotal (Val.longofsingle v)).
Lemma valid_singleoflong: forall f v, valid_val f (Val.maketotal (Val.singleoflong v)).
Lemma valid_floatoflong: forall f v, valid_val f (Val.maketotal (Val.floatoflong v)).
Lemma valid_val_singleoffloat: forall f v, valid_val f (Val.singleoffloat v).
Lemma valid_val_floatofsingle: forall f v, valid_val f (Val.floatofsingle v).
Lemma valid_val_neg: forall f v, valid_val f (Val.neg v).
Lemma valid_val_negl: forall f v, valid_val f (Val.negl v).
Lemma valid_val_sign_ext: forall f v n, valid_val f (Val.sign_ext n v).
Lemma valid_val_longofintu: forall f v, valid_val f (Val.longofintu v).
Lemma valid_val_longofint: forall f v, valid_val f (Val.longofint v).
Lemma valid_val_zero_ext: forall f v n, valid_val f (Val.zero_ext n v).
Lemma valid_val_mulhs: forall f v1 v2, valid_val f (Val.mulhs v1 v2).
Lemma valid_val_mullhs: forall f v1 v2, valid_val f (Val.mullhs v1 v2).
Lemma valid_val_undef: forall f, valid_val f Vundef.
Lemma valid_val_shl: forall f v1 v2, valid_val f (Val.shl v1 v2).
Lemma valid_val_shru: forall f v1 v2, valid_val f (Val.shru v1 v2).
Lemma valid_val_shr: forall f v1 v2, valid_val f (Val.shr v1 v2).
Lemma valid_val_ror: forall f v1 v2, valid_val f (Val.ror v1 v2).
Lemma valid_val_shll: forall f v1 v2, valid_val f (Val.shll v1 v2).
Lemma valid_val_shrlu: forall f v1 v2, valid_val f (Val.shrlu v1 v2).
Lemma valid_val_shrl: forall f v1 v2, valid_val f (Val.shrl v1 v2).
Lemma valid_val_rorl: forall f v1 v2, valid_val f (Val.rorl v1 v2).
Lemma valid_val_addf: forall f v1 v2, valid_val f (Val.addf v1 v2).
Lemma valid_val_mulf: forall f v1 v2, valid_val f (Val.mulf v1 v2).
Lemma valid_val_subf: forall f v1 v2, valid_val f (Val.subf v1 v2).
Lemma valid_val_divf: forall f v1 v2, valid_val f (Val.divf v1 v2).
Lemma valid_val_addfs: forall f v1 v2, valid_val f (Val.addfs v1 v2).
Lemma valid_val_mulfs: forall f v1 v2, valid_val f (Val.mulfs v1 v2).
Lemma valid_val_subfs: forall f v1 v2, valid_val f (Val.subfs v1 v2).
Lemma valid_val_divfs: forall f v1 v2, valid_val f (Val.divfs v1 v2).
Lemma valid_val_negf: forall f v, valid_val f (Val.negf v).
Lemma valid_val_absf: forall f v, valid_val f (Val.absf v).
Lemma valid_val_negfs: forall f v, valid_val f (Val.negfs v).
Lemma valid_val_absfs: forall f v, valid_val f (Val.absfs v).
Lemma valid_val_divu: forall f v1 v2 v, Val.divu v1 v2 = Some v -> valid_val f v.
Lemma valid_val_modu: forall f v1 v2 v, Val.modu v1 v2 = Some v -> valid_val f v.
Lemma valid_val_divs: forall f v1 v2 v, Val.divs v1 v2 = Some v -> valid_val f v.
Lemma valid_val_mods: forall f v1 v2 v, Val.mods v1 v2 = Some v -> valid_val f v.
Lemma valid_val_divlu: forall f v1 v2 v, Val.divlu v1 v2 = Some v -> valid_val f v.
Lemma valid_val_modlu: forall f v1 v2 v, Val.modlu v1 v2 = Some v -> valid_val f v.
Lemma valid_val_divls: forall f v1 v2 v, Val.divls v1 v2 = Some v -> valid_val f v.
Lemma valid_val_modls: forall f v1 v2 v, Val.modls v1 v2 = Some v -> valid_val f v.
Lemma valid_val_notint: forall f v, valid_val f (Val.notint v).
Lemma valid_val_notl: forall f v, valid_val f (Val.notl v).
Lemma valid_val_vzero: forall f, valid_val f (Vzero).
Lemma valid_val_of_optbool: forall f b, valid_val f (Val.of_optbool b).
Lemma valid_val_offset: forall f b ofs ofs', valid_val f (Vptr b ofs) -> valid_val f (Vptr b ofs').
Lemma valid_val_sub_overflow: forall f v1 v2, valid_val f (Val.sub_overflow v1 v2).
Lemma valid_val_subl_overflow: forall f v1 v2, valid_val f (Val.subl_overflow v1 v2).
Lemma valid_val_negative: forall f v, valid_val f (Val.negative v).
Lemma valid_val_negativel: forall f v, valid_val f (Val.negativel v).
Lemma valid_val_of_bool: forall f b, valid_val f (Val.of_bool b).
Lemma wd_val_valid: forall v m f (Hdomain: domain_memren f m), mem_wd.val_valid v m <-> valid_val f v.
Lemma restrPermMap_val_valid: forall m p (Hlt: permMapLt p (getMaxPerm m)) v, mem_wd.val_valid v m <-> mem_wd.val_valid v (restrPermMap Hlt).
Lemma restrPermMap_mem_valid : forall m p (Hlt: permMapLt p (getMaxPerm m)), valid_mem m <-> valid_mem (restrPermMap Hlt).
Lemma inj_bytes_type: forall bs mv, In mv (inj_bytes bs) -> match mv with | Byte _ => True | _ => False end.
Lemma decode_val_wd: forall f (vl : seq memval) (chunk : memory_chunk), valid_memval_list f vl -> valid_val f (decode_val chunk vl).
Lemma valid_val_encode: forall v m chunk (Hval_wd: mem_wd.val_valid v m), forall v', List.In v' (encode_val chunk v) -> match v' with | Undef => True | Byte _ => True | Fragment v'' _ _ => mem_wd.val_valid v'' m end.
Lemma valid_val_store: forall v m m' chunk b ofs v' (Hvalid: mem_wd.val_valid v m) (Hstore: Mem.store chunk m b ofs v' = Some m'), mem_wd.val_valid v m'.
Lemma valid_val_storebytes: forall v m m' b ofs mv (Hmem: mem_wd.val_valid v m) (Hstore: Mem.storebytes m b ofs mv = Some m'), mem_wd.val_valid v m'.
Lemma storebytes_wd_domain: forall (m m' : mem) mv b ofs f (Hdomain: domain_memren f m) (Hmval_wd: valid_memval_list f mv) (Hstore: Mem.storebytes m b ofs mv = Some m') (Hmem_wd: valid_mem m), valid_mem m' /\ domain_memren f m'.
Lemma In_valid_memval_list: forall f mvs mv, valid_memval_list f mvs -> In mv mvs -> valid_memval f mv.
Lemma store_wd_domain: forall (m m' : mem) (chunk : memory_chunk) (v : val) b ofs f (Hdomain: domain_memren f m) (Hstore: Mem.store chunk m b ofs v = Some m') (Hval_wd: mem_wd.val_valid v m) (Hmem_wd: valid_mem m), valid_mem m' /\ domain_memren f m'.
Lemma storev_wd_domain: forall (m m' : mem) (chunk : memory_chunk) (vptr v : val) f, domain_memren f m -> Mem.storev chunk m vptr v = Some m' -> mem_wd.val_valid v m -> valid_mem m -> valid_mem m' /\ domain_memren f m'.
Lemma valid_mem_load: forall chunk m b ofs v f (Hwd: valid_mem m) (Hdomain: domain_memren f m) (Hload: Mem.load chunk m b ofs = Some v), valid_val f v.
Lemma valid_mem_loadbytes: forall m b ofs sz mv f (Hwd: valid_mem m) (Hsz: sz >= 0) (Hdomain: domain_memren f m) (Hload: Mem.loadbytes m b ofs sz = Some mv), valid_memval_list f mv.
Lemma loadv_wd: forall chunk m vptr v f (Hwd: valid_mem m) (Hdomain: domain_memren f m) (Hload: Mem.loadv chunk m vptr = Some v), valid_val f v.
Lemma domain_memren_store: forall chunk m m' b ofs v f (Hdomain: domain_memren f m) (Hstore: Mem.store chunk m b ofs v = Some m'), domain_memren f m'.
Lemma domain_memren_storev: forall chunk m m' vptr v f (Hdomain: domain_memren f m) (Hstore: Mem.storev chunk m vptr v = Some m'), domain_memren f m'.