Ltac is_X t :=
match goal with
| |-context[is_X ?X] =>
let f := fresh "EQ" in
destruct (is_X X) as [t|] eqn:f ;
[apply is_X_inv in f|]
end.
Ltac cnf_simpl :=
repeat match goal with
| |- context[and_cnf_opt cnf_ff _ ] => rewrite and_cnf_opt_cnf_ff
| |- context[and_cnf_opt _ cnf_ff] => rewrite and_cnf_opt_cnf_ff_r
| |- context[and_cnf_opt _ cnf_tt] => rewrite and_cnf_opt_cnf_tt
| |- context[or_cnf_opt cnf_ff _] => rewrite or_cnf_opt_cnf_ff
| |- context[or_cnf_opt _ cnf_ff] => rewrite or_cnf_opt_cnf_ff_r
end.

(* Specifications: *)
Lemma or_is_X_inv : forall (k: kind) (f1 f2 : TFormula TX AF k),
or_is_X f1 f2 = true ->
exists k1, is_X f1 = Some k1 \/ is_X f2 = Some k1.
Lemma mk_iff_is_bool : forall (k: kind) (f1 f2:TFormula TX AF k) pol,
match is_bool f2 with
| Some isb => xcnf (if isb then pol else negb pol) f1
| None => mk_iff xcnf pol f1 f2
end = mk_iff xcnf pol f1 f2.
Lemma abst_iff_correct : forall
(k: kind)
(f1 f2 : GFormula k)
(IHf1 : forall pol : bool, xcnf pol f1 = xcnf pol (abst_form pol f1))
(IHf2 : forall pol : bool, xcnf pol f2 = xcnf pol (abst_form pol f2))
(pol : bool),
xcnf pol (IFF f1 f2) = xcnf pol (abst_iff abst_form pol f1 f2).
Lemma abst_eq_correct : forall
(f1 f2 : GFormula isBool)
(IHf1 : forall pol : bool, xcnf pol f1 = xcnf pol (abst_form pol f1))
(IHf2 : forall pol : bool, xcnf pol f2 = xcnf pol (abst_form pol f2))
(pol : bool),
xcnf pol (EQ f1 f2) = xcnf pol (abst_form pol (EQ f1 f2)).
Lemma abst_form_correct : forall b (f:TFormula TX AF b) pol,
xcnf pol f = xcnf pol (abst_form pol f).