Definition offset_in_range ofs p :=
  match p with
  | Vptr b iofs => 0 <= Ptrofs.unsigned iofs + ofs <= Ptrofs.modulus
  | _ => True
  end.Definition offset_strict_in_range ofs p :=
  match p with
  | Vptr b iofs => 0 <= Ptrofs.unsigned iofs + ofs < Ptrofs.modulus
  | _ => True
  end.Definition data_at_rec: forall t, reptype t -> val -> mpred :=
  type_func (fun t => reptype t -> val -> mpred)
    (fun t v p =>
       if type_is_volatile t
       then memory_block sh (sizeof t) p
       else mapsto sh t p (repinject t v))
    (fun t n a P v => array_pred 0 (Z.max 0 n) (fun i v => at_offset (P v) (sizeof t * i)) (unfold_reptype v))
    (fun id a P v => struct_data_at_rec_aux sh (co_members (get_co id)) (co_members (get_co id)) (co_sizeof (get_co id)) P (unfold_reptype v))
    (fun id a P v => union_data_at_rec_aux sh (co_members (get_co id)) (co_members (get_co id)) (co_sizeof (get_co id)) P (unfold_reptype v)).

(* Specifications: *)
Lemma data_at_rec_eq: forall t v, data_at_rec t v = match t return REPTYPE t -> val -> mpred with | Tvoid | Tfunction _ _ _ => fun _ _ => FF | Tint _ _ _ | Tfloat _ _ | Tlong _ _ | Tpointer _ _ => fun v p => if type_is_volatile t then memory_block sh (sizeof t) p else mapsto sh t p v | Tarray t0 n a => array_pred 0 (Z.max 0 n) (fun i v => at_offset (data_at_rec t0 v) (sizeof t0 * i)) | Tstruct id a => struct_pred (co_members (get_co id)) (fun it v => withspacer sh (field_offset cenv_cs (fst it) (co_members (get_co id)) + sizeof (field_type (fst it) (co_members (get_co id)))) (field_offset_next cenv_cs (fst it) (co_members (get_co id)) (co_sizeof (get_co id))) (at_offset (data_at_rec (field_type (fst it) (co_members (get_co id))) v) (field_offset cenv_cs (fst it) (co_members (get_co id))))) | Tunion id a => union_pred (co_members (get_co id)) (fun it v => withspacer sh (sizeof (field_type (fst it) (co_members (get_co id)))) (co_sizeof (get_co id)) (data_at_rec (field_type (fst it) (co_members (get_co id))) v)) end (unfold_reptype v).
Lemma data_at_rec_type_changable: forall (sh: Share.t) (t1 t2: type) v1 v2, t1 = t2 -> JMeq v1 v2 -> data_at_rec sh t1 v1 = data_at_rec sh t2 v2.
Lemma by_value_default_val: forall t:type, type_is_by_value t = true -> JMeq (default_val t) Vundef.
Lemma by_value_reptype: forall t, type_is_by_value t = true -> reptype t = val.
Lemma by_value_data_at_rec_volatile: forall sh t v p, type_is_by_value t = true -> type_is_volatile t = true -> data_at_rec sh t v p = memory_block sh (sizeof t) p.
Lemma by_value_data_at_rec_nonvolatile: forall sh t v p, type_is_by_value t = true -> type_is_volatile t = false -> data_at_rec sh t v p = mapsto sh t p (repinject t v).
Lemma by_value_data_at_rec_default_val: forall sh t p, type_is_by_value t = true -> size_compatible t p -> align_compatible t p -> data_at_rec sh t (default_val t) p = memory_block sh (sizeof t) p.
Lemma by_value_data_at_rec_nonreachable: forall sh t p v, type_is_by_value t = true -> size_compatible t p -> align_compatible t p -> ~ readable_share sh -> tc_val' t (repinject t v) -> data_at_rec sh t v p = memory_block sh (sizeof t) p.
Lemma by_value_data_at_rec_default_val2: forall sh t b ofs, type_is_by_value t = true -> 0 <= ofs /\ ofs + sizeof t < Ptrofs.modulus -> align_compatible_rec cenv_cs t ofs -> data_at_rec sh t (default_val t) (Vptr b (Ptrofs.repr ofs)) = memory_block sh (sizeof t) (Vptr b (Ptrofs.repr ofs)).
Lemma by_value_data_at_rec_nonreachable2: forall sh t b ofs v, type_is_by_value t = true -> 0 <= ofs /\ ofs + sizeof t < Ptrofs.modulus -> align_compatible_rec cenv_cs t ofs -> ~ readable_share sh -> tc_val' t (repinject t v) -> data_at_rec sh t v (Vptr b (Ptrofs.repr ofs)) = memory_block sh (sizeof t) (Vptr b (Ptrofs.repr ofs)).
Lemma lower_sepcon_val': forall (P Q: val->mpred) v, ((P*Q) v) = (P v * Q v).
Lemma Znth_nil: forall {A}{d: Inhabitant A} n, Znth n nil = default.
Lemma offset_val_zero_Vptr: forall b i, offset_val 0 (Vptr b i) = Vptr b i.
Lemma nth_list_repeat: forall A i n (x :A), nth i (list_repeat n x) x = x.
Lemma nth_list_repeat': forall A i n (x y :A), (i < n)%nat -> nth i (list_repeat n x) y = x.
Lemma Z2Nat_max0: forall z, Z.to_nat (Z.max 0 z) = Z.to_nat z.
Lemma range_max0: forall x z, 0 <= x < Z.max 0 z <-> 0 <= x < z.
Lemma memory_block_data_at_rec_default_val: forall sh t b ofs (LEGAL_COSU: complete_legal_cosu_type t = true), 0 <= ofs /\ ofs + sizeof t < Ptrofs.modulus -> align_compatible_rec cenv_cs t ofs -> data_at_rec sh t (default_val t) (Vptr b (Ptrofs.repr ofs)) = memory_block sh (sizeof t) (Vptr b (Ptrofs.repr ofs)).