Ltac flatten_in_SEP PQR :=
match PQR with
| PROPx ?P (LOCALx ?Q (SEPx (?R))) =>
match R with context [(?R1 * ?R2) :: ?R'] =>
let n := constr:((length R - Datatypes.S (length R'))%nat) in
let n' := eval lazy beta zeta iota delta in n in
erewrite(@flatten_sepcon_in_SEP'' n' P Q R1 R2 R _ (eq_refl _));
[ |
let RR := fresh "RR" in set (RR := R);
let RR1 := fresh "RR1" in set (RR1 := R1);
let RR2 := fresh "RR2" in set (RR2 := R2);
unfold firstn, app, skipn; subst RR RR1 RR2; cbv beta iota;
apply eq_refl
]
end
end.
Ltac flatten_sepcon_in_SEP :=
match goal with
| |- semax _ ?PQR _ _ => flatten_in_SEP PQR
| |-  ENTAIL _, ?PQR |-- _ => flatten_in_SEP PQR
end.

Lemma semax_ff:
forall Espec {cs: compspecs} Delta c R,
@semax cs Espec Delta FF c R.