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. *)
(* Lemma align_1_memory_block_data_at_: forall (sh : share) (t : type), legal_alignas_type t = true -> nested_legal_fieldlist t = true -> nested_non_volatile_type t = true -> alignof t = 1%Z -> (sizeof t < Ptrofs.modulus)%Z -> memory_block sh (Ptrofs.repr (sizeof t)) = data_at_ sh t.  *)
(* Lemma data_at_rec_readable: forall sh t v p, data_at_rec sh t v p |-- !! readable_share sh.  Definition value_fits: forall t, reptype t -> Prop := type_func (fun t => reptype t -> Prop) (fun t v => if type_is_volatile t then True else tc_val' t (repinject t v)) (fun t n a P v => Zlength (unfold_reptype v) =  Z.max 0 n /\ Forall P (unfold_reptype v)) (fun id a P v => struct_value_fits_aux (co_members (get_co id)) (co_members (get_co id)) P (unfold_reptype v)) (fun id a P v => union_value_fits_aux (co_members (get_co id)) (co_members (get_co id)) P (unfold_reptype v)).  Lemma value_fits_eq: forall t v, value_fits t v = match t as t0 return (reptype t0 -> Prop)  with | Tarray t' n a => fun v0 : reptype (Tarray t' n a) => (fun v1 : list (reptype t') => Zlength v1 = Z.max 0 n /\ Forall (value_fits t') v1) (unfold_reptype v0) | Tstruct i a => fun v0 : reptype (Tstruct i a) => struct_Prop (co_members (get_co i)) (fun it : ident * type => value_fits (field_type (fst it) (co_members (get_co i)))) (unfold_reptype v0) | Tunion i a => fun v0 : reptype (Tunion i a) => union_Prop (co_members (get_co i)) (fun it : ident * type => value_fits (field_type (fst it) (co_members (get_co i)))) (unfold_reptype v0) | t0 => fun v0: reptype t0 => (if type_is_volatile t0 then True else tc_val' t0 (repinject t0 v0)) end v.  Lemma value_fits_type_changable: forall (t1 t2: type) v1 v2, t1 = t2 -> JMeq v1 v2 -> value_fits t1 v1 = value_fits t2 v2.  Lemma default_value_fits: forall t, value_fits t (default_val t).  Lemma data_at_rec_value_fits: forall sh t v p, data_at_rec sh t v p |-- !! value_fits t v.  Lemma data_at_rec_share_join: forall sh1 sh2 sh t v b ofs, sepalg.join sh1 sh2 sh -> data_at_rec sh1 t v (Vptr b ofs) * data_at_rec sh2 t v (Vptr b ofs) = data_at_rec sh t v (Vptr b ofs).  Lemma nonreadable_memory_block_data_at_rec: forall sh t v b ofs (LEGAL_COSU: complete_legal_cosu_type t = true), 0 <= ofs /\ ofs + sizeof t < Ptrofs.modulus -> align_compatible_rec cenv_cs t ofs -> ~ readable_share sh -> value_fits t v -> memory_block sh (sizeof t) (Vptr b (Ptrofs.repr ofs)) = data_at_rec sh t v (Vptr b (Ptrofs.repr ofs)).  (* Lemma f_equal_Int_repr: forall i j, i=j -> Int.repr i = Int.repr j.  Lemma data_at_Tarray_ext_derives: forall sh t n a v v', (forall i, 0 <= i < n -> data_at sh t (Znth i v (default_val _)) |-- data_at sh t (Znth i v' (default_val _))) -> data_at sh (Tarray t n a) v |-- data_at sh (Tarray t n a) v'.  Lemma data_at_Tarray_ext: forall sh t n a v v', (forall i, 0 <= i < n -> data_at sh t (Znth i v (default_val _)) = data_at sh t (Znth i v' (default_val _))) -> data_at sh (Tarray t n a) v = data_at sh (Tarray t n a) v'.  *)
End CENV.

Lemma data_at_rec_change_composite {cs_from cs_to} {CCE: change_composite_env cs_from cs_to}: forall (sh: Share.t) (t: type) v1 v2,
JMeq v1 v2 ->
cs_preserve_type cs_from cs_to (coeq _ _) t = true ->
@data_at_rec cs_from sh t v1 = @data_at_rec cs_to sh t v2.