Ltac qcancel P :=
lazymatch P with
| sepcon ?A ?B =>
match goal with |- _ |-- ?Q =>
try match Q with context [A] =>
let a := fresh "A" in set (a:=A);
rewrite ?(pull_left_special0 a), ?(pull_left_special a);
apply cancel_left;
clear a
end;
qcancel B
end
| ?A =>
try match goal with |- _ |-- ?Q =>
lazymatch Q with context [A] =>
let a := fresh "A" in set (a:=A);
rewrite ?(pull_left_special0 a), ?(pull_left_special a);
rewrite ?(pull_left_special0 A), ?(pull_left_special A);
apply cancel_left;
clear a
end
end
end.
Ltac is_Type_or_type T :=
match type of T with
| Type => idtac
| type => idtac
end.

Lemma syntactic_cancel_spec3: forall G1 L1 G2 L2,
syntactic_cancel G1 L1 G2 L2 ->
fold_right_sepcon G2 |-- fold_right_sepcon L2 ->
fold_right_sepcon G1 |-- fold_right_sepcon L1.