Ltac data_at_valid_aux :=
 simpl sizeof; rewrite ?Z.max_r by rep_omega; rep_omega.(* MOVE ME *)

Ltac simplify_project_default_val :=
match goal with
  | |- context [@fst ?A ?B (?x, ?y)] =>
         change (@fst A B (x,y)) with x
  | |- context [@snd ?A ?B (?x, ?y)] =>
         change (@snd A B (x,y)) with y
  | |- context [fst (@default_val ?cs ?t)] =>
  let E := fresh "E" in let D := fresh "D" in let H := fresh in
   set (E := fst (@default_val cs t));
   set (D := @default_val cs t) in E;
   unfold compact_prod_sigT_type in E; simpl in E;
   assert (H := @default_val_eq cs t);
   simpl in H;
   match type of H with
      @eq (@reptype cs t) _ (@fold_reptype _ _ (@pair ?A ?B ?x ?y)) =>
   change (@reptype cs t) with (@prod A B) in *;
   change (@default_val cs t) with (x,y) in *
   end;
   clear H; subst D; simpl in E; subst E
 | |- context [snd (@default_val ?cs ?t)] =>
  let E := fresh "E" in let D := fresh "D" in let H := fresh in
   set (E := snd (@default_val cs t));
   set (D := @default_val cs t) in E;
   unfold compact_prod_sigT_type in E; simpl in E;
   assert (H := @default_val_eq cs t);
   simpl in H;
   match type of H with
      @eq (@reptype cs t) _ (@fold_reptype _ _ (@pair ?A ?B ?x ?y)) =>
   change (@reptype cs t) with (@prod A B) in *;
   change (@default_val cs t) with (x,y) in *
   end;
   clear H; subst D; simpl in E; subst E
end.Definition field_at_mark := @field_at.Definition field_at_hide := @field_at.Definition data_at_hide := @data_at.Ltac find_field_at N :=
 match N with
 | S O =>  change @field_at with field_at_mark at 1;
              change field_at_hide with @field_at
 | S ?k => change @field_at with field_at_hide at 1;
                find_field_at k
 end.Ltac find_data_at N :=
 match N with
 | S O =>  match goal with |- context[@data_at ?cs ?sh ?t] =>
                 change (@data_at cs sh t) with (field_at_mark cs sh t nil) at 1
                 end;
                 change data_at_hide with @data_at
 | S ?k => change @data_at with data_at_hide at 1;
                find_data_at k
 end.Definition protect (T: Type) (x: T) := x.

(* Specifications: *)
Lemma spacer_share_join: forall sh1 sh2 sh J K q, sepalg.join sh1 sh2 sh -> spacer sh1 J K q * spacer sh2 J K q = spacer sh J K q.
Lemma struct_pred_cons2: forall it it' m (A: ident*type -> Type) (P: forall it, A it -> val -> mpred) (v: compact_prod (map A (it::it'::m))) (p: val), struct_pred (it :: it' :: m) P v p = P _ (fst v) p * struct_pred (it'::m) P (snd v) p.
Lemma union_pred_cons2: forall it it' m (A: ident*type -> Type) (P: forall it, A it -> val -> mpred) (v: compact_sum (map A (it::it'::m))) (p: val), union_pred (it :: it' :: m) P v p = match v with inl v => P _ v p | inr v => union_pred (it'::m) P v p end.
Lemma data_at_rec_void: forall {cs: compspecs} sh t v q, t = Tvoid -> data_at_rec sh t v q = FF.
Lemma snd_reptype_structlist_aux {cs: compspecs}: forall (p: ident * type) (m: list (ident * type)), members_no_replicate (p :: m) = true -> map (fun it : ident * type => reptype (field_type (fst it) (p :: m))) m = map (fun it : ident * type => reptype (field_type (fst it) m)) m.
Lemma field_at_share_join{cs: compspecs}: forall sh1 sh2 sh t gfs v p, sepalg.join sh1 sh2 sh -> field_at sh1 t gfs v p * field_at sh2 t gfs v p = field_at sh t gfs v p.
Lemma field_at__share_join{cs: compspecs}: forall sh1 sh2 sh t gfs p, sepalg.join sh1 sh2 sh -> field_at_ sh1 t gfs p * field_at_ sh2 t gfs p = field_at_ sh t gfs p.
Lemma data_at_share_join{cs: compspecs}: forall sh1 sh2 sh t v p, sepalg.join sh1 sh2 sh -> data_at sh1 t v p * data_at sh2 t v p = data_at sh t v p.
Lemma data_at__share_join{cs: compspecs}: forall sh1 sh2 sh t p, sepalg.join sh1 sh2 sh -> data_at_ sh1 t p * data_at_ sh2 t p = data_at_ sh t p.
Lemma nonreadable_memory_block_field_at: forall {cs: compspecs} sh t gfs v p, ~ readable_share sh -> value_fits _ v -> memory_block sh (sizeof (nested_field_type t gfs)) (field_address t gfs p) = field_at sh t gfs v p.
Lemma nonreadable_memory_block_data_at: forall {cs: compspecs} sh t v p, ~ readable_share sh -> field_compatible t nil p -> value_fits t v -> memory_block sh (sizeof t) p = data_at sh t v p.
Lemma nonreadable_field_at_eq {cs: compspecs} : forall sh t gfs v v' p, ~ readable_share sh -> (value_fits (nested_field_type t gfs) v <-> value_fits (nested_field_type t gfs) v') -> field_at sh t gfs v p = field_at sh t gfs v' p.
Lemma nonreadable_readable_memory_block_data_at_join {cs: compspecs}: forall ash bsh psh t v p, sepalg.join ash bsh psh -> ~ readable_share ash -> memory_block ash (sizeof t) p * data_at bsh t v p = data_at psh t v p.
Lemma nonreadable_data_at_eq {cs: compspecs}: forall sh t v v' p, ~readable_share sh -> (value_fits t v <-> value_fits t v') -> data_at sh t v p = data_at sh t v' p.
Lemma value_fits_Tint_trivial {cs: compspecs} : forall s a i, value_fits (Tint I32 s a) (Vint i).
Lemma data_at_tuint_tint {cs: compspecs}: forall sh v p, data_at sh tuint v p = data_at sh tint v p.
Lemma mapsto_field_at {cs: compspecs} sh t gfs v v' p: type_is_by_value (nested_field_type t gfs) = true -> type_is_volatile (nested_field_type t gfs) = false -> field_compatible t gfs p -> JMeq v v' -> mapsto sh (nested_field_type t gfs) (field_address t gfs p) v = field_at sh t gfs v' p.
Lemma mapsto_data_at {cs: compspecs} sh t v v' p : (* not needed here *) type_is_by_value t = true -> type_is_volatile t = false -> isptr p -> size_compatible t p -> align_compatible t p -> complete_legal_cosu_type t = true -> JMeq v v' -> mapsto sh t p v = data_at sh t v' p.
Lemma mapsto_data_at' {cs: compspecs} sh t v v' p: type_is_by_value t = true -> type_is_volatile t = false -> field_compatible t nil p -> JMeq v v' -> mapsto sh t p v = data_at sh t v' p.