Section Completeness.
(* Lemma reduce_poly_of_formula_simpl : forall fl fr var, simpl_eval (var_of_list var) (reduce (poly_of_formula fl)) = simpl_eval (var_of_list var) (reduce (poly_of_formula fr)) -> formula_eval var fl = formula_eval var fr.  (* Soundness of the method ; immediate *)
Definition make_last {A} n (x def : A) :=
Pos.peano_rect (fun _ => list A)
(cons x nil)
(fun _ F => cons def F) n.
(* Replace the nth element of a list *)
Fixpoint list_replace l n b :=
match l with
| nil => make_last n b false
| cons a l =>
Pos.peano_rect _
(cons b l) (fun n _ => cons a (list_replace l n b)) n
end.
(** Extract a non-null witness from a polynomial *)
Existing Instance Decidable_null.
Fixpoint boolean_witness p :=
match p with
| Cst c => nil
| Poly p i q =>
if decide (null p) then
let var := boolean_witness q in
list_replace var i true
else
let var := boolean_witness p in
list_replace var i false
end.
(* The witness is correct only if the polynomial is linear *)
(* This should be better when using the [vm_compute] tactic instead of plain reflexivity. *)

Lemma reduce_poly_of_formula_sound_alt : forall var fl fr,
reduce (poly_add (poly_of_formula fl) (poly_of_formula fr)) = Cst false ->
formula_eval var fl = formula_eval var fr.