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 *)

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).