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.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.

(* Specifications: *)
Lemma list_nth_base : forall A (def : A) l, list_nth 1 l def = match l with nil => def | cons x _ => x end.
Lemma list_nth_succ : forall A n (def : A) l, list_nth (Pos.succ n) l def = match l with nil => def | cons _ l => list_nth n l def end.
Lemma list_nth_nil : forall A n (def : A), list_nth n nil def = def.
Lemma make_last_nth_1 : forall A n i x def, i <> n -> list_nth i (@make_last A n x def) def = def.
Lemma make_last_nth_2 : forall A n x def, list_nth n (@make_last A n x def) def = x.
Lemma list_replace_nth_1 : forall var i j x, i <> j -> list_nth i (list_replace var j x) false = list_nth i var false.
Lemma list_replace_nth_2 : forall var i x, list_nth i (list_replace var i x) false = x.
Lemma boolean_witness_nonzero : forall k p, linear k p -> ~ null p -> eval (boolean_witness p) p = true.
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.