Tactic Notation "semax_frame" constr(Qframe) constr(Rframe) :=
first
[ simple eapply (semax_frame_perm Qframe Rframe);
[auto 50 with closed | solve_perm | solve_perm | unfold app; fold @app ]
| eapply semax_post_flipped';
[simple eapply (semax_frame_perm Qframe Rframe);
[auto 50 with closed | solve_perm | solve_perm | unfold app; fold @app ]
| try solve [apply perm_derives; solve_perm]]
].
Tactic Notation "semax_frame" "[" "]" constr(Rframe) :=
first
[ simple eapply (semax_frame_perm nil Rframe);
[auto 50 with closed | solve_perm | solve_perm | unfold app; fold @app ]
| eapply semax_post_flipped';
[simple eapply (semax_frame_perm nil Rframe);
[auto 50 with closed | solve_perm | solve_perm | unfold app; fold @app ]
| try solve [apply perm_derives; solve_perm]]
].

Lemma semax_pre_later:
forall P' Espec {cs: compspecs} Delta P1 P2 P3 c R,
ENTAIL Delta, PROPx P1 (LOCALx P2 (SEPx P3)) |-- P' ->
@semax cs Espec Delta (|> P') c R  ->
@semax cs Espec Delta (|> (PROPx P1 (LOCALx P2 (SEPx P3)))) c R.