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.

(* 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.
(* The witness is correct only if the polynomial is linear *)
Lemma boolean_witness_nonzero : forall k p, linear k p -> ~ null p ->
eval (boolean_witness p) p = true.