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.

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.