Ltac quick_typecheck3 :=
clear;
repeat match goal with
| H := _ |- _ => clear H
| H : _ |- _ => clear H
end;
apply quick_derives_right; clear; go_lowerx; intros;
clear; repeat apply andp_right; auto; fail.
Ltac default_entailer_for_load_store :=
repeat match goal with H := _ |- _ => clear H end;
try quick_typecheck3;
unfold tc_efield, tc_LR, tc_LR_strong; simpl typeof;
try solve [entailer!].
Ltac entailer_for_load_tac := default_entailer_for_load_store.
Ltac entailer_for_store_tac := default_entailer_for_load_store.
Ltac check_hint_type :=
reflexivity ||
match goal with
| |- typeof ?A = ?B =>
let t0 := constr:(typeof A)
in let t1 := eval hnf in t0 in let t := eval simpl in t1
in let t' := eval hnf in B in let t'' := eval simpl in t'
in fail 1000 "unexpected failure in load/store_tac_with_hint."
"The expression" A "has type" t "but is expected to have type" t''
end.
Ltac load_tac_with_hint LOCAL2PTREE :=
eapply semax_PTree_field_load_with_hint;
[ exact LOCAL2PTREE
| reflexivity
| reflexivity
| reflexivity
| (solve_msubst_eval_lvalue               || fail 1 "Cannot evaluate right-hand-side expression (sometimes this is caused by missing LOCALs in your precondition)")
| eassumption (* This line can fail. If it does not, the following should not fail. *)
| check_hint_type
| (search_field_at_in_SEP                 || fail 1000 "unexpected failure in load_tac_with_hint."
"Required field_at does not exists in SEP")
| (auto                                   || fail 1000 "unexpected failure in load_tac_with_hint."
"Cannot prove readable_share")
| first [solve_load_rule_evaluation        | fail 1000 "unexpected failure in load_tac_with_hint."
"unexpected failure in generating loaded value"]
| first [entailer_for_load_tac             | fail 1000 "unexpected failure in load_tac_with_hint."
"unexpected failure in entailer_for_load_tac"]
| first [entailer_for_load_tac             | fail 1000 "unexpected failure in load_tac_with_hint."
"unexpected failure in entailer_for_load_tac"]
].
Ltac load_tac_no_hint LOCAL2PTREE :=
eapply semax_PTree_field_load_no_hint;
[ exact LOCAL2PTREE
| reflexivity (* compute_nested_efield *)
| reflexivity
| reflexivity
| reflexivity
| (solve_msubst_eval_LR                   || fail 1 "Cannot evaluate right-hand-side expression (sometimes this is caused by missing LOCALs in your precondition)")
| (solve_msubst_efield_denote             || fail 1 "Cannot evaluate right-hand-side expression (sometimes this is caused by missing LOCALs in your precondition)")
| econstructor
| solve_field_address_gen
| search_field_at_in_SEP (* This line can fail. If it does not, the following should not fail. *)
| (auto                                   || fail 1000 "unexpected failure in load_tac_no_hint."
"Cannot prove readable_share")
| first [solve_load_rule_evaluation        | fail 1000 "unexpected failure in load_tac_no_hint."
"unexpected failure in generating loaded value"]
| first [solve_legal_nested_field_in_entailment
| fail 1000 "unexpected failure in load_tac_no_hint."
"unexpected failure in solve_legal_nested_field_in_entailment"]
| first [entailer_for_load_tac             | fail 1000 "unexpected failure in load_tac_no_hint."
"unexpected failure in entailer_for_load_tac"]
| first [entailer_for_load_tac             | fail 1000 "unexpected failure in load_tac_no_hint."
"unexpected failure in entailer_for_load_tac"]
].
Ltac load_tac :=
match goal with
| |- semax ?Delta (|> (PROPx ?P (LOCALx ?Q (SEPx ?R)))) (Sset _ ?e) _ =>
let T1 := fresh "T1" in evar (T1: PTree.t val);
let T2 := fresh "T2" in evar (T2: PTree.t (type * val));
let G := fresh "GV" in evar (G: option globals);
let LOCAL2PTREE := fresh "LOCAL2PTREE" in
assert (local2ptree Q = (T1, T2, nil, G)) as LOCAL2PTREE;
[subst T1 T2 G; prove_local2ptree |];
first [ load_tac_with_hint LOCAL2PTREE | load_tac_no_hint LOCAL2PTREE | SEP_type_contradict LOCAL2PTREE Delta e R | hint_msg LOCAL2PTREE Delta e];
clear T1 T2 G LOCAL2PTREE
end.
Ltac cast_load_tac_with_hint LOCAL2PTREE :=
eapply semax_PTree_field_cast_load_with_hint;
[ exact LOCAL2PTREE
| reflexivity
| reflexivity
| reflexivity
| reflexivity
| (solve_msubst_eval_lvalue               || fail 1 "Cannot evaluate right-hand-side expression (sometimes this is caused by missing LOCALs in your precondition)")
| eassumption (* This line can fail. If it does not, the following should not fail. *)
| check_hint_type
| (search_field_at_in_SEP                 || fail 1000 "unexpected failure in cast_load_tac_with_hint."
"Required field_at does not exists in SEP")
| (auto                                   || fail 1000 "unexpected failure in cast_load_tac_with_hint."
"Cannot prove readable_share")
| first [solve_load_rule_evaluation        | fail 1000 "unexpected failure in cast_load_tac_with_hint."
"unexpected failure in generating loaded value"]
| first [entailer_for_load_tac             | fail 1000 "unexpected failure in cast_load_tac_with_hint."
"unexpected failure in entailer_for_load_tac"]
| first [entailer_for_load_tac             | fail 1000 "unexpected failure in cast_load_tac_with_hint."
"unexpected failure in entailer_for_load_tac"]
].
Ltac cast_load_tac_no_hint LOCAL2PTREE :=
eapply semax_PTree_field_cast_load_no_hint;
[ exact LOCAL2PTREE
| reflexivity (* compute_nested_efield *)
| reflexivity
| reflexivity
| reflexivity
| reflexivity
| (solve_msubst_eval_LR                   || fail 1 "Cannot evaluate right-hand-side expression (sometimes this is caused by missing LOCALs in your precondition)")
| (solve_msubst_efield_denote             || fail 1 "Cannot evaluate right-hand-side expression (sometimes this is caused by missing LOCALs in your precondition)")
| econstructor
| solve_field_address_gen
| search_field_at_in_SEP (* This line can fail. If it does not, the following should not fail. *)
| (auto                                   || fail 1000 "unexpected failure in cast_load_tac_no_hint."
"Cannot prove readable_share")
| first [solve_load_rule_evaluation        | fail 1000 "unexpected failure in cast_load_tac_no_hint."
"unexpected failure in generating loaded value"]
| first [solve_legal_nested_field_in_entailment
| fail 1000 "unexpected failure in cast_load_tac_no_hint."
"unexpected failure in solve_legal_nested_field_in_entailment"]
| first [entailer_for_load_tac             | fail 1000 "unexpected failure in cast_load_tac_no_hint."
"unexpected failure in entailer_for_load_tac"]
| first [entailer_for_load_tac             | fail 1000 "unexpected failure in cast_load_tac_no_hint."
"unexpected failure in entailer_for_load_tac"]
].
Ltac cast_load_tac :=
match goal with
| |- semax ?Delta (|> (PROPx ?P (LOCALx ?Q (SEPx ?R)))) (Sset _ (Ecast ?e _)) _ =>
let T1 := fresh "T1" in evar (T1: PTree.t val);
let T2 := fresh "T2" in evar (T2: PTree.t (type * val));
let G := fresh "GV" in evar (G: option globals);
let LOCAL2PTREE := fresh "LOCAL2PTREE" in
assert (local2ptree Q = (T1, T2, nil, G)) as LOCAL2PTREE;
[subst T1 T2 G; prove_local2ptree |];
first [ cast_load_tac_with_hint LOCAL2PTREE | cast_load_tac_no_hint LOCAL2PTREE | SEP_type_contradict LOCAL2PTREE Delta e R | hint_msg LOCAL2PTREE Delta e];
clear T1 T2 G LOCAL2PTREE
end.

(* Specifications: *)
Lemma data_equal_congr {cs: compspecs}:
forall T (v1 v2: reptype T),
v1 = v2 ->
data_equal v1 v2.