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