Section WITH_SHARE.
Variable sh: share.
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)).
End WITH_SHARE.
(************************************************  Transformation between data_at/data_at_ and mapsto.  ************************************************)
(* Lemma by_value_data_at_: forall sh t p, type_is_by_value t = true -> data_at_ sh t p = !! field_compatible t nil p && mapsto_ sh t p. *)
(************************************************  Transformation between data_at and data_at_rec. This is used in transformation between field_at and data_at.  ************************************************)
*)
(* Ltac AUTO_IND := match goal with | H: complete_legal_cosu_type (Tarray ?t ?n ?a) = true |- complete_legal_cosu_type ?t = true => simpl in H; auto | H: (alignof (Tarray ?t ?z ?a) | ?ofs) |- (alignof ?t | ?ofs + _) => apply Z.divide_add_r; [ eapply Z.divide_trans; [eapply alignof_divide_alignof_Tarray |]; eauto | apply Z.divide_mul_l; eapply legal_alignas_type_Tarray; eauto] | H: legal_alignas_type (Tstruct ?id ?a) = true |- legal_alignas_type (field_type ?i (co_members (get_co ?id))) = true => unfold legal_alignas_type in H; apply nested_pred_Tstruct2 with (i0 := i) in H; [exact H | auto] | H: legal_cosu_type (Tstruct ?id ?a) = true |- legal_cosu_type (field_type ?i (co_members (get_co ?id))) = true => unfold legal_cosu_type in H; apply nested_pred_Tstruct2 with (i0 := i) in H; [exact H | auto] | |- complete_type ?env (field_type ?i (co_members (get_co ?id))) = true => apply complete_type_field_type; auto | H: (alignof (Tstruct ?id ?a) | ?ofs) |- (alignof (field_type ?i (co_members (get_co ?id))) | ?ofs + _) => apply Z.divide_add_r; [ eapply Z.divide_trans; [apply alignof_field_type_divide_alignof; auto |]; eapply Z.divide_trans; [apply legal_alignas_type_Tstruct; eauto | auto] | apply field_offset_aligned] | H: legal_alignas_type (Tunion ?id ?a) = true |- legal_alignas_type (field_type ?i (co_members (get_co ?id))) = true => unfold legal_alignas_type in H; apply nested_pred_Tunion2 with (i0 := i) in H; [exact H | auto] | H: legal_cosu_type (Tunion ?id ?a) = true |- legal_cosu_type (field_type ?i (co_members (get_co ?id))) = true => unfold legal_cosu_type in H; apply nested_pred_Tunion2 with (i0 := i) in H; [exact H | auto] | H: (alignof (Tunion ?id ?a) | ?ofs) |- (alignof (field_type ?i (co_members (get_co ?id))) | ?ofs) => eapply Z.divide_trans; [apply alignof_field_type_divide_alignof; auto |]; eapply Z.divide_trans; [apply legal_alignas_type_Tunion; eauto | auto] end. *)

(* We use (Vptr b (Int.repr ofs)) instead of p because size_compatible is more  *)
(* difficult to use than simple arithmetic in induction proof.                  *)
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)).