Ltac field_at_saturate_local :=
unfold data_at;
match goal with |- field_at ?sh ?t ?path ?v ?c |-- _ =>
eapply derives_trans; [apply field_at_local_facts |];
cbv beta;
try rewrite proj_sumbool_is_true by auto;
try rewrite proj_sumbool_is_false by auto;
let p := fresh "p" in set (p := nested_field_type t path);
simpl in p; unfold field_type in p; simpl in p; subst p;
try rewrite value_fits_by_value by reflexivity;
try match goal with |- context [repinject ?t ?v] =>
change (repinject t v) with v
end;
apply derives_refl
end.
Ltac data_at_valid_aux :=
simpl sizeof; rewrite ?Z.max_r by rep_omega; rep_omega.
Hint Extern 1 (data_at _ _ _ _ |-- valid_pointer _) =>
(simple apply data_at_valid_ptr; [now auto | data_at_valid_aux]) : valid_pointer.
Hint Extern 1 (field_at _ _ _ _ _ |-- valid_pointer _) =>
(simple apply field_at_valid_ptr; [now auto | data_at_valid_aux]) : valid_pointer.
Hint Extern 1 (data_at_ _ _ _ |-- valid_pointer _) =>
(unfold data_at_, field_at_;
simple apply field_at_valid_ptr; [now auto | data_at_valid_aux]) : valid_pointer.
Hint Extern 1 (field_at_ _ _ _ _ |-- valid_pointer _) =>
(unfold field_at_; simple apply field_at_valid_ptr; [now auto | data_at_valid_aux]) : valid_pointer.
Hint Extern 1 (data_at_ _ _ _ |-- valid_pointer _) =>
(simple apply data_at_valid_ptr; [now auto | data_at_valid_aux]) : valid_pointer.
Hint Extern 1 (field_at_ _ _ _ _ |-- valid_pointer _) =>
(simple apply field_at_valid_ptr; [now auto | data_at_valid_aux]) : valid_pointer.
(* Hint Resolve data_at_valid_ptr field_at_valid_ptr field_at_valid_ptr0 : valid_pointer. *)
(*Hint Resolve field_at_local_facts : saturate_local.*)
Hint Extern 1 (field_at _ _ _ _ _ |-- _) =>
(field_at_saturate_local) : saturate_local.
(* Hint Resolve data_at_local_facts : saturate_local.*)
Hint Extern 1 (data_at _ _ _ _ |-- _) =>
(field_at_saturate_local) : saturate_local.
Hint Resolve @array_at_local_facts @array_at__local_facts : saturate_local.
Hint Resolve field_at__local_facts : saturate_local.
Hint Resolve data_at__local_facts : saturate_local.
Hint Extern 0 (data_at _ (Tarray _ _ _) _ _ |-- _) =>
(apply data_array_at_local_facts'; omega) : saturate_local.
Hint Extern 0 (data_at _ (tarray _ _) _ _ |-- _) =>
(apply data_array_at_local_facts'; omega) : saturate_local.
Hint Extern 1 (data_at _ (Tarray _ _ _) _ _ |-- _) =>
(apply data_array_at_local_facts) : saturate_local.
Hint Extern 1 (data_at _ (tarray _ _) _ _ |-- _) =>
(apply data_array_at_local_facts) : saturate_local.
Hint Rewrite <- @field_at_offset_zero: norm1.
Hint Rewrite <- @field_at__offset_zero: norm1.
Hint Rewrite <- @field_at_offset_zero: cancel.
Hint Rewrite <- @field_at__offset_zero: cancel.
Hint Rewrite <- @data_at__offset_zero: norm1.
Hint Rewrite <- @data_at_offset_zero: norm1.
Hint Rewrite <- @data_at__offset_zero: cancel.
Hint Rewrite <- @data_at_offset_zero: cancel.
(* We do these as specific lemmas, rather than as Hint Resolve derives_refl, to limit their application and make them fail faster *)

(* Specifications: *)
Lemma data_at_cancel:
forall {cs: compspecs} sh t v p,
data_at sh t v p |-- data_at sh t v p.
Lemma field_at_ptr_neq_andp_emp{cs: compspecs} :
forall sh t fld p1 p2 v1 v2,
sepalg.nonidentity sh ->
0 < sizeof (nested_field_type t (fld :: nil))  ->
field_at sh t (fld::nil) v1 p1 *
field_at sh t (fld::nil) v2 p2
|--
field_at sh t (fld::nil) v1 p1 *
field_at sh t (fld::nil) v2 p2 *
(!! (~ ptr_eq p1 p2) && emp).
Lemma field_at_ptr_neq_null{cs: compspecs} :
forall sh t fld v p,
field_at sh t fld v p |-- !! (~ ptr_eq p nullval).
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.