Fixpoint abstrX (i : nat) (t : tF) :=
match t with
| 'X_n => if n == i then [::0; 1] else [::t]
| - x => opppT (abstrX i x)
| x + y => sumpT (abstrX i x) (abstrX i y)
| x * y => mulpT (abstrX i x) (abstrX i y)
| x *+ n => natmulpT n (abstrX i x)
| x ^+ n => let ax := (abstrX i x) in iter n (mulpT ax) [::1]
| _ => [::t]
end%T.

(* Specifications: *)
Lemma abstrXP  (i : nat) (t : tF) (e : seq F) (x : F) :
rterm t -> (eval_poly e (abstrX i t)).[x] = eval (set_nth 0 e i x) t.
Lemma rabstrX (i : nat) (t : tF) : rterm t -> rpoly (abstrX i t).
Implicit Types tx ty : tF.
Lemma abstrX_mulM (i : nat) : {morph abstrX i : x y / x * y >-> mulpT x y}%T.
Definition ex_elim (x : nat) (pqs : seq tF * seq tF) :=
ex_elim_seq (map (abstrX x) pqs.1)
(abstrX x (\big[GRing.Mul/1%T]_(q <- pqs.2) q)).
Lemma ex_elim_qf (x : nat) (pqs : seq tF * seq tF) :
GRing.dnf_rterm pqs -> qf (ex_elim x pqs).