Section Bool.
(* Boolean formulas and their evaluations *)
Inductive formula :=
| formula_var : positive -> formula
| formula_btm : formula
| formula_top : formula
| formula_cnj : formula -> formula -> formula
| formula_dsj : formula -> formula -> formula
| formula_neg : formula -> formula
| formula_xor : formula -> formula -> formula
| formula_ifb : formula -> formula -> formula -> formula.
Fixpoint formula_eval var f := match f with
| formula_var x => list_nth x var false
| formula_btm => false
| formula_top => true
| formula_cnj fl fr => (formula_eval var fl) && (formula_eval var fr)
| formula_dsj fl fr => (formula_eval var fl) || (formula_eval var fr)
| formula_neg f => negb (formula_eval var f)
| formula_xor fl fr => xorb (formula_eval var fl) (formula_eval var fr)
| formula_ifb fc fl fr =>
if formula_eval var fc then formula_eval var fl else formula_eval var fr
end.
End Bool.
(* Translation of formulas into polynomials *)
Section Translation.
(* This is straightforward. *)
Fixpoint poly_of_formula f := match f with
| formula_var x => Poly (Cst false) x (Cst true)
| formula_btm => Cst false
| formula_top => Cst true
| formula_cnj fl fr =>
let pl := poly_of_formula fl in
let pr := poly_of_formula fr in
poly_mul pl pr
| formula_dsj fl fr =>
let pl := poly_of_formula fl in
let pr := poly_of_formula fr in
poly_add (poly_add pl pr) (poly_mul pl pr)
| formula_neg f => poly_add (Cst true) (poly_of_formula f)
| formula_xor fl fr => poly_add (poly_of_formula fl) (poly_of_formula fr)
| formula_ifb fc fl fr =>
let pc := poly_of_formula fc in
let pl := poly_of_formula fl in
let pr := poly_of_formula fr in
poly_add pr (poly_add (poly_mul pc pl) (poly_mul pc pr))
end.
Opaque poly_add.
(* Compatibility of translation wrt evaluation *)

Lemma poly_of_formula_eval_compat : forall var f,
eval var (poly_of_formula f) = formula_eval var f.