Ltac delete_FRZR_from_SEP :=
match goal with
| |- ENTAIL _, PROPx _ (LOCALx _ (SEPx ?R)) |-- _ =>
match R with context [FRZR] =>
eapply drop_SEP_tc;
[ first [apply extend_tc.extend_tc_expr
| apply extend_tc.extend_tc_exprlist
| apply extend_tc.extend_tc_lvalue]
| apply split_FRZ_in_SEP_spec; prove_split_FRZ_in_SEP
| ]
end end.
Ltac check_typecheck :=
try delete_FRZR_from_SEP;
first [goal_has_evars; idtac |
try apply local_True_right;
entailer!;
match goal with
| |- typecheck_error (deref_byvalue ?T) =>
elimtype (Function_arguments_include_a_memory_load_of_type T)
| |- _ => idtac
end].
Ltac prove_delete_temp := match goal with |- ?A = _ =>
let Q := fresh "Q" in set (Q:=A); hnf in Q; subst Q; reflexivity
end.
Ltac cancel_for_forward_call := cancel_for_evar_frame.
Ltac default_cancel_for_forward_call := cancel_for_evar_frame.
Ltac unfold_post := match goal with |- ?Post = _ => let A := fresh "A" in let B := fresh "B" in first
[evar (A : Type); evar (B : A -> environ -> mpred); unify Post (@exp _ _ ?A ?B);
change Post with (@exp _ _ A B); subst A B |
evar (A : list Prop); evar (B : environ -> mpred); unify Post (PROPx ?A ?B);
change Post with (PROPx A B); subst A B | idtac] end.

Lemma PROP_LOCAL_SEP_ext :
forall P P' Q Q' R R', P=P' -> Q=Q' -> R=R' ->
PROPx P (LOCALx Q (SEPx R)) = PROPx P' (LOCALx Q' (SEPx R')).