aboutsummaryrefslogtreecommitdiff
path: root/mathcomp
diff options
context:
space:
mode:
authorCyril Cohen2018-04-17 17:00:15 +0200
committerCyril Cohen2018-04-18 10:49:18 +0200
commit13479422b0286c86d0888e06aba112153ca6314d (patch)
tree6b921cad503e12fcea8dc7cc136667a54ea86bf4 /mathcomp
parentc1ec9cd8e7e50f73159613c492aad4c6c40bc3aa (diff)
Moving real_closed to another repo
Diffstat (limited to 'mathcomp')
-rw-r--r--mathcomp/Make11
l---------mathcomp/real_closed/AUTHORS1
l---------mathcomp/real_closed/CeCILL-B1
l---------mathcomp/real_closed/INSTALL1
-rw-r--r--mathcomp/real_closed/Make13
-rw-r--r--mathcomp/real_closed/Makefile25
l---------mathcomp/real_closed/README1
-rw-r--r--mathcomp/real_closed/all_real_closed.v10
-rw-r--r--mathcomp/real_closed/bigenough.v121
-rw-r--r--mathcomp/real_closed/cauchyreals.v1686
-rw-r--r--mathcomp/real_closed/complex.v1329
-rw-r--r--mathcomp/real_closed/descr7
-rw-r--r--mathcomp/real_closed/mxtens.v316
-rw-r--r--mathcomp/real_closed/opam16
-rw-r--r--mathcomp/real_closed/ordered_qelim.v1185
-rw-r--r--mathcomp/real_closed/polyorder.v274
-rw-r--r--mathcomp/real_closed/polyrcf.v1811
-rw-r--r--mathcomp/real_closed/qe_rcf.v1017
-rw-r--r--mathcomp/real_closed/qe_rcf_th.v1298
-rw-r--r--mathcomp/real_closed/realalg.v1537
20 files changed, 0 insertions, 10660 deletions
diff --git a/mathcomp/Make b/mathcomp/Make
index 1db29ba..ac48fc2 100644
--- a/mathcomp/Make
+++ b/mathcomp/Make
@@ -80,17 +80,6 @@ odd_order/PFsection8.v
odd_order/PFsection9.v
odd_order/stripped_odd_order_theorem.v
odd_order/wielandt_fixpoint.v
-real_closed/all_real_closed.v
-real_closed/bigenough.v
-real_closed/cauchyreals.v
-real_closed/complex.v
-real_closed/mxtens.v
-real_closed/ordered_qelim.v
-real_closed/polyorder.v
-real_closed/polyrcf.v
-real_closed/qe_rcf_th.v
-real_closed/qe_rcf.v
-real_closed/realalg.v
solvable/abelian.v
solvable/all_solvable.v
solvable/alt.v
diff --git a/mathcomp/real_closed/AUTHORS b/mathcomp/real_closed/AUTHORS
deleted file mode 120000
index b55a98d..0000000
--- a/mathcomp/real_closed/AUTHORS
+++ /dev/null
@@ -1 +0,0 @@
-../../etc/AUTHORS \ No newline at end of file
diff --git a/mathcomp/real_closed/CeCILL-B b/mathcomp/real_closed/CeCILL-B
deleted file mode 120000
index 83e22fd..0000000
--- a/mathcomp/real_closed/CeCILL-B
+++ /dev/null
@@ -1 +0,0 @@
-../../etc/CeCILL-B \ No newline at end of file
diff --git a/mathcomp/real_closed/INSTALL b/mathcomp/real_closed/INSTALL
deleted file mode 120000
index 573e04d..0000000
--- a/mathcomp/real_closed/INSTALL
+++ /dev/null
@@ -1 +0,0 @@
-../../etc/INSTALL.md \ No newline at end of file
diff --git a/mathcomp/real_closed/Make b/mathcomp/real_closed/Make
deleted file mode 100644
index 1e013d3..0000000
--- a/mathcomp/real_closed/Make
+++ /dev/null
@@ -1,13 +0,0 @@
-all_real_closed.v
-bigenough.v
-cauchyreals.v
-complex.v
-ordered_qelim.v
-polyorder.v
-polyrcf.v
-qe_rcf_th.v
-qe_rcf.v
-realalg.v
-mxtens.v
-
--R . mathcomp.real_closed \ No newline at end of file
diff --git a/mathcomp/real_closed/Makefile b/mathcomp/real_closed/Makefile
deleted file mode 100644
index 14acb5c..0000000
--- a/mathcomp/real_closed/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-H=@
-
-ifeq "$(COQBIN)" ""
-COQBIN=$(dir $(shell which coqtop))/
-endif
-
-COQDEP=$(COQBIN)/coqdep
-
-OLD_MAKEFLAGS:=$(MAKEFLAGS)
-MAKEFLAGS+=-B
-
-.DEFAULT_GOAL := all
-
-%:
- $(H)[ -e Makefile.coq ] || $(COQBIN)/coq_makefile -f Make -o Makefile.coq
- $(H)MAKEFLAGS="$(OLD_MAKEFLAGS)" $(MAKE) --no-print-directory \
- -f Makefile.coq $* \
- COQDEP='$(COQDEP) -c'
-
-.PHONY: clean
-clean:
- $(H)MAKEFLAGS="$(OLD_MAKEFLAGS)" $(MAKE) --no-print-directory \
- -f Makefile.coq clean
- $(H)rm -f Makefile.coq
-
diff --git a/mathcomp/real_closed/README b/mathcomp/real_closed/README
deleted file mode 120000
index e4e30e8..0000000
--- a/mathcomp/real_closed/README
+++ /dev/null
@@ -1 +0,0 @@
-../../etc/README \ No newline at end of file
diff --git a/mathcomp/real_closed/all_real_closed.v b/mathcomp/real_closed/all_real_closed.v
deleted file mode 100644
index 184ee4a..0000000
--- a/mathcomp/real_closed/all_real_closed.v
+++ /dev/null
@@ -1,10 +0,0 @@
-Require Export bigenough.
-Require Export cauchyreals.
-Require Export complex.
-Require Export ordered_qelim.
-Require Export polyorder.
-Require Export polyrcf.
-Require Export qe_rcf_th.
-Require Export qe_rcf.
-Require Export realalg.
-Require Export mxtens. \ No newline at end of file
diff --git a/mathcomp/real_closed/bigenough.v b/mathcomp/real_closed/bigenough.v
deleted file mode 100644
index 1ee8bef..0000000
--- a/mathcomp/real_closed/bigenough.v
+++ /dev/null
@@ -1,121 +0,0 @@
-(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-(* Distributed under the terms of CeCILL-B. *)
-Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp
-Require Import ssrfun ssrbool eqtype ssrnat seq choice fintype.
-
-(****************************************************************************)
-(* This is a small library to do epsilon - N reasonning. *)
-(* In order to use it, one only has to know the following tactics: *)
-(* *)
-(* pose_big_enough i == pose a big enough natural number i *)
-(* pose_big_modulus m F == pose a function m : F -> nat which should *)
-(* provide a big enough return value *)
-(* exists_big_modulus m F := pose_big_modulus m F; exists m *)
-(* big_enough == replaces a big enough constraint x <= i *)
-(* by true and implicity remembers that i should *)
-(* be bigger than x. *)
-(* close == all "pose" tactics create a dummy subgoal to *)
-(* force the user to explictely indicate that all *)
-(* constraints have been found *)
-(****************************************************************************)
-
-Set Implicit Arguments.
-Unset Strict Implicit.
-Unset Printing Implicit Defensive.
-
-Module BigEnough.
-
-Record big_rel_class_of T (leq : rel T) :=
- BigRelClass {
- leq_big_internal_op : rel T;
- bigger_than_op : seq T -> T;
- _ : leq_big_internal_op = leq;
- _ : forall i s, leq_big_internal_op i (bigger_than_op (i :: s));
- _ : forall i j s, leq_big_internal_op i (bigger_than_op s) ->
- leq_big_internal_op i (bigger_than_op (j :: s))
-}.
-
-Record big_rel_of T := BigRelOf {
- leq_big :> rel T;
- big_rel_class : big_rel_class_of leq_big
-}.
-
-Definition bigger_than_of T (b : big_rel_of T)
- (phb : phantom (rel T) b) :=
- bigger_than_op (big_rel_class b).
-Notation bigger_than leq := (@bigger_than_of _ _ (Phantom (rel _) leq)).
-
-Definition leq_big_internal_of T (b : big_rel_of T)
- (phb : phantom (rel T) b) :=
- leq_big_internal_op (big_rel_class b).
-Notation leq_big_internal leq := (@leq_big_internal_of _ _ (Phantom (rel _) leq)).
-
-Lemma next_bigger_than T (b : big_rel_of T) i j s :
- leq_big_internal b i (bigger_than b s) ->
- leq_big_internal b i (bigger_than b (j :: s)).
-Proof. by case: b i j s => [? []]. Qed.
-
-Lemma instantiate_bigger_than T (b : big_rel_of T) i s :
- leq_big_internal b i (bigger_than b (i :: s)).
-Proof. by case: b i s => [? []]. Qed.
-
-Lemma leq_big_internalE T (b : big_rel_of T) : leq_big_internal b = leq_big b.
-Proof. by case: b => [? []]. Qed.
-
-(* Lemma big_enough T (b : big_rel_of T) i s : *)
-(* leq_big_internal b i (bigger_than b s) -> *)
-(* leq_big b i (bigger_than b s). *)
-(* Proof. by rewrite leq_big_internalE. Qed. *)
-
-Lemma context_big_enough P T (b : big_rel_of T) i s :
- leq_big_internal b i (bigger_than b s) ->
- P true ->
- P (leq_big b i (bigger_than b s)).
-Proof. by rewrite leq_big_internalE => ->. Qed.
-
-Definition big_rel_leq_class : big_rel_class_of leq.
-Proof.
-exists leq (foldr maxn 0%N) => [|i s|i j s /leq_trans->] //;
-by rewrite (leq_maxl, leq_maxr).
-Qed.
-Canonical big_enough_nat := BigRelOf big_rel_leq_class.
-
-Definition closed T (i : T) := {j : T | j = i}.
-Ltac close := match goal with
- | |- context [closed ?i] =>
- instantiate (1 := [::]) in (Value of i); exists i
- end.
-
-Ltac pose_big_enough i :=
- evar (i : nat); suff : closed i; first do
- [move=> _; instantiate (1 := bigger_than leq _) in (Value of i)].
-
-Ltac pose_big_modulus m F :=
- evar (m : F -> nat); suff : closed m; first do
- [move=> _; instantiate (1 := (fun e => bigger_than leq _)) in (Value of m)].
-
-Ltac exists_big_modulus m F := pose_big_modulus m F; first exists m.
-
-Ltac olddone :=
- trivial; hnf; intros; solve
- [ do ![solve [trivial | apply: sym_equal; trivial]
- | discriminate | contradiction | split]
- | case not_locked_false_eq_true; assumption
- | match goal with H : ~ _ |- _ => solve [case H; trivial] end].
-
-Ltac big_enough :=
- do ?[ apply context_big_enough;
- first do [do ?[ now apply instantiate_bigger_than
- | apply next_bigger_than]]].
-
-Ltac big_enough_trans :=
- match goal with
- | [leq_nm : is_true (?n <= ?m)%N |- is_true (?x <= ?m)] =>
- apply: leq_trans leq_nm; big_enough; olddone
- | _ => big_enough; olddone
- end.
-
-Ltac done := do [olddone|big_enough_trans].
-
-End BigEnough.
diff --git a/mathcomp/real_closed/cauchyreals.v b/mathcomp/real_closed/cauchyreals.v
deleted file mode 100644
index 1456991..0000000
--- a/mathcomp/real_closed/cauchyreals.v
+++ /dev/null
@@ -1,1686 +0,0 @@
-(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-(* Distributed under the terms of CeCILL-B. *)
-Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp
-Require Import ssrfun ssrbool eqtype ssrnat seq choice fintype.
-From mathcomp
-Require Import bigop ssralg ssrnum ssrint rat poly polydiv polyorder.
-From mathcomp
-Require Import perm matrix mxpoly polyXY binomial bigenough.
-
-(***************************************************************************)
-(* This is a standalone construction of Cauchy reals over an arbitrary *)
-(* discrete archimedian field R. *)
-(* creals R == setoid of Cauchy sequences, it is not discrete and *)
-(* cannot be equipped with any ssreflect algebraic structure *)
-(***************************************************************************)
-
-Import GRing.Theory Num.Theory Num.Def BigEnough.
-
-Set Implicit Arguments.
-Unset Strict Implicit.
-Unset Printing Implicit Defensive.
-
-Delimit Scope creal_scope with CR.
-
-Section poly_extra.
-
-Local Open Scope ring_scope.
-
-Lemma monic_monic_from_neq0 (F : fieldType) (p : {poly F}) :
- (p != 0)%B -> (lead_coef p) ^-1 *: p \is monic.
-Proof. by move=> ?; rewrite monicE lead_coefZ mulVf ?lead_coef_eq0. Qed.
-
-(* GG -- lemmas with ssrnum dependencies cannot go in poly! *)
-Lemma size_derivn (R : realDomainType) (p : {poly R}) n :
- size p^`(n) = (size p - n)%N.
-Proof.
-elim: n=> [|n ihn]; first by rewrite derivn0 subn0.
-by rewrite derivnS size_deriv ihn -subnS.
-Qed.
-
-Lemma size_nderivn (R : realDomainType) (p : {poly R}) n :
- size p^`N(n) = (size p - n)%N.
-Proof.
-rewrite -size_derivn nderivn_def -mulr_natl.
-by rewrite -polyC1 -!polyC_muln size_Cmul // pnatr_eq0 -lt0n fact_gt0.
-Qed.
-
-End poly_extra.
-
-Local Notation eval := horner_eval.
-
-Section ordered_extra.
-
-Definition gtr0E := (invr_gt0, exprn_gt0, ltr0n, @ltr01).
-Definition ger0E := (invr_ge0, exprn_ge0, ler0n, @ler01).
-
-End ordered_extra.
-
-Section polyorder_extra.
-
-Variable F : realDomainType.
-
-Local Open Scope ring_scope.
-
-Definition poly_bound (p : {poly F}) (a r : F) : F
- := 1 + \sum_(i < size p) `|p`_i| * (`|a| + `|r|) ^+ i.
-
-Lemma poly_boundP p a r x : `|x - a| <= r ->
- `|p.[x]| <= poly_bound p a r.
-Proof.
-have [r_ge0|r_lt0] := lerP 0 r; last first.
- by move=> hr; have := ler_lt_trans hr r_lt0; rewrite normr_lt0.
-rewrite ler_distl=> /andP[lx ux].
-rewrite ler_paddl //.
-elim/poly_ind: p=> [|p c ihp].
- by rewrite horner0 normr0 size_poly0 big_ord0.
-rewrite hornerMXaddC size_MXaddC.
-have [->|p_neq0 /=] := altP eqP.
- rewrite horner0 !mul0r !add0r size_poly0.
- have [->|c_neq0] /= := altP eqP; first by rewrite normr0 big_ord0.
- rewrite big_ord_recl big_ord0 addr0 coefC /=.
- by rewrite ler_pmulr ?normr_gt0 // ler_addl ler_maxr !normr_ge0.
-rewrite big_ord_recl coefD coefMX coefC eqxx add0r.
-rewrite (ler_trans (ler_norm_add _ _)) // addrC ler_add //.
- by rewrite expr0 mulr1.
-rewrite normrM.
-move: ihp=> /(ler_wpmul2r (normr_ge0 x)) /ler_trans-> //.
-rewrite mulr_suml ler_sum // => i _.
-rewrite coefD coefC coefMX /= addr0 exprSr mulrA.
-rewrite ler_wpmul2l //.
- by rewrite ?mulr_ge0 ?exprn_ge0 ?ler_maxr ?addr_ge0 ?normr_ge0 // ltrW.
-rewrite (ger0_norm r_ge0) ler_norml opprD.
-rewrite (ler_trans _ lx) ?(ler_trans ux) // ler_add2r.
- by rewrite ler_normr lerr.
-by rewrite ler_oppl ler_normr lerr orbT.
-Qed.
-
-Lemma poly_bound_gt0 p a r : 0 < poly_bound p a r.
-Proof.
-rewrite ltr_paddr // sumr_ge0 // => i _.
-by rewrite mulr_ge0 ?exprn_ge0 ?addr_ge0 ?ler_maxr ?normr_ge0 // ltrW.
-Qed.
-
-Lemma poly_bound_ge0 p a r : 0 <= poly_bound p a r.
-Proof. by rewrite ltrW // poly_bound_gt0. Qed.
-
-Definition poly_accr_bound (p : {poly F}) (a r : F) : F
- := (maxr 1 (2%:R * r)) ^+ (size p).-1
- * (1 + \sum_(i < (size p).-1) poly_bound p^`N(i.+1) a r).
-
-Lemma poly_accr_bound1P p a r x y :
- `|x - a| <= r -> `|y - a| <= r ->
- `|p.[y] - p.[x]| <= `|y - x| * poly_accr_bound p a r.
-Proof.
-have [|r_lt0] := lerP 0 r; last first.
- by move=> hr; have := ler_lt_trans hr r_lt0; rewrite normr_lt0.
-rewrite le0r=> /orP[/eqP->|r_gt0 hx hy].
- by rewrite !normr_le0 !subr_eq0=> /eqP-> /eqP->; rewrite !subrr normr0 mul0r.
-rewrite mulrA mulrDr mulr1 ler_paddl ?mulr_ge0 ?normr_ge0 //=.
- by rewrite exprn_ge0 ?ler_maxr ?mulr_ge0 ?ger0E ?ltrW.
-rewrite -{1}(addNKr x y) [- _ + _]addrC /= -mulrA.
-rewrite nderiv_taylor; last exact: mulrC.
-have [->|p_neq0] := eqVneq p 0.
- rewrite size_poly0 big_ord0 horner0 subr0 normr0 mulr_ge0 ?normr_ge0 //.
- by rewrite big_ord0 mulr0 lerr.
-rewrite -[size _]prednK ?lt0n ?size_poly_eq0 //.
-rewrite big_ord_recl expr0 mulr1 nderivn0 addrC addKr !mulr_sumr.
-have := ler_trans (ler_norm_sum _ _ _); apply.
-rewrite ler_sum // => i _.
-rewrite exprSr mulrA !normrM mulrC ler_wpmul2l ?normr_ge0 //.
-suff /ler_wpmul2l /ler_trans :
- `|(y - x) ^+ i| <= maxr 1 (2%:R * r) ^+ (size p).-1.
- apply; rewrite ?normr_ge0 // mulrC ler_wpmul2l ?poly_boundP //.
- by rewrite ?exprn_ge0 // ler_maxr ler01 mulr_ge0 ?ler0n ?ltrW.
-case: maxrP=> hr.
- rewrite expr1n normrX exprn_ile1 ?normr_ge0 //.
- rewrite (ler_trans (ler_dist_add a _ _)) // addrC distrC.
- by rewrite (ler_trans _ hr) // mulrDl ler_add ?mul1r.
-rewrite (@ler_trans _ ((2%:R * r) ^+ i)) //.
- rewrite normrX @ler_expn2r -?topredE /= ?normr_ge0 ?mulr_ge0 ?ler0n //.
- by rewrite ltrW.
- rewrite (ler_trans (ler_dist_add a _ _)) // addrC distrC.
- by rewrite mulrDl ler_add ?mul1r.
-by rewrite ler_eexpn2l // ltnW.
-Qed.
-
-Lemma poly_accr_bound_gt0 p a r : 0 < poly_accr_bound p a r.
-Proof.
-rewrite /poly_accr_bound pmulr_rgt0 //.
- rewrite ltr_paddr ?ltr01 //.
- by rewrite sumr_ge0 // => i; rewrite poly_bound_ge0.
-by rewrite exprn_gt0 // ltr_maxr ltr01 pmulr_rgt0 ?ltr0n.
-Qed.
-
-Lemma poly_accr_bound_ge0 p a r : 0 <= poly_accr_bound p a r.
-Proof. by rewrite ltrW // poly_accr_bound_gt0. Qed.
-
-(* Todo : move to polyorder => need char 0 *)
-Lemma gdcop_eq0 (p q : {poly F}) :
- (gdcop p q == 0)%B = (q == 0)%B && (p != 0)%B.
-Proof.
-have [[->|q_neq0] [->|p_neq0] /=] := (altP (q =P 0), altP (p =P 0)).
-+ by rewrite gdcop0 eqxx oner_eq0.
-+ by rewrite gdcop0 (negPf p_neq0) eqxx.
-+ apply/negP=> /eqP hg; have := coprimep_gdco 0 q_neq0.
- by rewrite hg coprimep0 eqp01.
-by apply/negP=> /eqP hg; have := dvdp_gdco p q; rewrite hg dvd0p; apply/negP.
-Qed.
-
-End polyorder_extra.
-
-Section polyXY_order_extra.
-
-Variable F : realFieldType.
-Local Open Scope ring_scope.
-
-Local Notation "p ^ f" := (map_poly f p) : ring_scope.
-Local Notation "'Y" := 'X%:P.
-
-Definition norm_poly2 (p : {poly {poly F}}) := p ^ (map_poly (fun x => `|x|)).
-
-Lemma coef_norm_poly2 p i j : (norm_poly2 p)`_i`_j = `|p`_i`_j|.
-Proof.
-rewrite !coef_map_id0 ?normr0 //; last first.
-by rewrite /map_poly poly_def size_poly0 big_ord0.
-Qed.
-
-Lemma size_norm_poly2 p : size (norm_poly2 p) = size p.
-Proof.
-rewrite /norm_poly2; have [->|p0] := eqVneq p 0.
- by rewrite /map_poly poly_def !(size_poly0, big_ord0).
-rewrite /map_poly size_poly_eq // -size_poly_eq0 size_poly_eq //.
- by rewrite -lead_coefE size_poly_eq0 lead_coef_eq0.
-by rewrite -!lead_coefE normr_eq0 !lead_coef_eq0.
-Qed.
-
-End polyXY_order_extra.
-
-Section polyorder_field_extra.
-
-Variable F : realFieldType.
-
-Local Open Scope ring_scope.
-
-Definition poly_accr_bound2 (p : {poly F}) (a r : F) : F
- := (maxr 1 (2%:R * r)) ^+ (size p).-2
- * (1 + \sum_(i < (size p).-2) poly_bound p^`N(i.+2) a r).
-
-Lemma poly_accr_bound2_gt0 p a r : 0 < poly_accr_bound2 p a r.
-Proof.
-rewrite /poly_accr_bound pmulr_rgt0 //.
- rewrite ltr_paddr ?ltr01 //.
- by rewrite sumr_ge0 // => i; rewrite poly_bound_ge0.
-by rewrite exprn_gt0 // ltr_maxr ltr01 pmulr_rgt0 ?ltr0n.
-Qed.
-
-Lemma poly_accr_bound2_ge0 p a r : 0 <= poly_accr_bound2 p a r.
-Proof. by rewrite ltrW // poly_accr_bound2_gt0. Qed.
-
-Lemma poly_accr_bound2P p (a r x y : F) : (x != y)%B ->
- `|x - a| <= r -> `|y - a| <= r ->
- `|(p.[y] - p.[x]) / (y - x) - p^`().[x]|
- <= `|y - x| * poly_accr_bound2 p a r.
-Proof.
-have [|r_lt0] := lerP 0 r; last first.
- by move=> _ hr; have := ler_lt_trans hr r_lt0; rewrite normr_lt0.
-rewrite le0r=> /orP[/eqP->|r_gt0].
- rewrite !normr_le0 !subr_eq0.
- by move=> nxy /eqP xa /eqP xb; rewrite xa xb eqxx in nxy.
-move=> neq_xy hx hy.
-rewrite mulrA mulrDr mulr1 ler_paddl ?mulr_ge0 ?normr_ge0 //=.
- by rewrite exprn_ge0 ?ler_maxr ?mulr_ge0 ?ger0E ?ltrW.
-rewrite -{1}(addNKr x y) [- _ + _]addrC /= -mulrA.
-rewrite nderiv_taylor; last exact: mulrC.
-have [->|p_neq0] := eqVneq p 0.
- by rewrite derivC !horner0 size_poly0 !(big_ord0, subrr, mul0r) normr0 !mulr0.
-rewrite -[size _]prednK ?lt0n ?size_poly_eq0 //.
-rewrite big_ord_recl expr0 mulr1 nderivn0 /= -size_deriv.
-have [->|p'_neq0] := eqVneq p^`() 0.
- by rewrite horner0 size_poly0 !big_ord0 addr0 !(subrr, mul0r) normr0 !mulr0.
-rewrite -[size _]prednK ?lt0n ?size_poly_eq0 // big_ord_recl expr1.
-rewrite addrAC subrr add0r mulrDl mulfK; last by rewrite subr_eq0 eq_sym.
-rewrite nderivn1 addrAC subrr add0r mulr_sumr normrM normfV.
-rewrite ler_pdivr_mulr ?normr_gt0; last by rewrite subr_eq0 eq_sym.
-rewrite mulrAC -expr2 mulrC mulr_suml.
-have := ler_trans (ler_norm_sum _ _ _); apply.
-rewrite ler_sum // => i _ /=; rewrite /bump /= !add1n.
-rewrite normrM normrX 3!exprSr expr1 !mulrA !ler_wpmul2r ?normr_ge0 //.
-suff /ler_wpmul2l /ler_trans :
- `|(y - x)| ^+ i <= maxr 1 (2%:R * r) ^+ (size p^`()).-1.
- apply; rewrite ?normr_ge0 // mulrC ler_wpmul2l ?poly_boundP //.
- by rewrite ?exprn_ge0 // ler_maxr ler01 mulr_ge0 ?ler0n ?ltrW.
-case: maxrP=> hr.
- rewrite expr1n exprn_ile1 ?normr_ge0 //.
- rewrite (ler_trans (ler_dist_add a _ _)) // addrC distrC.
- by rewrite (ler_trans _ hr) // mulrDl ler_add ?mul1r.
-rewrite (@ler_trans _ ((2%:R * r) ^+ i)) //.
- rewrite @ler_expn2r -?topredE /= ?normr_ge0 ?mulr_ge0 ?ler0n //.
- by rewrite ltrW.
- rewrite (ler_trans (ler_dist_add a _ _)) // addrC distrC.
- by rewrite mulrDl ler_add ?mul1r.
-by rewrite ler_eexpn2l // ltnW.
-Qed.
-
-End polyorder_field_extra.
-
-Section monotony.
-
-Variable F : realFieldType.
-
-Local Open Scope ring_scope.
-
-Definition accr_pos p (a r : F) :=
- ({ k | 0 < k & forall x y, (x != y)%B ->
- `|x - a| <= r -> `|y - a| <= r -> (p.[x] - p.[y]) / (x - y) > k }
- * forall x, `|x - a| <= r -> p^`().[x] > 0)%type.
-
-Definition accr_neg p (a r : F) :=
- ({ k | 0 < k & forall x y, (x != y)%B ->
- `|x - a| <= r -> `|y - a| <= r -> (p.[x] - p.[y]) / (x - y) < - k}
- * forall x, `|x - a| <= r -> p^`().[x] < 0)%type.
-
-Definition strong_mono p (a r : F) := (accr_pos p a r + accr_neg p a r)%type.
-
-Lemma accr_pos_incr p a r : accr_pos p a r ->
- forall x y, `|x - a| <= r -> `|y - a| <= r -> (p.[x] <= p.[y]) = (x <= y).
-Proof.
-move=> [[k k_gt0 hk] _] x y hx hy.
-have [->|neq_xy] := eqVneq x y; first by rewrite !lerr.
-have hkxy := hk _ _ neq_xy hx hy.
-have := ltr_trans k_gt0 hkxy.
-have [lpxpy|lpypx|->] := ltrgtP p.[x] p.[y].
-+ by rewrite nmulr_rgt0 ?subr_lt0 // ?invr_lt0 subr_lt0=> /ltrW->.
-+ by rewrite pmulr_rgt0 ?subr_gt0 // ?invr_gt0 subr_gt0 lerNgt=> ->.
-by rewrite subrr mul0r ltrr.
-Qed.
-
-Lemma accr_neg_decr p a r : accr_neg p a r ->
- forall x y, `|x - a| <= r -> `|y - a| <= r -> (p.[x] <= p.[y]) = (y <= x).
-Proof.
-move=> [] [k]; rewrite -oppr_lt0=> Nk_lt0 hk _ x y hx hy.
-have [->|neq_xy] := eqVneq x y; first by rewrite !lerr.
-have hkxy := hk _ _ neq_xy hx hy.
-have := ltr_trans hkxy Nk_lt0.
-have [lpxpy|lpypx|->] := ltrgtP p.[x] p.[y].
-+ by rewrite nmulr_rlt0 ?subr_lt0 // ?invr_gt0 subr_gt0=> /ltrW->.
-+ by rewrite pmulr_rlt0 ?subr_gt0 // ?invr_lt0 subr_lt0 lerNgt=> ->.
-by rewrite subrr mul0r ltrr.
-Qed.
-
-Lemma accr_negN p a r : accr_pos p a r -> accr_neg (- p) a r.
-Proof.
-case=> [[k k_gt0 hk] h].
-split; [ exists k=> // x y nxy hx hy;
- by rewrite !hornerN -opprD mulNr ltr_opp2; apply: hk
- | by move=> x hx; rewrite derivN hornerN oppr_lt0; apply: h ].
-Qed.
-
-Lemma accr_posN p a r : accr_neg p a r -> accr_pos (- p) a r.
-Proof.
-case=> [[k k_gt0 hk] h].
-split; [ exists k=> // x y nxy hx hy;
- by rewrite !hornerN -opprD mulNr ltr_oppr; apply: hk
- | by move=> x hx; rewrite derivN hornerN oppr_gt0; apply: h ].
-Qed.
-
-Lemma strong_monoN p a r : strong_mono p a r -> strong_mono (- p) a r.
-Proof. by case=> [] hp; [right; apply: accr_negN|left; apply: accr_posN]. Qed.
-
-Lemma strong_mono_bound p a r : strong_mono p a r
- -> {k | 0 < k & forall x y, `|x - a| <= r -> `|y - a| <= r ->
- `| x - y | <= k * `| p.[x] - p.[y] | }.
-Proof.
-case=> [] [[k k_gt0 hk] _]; exists k^-1; rewrite ?invr_gt0=> // x y hx hy;
-have [->|neq_xy] := eqVneq x y; do ?[by rewrite !subrr normr0 mulr0];
-move: (hk _ _ neq_xy hx hy); rewrite 1?ltr_oppr ler_pdivl_mull //;
-rewrite -ler_pdivl_mulr ?normr_gt0 ?subr_eq0 // => /ltrW /ler_trans-> //;
-by rewrite -normfV -normrM ler_normr lerr ?orbT.
-Qed.
-
-Definition merge_intervals (ar1 ar2 : F * F) :=
- let l := minr (ar1.1 - ar1.2) (ar2.1 - ar2.2) in
- let u := maxr (ar1.1 + ar1.2) (ar2.1 + ar2.2) in
- ((l + u) / 2%:R, (u - l) / 2%:R).
-Local Notation center ar1 ar2 := ((merge_intervals ar1 ar2).1).
-Local Notation radius ar1 ar2 := ((merge_intervals ar1 ar2).2).
-
-Lemma split_interval (a1 a2 r1 r2 x : F) :
- 0 < r1 -> 0 < r2 -> `|a1 - a2| <= r1 + r2 ->
- (`|x - center (a1, r1) (a2, r2)| <= radius (a1, r1) (a2, r2))
- = (`|x - a1| <= r1) || (`|x - a2| <= r2).
-Proof.
-move=> r1_gt0 r2_gt0 le_ar.
-rewrite /merge_intervals /=.
-set l := minr _ _; set u := maxr _ _.
-rewrite ler_pdivl_mulr ?gtr0E // -{2}[2%:R]ger0_norm ?ger0E //.
-rewrite -normrM mulrBl mulfVK ?pnatr_eq0 // ler_distl.
-rewrite opprB addrCA addrK (addrC (l + u)) addrA addrNK.
-rewrite -!mulr2n !mulr_natr !ler_muln2r !orFb.
-rewrite ler_minl ler_maxr !ler_distl.
-have [] := lerP=> /= a1N; have [] := lerP=> //= a1P;
-have [] := lerP=> //= a2P; rewrite ?(andbF, andbT) //; symmetry.
- rewrite ltrW // (ler_lt_trans _ a1P) //.
- rewrite (monoLR (addrK _) (ler_add2r _)) -addrA.
- rewrite (monoRL (addNKr _) (ler_add2l _)) addrC.
- by rewrite (ler_trans _ le_ar) // ler_normr opprB lerr orbT.
-rewrite ltrW // (ltr_le_trans a1N) //.
-rewrite (monoLR (addrK _) (ler_add2r _)) -addrA.
-rewrite (monoRL (addNKr _) (ler_add2l _)) addrC ?[r2 + _]addrC.
-by rewrite (ler_trans _ le_ar) // ler_normr lerr.
-Qed.
-
-Lemma merge_mono p a1 a2 r1 r2 :
- 0 < r1 -> 0 < r2 ->
- `|a1 - a2| <= (r1 + r2) ->
- strong_mono p a1 r1 -> strong_mono p a2 r2 ->
- strong_mono p (center (a1, r1) (a2, r2)) (radius (a1, r1) (a2, r2)).
-Proof.
-move=> r1_gt0 r2_gt0 har sm1; wlog : p sm1 / accr_pos p a1 r1.
- move=> hwlog; case: (sm1); first exact: hwlog.
- move=> accr_p smp; rewrite -[p]opprK; apply: strong_monoN.
- apply: hwlog=> //; do ?exact: strong_monoN.
- exact: accr_posN.
-case=> [[k1 k1_gt0 hk1]] h1.
-move=> [] accr2_p; last first.
- set m := (r2 * a1 + r1 * a2) / (r1 + r2).
- have pm_gt0 := h1 m.
- case: accr2_p=> [_] /(_ m) pm_lt0.
- suff: 0 < 0 :> F by rewrite ltrr.
- have r_gt0 : 0 < r1 + r2 by rewrite ?addr_gt0.
- apply: (ltr_trans (pm_gt0 _) (pm_lt0 _)).
- rewrite -(@ler_pmul2l _ (r1 + r2)) //.
- rewrite -{1}[r1 + r2]ger0_norm ?(ltrW r_gt0) //.
- rewrite -normrM mulrBr /m mulrC mulrVK ?unitfE ?gtr_eqF //.
- rewrite mulrDl opprD addrA addrC addrA addKr.
- rewrite distrC -mulrBr normrM ger0_norm ?(ltrW r1_gt0) //.
- by rewrite mulrC ler_wpmul2r // ltrW.
- rewrite -(@ler_pmul2l _ (r1 + r2)) //.
- rewrite -{1}[r1 + r2]ger0_norm ?(ltrW r_gt0) //.
- rewrite -normrM mulrBr /m mulrC mulrVK ?unitfE ?gtr_eqF //.
- rewrite mulrDl opprD addrA addrK.
- rewrite -mulrBr normrM ger0_norm ?(ltrW r2_gt0) //.
- by rewrite mulrC ler_wpmul2r // ltrW.
-case: accr2_p=> [[k2 k2_gt0 hk2]] h2.
-left; split; last by move=> x; rewrite split_interval // => /orP [/h1|/h2].
-exists (minr k1 k2); first by rewrite ltr_minr k1_gt0.
-move=> x y neq_xy; rewrite !split_interval //.
-wlog lt_xy: x y neq_xy / y < x.
- move=> hwlog; have [] := ltrP y x; first exact: hwlog.
- rewrite ler_eqVlt (negPf neq_xy) /= => /hwlog hwlog' hx hy.
- rewrite -mulrNN -!invrN !opprB.
- by apply: hwlog'; rewrite // eq_sym.
-move=> {h1} {h2} {sm1}.
-wlog le_xr1 : a1 a2 r1 r2 k1 k2
- r1_gt0 r2_gt0 k1_gt0 k2_gt0 har hk1 hk2 / `|x - a1| <= r1.
- move=> hwlog h; move: (h)=> /orP [/hwlog|]; first exact.
- move=> /(hwlog a2 a1 r2 r1 k2 k1) hwlog' ley; rewrite minrC.
- by apply: hwlog'; rewrite 1?orbC // distrC [r2 + _]addrC.
-move=> _.
-have [le_yr1|gt_yr1] := (lerP _ r1)=> /= [_|le_yr2].
- by rewrite ltr_minl hk1.
-rewrite ltr_pdivl_mulr ?subr_gt0 //.
-pose z := a1 - r1.
-have hz1 : `|z - a1| <= r1 by rewrite addrC addKr normrN gtr0_norm.
-have gt_yr1' : y + r1 < a1.
- rewrite addrC; move: gt_yr1.
- rewrite (monoLR (addrNK _) (ltr_add2r _)).
- rewrite /z ltr_normr opprB=> /orP[|-> //].
- rewrite (monoRL (addrK a1) (ltr_add2r _))=> /ltr_trans /(_ lt_xy).
- by rewrite ltrNge addrC; move: le_xr1; rewrite ler_distl=> /andP [_ ->].
-have lt_yz : y < z by rewrite (monoRL (addrK _) (ltr_add2r _)).
-have hz2 : `|z - a2| <= r2.
- move: (har); rewrite ler_norml=> /andP [la ua].
- rewrite addrAC ler_distl ua andbT.
- rewrite -[a1](addrNK y) -[_ - _ + _ - _]addrA.
- rewrite ler_add //.
- by rewrite (monoRL (addrK _) (ler_add2r _)) addrC ltrW.
- by move: le_yr2; rewrite ler_norml=> /andP[].
-have [<-|neq_zx] := eqVneq z x.
- by rewrite -ltr_pdivl_mulr ?subr_gt0 // ltr_minl hk2 ?orbT // gtr_eqF.
-have lt_zx : z < x.
- rewrite ltr_neqAle neq_zx /=.
- move: le_xr1; rewrite distrC ler_norml=> /andP[_].
- by rewrite !(monoLR (addrK _) (ler_add2r _)) addrC.
-rewrite -{1}[x](addrNK z) -{1}[p.[x]](addrNK p.[z]).
-rewrite !addrA -![_ - _ + _ - _]addrA mulrDr ltr_add //.
- rewrite -ltr_pdivl_mulr ?subr_gt0 //.
- by rewrite ltr_minl hk1 ?gtr_eqF.
-rewrite -ltr_pdivl_mulr ?subr_gt0 //.
-by rewrite ltr_minl hk2 ?orbT ?gtr_eqF.
-Qed.
-
-End monotony.
-
-Section CauchyReals.
-
-Local Open Scope nat_scope.
-Local Open Scope creal_scope.
-Local Open Scope ring_scope.
-
-Definition asympt1 (R : numDomainType) (P : R -> nat -> Prop)
- := {m : R -> nat | forall eps i, 0 < eps -> (m eps <= i)%N -> P eps i}.
-
-Definition asympt2 (R : numDomainType) (P : R -> nat -> nat -> Prop)
- := {m : R -> nat | forall eps i j, 0 < eps -> (m eps <= i)%N -> (m eps <= j)%N -> P eps i j}.
-
-Notation "{ 'asympt' e : i / P }" := (asympt1 (fun e i => P))
- (at level 0, e ident, i ident, format "{ 'asympt' e : i / P }") : type_scope.
-
-Notation "{ 'asympt' e : i j / P }" := (asympt2 (fun e i j => P))
- (at level 0, e ident, i ident, j ident, format "{ 'asympt' e : i j / P }") : type_scope.
-
-Lemma asympt1modP (R : numDomainType) P (a : asympt1 P) e i :
- 0 < e :> R -> (projT1 a e <= i)%N -> P e i.
-Proof. by case: a e i. Qed.
-
-Lemma asympt2modP (R : numDomainType) P (a : asympt2 P) e i j :
- 0 < e :> R -> (projT1 a e <= i)%N -> (projT1 a e <= j)%N -> P e i j.
-Proof. by case: a e i j. Qed.
-
-Variable F : realFieldType.
-
-(* Lemma asympt_mulLR (k : F) (hk : 0 < k) (P : F -> nat -> Prop) : *)
-(* {asympt e : i / P e i} -> {asympt e : i / P (e * k) i}. *)
-(* Proof. *)
-(* case=> m hm; exists (fun e => m (e * k))=> e i he hi. *)
-(* by apply: hm=> //; rewrite -ltr_pdivr_mulr // mul0r. *)
-(* Qed. *)
-
-(* Lemma asympt_mulRL (k : F) (hk : 0 < k) (P : F -> nat -> Prop) : *)
-(* {asympt e : i / P (e * k) i} -> {asympt e : i / P e i}. *)
-(* Proof. *)
-(* case=> m hm; exists (fun e => m (e / k))=> e i he hi. *)
-(* rewrite -[e](@mulfVK _ k) ?gtr_eqF //. *)
-(* by apply: hm=> //; rewrite -ltr_pdivr_mulr ?invr_gt0 // mul0r. *)
-(* Qed. *)
-
-Lemma asymptP (P1 : F -> nat -> Prop) (P2 : F -> nat -> Prop) :
- (forall e i, 0 < e -> P1 e i -> P2 e i) ->
- {asympt e : i / P1 e i} -> {asympt e : i / P2 e i}.
-Proof.
-by move=> hP; case=> m hm; exists m=> e i he me; apply: hP=> //; apply: hm.
-Qed.
-
-(* Lemma asympt2_mulLR (k : F) (hk : 0 < k) (P : F -> nat -> nat -> Prop) : *)
-(* {asympt e : i j / P e i j} -> {asympt e : i j / P (e * k) i j}. *)
-(* Proof. *)
-(* case=> m hm; exists (fun e => m (e * k))=> e i j he hi hj. *)
-(* by apply: hm=> //; rewrite -ltr_pdivr_mulr // mul0r. *)
-(* Qed. *)
-
-(* Lemma asympt2_mulRL (k : F) (hk : 0 < k) (P : F -> nat -> nat -> Prop) : *)
-(* {asympt e : i j / P (e * k) i j} -> {asympt e : i j / P e i j}. *)
-(* Proof. *)
-(* case=> m hm; exists (fun e => m (e / k))=> e i j he hi hj. *)
-(* rewrite -[e](@mulfVK _ k) ?gtr_eqF //. *)
-(* by apply: hm=> //; rewrite -ltr_pdivr_mulr ?invr_gt0 // mul0r. *)
-(* Qed. *)
-
-(* Lemma asympt2P (P1 : F -> nat -> nat -> Prop) (P2 : F -> nat -> nat -> Prop) : *)
-(* (forall e i j, 0 < e -> P1 e i j -> P2 e i j) -> *)
-(* {asympt e : i j / P1 e i j} -> {asympt e : i j / P2 e i j}. *)
-(* Proof. *)
-(* move=> hP; case=> m hm; exists m=> e i j he mei mej. *)
-(* by apply: hP=> //; apply: hm. *)
-(* Qed. *)
-
-Lemma splitf (n : nat) (e : F) : e = iterop n +%R (e / n%:R) e.
-Proof.
-case: n=> // n; set e' := (e / _).
-have -> : e = e' * n.+1%:R by rewrite mulfVK ?pnatr_eq0.
-move: e'=> {e} e; rewrite iteropS.
-by elim: n=> /= [|n <-]; rewrite !mulr_natr ?mulr1n.
-Qed.
-
-Lemma splitD (x y e : F) : x < e / 2%:R -> y < e / 2%:R -> x + y < e.
-Proof. by move=> hx hy; rewrite [e](splitf 2) ltr_add. Qed.
-
-Lemma divrn_gt0 (e : F) (n : nat) : 0 < e -> (0 < n)%N -> 0 < e / n%:R.
-Proof. by move=> e_gt0 n_gt0; rewrite pmulr_rgt0 ?gtr0E. Qed.
-
-Lemma split_norm_add (x y e : F) :
- `|x| < e / 2%:R -> `|y| < e / 2%:R -> `|x + y| < e.
-Proof. by move=> hx hy; rewrite (ler_lt_trans (ler_norm_add _ _)) // splitD. Qed.
-
-Lemma split_norm_sub (x y e : F) :
- `|x| < e / 2%:R -> `|y| < e / 2%:R -> `|x - y| < e.
-Proof. by move=> hx hy; rewrite (ler_lt_trans (ler_norm_sub _ _)) // splitD. Qed.
-
-Lemma split_dist_add (z x y e : F) :
- `|x - z| < e / 2%:R -> `|z - y| < e / 2%:R -> `|x - y| < e.
-Proof.
-by move=> *; rewrite (ler_lt_trans (ler_dist_add z _ _)) ?splitD // 1?distrC.
-Qed.
-
-Definition creal_axiom (x : nat -> F) := {asympt e : i j / `|x i - x j| < e}.
-
-CoInductive creal := CReal {cauchyseq :> nat -> F; _ : creal_axiom cauchyseq}.
-Bind Scope creal_scope with creal.
-
-Lemma crealP (x : creal) : {asympt e : i j / `|x i - x j| < e}.
-Proof. by case: x. Qed.
-
-Definition cauchymod :=
- nosimpl (fun (x : creal) => let: CReal _ m := x in projT1 m).
-
-Lemma cauchymodP (x : creal) eps i j : 0 < eps ->
- (cauchymod x eps <= i)%N -> (cauchymod x eps <= j)%N -> `|x i - x j| < eps.
-Proof. by case: x=> [x [m mP] //] /mP; apply. Qed.
-
-Definition neq_creal (x y : creal) : Prop :=
- exists eps, (0 < eps) &&
- (eps * 3%:R <= `|x (cauchymod x eps) - y (cauchymod y eps)|).
-Notation "!=%CR" := neq_creal : creal_scope.
-Notation "x != y" := (neq_creal x y) : creal_scope.
-
-Definition eq_creal x y := (~ (x != y)%CR).
-Notation "x == y" := (eq_creal x y) : creal_scope.
-
-Lemma ltr_distl_creal (e : F) (i : nat) (x : creal) (j : nat) (a b : F) :
- 0 < e -> (cauchymod x e <= i)%N -> (cauchymod x e <= j)%N ->
- `| x i - a | <= b - e -> `| x j - a | < b.
-Proof.
-move=> e_gt0 hi hj hb.
-rewrite (ler_lt_trans (ler_dist_add (x i) _ _)) ?ltr_le_add //.
-by rewrite -[b](addrNK e) addrC ler_lt_add ?cauchymodP.
-Qed.
-
-Lemma ltr_distr_creal (e : F) (i : nat) (x : creal) (j : nat) (a b : F) :
- 0 < e -> (cauchymod x e <= i)%N -> (cauchymod x e <= j)%N ->
- a + e <= `| x i - b | -> a < `| x j - b |.
-Proof.
-move=> e_gt0 hi hj hb; apply: contraLR hb; rewrite -ltrNge -lerNgt.
-by move=> ha; rewrite (@ltr_distl_creal e j) // addrK.
-Qed.
-
-(* Lemma asympt_neq (x y : creal) : x != y -> *)
-(* {e | 0 < e & forall i, (cauchymod x e <= i)%N -> *)
-(* (cauchymod y e <= i)%N -> `|x i - y i| >= e}. *)
-(* Proof. *)
-(* case/sigW=> e /andP[e_gt0 hxy]. *)
-(* exists e=> // i hi hj; move: hxy; rewrite !lerNgt; apply: contra=> hxy. *)
-(* rewrite !mulrDr !mulr1 distrC (@ltr_distl_creal i) //. *)
-(* by rewrite distrC ltrW // (@ltr_distl_creal i) // ltrW. *)
-(* Qed. *)
-
-Definition lbound (x y : creal) (neq_xy : x != y) : F :=
- projT1 (sigW neq_xy).
-
-Lemma lboundP (x y : creal) (neq_xy : x != y) i :
- (cauchymod x (lbound neq_xy) <= i)%N ->
- (cauchymod y (lbound neq_xy) <= i)%N -> lbound neq_xy <= `|x i - y i|.
-Proof.
-rewrite /lbound; case: (sigW _)=> /= d /andP[d_gt0 hd] hi hj.
-apply: contraLR hd; rewrite -!ltrNge=> hd.
-rewrite (@ltr_distl_creal d i) // distrC ltrW // (@ltr_distl_creal d i) //.
-by rewrite distrC ltrW // !mulrDr mulr1 !addrA !addrK.
-Qed.
-
-Notation lbound_of p := (@lboundP _ _ p _ _ _).
-
-Lemma lbound_gt0 (x y : creal) (neq_xy : x != y) : lbound neq_xy > 0.
-Proof. by rewrite /lbound; case: (sigW _)=> /= d /andP[]. Qed.
-
-Definition lbound_ge0 x y neq_xy := (ltrW (@lbound_gt0 x y neq_xy)).
-
-Lemma cst_crealP (x : F) : creal_axiom (fun _ => x).
-Proof. by exists (fun _ => 0%N)=> *; rewrite subrr normr0. Qed.
-Definition cst_creal (x : F) := CReal (cst_crealP x).
-Notation "x %:CR" := (cst_creal x)
- (at level 2, left associativity, format "x %:CR") : creal_scope.
-Notation "0" := (0 %:CR) : creal_scope.
-
-Lemma lbound0P (x : creal) (x_neq0 : x != 0) i :
- (cauchymod x (lbound x_neq0) <= i)%N ->
- (cauchymod 0%CR (lbound x_neq0) <= i)%N -> lbound x_neq0 <= `|x i|.
-Proof. by move=> cx c0; rewrite -[X in `|X|]subr0 -[0]/(0%CR i) lboundP. Qed.
-
-Notation lbound0_of p := (@lbound0P _ p _ _ _).
-
-Lemma neq_crealP e i j (e_gt0 : 0 < e) (x y : creal) :
- (cauchymod x (e / 5%:R) <= i)%N -> (cauchymod y (e / 5%:R) <= j)%N ->
- e <= `|x i - y j| -> x != y.
-Proof.
-move=> hi hj he; exists (e / 5%:R); rewrite pmulr_rgt0 ?gtr0E //=.
-rewrite distrC ltrW // (@ltr_distr_creal (e / 5%:R) j) ?pmulr_rgt0 ?gtr0E //.
-rewrite distrC ltrW // (@ltr_distr_creal (e / 5%:R) i) ?pmulr_rgt0 ?gtr0E //.
-by rewrite mulr_natr -!mulrSr -mulrnAr -mulr_natr mulVf ?pnatr_eq0 ?mulr1.
-Qed.
-
-Lemma eq_crealP (x y : creal) : {asympt e : i / `|x i - y i| < e} ->
- (x == y)%CR.
-Proof.
-case=> m hm neq_xy; pose d := lbound neq_xy.
-pose_big_enough i.
- have := (hm d i); rewrite lbound_gt0; big_enough => /(_ isT isT).
- by apply/negP; rewrite -lerNgt lboundP.
-by close.
-Qed.
-
-Lemma eq0_crealP (x : creal) : {asympt e : i / `|x i| < e} -> x == 0.
-Proof.
-by move=> hx; apply: eq_crealP; apply: asymptP hx=> e i; rewrite subr0.
-Qed.
-
-Lemma asympt_eq (x y : creal) (eq_xy : x == y) :
- {asympt e : i / `|x i - y i| < e}.
-Proof.
-exists_big_modulus m F.
- move=> e i e0 hi; rewrite ltrNge; apply/negP=> he; apply: eq_xy.
- by apply: (@neq_crealP e i i).
-by close.
-Qed.
-
-Lemma asympt_eq0 (x : creal) : x == 0 -> {asympt e : i / `|x i| < e}.
-Proof. by move/asympt_eq; apply: asymptP=> e i; rewrite subr0. Qed.
-
-Definition eq_mod (x y : creal) (eq_xy : x == y) := projT1 (asympt_eq eq_xy).
-Lemma eq_modP (x y : creal) (eq_xy : x == y) eps i : 0 < eps ->
- (eq_mod eq_xy eps <= i)%N -> `|x i - y i| < eps.
-Proof.
-by move=> eps_gt0; rewrite /eq_mod; case: (asympt_eq _)=> /= m hm /hm; apply.
-Qed.
-Lemma eq0_modP (x : creal) (x_eq0 : x == 0) eps i : 0 < eps ->
- (eq_mod x_eq0 eps <= i)%N -> `|x i| < eps.
-Proof.
-by move=> eps_gt0 hi; rewrite -[X in `|X|]subr0 -[0]/(0%CR i) eq_modP.
-Qed.
-
-Lemma eq_creal_refl x : x == x.
-Proof.
-apply: eq_crealP; exists (fun _ => 0%N).
-by move=> e i e_gt0 _; rewrite subrr normr0.
-Qed.
-Hint Resolve eq_creal_refl.
-
-Lemma neq_creal_sym x y : x != y -> y != x.
-Proof.
-move=> neq_xy; pose_big_enough i.
- apply: (@neq_crealP (lbound neq_xy) i i);
- by rewrite ?lbound_gt0 1?distrC ?(lbound_of neq_xy).
-by close.
-Qed.
-
-Lemma eq_creal_sym x y : x == y -> y == x.
-Proof. by move=> eq_xy /neq_creal_sym. Qed.
-
-Lemma eq_creal_trans x y z : x == y -> y == z -> x == z.
-Proof.
-move=> eq_xy eq_yz; apply: eq_crealP; exists_big_modulus m F.
- by move=> e i *; rewrite (@split_dist_add (y i)) ?eq_modP ?divrn_gt0.
-by close.
-Qed.
-
-Lemma creal_neq_always (x y : creal) i (neq_xy : x != y) :
- (cauchymod x (lbound neq_xy) <= i)%N ->
- (cauchymod y (lbound neq_xy) <= i)%N -> (x i != y i)%B.
-Proof.
-move=> hx hy; rewrite -subr_eq0 -normr_gt0.
-by rewrite (ltr_le_trans _ (lbound_of neq_xy)) ?lbound_gt0.
-Qed.
-
-Definition creal_neq0_always (x : creal) := @creal_neq_always x 0.
-
-Definition lt_creal (x y : creal) : Prop :=
- exists eps, (0 < eps) &&
- (x (cauchymod x eps) + eps * 3%:R <= y (cauchymod y eps)).
-Notation "<%CR" := lt_creal : creal_scope.
-Notation "x < y" := (lt_creal x y) : creal_scope.
-
-Definition le_creal (x y : creal) : Prop := ~ (y < x)%CR.
-Notation "<=%CR" := le_creal : creal_scope.
-Notation "x <= y" := (le_creal x y) : creal_scope.
-
-Lemma ltr_creal (e : F) (i : nat) (x : creal) (j : nat) (a : F) :
- 0 < e -> (cauchymod x e <= i)%N -> (cauchymod x e <= j)%N ->
- x i <= a - e -> x j < a.
-Proof.
-move=> e_gt0 hi hj ha; have := cauchymodP e_gt0 hj hi.
-rewrite ltr_distl=> /andP[_ /ltr_le_trans-> //].
-by rewrite -(ler_add2r (- e)) addrK.
-Qed.
-
-Lemma gtr_creal (e : F) (i : nat) (x : creal) (j : nat) (a : F) :
- 0 < e -> (cauchymod x e <= i)%N -> (cauchymod x e <= j)%N ->
- a + e <= x i-> a < x j.
-Proof.
-move=> e_gt0 hi hj ha; have := cauchymodP e_gt0 hj hi.
-rewrite ltr_distl=> /andP[/(ler_lt_trans _)-> //].
-by rewrite -(ler_add2r e) addrNK.
-Qed.
-
-Definition diff (x y : creal) (lt_xy : (x < y)%CR) : F := projT1 (sigW lt_xy).
-
-Lemma diff_gt0 (x y : creal) (lt_xy : (x < y)%CR) : diff lt_xy > 0.
-Proof. by rewrite /diff; case: (sigW _)=> /= d /andP[]. Qed.
-
-Definition diff_ge0 x y lt_xy := (ltrW (@diff_gt0 x y lt_xy)).
-
-Lemma diffP (x y : creal) (lt_xy : (x < y)%CR) i :
- (cauchymod x (diff lt_xy) <= i)%N ->
- (cauchymod y (diff lt_xy) <= i)%N -> x i + diff lt_xy <= y i.
-Proof.
-rewrite /diff; case: (sigW _)=> /= e /andP[e_gt0 he] hi hj.
-rewrite ltrW // (@gtr_creal e (cauchymod y e)) // (ler_trans _ he) //.
-rewrite !mulrDr mulr1 !addrA !ler_add2r ltrW //.
-by rewrite (@ltr_creal e (cauchymod x e)) // addrK.
-Qed.
-
-Notation diff_of p := (@diffP _ _ p _ _ _).
-
-Lemma diff0P (x : creal) (x_gt0 : (0 < x)%CR) i :
- (cauchymod x (diff x_gt0) <= i)%N ->
- (cauchymod 0%CR (diff x_gt0) <= i)%N -> diff x_gt0 <= x i.
-Proof. by move=> cx c0; rewrite -[diff _]add0r -[0]/(0%CR i) diffP. Qed.
-
-Notation diff0_of p := (@diff0P _ p _ _ _).
-
-Lemma lt_crealP e i j (e_gt0 : 0 < e) (x y : creal) :
- (cauchymod x (e / 5%:R) <= i)%N -> (cauchymod y (e / 5%:R) <= j)%N ->
- x i + e <= y j -> (x < y)%CR.
-Proof.
-move=> hi hj he; exists (e / 5%:R); rewrite pmulr_rgt0 ?gtr0E //=.
-rewrite ltrW // (@gtr_creal (e / 5%:R) j) ?pmulr_rgt0 ?gtr0E //.
-rewrite (ler_trans _ he) // -addrA (monoLR (addrNK _) (ler_add2r _)).
-rewrite ltrW // (@ltr_creal (e / 5%:R) i) ?pmulr_rgt0 ?gtr0E //.
-rewrite -!addrA ler_addl !addrA -mulrA -{1}[e]mulr1 -!(mulrBr, mulrDr).
-rewrite pmulr_rge0 // {1}[1](splitf 5) /= !mul1r !mulrDr mulr1.
-by rewrite !opprD !addrA !addrK addrN.
-Qed.
-
-Lemma le_crealP i (x y : creal) :
- (forall j, (i <= j)%N -> x j <= y j) -> (x <= y)%CR.
-Proof.
-move=> hi lt_yx; pose_big_enough j.
- have := hi j; big_enough => /(_ isT); apply/negP; rewrite -ltrNge.
- by rewrite (ltr_le_trans _ (diff_of lt_yx)) ?ltr_spaddr ?diff_gt0.
-by close.
-Qed.
-
-Lemma le_creal_refl (x : creal) : (x <= x)%CR.
-Proof. by apply: (@le_crealP 0%N). Qed.
-Hint Resolve le_creal_refl.
-
-Lemma lt_neq_creal (x y : creal) : (x < y)%CR -> x != y.
-Proof.
-move=> ltxy; pose_big_enough i.
- apply: (@neq_crealP (diff ltxy) i i) => //; first by rewrite diff_gt0.
- by rewrite distrC lerNgt ltr_distl negb_and -!lerNgt diffP ?orbT.
-by close.
-Qed.
-
-Lemma creal_lt_always (x y : creal) i (lt_xy : (x < y)%CR) :
- (cauchymod x (diff lt_xy) <= i)%N ->
- (cauchymod y (diff lt_xy) <= i)%N -> x i < y i.
-Proof.
-by move=> hx hy; rewrite (ltr_le_trans _ (diff_of lt_xy)) ?ltr_addl ?diff_gt0.
-Qed.
-
-Definition creal_gt0_always := @creal_lt_always 0.
-
-Lemma eq_le_creal (x y : creal) : x == y -> (x <= y)%CR.
-Proof. by move=> /eq_creal_sym ? /lt_neq_creal. Qed.
-
-Lemma asympt_le (x y : creal) (le_xy : (x <= y)%CR) :
- {asympt e : i / x i < y i + e}.
-Proof.
-exists_big_modulus m F.
- move=> e i e0 hm; rewrite ltrNge; apply/negP=> he; apply: le_xy.
- by apply: (@lt_crealP e i i).
-by close.
-Qed.
-
-Lemma asympt_ge0 (x : creal) : (0 <= x)%CR -> {asympt e : i / - e < x i}.
-Proof. by move/asympt_le; apply: asymptP=> *; rewrite -subr_gt0 opprK. Qed.
-
-Definition le_mod (x y : creal) (le_xy : (x <= y)%CR) := projT1 (asympt_le le_xy).
-
-Lemma le_modP (x y : creal) (le_xy : (x <= y)%CR) eps i : 0 < eps ->
- (le_mod le_xy eps <= i)%N -> x i < y i + eps.
-Proof.
-by move=> eps_gt0; rewrite /le_mod; case: (asympt_le _)=> /= m hm /hm; apply.
-Qed.
-
-Lemma ge0_modP (x : creal) (x_ge0 : (0 <= x)%CR) eps i : 0 < eps ->
- (le_mod x_ge0 eps <= i)%N -> - eps < x i.
-Proof.
-by move=> eps_gt0 hi; rewrite -(ltr_add2r eps) addNr -[0]/(0%CR i) le_modP.
-Qed.
-
-Lemma opp_crealP (x : creal) : creal_axiom (fun i => - x i).
-Proof. by case: x=> [x [m mP]]; exists m=> *; rewrite /= -opprD normrN mP. Qed.
-Definition opp_creal (x : creal) := CReal (opp_crealP x).
-Notation "-%CR" := opp_creal : creal_scope.
-Notation "- x" := (opp_creal x) : creal_scope.
-
-Lemma add_crealP (x y : creal) : creal_axiom (fun i => x i + y i).
-Proof.
-exists_big_modulus m F.
- move=> e i j he hi hj; rewrite opprD addrAC addrA -addrA [- _ + _]addrC.
- by rewrite split_norm_add ?cauchymodP ?divrn_gt0.
-by close.
-Qed.
-Definition add_creal (x y : creal) := CReal (add_crealP x y).
-Notation "+%CR" := add_creal : creal_scope.
-Notation "x + y" := (add_creal x y) : creal_scope.
-Notation "x - y" := (x + - y)%CR : creal_scope.
-
-
-Lemma ubound_subproof (x : creal) : {b : F | b > 0 & forall i, `|x i| <= b}.
-Proof.
-pose_big_enough i; first set b := 1 + `|x i|.
- exists (foldl maxr b [seq `|x n| | n <- iota 0 i]) => [|n].
- have : 0 < b by rewrite ltr_spaddl.
- by elim: iota b => //= a l IHl b b_gt0; rewrite IHl ?ltr_maxr ?b_gt0.
- have [|le_in] := (ltnP n i).
- elim: i b => [|i IHi] b //.
- rewrite ltnS -addn1 iota_add add0n map_cat foldl_cat /= ler_maxr leq_eqVlt.
- by case/orP=> [/eqP->|/IHi->] //; rewrite lerr orbT.
- set xn := `|x n|; suff : xn <= b.
- by elim: iota xn b => //= a l IHl xn b Hxb; rewrite IHl ?ler_maxr ?Hxb.
- rewrite -ler_subl_addr (ler_trans (ler_norm _)) //.
- by rewrite (ler_trans (ler_dist_dist _ _)) ?ltrW ?cauchymodP.
-by close.
-Qed.
-
-Definition ubound (x : creal) :=
- nosimpl (let: exist2 b _ _ := ubound_subproof x in b).
-
-Lemma uboundP (x : creal) i : `|x i| <= ubound x.
-Proof. by rewrite /ubound; case: ubound_subproof. Qed.
-
-Lemma ubound_gt0 x : 0 < ubound x.
-Proof. by rewrite /ubound; case: ubound_subproof. Qed.
-
-Definition ubound_ge0 x := (ltrW (ubound_gt0 x)).
-
-Lemma mul_crealP (x y : creal) : creal_axiom (fun i => x i * y i).
-Proof.
-exists_big_modulus m F.
- move=> e i j e_gt0 hi hj.
- rewrite -[_ * _]subr0 -(subrr (x j * y i)) opprD opprK addrA.
- rewrite -mulrBl -addrA -mulrBr split_norm_add // !normrM.
- have /ler_wpmul2l /ler_lt_trans-> // := uboundP y i.
- rewrite -ltr_pdivl_mulr ?ubound_gt0 ?cauchymodP //.
- by rewrite !pmulr_rgt0 ?invr_gt0 ?ubound_gt0 ?ltr0n.
- rewrite mulrC; have /ler_wpmul2l /ler_lt_trans-> // := uboundP x j.
- rewrite -ltr_pdivl_mulr ?ubound_gt0 ?cauchymodP //.
- by rewrite !pmulr_rgt0 ?gtr0E ?ubound_gt0.
-by close.
-Qed.
-Definition mul_creal (x y : creal) := CReal (mul_crealP x y).
-Notation "*%CR" := mul_creal : creal_scope.
-Notation "x * y" := (mul_creal x y) : creal_scope.
-
-Lemma inv_crealP (x : creal) (x_neq0 : x != 0) : creal_axiom (fun i => (x i)^-1).
-Proof.
-pose d := lbound x_neq0.
-exists_big_modulus m F.
- (* exists (fun e => [CC x # e * d ^+ 2; ! x_neq0]). *)
- move=> e i j e_gt0 hi hj.
- have /andP[xi_neq0 xj_neq0] : (x i != 0) && (x j != 0).
- by rewrite -!normr_gt0 !(ltr_le_trans _ (lbound0_of x_neq0)) ?lbound_gt0.
- rewrite -(@ltr_pmul2r _ `|x i * x j|); last by rewrite normr_gt0 mulf_neq0.
- rewrite -normrM !mulrBl mulrA mulVf // mulrCA mulVf // mul1r mulr1.
- apply: (@ltr_le_trans _ (e * d ^+ 2)).
- by apply: cauchymodP; rewrite // !pmulr_rgt0 ?lbound_gt0.
- rewrite ler_wpmul2l ?(ltrW e_gt0) // normrM.
- have /(_ j) hx := lbound0_of x_neq0; rewrite /=.
- have -> // := (ler_trans (@ler_wpmul2l _ d _ _ _ (hx _ _))).
- by rewrite ltrW // lbound_gt0.
- by rewrite ler_wpmul2r ?normr_ge0 // lbound0P.
-by close.
-Qed.
-Definition inv_creal (x : creal) (x_neq0 : x != 0) := CReal (inv_crealP x_neq0).
-Notation "x_neq0 ^-1" := (inv_creal x_neq0) : creal_scope.
-Notation "x / y_neq0" := (x * (y_neq0 ^-1))%CR : creal_scope.
-
-Lemma norm_crealP (x : creal) : creal_axiom (fun i => `|x i|).
-Proof.
-exists (cauchymod x).
-by move=> *; rewrite (ler_lt_trans (ler_dist_dist _ _)) ?cauchymodP.
-Qed.
-Definition norm_creal x := CReal (norm_crealP x).
-Local Notation "`| x |" := (norm_creal x) : creal_scope.
-
-Lemma horner_crealP (p : {poly F}) (x : creal) :
- creal_axiom (fun i => p.[x i]).
-Proof.
-exists_big_modulus m F=> [e i j e_gt0 hi hj|].
- rewrite (ler_lt_trans (@poly_accr_bound1P _ p (x (cauchymod x 1)) 1 _ _ _ _));
- do ?[by rewrite ?e_gt0 | by rewrite ltrW // cauchymodP].
- rewrite -ltr_pdivl_mulr ?poly_accr_bound_gt0 ?cauchymodP //.
- by rewrite pmulr_rgt0 ?invr_gt0 ?poly_accr_bound_gt0.
-by close.
-Qed.
-Definition horner_creal (p : {poly F}) (x : creal) := CReal (horner_crealP p x).
-Notation "p .[ x ]" := (horner_creal p x) : creal_scope.
-
-Lemma neq_creal_horner p (x y : creal) : p.[x] != p.[y] -> x != y.
-Proof.
-move=> neq_px_py.
-pose d := lbound neq_px_py.
-pose_big_enough i.
- pose k := 2%:R + poly_accr_bound p (y i) d.
- have /andP[d_gt0 k_gt0] : (0 < d) && (0 < k).
- rewrite ?(ltr_spaddl, poly_accr_bound_ge0);
- by rewrite ?ltr0n ?ltrW ?ltr01 ?lbound_gt0.
- pose_big_enough j.
- apply: (@neq_crealP (d / k) j j) => //.
- by rewrite ?(pmulr_lgt0, invr_gt0, ltr0n).
- rewrite ler_pdivr_mulr //.
- have /(_ j) // := (lbound_of neq_px_py).
- big_enough=> /(_ isT isT).
- apply: contraLR; rewrite -!ltrNge=> hxy.
- rewrite (ler_lt_trans (@poly_accr_bound1P _ _ (y i) d _ _ _ _)) //.
- + by rewrite ltrW // cauchymodP.
- + rewrite ltrW // (@split_dist_add (y j)) //; last first.
- by rewrite cauchymodP ?divrn_gt0.
- rewrite ltr_pdivl_mulr ?ltr0n // (ler_lt_trans _ hxy) //.
- by rewrite ler_wpmul2l ?normr_ge0 // ler_paddr // poly_accr_bound_ge0.
- rewrite (ler_lt_trans _ hxy) // ler_wpmul2l ?normr_ge0 //.
- by rewrite ler_paddl // ?ler0n.
- by close.
-by close.
-Qed.
-
-Lemma eq_creal_horner p (x y : creal) : x == y -> p.[x] == p.[y].
-Proof. by move=> hxy /neq_creal_horner. Qed.
-
-Import Setoid Relation_Definitions.
-
-Add Relation creal eq_creal
- reflexivity proved by eq_creal_refl
- symmetry proved by eq_creal_sym
- transitivity proved by eq_creal_trans
-as eq_creal_rel.
-Global Existing Instance eq_creal_rel.
-
-Add Morphism add_creal with
- signature eq_creal ==> eq_creal ==> eq_creal as add_creal_morph.
-Proof.
-move=> x y eq_xy z t eq_zt; apply: eq_crealP.
-exists_big_modulus m F.
- move=> e i e_gt0 hi; rewrite opprD addrA [X in X + _]addrAC -addrA.
- by rewrite split_norm_add ?eq_modP ?divrn_gt0.
-by close.
-Qed.
-Global Existing Instance add_creal_morph_Proper.
-
-
-Add Morphism opp_creal with
- signature eq_creal ==> eq_creal as opp_creal_morph.
-Proof.
-move=> x y /asympt_eq [m hm]; apply: eq_crealP; exists m.
-by move=> e i e_gt0 hi /=; rewrite -opprD normrN hm.
-Qed.
-Global Existing Instance opp_creal_morph_Proper.
-
-Add Morphism mul_creal with
- signature eq_creal ==> eq_creal ==> eq_creal as mul_creal_morph.
-Proof.
-move=> x y eq_xy z t eq_zt; apply: eq_crealP.
-exists_big_modulus m F.
- move=> e i e_gt0 hi.
- rewrite (@split_dist_add (y i * z i)) // -(mulrBl, mulrBr) normrM.
- have /ler_wpmul2l /ler_lt_trans-> // := uboundP z i.
- rewrite -ltr_pdivl_mulr ?ubound_gt0 ?eq_modP //.
- by rewrite !pmulr_rgt0 ?invr_gt0 ?ubound_gt0 ?ltr0n.
- rewrite mulrC; have /ler_wpmul2l /ler_lt_trans-> // := uboundP y i.
- rewrite -ltr_pdivl_mulr ?ubound_gt0 ?eq_modP //.
- by rewrite !pmulr_rgt0 ?invr_gt0 ?ubound_gt0 ?ltr0n.
-by close.
-Qed.
-Global Existing Instance mul_creal_morph_Proper.
-
-Lemma eq_creal_inv (x y : creal) (x_neq0 : x != 0) (y_neq0 : y != 0) :
- (x == y) -> (x_neq0^-1 == y_neq0^-1).
-Proof.
-move=> eq_xy; apply: eq_crealP; exists_big_modulus m F.
- move=> e i e_gt0 hi /=.
- rewrite -(@ltr_pmul2r _ (lbound x_neq0 * lbound y_neq0));
- do ?by rewrite ?pmulr_rgt0 ?lbound_gt0.
- rewrite (@ler_lt_trans _ (`|(x i)^-1 - (y i)^-1| * (`|x i| * `|y i|))) //.
- rewrite ler_wpmul2l ?normr_ge0 //.
- rewrite (@ler_trans _ (`|x i| * lbound y_neq0)) //.
- by rewrite ler_wpmul2r ?lbound_ge0 ?lbound0P.
- by rewrite ler_wpmul2l ?normr_ge0 ?lbound0P.
- rewrite -!normrM mulrBl mulKf ?creal_neq0_always //.
- rewrite mulrCA mulVf ?mulr1 ?creal_neq0_always //.
- by rewrite distrC eq_modP ?pmulr_rgt0 ?lbound_gt0.
-by close.
-Qed.
-
-Add Morphism horner_creal with
- signature (@eq _) ==> eq_creal ==> eq_creal as horner_creal_morph.
-Proof. exact: eq_creal_horner. Qed.
-Global Existing Instance horner_creal_morph_Proper.
-
-Add Morphism lt_creal with
- signature eq_creal ==> eq_creal ==> iff as lt_creal_morph.
-Proof.
-move=> x y eq_xy z t eq_zt.
-wlog lxz : x y z t eq_xy eq_zt / (x < z)%CR.
- move=> hwlog; split=> h1; move: (h1) => /hwlog; apply=> //;
- by apply: eq_creal_sym.
-split=> // _.
-pose e' := diff lxz / 4%:R.
-have e'_gt0 : e' > 0 by rewrite pmulr_rgt0 ?gtr0E ?diff_gt0.
-have le_zt : (z <= t)%CR by apply: eq_le_creal.
-have le_xy : (y <= x)%CR by apply: eq_le_creal; apply: eq_creal_sym.
-pose_big_enough i.
- apply: (@lt_crealP e' i i)=> //.
- rewrite ltrW // -(ltr_add2r e').
- rewrite (ler_lt_trans _ (@le_modP _ _ le_zt _ _ _ _)) //.
- rewrite -addrA (monoLR (@addrNK _ _) (@ler_add2r _ _)) ltrW //.
- rewrite (ltr_le_trans (@le_modP _ _ le_xy e' _ _ _)) //.
- rewrite -(monoLR (@addrNK _ _) (@ler_add2r _ _)) ltrW //.
- rewrite (ltr_le_trans _ (diff_of lxz)) //.
- rewrite -addrA ler_lt_add // /e' -!mulrDr gtr_pmulr ?diff_gt0 //.
- by rewrite [X in _ < X](splitf 4) /= mul1r !ltr_addr ?gtr0E.
-by close.
-Qed.
-Global Existing Instance lt_creal_morph_Proper.
-
-Add Morphism le_creal with
- signature eq_creal ==> eq_creal ==> iff as le_creal_morph.
-Proof. by move=> x y exy z t ezt; rewrite /le_creal exy ezt. Qed.
-Global Existing Instance le_creal_morph_Proper.
-
-Add Morphism norm_creal
- with signature eq_creal ==> eq_creal as norm_creal_morph.
-Proof.
-move=> x y hxy; apply: eq_crealP; exists_big_modulus m F.
- move=> e i e_gt0 hi.
- by rewrite (ler_lt_trans (ler_dist_dist _ _)) ?eq_modP.
-by close.
-Qed.
-Global Existing Instance norm_creal_morph_Proper.
-
-Lemma neq_creal_ltVgt (x y : creal) : x != y -> {(x < y)%CR} + {(y < x)%CR}.
-Proof.
-move=> neq_xy; pose_big_enough i.
- have := (@lboundP _ _ neq_xy i); big_enough => /(_ isT isT).
- have [le_xy|/ltrW le_yx'] := lerP (x i) (y i).
- rewrite -(ler_add2r (x i)) ?addrNK addrC.
- move=> /lt_crealP; rewrite ?lbound_gt0; big_enough.
- by do 3!move/(_ isT); left.
- rewrite -(ler_add2r (y i)) ?addrNK addrC.
- move=> /lt_crealP; rewrite ?lbound_gt0; big_enough.
- by do 3!move/(_ isT); right.
-by close.
-Qed.
-
-Lemma lt_creal_neq (x y : creal) : (x < y -> x != y)%CR.
-Proof.
-move=> lxy; pose_big_enough i.
- apply: (@neq_crealP (diff lxy) i i); rewrite ?diff_gt0 //.
- rewrite distrC ler_normr (monoRL (addrK _) (ler_add2r _)) addrC.
- by rewrite (diff_of lxy).
-by close.
-Qed.
-
-Lemma gt_creal_neq (x y : creal) : (y < x -> x != y)%CR.
-Proof. by move/lt_creal_neq /neq_creal_sym. Qed.
-
-Lemma lt_creal_trans (x y z : creal) : (x < y -> y < z -> x < z)%CR.
-Proof.
-move=> lt_xy lt_yz; pose_big_enough i.
- apply: (@lt_crealP (diff lt_xy + diff lt_yz) i i) => //.
- by rewrite addr_gt0 ?diff_gt0.
- rewrite (ler_trans _ (diff_of lt_yz)) //.
- by rewrite addrA ler_add2r (diff_of lt_xy).
-by close.
-Qed.
-
-Lemma lt_crealW (x y : creal) : (x < y)%CR -> (x <= y)%CR.
-Proof. by move=> /lt_creal_trans /(_ _) /le_creal_refl. Qed.
-
-Add Morphism neq_creal with
- signature eq_creal ==> eq_creal ==> iff as neq_creal_morph.
-Proof.
-move=> x y eq_xy z t eq_zt; split=> /neq_creal_ltVgt [].
-+ by rewrite eq_xy eq_zt=> /lt_creal_neq.
-+ by rewrite eq_xy eq_zt=> /gt_creal_neq.
-+ by rewrite -eq_xy -eq_zt=> /lt_creal_neq.
-by rewrite -eq_xy -eq_zt=> /gt_creal_neq.
-Qed.
-Global Existing Instance neq_creal_morph_Proper.
-
-Local Notation m0 := (fun (_ : F) => 0%N).
-
-Lemma add_0creal x : 0 + x == x.
-Proof. by apply: eq_crealP; exists m0=> * /=; rewrite add0r subrr normr0. Qed.
-
-Lemma add_creal0 x : x + 0 == x.
-Proof. by apply: eq_crealP; exists m0=> * /=; rewrite addr0 subrr normr0. Qed.
-
-Lemma mul_creal0 x : x * 0 == 0.
-Proof. by apply: eq_crealP; exists m0=> * /=; rewrite mulr0 subrr normr0. Qed.
-
-Lemma mul_0creal x : 0 * x == 0.
-Proof. by apply: eq_crealP; exists m0=> * /=; rewrite mul0r subrr normr0. Qed.
-
-Lemma mul_creal1 x : x * 1%:CR == x.
-Proof. by apply: eq_crealP; exists m0=> * /=; rewrite mulr1 subrr normr0. Qed.
-
-Lemma mul_1creal x : 1%:CR * x == x.
-Proof. by apply: eq_crealP; exists m0=> * /=; rewrite mul1r subrr normr0. Qed.
-
-Lemma opp_creal0 : - 0 == 0.
-Proof. by apply: eq_crealP; exists m0=> * /=; rewrite oppr0 addr0 normr0. Qed.
-
-Lemma horner_crealX (x : creal) : 'X.[x] == x.
-Proof. by apply: eq_crealP; exists m0=> *; rewrite /= hornerX subrr normr0. Qed.
-
-Lemma horner_crealM (p q : {poly F}) (x : creal) :
- ((p * q).[x] == p.[x] * q.[x])%CR.
-Proof.
-by apply: eq_crealP; exists m0=> * /=; rewrite hornerM subrr normr0.
-Qed.
-
-Lemma neq_creal_cst x y : reflect (cst_creal x != cst_creal y) (x != y).
-Proof.
-apply: (iffP idP)=> neq_xy; pose_big_enough i.
-+ by apply (@neq_crealP `|x - y| i i); rewrite ?normr_gt0 ?subr_eq0 .
-+ by close.
-+ by rewrite (@creal_neq_always _ _ i neq_xy).
-+ by close.
-Qed.
-
-Lemma eq_creal_cst x y : reflect (cst_creal x == cst_creal y) (x == y).
-Proof.
-apply: (iffP idP)=> [|eq_xy]; first by move/eqP->.
-by apply/negP=> /negP /neq_creal_cst; rewrite eq_xy; apply: eq_creal_refl.
-Qed.
-
-Lemma lt_creal_cst x y : reflect (cst_creal x < cst_creal y)%CR (x < y).
-Proof.
-apply: (iffP idP)=> lt_xy; pose_big_enough i.
-+ apply: (@lt_crealP (y - x) i i); rewrite ?subr_gt0 //=.
- by rewrite addrCA subrr addr0.
-+ by close.
-+ by rewrite (@creal_lt_always _ _ i lt_xy).
-+ by close.
-Qed.
-
-Lemma le_creal_cst x y : reflect (cst_creal x <= cst_creal y)%CR (x <= y).
-Proof.
-apply: (iffP idP)=> [le_xy /lt_creal_cst|eq_xy]; first by rewrite ltrNge le_xy.
-by rewrite lerNgt; apply/negP=> /lt_creal_cst.
-Qed.
-
-
-Lemma mul_creal_neq0 x y : x != 0 -> y != 0 -> x * y != 0.
-Proof.
-move=> x_neq0 y_neq0.
-pose d := lbound x_neq0 * lbound y_neq0.
-have d_gt0 : 0 < d by rewrite pmulr_rgt0 lbound_gt0.
-pose_big_enough i.
- apply: (@neq_crealP d i i)=> //; rewrite subr0 normrM.
- rewrite (@ler_trans _ (`|x i| * lbound y_neq0)) //.
- by rewrite ler_wpmul2r ?lbound_ge0 // lbound0P.
- by rewrite ler_wpmul2l ?normr_ge0 // lbound0P.
-by close.
-Qed.
-
-Lemma mul_neq0_creal x y : x * y != 0 -> y != 0.
-Proof.
-move=> xy_neq0; pose_big_enough i.
- apply: (@neq_crealP ((ubound x)^-1 * lbound xy_neq0) i i) => //.
- by rewrite pmulr_rgt0 ?invr_gt0 ?lbound_gt0 ?ubound_gt0.
- rewrite subr0 ler_pdivr_mull ?ubound_gt0 //.
- have /(_ i)-> // := (ler_trans (lbound0_of xy_neq0)).
- by rewrite normrM ler_wpmul2r ?normr_ge0 ?uboundP.
-by close.
-Qed.
-
-Lemma poly_mul_creal_eq0_coprime p q x :
- coprimep p q ->
- p.[x] * q.[x] == 0 -> {p.[x] == 0} + {q.[x] == 0}.
-Proof.
-move=> /Bezout_eq1_coprimepP /sig_eqW [[u v] /= hpq]; pose_big_enough i.
- have := (erefl ((1 : {poly F}).[x i])).
- rewrite -{1}hpq /= hornerD hornerC.
- set upxi := (u * _).[_].
- move=> hpqi.
- have [p_small|p_big] := lerP `|upxi| 2%:R^-1=> pqx0; [left|right].
- move=> px0; apply: pqx0; apply: mul_creal_neq0=> //.
- apply: (@mul_neq0_creal v.[x]).
- apply: (@neq_crealP 2%:R^-1 i i); rewrite ?gtr0E //.
- rewrite /= subr0 -hornerM -(ler_add2l `|upxi|).
- rewrite (ler_trans _ (ler_norm_add _ _)) // hpqi normr1.
- rewrite (monoLR (addrNK _) (ler_add2r _)).
- by rewrite {1}[1](splitf 2) /= mul1r addrK.
- move=> qx0; apply: pqx0; apply: mul_creal_neq0=> //.
- apply: (@mul_neq0_creal u.[x]).
- apply: (@neq_crealP 2%:R^-1 i i); rewrite ?gtr0E //.
- by rewrite /= subr0 -hornerM ltrW.
-by close.
-Qed.
-
-Lemma dvdp_creal_eq0 p q x : p %| q -> p.[x] == 0 -> q.[x] == 0.
-Proof.
-by move=> dpq px0; rewrite -[q](divpK dpq) horner_crealM px0 mul_creal0.
-Qed.
-
-Lemma root_poly_expn_creal p k x : (0 < k)%N
- -> (p ^+ k).[x] == 0 -> p.[x] == 0.
-Proof.
-move=> k_gt0 pkx_eq0; apply: eq_crealP; exists_big_modulus m F.
- move=> e i e_gt0 hi; rewrite /= subr0.
- rewrite -(@ltr_pexpn2r _ k) -?topredE /= ?normr_ge0 ?ltrW //.
- by rewrite -normrX -horner_exp (@eq0_modP _ pkx_eq0) ?exprn_gt0 //.
-by close.
-Qed.
-
-Lemma horner_cst_creal c x : c%:P.[x] == c%:CR.
-Proof.
-apply: eq_crealP; exists (fun _ => 0%N)=> e i e_gt0 _.
-by rewrite /= hornerC subrr normr0.
-Qed.
-
-Lemma horner_creal_cst (p : {poly F}) (x : F) : p.[x%:CR] == p.[x]%:CR.
-Proof. by apply: eq_crealP; exists m0=> *; rewrite /= subrr normr0. Qed.
-
-
-Lemma poly_mul_creal_eq0 p q x :
- p.[x] * q.[x] == 0 -> {p.[x] == 0} + {q.[x] == 0}.
-Proof.
-move=> mul_px_qx_eq0.
-have [->|p_neq0] := altP (p =P 0); first by left; rewrite horner_cst_creal.
-have [->|q_neq0] := altP (q =P 0); first by right; rewrite horner_cst_creal.
-pose d := gcdp p q; pose p' := gdcop d p; pose q' := gdcop d q.
-have cop_q'_d': coprimep p' q'.
- rewrite /coprimep size_poly_eq1.
- apply: (@coprimepP _ p' d _).
- + by rewrite coprimep_gdco.
- + by rewrite dvdp_gcdl.
- rewrite dvdp_gcd (dvdp_trans (dvdp_gcdl _ _)) ?dvdp_gdco //.
- by rewrite (dvdp_trans (dvdp_gcdr _ _)) ?dvdp_gdco.
-suff : (p' * q').[x] * (d ^+ (size p + size q)).[x] == 0.
- case/poly_mul_creal_eq0_coprime.
- + by rewrite coprimep_expr // coprimep_mull ?coprimep_gdco.
- + move=> p'q'x_eq0.
- have : p'.[x] * q'.[x] == 0 by rewrite -horner_crealM.
- case/poly_mul_creal_eq0_coprime=> // /dvdp_creal_eq0 hp'q'.
- by left; apply: hp'q'; rewrite dvdp_gdco.
- by right; apply: hp'q'; rewrite dvdp_gdco.
- move/root_poly_expn_creal.
- rewrite addn_gt0 lt0n size_poly_eq0 p_neq0=> /(_ isT) dx_eq0.
- by left; apply: dvdp_creal_eq0 dx_eq0; rewrite dvdp_gcdl.
-move: mul_px_qx_eq0; rewrite -!horner_crealM.
-rewrite exprD mulrAC mulrA -mulrA [_ ^+ _ * _]mulrC.
-apply: dvdp_creal_eq0; rewrite ?dvdp_mul // dvdp_gdcor //;
-by rewrite gcdp_eq0 negb_and p_neq0.
-Qed.
-
-Lemma coprimep_root (p q : {poly F}) x :
- coprimep p q -> p.[x] == 0 -> q.[x] != 0.
-Proof.
-move=> /Bezout_eq1_coprimepP /sig_eqW [[u v] hpq] px0.
-have upx_eq0 : u.[x] * p.[x] == 0 by rewrite px0 mul_creal0.
-pose_big_enough i.
- have := (erefl ((1 : {poly F}).[x i])).
- rewrite -{1}hpq /= hornerD hornerC.
- set upxi := (u * _).[_] => hpqi.
- apply: (@neq_crealP ((ubound v.[x])%CR^-1 / 2%:R) i i) => //.
- by rewrite pmulr_rgt0 ?gtr0E // ubound_gt0.
- rewrite /= subr0 ler_pdivr_mull ?ubound_gt0 //.
- rewrite (@ler_trans _ `|(v * q).[x i]|) //; last first.
- by rewrite hornerM normrM ler_wpmul2r ?normr_ge0 ?(uboundP v.[x]).
- rewrite -(ler_add2l `|upxi|) (ler_trans _ (ler_norm_add _ _)) // hpqi normr1.
- rewrite (monoLR (addrNK _) (ler_add2r _)).
- rewrite {1}[1](splitf 2) /= mul1r addrK ltrW // /upxi hornerM.
- by rewrite (@eq0_modP _ upx_eq0) ?gtr0E.
-by close.
-Qed.
-
-Lemma deriv_neq0_mono (p : {poly F}) (x : creal) : p^`().[x] != 0 ->
- { r : F & 0 < r &
- { i : nat & (cauchymod x r <= i)%N & (strong_mono p (x i) r)} }.
-Proof.
-move=> px_neq0.
-wlog : p px_neq0 / (0 < p^`().[x])%CR.
- case/neq_creal_ltVgt: (px_neq0)=> px_lt0; last exact.
- case/(_ (- p)).
- + pose_big_enough i.
- apply: (@neq_crealP (lbound px_neq0) i i); do ?by rewrite ?lbound_gt0.
- rewrite /= derivN hornerN subr0 normrN.
- by rewrite (lbound0_of px_neq0).
- by close.
- + pose_big_enough i.
- apply: (@lt_crealP (diff px_lt0) i i); do ?by rewrite ?diff_gt0.
- rewrite /= add0r derivN hornerN -subr_le0 opprK addrC.
- by rewrite (diff_of px_lt0) //.
- by close.
- move=> r r_ge0 [i hi]; move/strong_monoN; rewrite opprK=> sm.
- by exists r=> //; exists i.
-move=> px_gt0.
-pose b1 := poly_accr_bound p^`() 0 (1 + ubound x).
-pose b2 := poly_accr_bound2 p 0 (1 + ubound x).
-pose r := minr 1 (minr
- (diff px_gt0 / 4%:R / b1)
- (diff px_gt0 / 4%:R / b2 / 2%:R)).
-exists r.
- rewrite !ltr_minr ?ltr01 ?pmulr_rgt0 ?gtr0E ?diff_gt0;
- by rewrite ?poly_accr_bound2_gt0 ?poly_accr_bound_gt0.
-pose_big_enough i.
- exists i => //; left; split; last first.
- move=> y hy; have := (@poly_accr_bound1P _ p^`() 0 (1 + ubound x) (x i) y).
- rewrite ?subr0 ler_paddl ?ler01 ?uboundP //.
- rewrite (@ler_trans _ (r + `|x i|)) ?subr0; last 2 first.
- + rewrite (monoRL (addrNK _) (ler_add2r _)).
- by rewrite (ler_trans (ler_sub_dist _ _)).
- + by rewrite ler_add ?ler_minl ?lerr ?uboundP.
- move=> /(_ isT isT).
- rewrite ler_distl=> /andP[le_py ge_py].
- rewrite (ltr_le_trans _ le_py) // subr_gt0 -/b1.
- rewrite (ltr_le_trans _ (diff0_of px_gt0)) //.
- rewrite (@ler_lt_trans _ (r * b1)) //.
- by rewrite ler_wpmul2r ?poly_accr_bound_ge0.
- rewrite -ltr_pdivl_mulr ?poly_accr_bound_gt0 //.
- rewrite !ltr_minl ltr_pmul2r ?invr_gt0 ?poly_accr_bound_gt0 //.
- by rewrite gtr_pmulr ?diff_gt0 // invf_lt1 ?gtr0E ?ltr1n ?orbT.
- exists (diff px_gt0 / 4%:R).
- by rewrite pmulr_rgt0 ?gtr0E ?diff_gt0.
- move=> y z neq_yz hy hz.
- have := (@poly_accr_bound1P _ p^`() 0 (1 + ubound x) (x i) z).
- have := @poly_accr_bound2P _ p 0 (1 + ubound x) z y; rewrite eq_sym !subr0.
- rewrite neq_yz ?ler01 ?ubound_ge0=> // /(_ isT).
- rewrite (@ler_trans _ (r + `|x i|)); last 2 first.
- + rewrite (monoRL (addrNK _) (ler_add2r _)).
- by rewrite (ler_trans (ler_sub_dist _ _)).
- + rewrite ler_add ?ler_minl ?lerr ?uboundP //.
- rewrite (@ler_trans _ (r + `|x i|)); last 2 first.
- + rewrite (monoRL (addrNK _) (ler_add2r _)).
- by rewrite (ler_trans (ler_sub_dist _ _)).
- + rewrite ler_add ?ler_minl ?lerr ?uboundP //.
- rewrite ler_paddl ?uboundP ?ler01 //.
- move=> /(_ isT isT); rewrite ler_distl=> /andP [haccr _].
- move=> /(_ isT isT); rewrite ler_distl=> /andP [hp' _].
- rewrite (ltr_le_trans _ haccr) // (monoRL (addrK _) (ltr_add2r _)).
- rewrite (ltr_le_trans _ hp') // (monoRL (addrK _) (ltr_add2r _)).
- rewrite (ltr_le_trans _ (diff0_of px_gt0)) //.
- rewrite {2}[diff _](splitf 4) /= -!addrA ltr_add2l ltr_spaddl //.
- by rewrite pmulr_rgt0 ?gtr0E ?diff_gt0.
- rewrite -/b1 -/b2 ler_add //.
- rewrite -ler_pdivl_mulr ?poly_accr_bound2_gt0 //.
- rewrite (@ler_trans _ (r * 2%:R)) //.
- rewrite (ler_trans (ler_dist_add (x i) _ _)) //.
- by rewrite mulrDr mulr1 ler_add // distrC.
- by rewrite -ler_pdivl_mulr ?ltr0n // !ler_minl lerr !orbT.
- rewrite -ler_pdivl_mulr ?poly_accr_bound_gt0 //.
- by rewrite (@ler_trans _ r) // !ler_minl lerr !orbT.
-by close.
-Qed.
-
-Lemma smaller_factor (p q : {poly F}) x :
- p \is monic-> p.[x] == 0 ->
- ~~(p %| q) -> ~~ coprimep p q ->
- {r : {poly F} | (size r < size p)%N && (r \is monic) & r.[x] == 0}.
-Proof.
-move=> monic_p px0 ndvd_pq.
-rewrite /coprimep; set d := gcdp _ _=> sd_neq1.
-pose r1 : {poly F} := (lead_coef d)^-1 *: d.
-pose r2 := p %/ r1.
-have ld_neq0 : lead_coef d != 0 :> F.
- by rewrite lead_coef_eq0 gcdp_eq0 negb_and monic_neq0.
-have monic_r1 : r1 \is monic.
- by rewrite monicE /r1 -mul_polyC lead_coefM lead_coefC mulVf.
-have eq_p_r2r1: p = r2 * r1.
- by rewrite divpK // (@eqp_dvdl _ d) ?dvdp_gcdl // eqp_scale ?invr_eq0.
-have monic_r2 : r2 \is monic by rewrite -(monicMr _ monic_r1) -eq_p_r2r1.
-have eq_sr1_sd : size r1 = size d by rewrite size_scale ?invr_eq0.
-have sr1 : (1 < size r1)%N.
- by rewrite ltn_neqAle eq_sym lt0n size_poly_eq0 monic_neq0 ?andbT ?eq_sr1_sd.
-have sr2 : (1 < size r2)%N.
- rewrite size_divp ?size_dvdp ?monic_neq0 //.
- rewrite ltn_subRL addn1 prednK ?(leq_trans _ sr1) // eq_sr1_sd.
- rewrite ltn_neqAle dvdp_leq ?monic_neq0 ?andbT ?dvdp_size_eqp ?dvdp_gcdl //.
- by apply: contra ndvd_pq=> /eqp_dvdl <-; rewrite dvdp_gcdr.
-move: (px0); rewrite eq_p_r2r1=> r2r1x_eq0.
-have : (r2.[x] * r1.[x] == 0) by rewrite -horner_crealM.
-case/poly_mul_creal_eq0=> [r2x_eq0|r1x_eq0].
- exists r2; rewrite ?monic_r2 ?andbT // mulrC.
- by rewrite -ltn_divpl ?divpp ?monic_neq0 // size_poly1.
-exists r1; rewrite ?monic_r1 ?andbT //.
-by rewrite -ltn_divpl ?divpp ?monic_neq0 // size_poly1.
-Qed.
-
-Lemma root_cst_creal (x : F) : ('X - x%:P).[cst_creal x] == 0.
-Proof.
-apply: eq_crealP; exists_big_modulus m F.
- by move=> e i e_gt0 hi; rewrite /= subr0 !hornerE subrr normr0.
-by close.
-Qed.
-
-Lemma has_root_creal_size_gt1 (x : creal) (p : {poly F}) :
- (p != 0)%B -> p.[x] == 0 -> (1 < size p)%N.
-Proof.
-move=> p_neq0 rootpa.
-rewrite ltnNge leq_eqVlt ltnS leqn0 size_poly_eq0 (negPf p_neq0) orbF.
-apply/negP=> /size_poly1P [c c_neq0 eq_pc]; apply: rootpa.
-by rewrite eq_pc horner_cst_creal; apply/neq_creal_cst.
-Qed.
-
-Definition bound_poly_bound (z : creal) (q : {poly {poly F}}) (a r : F) i :=
- (1 + \sum_(j < sizeY q)
- `|(norm_poly2 q).[(ubound z)%:P]^`N(i.+1)`_j| * (`|a| + `|r|) ^+ j).
-
-Lemma bound_poly_boundP (z : creal) i (q : {poly {poly F}}) (a r : F) j :
- poly_bound q.[(z i)%:P]^`N(j.+1) a r <= bound_poly_bound z q a r j.
-Proof.
-rewrite /poly_bound.
-pose f q (k : nat) := `|q^`N(j.+1)`_k| * (`|a| + `|r|) ^+ k.
-rewrite ler_add //=.
-rewrite (big_ord_widen (sizeY q) (f q.[(z i)%:P])); last first.
- rewrite size_nderivn leq_subLR (leq_trans (max_size_evalC _ _)) //.
- by rewrite leq_addl.
-rewrite big_mkcond /= ler_sum // /f => k _.
-case: ifP=> _; last by rewrite mulr_ge0 ?exprn_ge0 ?addr_ge0 ?normr_ge0.
-rewrite ler_wpmul2r ?exprn_ge0 ?addr_ge0 ?normr_ge0 //.
-rewrite !horner_coef.
-rewrite !(@big_morph _ _ (fun p => p^`N(j.+1)) 0 +%R);
- do ?[by rewrite raddf0|by move=> x y /=; rewrite raddfD].
-rewrite !coef_sum.
-rewrite (ler_trans (ler_norm_sum _ _ _)) //.
-rewrite ger0_norm; last first.
- rewrite sumr_ge0=> //= l _.
- rewrite coef_nderivn mulrn_wge0 ?natr_ge0 //.
- rewrite -polyC_exp coefMC coef_norm_poly2 mulr_ge0 ?normr_ge0 //.
- by rewrite exprn_ge0 ?ltrW ?ubound_gt0.
-rewrite size_norm_poly2 ler_sum //= => l _.
-rewrite !{1}coef_nderivn normrMn ler_pmuln2r ?bin_gt0 ?leq_addr //.
-rewrite -!polyC_exp !coefMC coef_norm_poly2 normrM ler_wpmul2l ?normr_ge0 //.
-rewrite normrX; case: (val l)=> // {l} l.
-by rewrite ler_pexpn2r -?topredE //= ?uboundP ?ltrW ?ubound_gt0.
-Qed.
-
-Lemma bound_poly_bound_ge0 z q a r i : 0 <= bound_poly_bound z q a r i.
-Proof.
-by rewrite (ler_trans _ (bound_poly_boundP _ 0%N _ _ _ _)) ?poly_bound_ge0.
-Qed.
-
-Definition bound_poly_accr_bound (z : creal) (q : {poly {poly F}}) (a r : F) :=
- maxr 1 (2%:R * r) ^+ (sizeY q).-1 *
- (1 + \sum_(i < (sizeY q).-1) bound_poly_bound z q a r i).
-
-Lemma bound_poly_accr_boundP (z : creal) i (q : {poly {poly F}}) (a r : F) :
- poly_accr_bound q.[(z i)%:P] a r <= bound_poly_accr_bound z q a r.
-Proof.
-rewrite /poly_accr_bound /bound_poly_accr_bound /=.
-set ui := _ ^+ _; set u := _ ^+ _; set vi := 1 + _.
-rewrite (@ler_trans _ (u * vi)) //.
- rewrite ler_wpmul2r //.
- by rewrite addr_ge0 ?ler01 // sumr_ge0 //= => j _; rewrite poly_bound_ge0.
- rewrite /ui /u; case: maxrP; first by rewrite !expr1n.
- move=> r2_gt1; rewrite ler_eexpn2l //.
- rewrite -subn1 leq_subLR add1n (leq_trans _ (leqSpred _)) //.
- by rewrite max_size_evalC.
-rewrite ler_wpmul2l ?exprn_ge0 ?ler_maxr ?ler01 // ler_add //.
-pose f j := poly_bound q.[(z i)%:P]^`N(j.+1) a r.
-rewrite (big_ord_widen (sizeY q).-1 f); last first.
- rewrite -subn1 leq_subLR add1n (leq_trans _ (leqSpred _)) //.
- by rewrite max_size_evalC.
-rewrite big_mkcond /= ler_sum // /f => k _.
-by case: ifP=> _; rewrite ?bound_poly_bound_ge0 ?bound_poly_boundP.
-Qed.
-
-Lemma bound_poly_accr_bound_gt0 (z : creal) (q : {poly {poly F}}) (a r : F) :
- 0 < bound_poly_accr_bound z q a r.
-Proof.
-rewrite (ltr_le_trans _ (bound_poly_accr_boundP _ 0%N _ _ _)) //.
-by rewrite poly_accr_bound_gt0.
-Qed.
-
-Lemma horner2_crealP (p : {poly {poly F}}) (x y : creal) :
- creal_axiom (fun i => p.[x i, y i]).
-Proof.
-set a := x (cauchymod x 1).
-exists_big_modulus m F.
- move=> e i j e_gt0 hi hj; rewrite (@split_dist_add p.[x i, y j]) //.
- rewrite (ler_lt_trans (@poly_accr_bound1P _ _ 0 (ubound y) _ _ _ _)) //;
- do ?by rewrite ?subr0 ?uboundP.
- rewrite (@ler_lt_trans _ (`|y i - y j|
- * bound_poly_accr_bound x p 0 (ubound y))) //.
- by rewrite ler_wpmul2l ?normr_ge0 // bound_poly_accr_boundP.
- rewrite -ltr_pdivl_mulr ?bound_poly_accr_bound_gt0 //.
- by rewrite cauchymodP // !pmulr_rgt0 ?gtr0E ?bound_poly_accr_bound_gt0.
- rewrite -[p]swapXYK ![(swapXY (swapXY _)).[_, _]]horner2_swapXY.
- rewrite (ler_lt_trans (@poly_accr_bound1P _ _ 0 (ubound x) _ _ _ _)) //;
- do ?by rewrite ?subr0 ?uboundP.
- rewrite (@ler_lt_trans _ (`|x i - x j|
- * bound_poly_accr_bound y (swapXY p) 0 (ubound x))) //.
- by rewrite ler_wpmul2l ?normr_ge0 // bound_poly_accr_boundP.
- rewrite -ltr_pdivl_mulr ?bound_poly_accr_bound_gt0 //.
- by rewrite cauchymodP // !pmulr_rgt0 ?gtr0E ?bound_poly_accr_bound_gt0.
-by close.
-Qed.
-
-Definition horner2_creal (p : {poly {poly F}}) (x y : creal) :=
- CReal (horner2_crealP p x y).
-Notation "p .[ x , y ]" := (horner2_creal p x y)
- (at level 2, left associativity) : creal_scope.
-
-Lemma root_monic_from_neq0 (p : {poly F}) (x : creal) :
- p.[x] == 0 -> ((lead_coef p) ^-1 *: p).[x] == 0.
-Proof. by rewrite -mul_polyC horner_crealM; move->; rewrite mul_creal0. Qed.
-
-Lemma root_sub_annihilant_creal (x y : creal) (p q : {poly F}) :
- (p != 0)%B -> (q != 0)%B -> p.[x] == 0 -> q.[y] == 0 ->
- (sub_annihilant p q).[x - y] == 0.
-Proof.
-move=> p_neq0 q_neq0 px_eq0 qy_eq0.
-have [||[u v] /= [hu hv] hpq] := @sub_annihilant_in_ideal _ p q.
-+ by rewrite (@has_root_creal_size_gt1 x).
-+ by rewrite (@has_root_creal_size_gt1 y).
-apply: eq_crealP; exists_big_modulus m F.
- move=> e i e_gt0 hi /=; rewrite subr0.
- rewrite (hpq (y i)) addrCA subrr addr0 split_norm_add // normrM.
- rewrite (@ler_lt_trans _ ((ubound u.[y, x - y]) * `|p.[x i]|)) //.
- by rewrite ler_wpmul2r ?normr_ge0 // (uboundP u.[y, x - y] i).
- rewrite -ltr_pdivl_mull ?ubound_gt0 //.
- by rewrite (@eq0_modP _ px_eq0) // !pmulr_rgt0 ?gtr0E ?ubound_gt0.
- rewrite (@ler_lt_trans _ ((ubound v.[y, x - y]) * `|q.[y i]|)) //.
- by rewrite ler_wpmul2r ?normr_ge0 // (uboundP v.[y, x - y] i).
- rewrite -ltr_pdivl_mull ?ubound_gt0 //.
- by rewrite (@eq0_modP _ qy_eq0) // !pmulr_rgt0 ?gtr0E ?ubound_gt0.
-by close.
-Qed.
-
-Lemma root_div_annihilant_creal (x y : creal) (p q : {poly F}) (y_neq0 : y != 0) :
- (p != 0)%B -> (q != 0)%B -> p.[x] == 0 -> q.[y] == 0 ->
- (div_annihilant p q).[(x / y_neq0)%CR] == 0.
-Proof.
-move=> p_neq0 q_neq0 px_eq0 qy_eq0.
-have [||[u v] /= [hu hv] hpq] := @div_annihilant_in_ideal _ p q.
-+ by rewrite (@has_root_creal_size_gt1 x).
-+ by rewrite (@has_root_creal_size_gt1 y).
-apply: eq_crealP; exists_big_modulus m F.
- move=> e i e_gt0 hi /=; rewrite subr0.
- rewrite (hpq (y i)) mulrCA divff ?mulr1; last first.
- by rewrite -normr_gt0 (ltr_le_trans _ (lbound0_of y_neq0)) ?lbound_gt0.
- rewrite split_norm_add // normrM.
- rewrite (@ler_lt_trans _ ((ubound u.[y, x / y_neq0]) * `|p.[x i]|)) //.
- by rewrite ler_wpmul2r ?normr_ge0 // (uboundP u.[y, x / y_neq0] i).
- rewrite -ltr_pdivl_mull ?ubound_gt0 //.
- by rewrite (@eq0_modP _ px_eq0) // !pmulr_rgt0 ?gtr0E ?ubound_gt0.
- rewrite (@ler_lt_trans _ ((ubound v.[y, x / y_neq0]) * `|q.[y i]|)) //.
- by rewrite ler_wpmul2r ?normr_ge0 // (uboundP v.[y, x / y_neq0] i).
- rewrite -ltr_pdivl_mull ?ubound_gt0 //.
- by rewrite (@eq0_modP _ qy_eq0) // !pmulr_rgt0 ?gtr0E ?ubound_gt0.
-by close.
-Qed.
-
-Definition exp_creal x n := (iterop n *%CR x 1%:CR).
-Notation "x ^+ n" := (exp_creal x n) : creal_scope.
-
-Add Morphism exp_creal with
- signature eq_creal ==> (@eq _) ==> eq_creal as exp_creal_morph.
-Proof.
-move=> x y eq_xy [//|n]; rewrite /exp_creal !iteropS.
-by elim: n=> //= n ->; rewrite eq_xy.
-Qed.
-Global Existing Instance exp_creal_morph_Proper.
-
-Lemma horner_coef_creal p x :
- p.[x] == \big[+%CR/0%:CR]_(i < size p) ((p`_i)%:CR * (x ^+ i))%CR.
-Proof.
-apply: eq_crealP; exists m0=> e n e_gt0 hn /=; rewrite horner_coef.
-rewrite (@big_morph _ _ (fun u : creal => u n) 0%R +%R) //.
-rewrite -sumrB /= big1 ?normr0=> //= i _.
-apply/eqP; rewrite subr_eq0; apply/eqP; congr (_ * _).
-case: val=> {i} // i; rewrite exprS /exp_creal iteropS.
-by elim: i=> [|i ihi]; rewrite ?expr0 ?mulr1 //= exprS ihi.
-Qed.
-
-End CauchyReals.
-
-Notation "x == y" := (eq_creal x y) : creal_scope.
-Notation "!=%CR" := neq_creal : creal_scope.
-Notation "x != y" := (neq_creal x y) : creal_scope.
-
-Notation "x %:CR" := (cst_creal x)
- (at level 2, left associativity, format "x %:CR") : creal_scope.
-Notation "0" := (0 %:CR)%CR : creal_scope.
-
-Notation "<%CR" := lt_creal : creal_scope.
-Notation "x < y" := (lt_creal x y) : creal_scope.
-
-Notation "<=%CR" := le_creal : creal_scope.
-Notation "x <= y" := (le_creal x y) : creal_scope.
-
-Notation "-%CR" := opp_creal : creal_scope.
-Notation "- x" := (opp_creal x) : creal_scope.
-
-Notation "+%CR" := add_creal : creal_scope.
-Notation "x + y" := (add_creal x y) : creal_scope.
-Notation "x - y" := (x + - y)%CR : creal_scope.
-
-Notation "*%CR" := mul_creal : creal_scope.
-Notation "x * y" := (mul_creal x y) : creal_scope.
-
-Notation "x_neq0 ^-1" := (inv_creal x_neq0) : creal_scope.
-Notation "x / y_neq0" := (x * (y_neq0 ^-1))%CR : creal_scope.
-Notation "p .[ x ]" := (horner_creal p x) : creal_scope.
-Notation "p .[ x , y ]" := (horner2_creal p x y)
- (at level 2, left associativity) : creal_scope.
-Notation "x ^+ n" := (exp_creal x n) : creal_scope.
-
-Notation "`| x |" := (norm_creal x) : creal_scope.
-
-Hint Resolve eq_creal_refl.
-Hint Resolve le_creal_refl.
-
-Notation lbound_of p := (@lboundP _ _ _ p _ _ _).
-Notation lbound0_of p := (@lbound0P _ _ p _ _ _).
-Notation diff_of p := (@diffP _ _ _ p _ _ _).
-Notation diff0_of p := (@diff0P _ _ p _ _ _).
-
-Notation "{ 'asympt' e : i / P }" := (asympt1 (fun e i => P))
- (at level 0, e ident, i ident, format "{ 'asympt' e : i / P }") : type_scope.
-Notation "{ 'asympt' e : i j / P }" := (asympt2 (fun e i j => P))
- (at level 0, e ident, i ident, j ident, format "{ 'asympt' e : i j / P }") : type_scope.
diff --git a/mathcomp/real_closed/complex.v b/mathcomp/real_closed/complex.v
deleted file mode 100644
index 22edf79..0000000
--- a/mathcomp/real_closed/complex.v
+++ /dev/null
@@ -1,1329 +0,0 @@
-(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-(* Distributed under the terms of CeCILL-B. *)
-Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp
-Require Import ssrfun ssrbool eqtype ssrnat seq choice fintype.
-From mathcomp
-Require Import bigop ssralg ssrint div ssrnum rat poly closed_field polyrcf.
-From mathcomp
-Require Import matrix mxalgebra tuple mxpoly zmodp binomial realalg.
-
-(**********************************************************************)
-(* This files defines the extension R[i] of a real field R, *)
-(* and provide it a structure of numeric field with a norm operator. *)
-(* When R is a real closed field, it also provides a structure of *)
-(* algebraically closed field for R[i], using a proof by Derksen *)
-(* (cf comments below, thanks to Pierre Lairez for finding the paper) *)
-(**********************************************************************)
-
-Import GRing.Theory Num.Theory.
-
-Set Implicit Arguments.
-Unset Strict Implicit.
-Unset Printing Implicit Defensive.
-Obligation Tactic := idtac.
-
-Local Open Scope ring_scope.
-
-Reserved Notation "x +i* y"
- (at level 40, left associativity, format "x +i* y").
-Reserved Notation "x -i* y"
- (at level 40, left associativity, format "x -i* y").
-Reserved Notation "R [i]"
- (at level 2, left associativity, format "R [i]").
-
-Local Notation sgr := Num.sg.
-Local Notation sqrtr := Num.sqrt.
-
-CoInductive complex (R : Type) : Type := Complex { Re : R; Im : R }.
-
-Delimit Scope complex_scope with C.
-Local Open Scope complex_scope.
-
-Definition real_complex_def (F : ringType) (phF : phant F) (x : F) :=
- Complex x 0.
-Notation real_complex F := (@real_complex_def _ (Phant F)).
-Notation "x %:C" := (real_complex _ x)
- (at level 2, left associativity, format "x %:C") : complex_scope.
-Notation "x +i* y" := (Complex x y) : complex_scope.
-Notation "x -i* y" := (Complex x (- y)) : complex_scope.
-Notation "x *i " := (Complex 0 x) (at level 8, format "x *i") : complex_scope.
-Notation "''i'" := (Complex 0 1) : complex_scope.
-Notation "R [i]" := (complex R)
- (at level 2, left associativity, format "R [i]").
-
-(* Module ComplexInternal. *)
-Module ComplexEqChoice.
-Section ComplexEqChoice.
-
-Variable R : Type.
-
-Definition sqR_of_complex (x : R[i]) := let: a +i* b := x in [:: a; b].
-Definition complex_of_sqR (x : seq R) :=
- if x is [:: a; b] then Some (a +i* b) else None.
-
-Lemma complex_of_sqRK : pcancel sqR_of_complex complex_of_sqR.
-Proof. by case. Qed.
-
-End ComplexEqChoice.
-End ComplexEqChoice.
-
-Definition complex_eqMixin (R : eqType) :=
- PcanEqMixin (@ComplexEqChoice.complex_of_sqRK R).
-Definition complex_choiceMixin (R : choiceType) :=
- PcanChoiceMixin (@ComplexEqChoice.complex_of_sqRK R).
-Definition complex_countMixin (R : countType) :=
- PcanCountMixin (@ComplexEqChoice.complex_of_sqRK R).
-
-Canonical complex_eqType (R : eqType) :=
- EqType R[i] (complex_eqMixin R).
-Canonical complex_choiceType (R : choiceType) :=
- ChoiceType R[i] (complex_choiceMixin R).
-Canonical complex_countType (R : countType) :=
- CountType R[i] (complex_countMixin R).
-
-Lemma eq_complex : forall (R : eqType) (x y : complex R),
- (x == y) = (Re x == Re y) && (Im x == Im y).
-Proof.
-move=> R [a b] [c d] /=.
-apply/eqP/andP; first by move=> [-> ->]; split.
-by case; move/eqP->; move/eqP->.
-Qed.
-
-Lemma complexr0 : forall (R : ringType) (x : R), x +i* 0 = x%:C. Proof. by []. Qed.
-
-Module ComplexField.
-Section ComplexField.
-
-Variable R : rcfType.
-Local Notation C := R[i].
-Local Notation C0 := ((0 : R)%:C).
-Local Notation C1 := ((1 : R)%:C).
-
-Definition addc (x y : R[i]) := let: a +i* b := x in let: c +i* d := y in
- (a + c) +i* (b + d).
-Definition oppc (x : R[i]) := let: a +i* b := x in (- a) +i* (- b).
-
-Program Definition complex_zmodMixin := @ZmodMixin _ C0 oppc addc _ _ _ _.
-Next Obligation. by move=> [a b] [c d] [e f] /=; rewrite !addrA. Qed.
-Next Obligation. by move=> [a b] [c d] /=; congr (_ +i* _); rewrite addrC. Qed.
-Next Obligation. by move=> [a b] /=; rewrite !add0r. Qed.
-Next Obligation. by move=> [a b] /=; rewrite !addNr. Qed.
-Canonical complex_zmodType := ZmodType R[i] complex_zmodMixin.
-
-Definition scalec (a : R) (x : R[i]) :=
- let: b +i* c := x in (a * b) +i* (a * c).
-
-Program Definition complex_lmodMixin := @LmodMixin _ _ scalec _ _ _ _.
-Next Obligation. by move=> a b [c d] /=; rewrite !mulrA. Qed.
-Next Obligation. by move=> [a b] /=; rewrite !mul1r. Qed.
-Next Obligation. by move=> a [b c] [d e] /=; rewrite !mulrDr. Qed.
-Next Obligation. by move=> [a b] c d /=; rewrite !mulrDl. Qed.
-Canonical complex_lmodType := LmodType R R[i] complex_lmodMixin.
-
-Definition mulc (x y : R[i]) := let: a +i* b := x in let: c +i* d := y in
- ((a * c) - (b * d)) +i* ((a * d) + (b * c)).
-
-Lemma mulcC : commutative mulc.
-Proof.
-move=> [a b] [c d] /=.
-by rewrite [c * b + _]addrC ![_ * c]mulrC ![_ * d]mulrC.
-Qed.
-
-Lemma mulcA : associative mulc.
-Proof.
-move=> [a b] [c d] [e f] /=.
-rewrite !mulrDr !mulrDl !mulrN !mulNr !mulrA !opprD -!addrA.
-by congr ((_ + _) +i* (_ + _)); rewrite !addrA addrAC;
- congr (_ + _); rewrite addrC.
-Qed.
-
-Definition invc (x : R[i]) := let: a +i* b := x in let n2 := (a ^+ 2 + b ^+ 2) in
- (a / n2) -i* (b / n2).
-
-Lemma mul1c : left_id C1 mulc.
-Proof. by move=> [a b] /=; rewrite !mul1r !mul0r subr0 addr0. Qed.
-
-Lemma mulc_addl : left_distributive mulc addc.
-Proof.
-move=> [a b] [c d] [e f] /=; rewrite !mulrDl !opprD -!addrA.
-by congr ((_ + _) +i* (_ + _)); rewrite addrCA.
-Qed.
-
-Lemma nonzero1c : C1 != C0. Proof. by rewrite eq_complex /= oner_eq0. Qed.
-
-Definition complex_comRingMixin :=
- ComRingMixin mulcA mulcC mul1c mulc_addl nonzero1c.
-Canonical complex_ringType :=RingType R[i] complex_comRingMixin.
-Canonical complex_comRingType := ComRingType R[i] mulcC.
-
-Lemma mulVc : forall x, x != C0 -> mulc (invc x) x = C1.
-Proof.
-move=> [a b]; rewrite eq_complex => /= hab; rewrite !mulNr opprK.
-rewrite ![_ / _ * _]mulrAC [b * a]mulrC subrr complexr0 -mulrDl mulfV //.
-by rewrite paddr_eq0 -!expr2 ?expf_eq0 ?sqr_ge0.
-Qed.
-
-Lemma invc0 : invc C0 = C0. Proof. by rewrite /= !mul0r oppr0. Qed.
-
-Definition complex_fieldUnitMixin := FieldUnitMixin mulVc invc0.
-Canonical complex_unitRingType := UnitRingType C complex_fieldUnitMixin.
-Canonical complex_comUnitRingType := Eval hnf in [comUnitRingType of R[i]].
-
-Lemma field_axiom : GRing.Field.mixin_of complex_unitRingType.
-Proof. by []. Qed.
-
-Definition ComplexFieldIdomainMixin := (FieldIdomainMixin field_axiom).
-Canonical complex_idomainType := IdomainType R[i] (FieldIdomainMixin field_axiom).
-Canonical complex_fieldType := FieldType R[i] field_axiom.
-
-Ltac simpc := do ?
- [ rewrite -[(_ +i* _) - (_ +i* _)]/(_ +i* _)
- | rewrite -[(_ +i* _) + (_ +i* _)]/(_ +i* _)
- | rewrite -[(_ +i* _) * (_ +i* _)]/(_ +i* _)].
-
-Lemma real_complex_is_rmorphism : rmorphism (real_complex R).
-Proof.
-split; [|split=> //] => a b /=; simpc; first by rewrite subrr.
-by rewrite !mulr0 !mul0r addr0 subr0.
-Qed.
-
-Canonical real_complex_rmorphism :=
- RMorphism real_complex_is_rmorphism.
-Canonical real_complex_additive :=
- Additive real_complex_is_rmorphism.
-
-Lemma Re_is_scalar : scalar (@Re R).
-Proof. by move=> a [b c] [d e]. Qed.
-
-Canonical Re_additive := Additive Re_is_scalar.
-Canonical Re_linear := Linear Re_is_scalar.
-
-Lemma Im_is_scalar : scalar (@Im R).
-Proof. by move=> a [b c] [d e]. Qed.
-
-Canonical Im_additive := Additive Im_is_scalar.
-Canonical Im_linear := Linear Im_is_scalar.
-
-Definition lec (x y : R[i]) :=
- let: a +i* b := x in let: c +i* d := y in
- (d == b) && (a <= c).
-
-Definition ltc (x y : R[i]) :=
- let: a +i* b := x in let: c +i* d := y in
- (d == b) && (a < c).
-
-Definition normc (x : R[i]) : R :=
- let: a +i* b := x in sqrtr (a ^+ 2 + b ^+ 2).
-
-Notation normC x := (normc x)%:C.
-
-Lemma ltc0_add : forall x y, ltc 0 x -> ltc 0 y -> ltc 0 (x + y).
-Proof.
-move=> [a b] [c d] /= /andP [/eqP-> ha] /andP [/eqP-> hc].
-by rewrite addr0 eqxx addr_gt0.
-Qed.
-
-Lemma eq0_normc x : normc x = 0 -> x = 0.
-Proof.
-case: x => a b /= /eqP; rewrite sqrtr_eq0 ler_eqVlt => /orP [|]; last first.
- by rewrite ltrNge addr_ge0 ?sqr_ge0.
-by rewrite paddr_eq0 ?sqr_ge0 ?expf_eq0 //= => /andP[/eqP -> /eqP ->].
-Qed.
-
-Lemma eq0_normC x : normC x = 0 -> x = 0. Proof. by case=> /eq0_normc. Qed.
-
-Lemma ge0_lec_total x y : lec 0 x -> lec 0 y -> lec x y || lec y x.
-Proof.
-move: x y => [a b] [c d] /= /andP[/eqP -> a_ge0] /andP[/eqP -> c_ge0].
-by rewrite eqxx ler_total.
-Qed.
-
-Lemma normcM x y : normc (x * y) = normc x * normc y.
-Proof.
-move: x y => [a b] [c d] /=; rewrite -sqrtrM ?addr_ge0 ?sqr_ge0 //.
-rewrite sqrrB sqrrD mulrDl !mulrDr -!exprMn.
-rewrite mulrAC [b * d]mulrC !mulrA.
-suff -> : forall (u v w z t : R), (u - v + w) + (z + v + t) = u + w + (z + t).
- by rewrite addrAC !addrA.
-by move=> u v w z t; rewrite [_ - _ + _]addrAC [z + v]addrC !addrA addrNK.
-Qed.
-
-Lemma normCM x y : normC (x * y) = normC x * normC y.
-Proof. by rewrite -rmorphM normcM. Qed.
-
-Lemma subc_ge0 x y : lec 0 (y - x) = lec x y.
-Proof. by move: x y => [a b] [c d] /=; simpc; rewrite subr_ge0 subr_eq0. Qed.
-
-Lemma lec_def x y : lec x y = (normC (y - x) == y - x).
-Proof.
-rewrite -subc_ge0; move: (_ - _) => [a b]; rewrite eq_complex /= eq_sym.
-have [<- /=|_] := altP eqP; last by rewrite andbF.
-by rewrite [0 ^+ _]mul0r addr0 andbT sqrtr_sqr ger0_def.
-Qed.
-
-Lemma ltc_def x y : ltc x y = (y != x) && lec x y.
-Proof.
-move: x y => [a b] [c d] /=; simpc; rewrite eq_complex /=.
-by have [] := altP eqP; rewrite ?(andbF, andbT) //= ltr_def.
-Qed.
-
-Lemma lec_normD x y : lec (normC (x + y)) (normC x + normC y).
-Proof.
-move: x y => [a b] [c d] /=; simpc; rewrite addr0 eqxx /=.
-rewrite -(@ler_pexpn2r _ 2) -?topredE /= ?(ler_paddr, sqrtr_ge0) //.
-rewrite [X in _ <= X] sqrrD ?sqr_sqrtr;
- do ?by rewrite ?(ler_paddr, sqrtr_ge0, sqr_ge0, mulr_ge0) //.
-rewrite -addrA addrCA (monoRL (addrNK _) (ler_add2r _)) !sqrrD.
-set u := _ *+ 2; set v := _ *+ 2.
-rewrite [a ^+ _ + _ + _]addrAC [b ^+ _ + _ + _]addrAC -addrA.
-rewrite [u + _] addrC [X in _ - X]addrAC [b ^+ _ + _]addrC.
-rewrite [u]lock [v]lock !addrA; set x := (a ^+ 2 + _ + _ + _).
-rewrite -addrA addrC addKr -!lock addrC.
-have [huv|] := ger0P (u + v); last first.
- by move=> /ltrW /ler_trans -> //; rewrite pmulrn_lge0 // mulr_ge0 ?sqrtr_ge0.
-rewrite -(@ler_pexpn2r _ 2) -?topredE //=; last first.
- by rewrite ?(pmulrn_lge0, mulr_ge0, sqrtr_ge0) //.
-rewrite -mulr_natl !exprMn !sqr_sqrtr ?(ler_paddr, sqr_ge0) //.
-rewrite -mulrnDl -mulr_natl !exprMn ler_pmul2l ?exprn_gt0 ?ltr0n //.
-rewrite sqrrD mulrDl !mulrDr -!exprMn addrAC -!addrA ler_add2l !addrA.
-rewrite [_ + (b * d) ^+ 2]addrC -addrA ler_add2l.
-have: 0 <= (a * d - b * c) ^+ 2 by rewrite sqr_ge0.
-by rewrite sqrrB addrAC subr_ge0 [_ * c]mulrC mulrACA [d * _]mulrC.
-Qed.
-
-Definition complex_numMixin := NumMixin lec_normD ltc0_add eq0_normC
- ge0_lec_total normCM lec_def ltc_def.
-Canonical complex_numDomainType := NumDomainType R[i] complex_numMixin.
-
-End ComplexField.
-End ComplexField.
-
-Canonical ComplexField.complex_zmodType.
-Canonical ComplexField.complex_lmodType.
-Canonical ComplexField.complex_ringType.
-Canonical ComplexField.complex_comRingType.
-Canonical ComplexField.complex_unitRingType.
-Canonical ComplexField.complex_comUnitRingType.
-Canonical ComplexField.complex_idomainType.
-Canonical ComplexField.complex_fieldType.
-Canonical ComplexField.complex_numDomainType.
-Canonical complex_numFieldType (R : rcfType) := [numFieldType of complex R].
-Canonical ComplexField.real_complex_rmorphism.
-Canonical ComplexField.real_complex_additive.
-Canonical ComplexField.Re_additive.
-Canonical ComplexField.Im_additive.
-
-Definition conjc {R : ringType} (x : R[i]) := let: a +i* b := x in a -i* b.
-Notation "x ^*" := (conjc x) (at level 2, format "x ^*") : complex_scope.
-Local Open Scope complex_scope.
-Delimit Scope complex_scope with C.
-
-Ltac simpc := do ?
- [ rewrite -[- (_ +i* _)%C]/(_ +i* _)%C
- | rewrite -[(_ +i* _)%C - (_ +i* _)%C]/(_ +i* _)%C
- | rewrite -[(_ +i* _)%C + (_ +i* _)%C]/(_ +i* _)%C
- | rewrite -[(_ +i* _)%C * (_ +i* _)%C]/(_ +i* _)%C
- | rewrite -[(_ +i* _)%C ^*]/(_ +i* _)%C
- | rewrite -[_ *: (_ +i* _)%C]/(_ +i* _)%C
- | rewrite -[(_ +i* _)%C <= (_ +i* _)%C]/((_ == _) && (_ <= _))
- | rewrite -[(_ +i* _)%C < (_ +i* _)%C]/((_ == _) && (_ < _))
- | rewrite -[`|(_ +i* _)%C|]/(sqrtr (_ + _))%:C%C
- | rewrite (mulrNN, mulrN, mulNr, opprB, opprD, mulr0, mul0r,
- subr0, sub0r, addr0, add0r, mulr1, mul1r, subrr, opprK, oppr0,
- eqxx) ].
-
-
-Section ComplexTheory.
-
-Variable R : rcfType.
-
-Lemma ReiNIm : forall x : R[i], Re (x * 'i%C) = - Im x.
-Proof. by case=> a b; simpc. Qed.
-
-Lemma ImiRe : forall x : R[i], Im (x * 'i%C) = Re x.
-Proof. by case=> a b; simpc. Qed.
-
-Lemma complexE x : x = (Re x)%:C + 'i%C * (Im x)%:C :> R[i].
-Proof. by case: x => *; simpc. Qed.
-
-Lemma real_complexE x : x%:C = x +i* 0 :> R[i]. Proof. done. Qed.
-
-Lemma sqr_i : 'i%C ^+ 2 = -1 :> R[i].
-Proof. by rewrite exprS; simpc; rewrite -real_complexE rmorphN. Qed.
-
-Lemma complexI : injective (real_complex R). Proof. by move=> x y []. Qed.
-
-Lemma ler0c (x : R) : (0 <= x%:C) = (0 <= x). Proof. by simpc. Qed.
-
-Lemma lecE : forall x y : R[i], (x <= y) = (Im y == Im x) && (Re x <= Re y).
-Proof. by move=> [a b] [c d]. Qed.
-
-Lemma ltcE : forall x y : R[i], (x < y) = (Im y == Im x) && (Re x < Re y).
-Proof. by move=> [a b] [c d]. Qed.
-
-Lemma lecR : forall x y : R, (x%:C <= y%:C) = (x <= y).
-Proof. by move=> x y; simpc. Qed.
-
-Lemma ltcR : forall x y : R, (x%:C < y%:C) = (x < y).
-Proof. by move=> x y; simpc. Qed.
-
-Lemma conjc_is_rmorphism : rmorphism (@conjc R).
-Proof.
-split=> [[a b] [c d]|] /=; first by simpc; rewrite [d - _]addrC.
-by split=> [[a b] [c d]|] /=; simpc.
-Qed.
-
-Lemma conjc_is_scalable : scalable (@conjc R).
-Proof. by move=> a [b c]; simpc. Qed.
-
-Canonical conjc_rmorphism := RMorphism conjc_is_rmorphism.
-Canonical conjc_additive := Additive conjc_is_rmorphism.
-Canonical conjc_linear := AddLinear conjc_is_scalable.
-
-Lemma conjcK : involutive (@conjc R).
-Proof. by move=> [a b] /=; rewrite opprK. Qed.
-
-Lemma mulcJ_ge0 (x : R[i]) : 0 <= x * x^*%C.
-Proof.
-by move: x=> [a b]; simpc; rewrite mulrC addNr eqxx addr_ge0 ?sqr_ge0.
-Qed.
-
-Lemma conjc_real (x : R) : x%:C^* = x%:C.
-Proof. by rewrite /= oppr0. Qed.
-
-Lemma ReJ_add (x : R[i]) : (Re x)%:C = (x + x^*%C) / 2%:R.
-Proof.
-case: x => a b; simpc; rewrite [0 ^+ 2]mul0r addr0 /=.
-rewrite -!mulr2n -mulr_natr -mulrA [_ * (_ / _)]mulrA.
-by rewrite divff ?mulr1 // -natrM pnatr_eq0.
-Qed.
-
-Lemma ImJ_sub (x : R[i]) : (Im x)%:C = (x^*%C - x) / 2%:R * 'i%C.
-Proof.
-case: x => a b; simpc; rewrite [0 ^+ 2]mul0r addr0 /=.
-rewrite -!mulr2n -mulr_natr -mulrA [_ * (_ / _)]mulrA.
-by rewrite divff ?mulr1 ?opprK // -natrM pnatr_eq0.
-Qed.
-
-Lemma ger0_Im (x : R[i]) : 0 <= x -> Im x = 0.
-Proof. by move: x=> [a b] /=; simpc => /andP [/eqP]. Qed.
-
-(* Todo : extend theory of : *)
-(* - signed exponents *)
-
-Lemma conj_ge0 : forall x : R[i], (0 <= x ^*) = (0 <= x).
-Proof. by move=> [a b] /=; simpc; rewrite oppr_eq0. Qed.
-
-Lemma conjc_nat : forall n, (n%:R : R[i])^* = n%:R.
-Proof. exact: rmorph_nat. Qed.
-
-Lemma conjc0 : (0 : R[i]) ^* = 0.
-Proof. exact: (conjc_nat 0). Qed.
-
-Lemma conjc1 : (1 : R[i]) ^* = 1.
-Proof. exact: (conjc_nat 1). Qed.
-
-Lemma conjc_eq0 : forall x : R[i], (x ^* == 0) = (x == 0).
-Proof. by move=> [a b]; rewrite !eq_complex /= eqr_oppLR oppr0. Qed.
-
-Lemma conjc_inv: forall x : R[i], (x^-1)^* = (x^*%C )^-1.
-Proof. exact: fmorphV. Qed.
-
-Lemma complex_root_conj (p : {poly R[i]}) (x : R[i]) :
- root (map_poly conjc p) x = root p x^*.
-Proof. by rewrite /root -{1}[x]conjcK horner_map /= conjc_eq0. Qed.
-
-Lemma complex_algebraic_trans (T : comRingType) (toR : {rmorphism T -> R}) :
- integralRange toR -> integralRange (real_complex R \o toR).
-Proof.
-set f := _ \o _ => R_integral [a b].
-have integral_real x : integralOver f (x%:C) by apply: integral_rmorph.
-rewrite [_ +i* _]complexE.
-apply: integral_add => //; apply: integral_mul => //=.
-exists ('X^2 + 1).
- by rewrite monicE lead_coefDl ?size_polyXn ?size_poly1 ?lead_coefXn.
-by rewrite rmorphD rmorph1 /= ?map_polyXn rootE !hornerE -expr2 sqr_i addNr.
-Qed.
-
-Lemma normc_def (z : R[i]) : `|z| = (sqrtr ((Re z)^+2 + (Im z)^+2))%:C.
-Proof. by case: z. Qed.
-
-Lemma add_Re2_Im2 (z : R[i]) : ((Re z)^+2 + (Im z)^+2)%:C = `|z|^+2.
-Proof. by rewrite normc_def -rmorphX sqr_sqrtr ?addr_ge0 ?sqr_ge0. Qed.
-
-Lemma addcJ (z : R[i]) : z + z^*%C = 2%:R * (Re z)%:C.
-Proof. by rewrite ReJ_add mulrC mulfVK ?pnatr_eq0. Qed.
-
-Lemma subcJ (z : R[i]) : z - z^*%C = 2%:R * (Im z)%:C * 'i%C.
-Proof.
-rewrite ImJ_sub mulrCA mulrA mulfVK ?pnatr_eq0 //.
-by rewrite -mulrA ['i%C * _]sqr_i mulrN1 opprB.
-Qed.
-
-Lemma complex_real (a b : R) : a +i* b \is Num.real = (b == 0).
-Proof.
-rewrite realE; simpc; rewrite [0 == _]eq_sym.
-by have [] := ltrgtP 0 a; rewrite ?(andbF, andbT, orbF, orbb).
-Qed.
-
-Lemma complex_realP (x : R[i]) : reflect (exists y, x = y%:C) (x \is Num.real).
-Proof.
-case: x=> [a b] /=; rewrite complex_real.
-by apply: (iffP eqP) => [->|[c []//]]; exists a.
-Qed.
-
-Lemma RRe_real (x : R[i]) : x \is Num.real -> (Re x)%:C = x.
-Proof. by move=> /complex_realP [y ->]. Qed.
-
-Lemma RIm_real (x : R[i]) : x \is Num.real -> (Im x)%:C = 0.
-Proof. by move=> /complex_realP [y ->]. Qed.
-
-End ComplexTheory.
-
-(* Section RcfDef. *)
-
-(* Variable R : realFieldType. *)
-(* Notation C := (complex R). *)
-
-(* Definition rcf_odd := forall (p : {poly R}), *)
-(* ~~odd (size p) -> {x | p.[x] = 0}. *)
-(* Definition rcf_square := forall x : R, *)
-(* {y | (0 <= y) && if 0 <= x then (y ^ 2 == x) else y == 0}. *)
-
-(* Lemma rcf_odd_sqr_from_ivt : rcf_axiom R -> rcf_odd * rcf_square. *)
-(* Proof. *)
-(* move=> ivt. *)
-(* split. *)
-(* move=> p sp. *)
-(* move: (ivt p). *)
-(* admit. *)
-(* move=> x. *)
-(* case: (boolP (0 <= x)) (@ivt ('X^2 - x%:P) 0 (1 + x))=> px; last first. *)
-(* by move=> _; exists 0; rewrite lerr eqxx. *)
-(* case. *)
-(* * by rewrite ler_paddr ?ler01. *)
-(* * rewrite !horner_lin oppr_le0 px /=. *)
-(* rewrite subr_ge0 (@ler_trans _ (1 + x)) //. *)
-(* by rewrite ler_paddl ?ler01 ?lerr. *)
-(* by rewrite ler_pemulr // addrC -subr_ge0 ?addrK // subr0 ler_paddl ?ler01. *)
-(* * move=> y hy; rewrite /root !horner_lin; move/eqP. *)
-(* move/(canRL (@addrNK _ _)); rewrite add0r=> <-. *)
-(* by exists y; case/andP: hy=> -> _; rewrite eqxx. *)
-(* Qed. *)
-
-(* Lemma ivt_from_closed : GRing.ClosedField.axiom [ringType of C] -> rcf_axiom R. *)
-(* Proof. *)
-(* rewrite /GRing.ClosedField.axiom /= => hclosed. *)
-(* move=> p a b hab. *)
-(* Admitted. *)
-
-(* Lemma closed_form_rcf_odd_sqr : rcf_odd -> rcf_square *)
-(* -> GRing.ClosedField.axiom [ringType of C]. *)
-(* Proof. *)
-(* Admitted. *)
-
-(* Lemma closed_form_ivt : rcf_axiom R -> GRing.ClosedField.axiom [ringType of C]. *)
-(* Proof. *)
-(* move/rcf_odd_sqr_from_ivt; case. *)
-(* exact: closed_form_rcf_odd_sqr. *)
-(* Qed. *)
-
-(* End RcfDef. *)
-
-Section ComplexClosed.
-
-Variable R : rcfType.
-
-Definition sqrtc (x : R[i]) : R[i] :=
- let: a +i* b := x in
- let sgr1 b := if b == 0 then 1 else sgr b in
- let r := sqrtr (a^+2 + b^+2) in
- (sqrtr ((r + a)/2%:R)) +i* (sgr1 b * sqrtr ((r - a)/2%:R)).
-
-Lemma sqr_sqrtc : forall x, (sqrtc x) ^+ 2 = x.
-Proof.
-have sqr: forall x : R, x ^+ 2 = x * x.
- by move=> x; rewrite exprS expr1.
-case=> a b; rewrite exprS expr1; simpc.
-have F0: 2%:R != 0 :> R by rewrite pnatr_eq0.
-have F1: 0 <= 2%:R^-1 :> R by rewrite invr_ge0 ler0n.
-have F2: `|a| <= sqrtr (a^+2 + b^+2).
- rewrite -sqrtr_sqr ler_wsqrtr //.
- by rewrite addrC -subr_ge0 addrK exprn_even_ge0.
-have F3: 0 <= (sqrtr (a ^+ 2 + b ^+ 2) - a) / 2%:R.
- rewrite mulr_ge0 // subr_ge0 (ler_trans _ F2) //.
- by rewrite -(maxrN a) ler_maxr lerr.
-have F4: 0 <= (sqrtr (a ^+ 2 + b ^+ 2) + a) / 2%:R.
- rewrite mulr_ge0 // -{2}[a]opprK subr_ge0 (ler_trans _ F2) //.
- by rewrite -(maxrN a) ler_maxr lerr orbT.
-congr (_ +i* _); set u := if _ then _ else _.
- rewrite mulrCA !mulrA.
- have->: (u * u) = 1.
- rewrite /u; case: (altP (_ =P _)); rewrite ?mul1r //.
- by rewrite -expr2 sqr_sg => ->.
- rewrite mul1r -!sqr !sqr_sqrtr //.
- rewrite [_+a]addrC -mulrBl opprD addrA addrK.
- by rewrite opprK -mulr2n -mulr_natl [_*a]mulrC mulfK.
-rewrite mulrCA -mulrA -mulrDr [sqrtr _ * _]mulrC.
-rewrite -mulr2n -sqrtrM // mulrAC !mulrA ?[_ * (_ - _)]mulrC -subr_sqr.
-rewrite sqr_sqrtr; last first.
- by rewrite ler_paddr // exprn_even_ge0.
-rewrite [_^+2 + _]addrC addrK -mulrA -expr2 sqrtrM ?exprn_even_ge0 //.
-rewrite !sqrtr_sqr -mulr_natr.
-rewrite [`|_^-1|]ger0_norm // -mulrA [_ * _%:R]mulrC divff //.
-rewrite mulr1 /u; case: (_ =P _)=>[->|].
- by rewrite normr0 mulr0.
-by rewrite mulr_sg_norm.
-Qed.
-
-Lemma sqrtc_sqrtr :
- forall (x : R[i]), 0 <= x -> sqrtc x = (sqrtr (Re x))%:C.
-Proof.
-move=> [a b] /andP [/eqP->] /= a_ge0.
-rewrite eqxx mul1r [0 ^+ _]exprS mul0r addr0 sqrtr_sqr.
-rewrite ger0_norm // subrr mul0r sqrtr0 -mulr2n.
-by rewrite -[_*+2]mulr_natr mulfK // pnatr_eq0.
-Qed.
-
-Lemma sqrtc0 : sqrtc 0 = 0.
-Proof. by rewrite sqrtc_sqrtr ?lerr // sqrtr0. Qed.
-
-Lemma sqrtc1 : sqrtc 1 = 1.
-Proof. by rewrite sqrtc_sqrtr ?ler01 // sqrtr1. Qed.
-
-Lemma sqrtN1 : sqrtc (-1) = 'i.
-Proof.
-rewrite /sqrtc /= oppr0 eqxx [0^+_]exprS mulr0 addr0.
-rewrite exprS expr1 mulN1r opprK sqrtr1 subrr mul0r sqrtr0.
-by rewrite mul1r -mulr2n divff ?sqrtr1 // pnatr_eq0.
-Qed.
-
-Lemma sqrtc_ge0 (x : R[i]) : (0 <= sqrtc x) = (0 <= x).
-Proof.
-apply/idP/idP=> [psx|px]; last first.
- by rewrite sqrtc_sqrtr // lecR sqrtr_ge0.
-by rewrite -[x]sqr_sqrtc exprS expr1 mulr_ge0.
-Qed.
-
-Lemma sqrtc_eq0 (x : R[i]) : (sqrtc x == 0) = (x == 0).
-Proof.
-apply/eqP/eqP=> [eqs|->]; last by rewrite sqrtc0.
-by rewrite -[x]sqr_sqrtc eqs exprS mul0r.
-Qed.
-
-Lemma normcE x : `|x| = sqrtc (x * x^*%C).
-Proof.
-case: x=> a b; simpc; rewrite [b * a]mulrC addNr sqrtc_sqrtr //.
-by simpc; rewrite /= addr_ge0 ?sqr_ge0.
-Qed.
-
-Lemma sqr_normc (x : R[i]) : (`|x| ^+ 2) = x * x^*%C.
-Proof. by rewrite normcE sqr_sqrtc. Qed.
-
-Lemma normc_ge_Re (x : R[i]) : `|Re x|%:C <= `|x|.
-Proof.
-by case: x => a b; simpc; rewrite -sqrtr_sqr ler_wsqrtr // ler_addl sqr_ge0.
-Qed.
-
-Lemma normcJ (x : R[i]) : `|x^*%C| = `|x|.
-Proof. by case: x => a b; simpc; rewrite /= sqrrN. Qed.
-
-Lemma invc_norm (x : R[i]) : x^-1 = `|x|^-2 * x^*%C.
-Proof.
-case: (altP (x =P 0)) => [->|dx]; first by rewrite rmorph0 mulr0 invr0.
-apply: (mulIf dx); rewrite mulrC divff // -mulrA [_^*%C * _]mulrC -(sqr_normc x).
-by rewrite mulVf // expf_neq0 ?normr_eq0.
-Qed.
-
-Lemma canonical_form (a b c : R[i]) :
- a != 0 ->
- let d := b ^+ 2 - 4%:R * a * c in
- let r1 := (- b - sqrtc d) / 2%:R / a in
- let r2 := (- b + sqrtc d) / 2%:R / a in
- a *: 'X^2 + b *: 'X + c%:P = a *: (('X - r1%:P) * ('X - r2%:P)).
-Proof.
-move=> a_neq0 d r1 r2.
-rewrite !(mulrDr, mulrDl, mulNr, mulrN, opprK, scalerDr).
-rewrite [_ * _%:P]mulrC !mul_polyC !scalerN !scalerA -!addrA; congr (_ + _).
-rewrite addrA; congr (_ + _).
- rewrite -opprD -scalerDl -scaleNr; congr(_ *: _).
- rewrite ![a * _]mulrC !divfK // !mulrDl addrACA !mulNr addNr addr0.
- by rewrite -opprD opprK -mulrDr -mulr2n -mulr_natl divff ?mulr1 ?pnatr_eq0.
-symmetry; rewrite -!alg_polyC scalerA; congr (_%:A).
-rewrite [a * _]mulrC divfK // /r2 mulrA mulrACA -invfM -natrM -subr_sqr.
-rewrite sqr_sqrtc sqrrN /d opprB addrC addrNK -2!mulrA.
-by rewrite mulrACA -natf_div // mul1r mulrAC divff ?mul1r.
-Qed.
-
-Lemma monic_canonical_form (b c : R[i]) :
- let d := b ^+ 2 - 4%:R * c in
- let r1 := (- b - sqrtc d) / 2%:R in
- let r2 := (- b + sqrtc d) / 2%:R in
- 'X^2 + b *: 'X + c%:P = (('X - r1%:P) * ('X - r2%:P)).
-Proof.
-by rewrite /= -['X^2]scale1r canonical_form ?oner_eq0 // scale1r mulr1 !divr1.
-Qed.
-
-Section extramx.
-(* missing lemmas from matrix.v or mxalgebra.v *)
-
-Lemma mul_mx_rowfree_eq0 (K : fieldType) (m n p: nat)
- (W : 'M[K]_(m,n)) (V : 'M[K]_(n,p)) :
- row_free V -> (W *m V == 0) = (W == 0).
-Proof. by move=> free; rewrite -!mxrank_eq0 mxrankMfree ?mxrank_eq0. Qed.
-
-Lemma sub_sums_genmxP (F : fieldType) (I : finType) (P : pred I) (m n : nat)
- (A : 'M[F]_(m, n)) (B_ : I -> 'M_(m, n)) :
-reflect (exists u_ : I -> 'M_m, A = \sum_(i | P i) u_ i *m B_ i)
- (A <= \sum_(i | P i) <<B_ i>>)%MS.
-Proof.
-apply: (iffP idP); last first.
- by move=> [u_ ->]; rewrite summx_sub_sums // => i _; rewrite genmxE submxMl.
-move=> /sub_sumsmxP [u_ hA].
-have Hu i : exists v, u_ i *m <<B_ i>>%MS = v *m B_ i.
- by apply/submxP; rewrite (submx_trans (submxMl _ _)) ?genmxE.
-exists (fun i => projT1 (sig_eqW (Hu i))); rewrite hA.
-by apply: eq_bigr => i /= P_i; case: sig_eqW.
-Qed.
-
-Lemma mulmxP (K : fieldType) (m n : nat) (A B : 'M[K]_(m, n)) :
- reflect (forall u : 'rV__, u *m A = u *m B) (A == B).
-Proof.
-apply: (iffP eqP) => [-> //|eqAB].
-apply: (@row_full_inj _ _ _ _ 1%:M); first by rewrite row_full_unit unitmx1.
-by apply/row_matrixP => i; rewrite !row_mul eqAB.
-Qed.
-
-Section Skew.
-
-Variable (K : numFieldType).
-
-Implicit Types (phK : phant K) (n : nat).
-
-Definition skew_vec n i j : 'rV[K]_(n * n) :=
- (mxvec ((delta_mx i j)) - (mxvec (delta_mx j i))).
-
-Definition skew_def phK n : 'M[K]_(n * n) :=
- (\sum_(i | ((i.2 : 'I__) < (i.1 : 'I__))%N) <<skew_vec i.1 i.2>>)%MS.
-
-Variable (n : nat).
-Local Notation skew := (@skew_def (Phant K) n).
-
-
-Lemma skew_direct_sum : mxdirect skew.
-Proof.
-apply/mxdirect_sumsE => /=; split => [i _|]; first exact: mxdirect_trivial.
-apply/mxdirect_sumsP => [] [i j] /= lt_ij; apply/eqP; rewrite -submx0.
-apply/rV_subP => v; rewrite sub_capmx => /andP []; rewrite !genmxE.
-move=> /submxP [w ->] /sub_sums_genmxP [/= u_].
-move/matrixP => /(_ 0 (mxvec_index i j)); rewrite !mxE /= big_ord1.
-rewrite /skew_vec /= !mxvec_delta !mxE !eqxx /=.
-have /(_ _ _ (_, _) (_, _)) /= eq_mviE :=
- inj_eq (bij_inj (onT_bij (curry_mxvec_bij _ _))).
-rewrite eq_mviE xpair_eqE -!val_eqE /= eq_sym andbb.
-rewrite ltn_eqF // subr0 mulr1 summxE big1.
- rewrite [w as X in X *m _]mx11_scalar => ->.
- by rewrite mul_scalar_mx scale0r submx0.
-move=> [i' j'] /= /andP[lt_j'i'].
-rewrite xpair_eqE /= => neq'_ij.
-rewrite /= !mxvec_delta !mxE big_ord1 !mxE !eqxx !eq_mviE.
-rewrite !xpair_eqE /= [_ == i']eq_sym [_ == j']eq_sym (negPf neq'_ij) /=.
-set z := (_ && _); suff /negPf -> : ~~ z by rewrite subrr mulr0.
-by apply: contraL lt_j'i' => /andP [/eqP <- /eqP <-]; rewrite ltnNge ltnW.
-Qed.
-Hint Resolve skew_direct_sum.
-
-Lemma rank_skew : \rank skew = (n * n.-1)./2.
-Proof.
-rewrite /skew (mxdirectP _) //= -bin2 -triangular_sum big_mkord.
-rewrite (eq_bigr (fun _ => 1%N)); last first.
- move=> [i j] /= lt_ij; rewrite genmxE.
- apply/eqP; rewrite eqn_leq rank_leq_row /= lt0n mxrank_eq0.
- rewrite /skew_vec /= !mxvec_delta /= subr_eq0.
- set j1 := mxvec_index _ _.
- apply/negP => /eqP /matrixP /(_ 0 j1) /=; rewrite !mxE eqxx /=.
- have /(_ _ _ (_, _) (_, _)) -> :=
- inj_eq (bij_inj (onT_bij (curry_mxvec_bij _ _))).
- rewrite xpair_eqE -!val_eqE /= eq_sym andbb ltn_eqF //.
- by move/eqP; rewrite oner_eq0.
-transitivity (\sum_(i < n) (\sum_(j < n | j < i) 1))%N.
- by rewrite pair_big_dep.
-apply: eq_bigr => [] [[|i] Hi] _ /=; first by rewrite big1.
-rewrite (eq_bigl _ _ (fun _ => ltnS _ _)).
-have [n_eq0|n_gt0] := posnP n; first by move: Hi (Hi); rewrite {1}n_eq0.
-rewrite -[n]prednK // big_ord_narrow_leq /=.
- by rewrite -ltnS prednK // (leq_trans _ Hi).
-by rewrite sum_nat_const card_ord muln1.
-Qed.
-
-Lemma skewP (M : 'rV_(n * n)) :
- reflect ((vec_mx M)^T = - vec_mx M) (M <= skew)%MS.
-Proof.
-apply: (iffP idP).
- move/sub_sumsmxP => [v ->]; rewrite !linear_sum /=.
- apply: eq_bigr => [] [i j] /= lt_ij; rewrite !mulmx_sum_row !linear_sum /=.
- apply: eq_bigr => k _; rewrite !linearZ /=; congr (_ *: _) => {v}.
- set r := << _ >>%MS; move: (row _ _) (row_sub k r) => v.
- move: @r; rewrite /= genmxE => /sub_rVP [a ->]; rewrite !linearZ /=.
- by rewrite /skew_vec !linearB /= !mxvecK !scalerN opprK addrC !trmx_delta.
-move=> skewM; pose M' := vec_mx M.
-pose xM i j := (M' i j - M' j i) *: skew_vec i j.
-suff -> : M = 2%:R^-1 *:
- (\sum_(i | true && ((i.2 : 'I__) < (i.1 : 'I__))%N) xM i.1 i.2).
- rewrite scalemx_sub // summx_sub_sums // => [] [i j] /= lt_ij.
- by rewrite scalemx_sub // genmxE.
-rewrite /xM /= /skew_vec (eq_bigr _ (fun _ _ => scalerBr _ _ _)).
-rewrite big_split /= sumrN !(eq_bigr _ (fun _ _ => scalerBl _ _ _)).
-rewrite !big_split /= !sumrN opprD ?opprK addrACA [- _ + _]addrC.
-rewrite -!sumrN -2!big_split /=.
-rewrite /xM /= /skew_vec -!(eq_bigr _ (fun _ _ => scalerBr _ _ _)).
-apply: (can_inj vec_mxK); rewrite !(linearZ, linearB, linearD, linear_sum) /=.
-have -> /= : vec_mx M = 2%:R^-1 *: (M' - M'^T).
- by rewrite skewM opprK -mulr2n -scaler_nat scalerA mulVf ?pnatr_eq0 ?scale1r.
-rewrite {1 2}[M']matrix_sum_delta; congr (_ *: _).
-rewrite pair_big /= !linear_sum /= -big_split /=.
-rewrite (bigID (fun ij => (ij.2 : 'I__) < (ij.1 : 'I__))%N) /=; congr (_ + _).
- apply: eq_bigr => [] [i j] /= lt_ij.
- by rewrite !linearZ linearB /= ?mxvecK trmx_delta scalerN scalerBr.
-rewrite (bigID (fun ij => (ij.1 : 'I__) == (ij.2 : 'I__))%N) /=.
-rewrite big1 ?add0r; last first.
- by move=> [i j] /= /andP[_ /eqP ->]; rewrite linearZ /= trmx_delta subrr.
-rewrite (@reindex_inj _ _ _ _ (fun ij => (ij.2, ij.1))) /=; last first.
- by move=> [? ?] [? ?] [] -> ->.
-apply: eq_big => [] [i j] /=; first by rewrite -leqNgt ltn_neqAle andbC.
-by rewrite !linearZ linearB /= ?mxvecK trmx_delta scalerN scalerBr.
-Qed.
-
-End Skew.
-
-Notation skew K n := (@skew_def _ (Phant K) n).
-
-Section Companion.
-
-Variable (K : fieldType).
-
-Lemma companion_subproof (p : {poly K}) :
- {M : 'M[K]_((size p).-1)| p \is monic -> char_poly M = p}.
-Proof.
-have simp := (castmxE, mxE, castmx_id, cast_ord_id).
-case Hsp: (size p) => [|sp] /=.
- move/eqP: Hsp; rewrite size_poly_eq0 => /eqP ->.
- by exists 0; rewrite qualifE lead_coef0 eq_sym oner_eq0.
-case: sp => [|sp] in Hsp *.
- move: Hsp => /eqP/size_poly1P/sig2_eqW [c c_neq0 ->].
- by exists ((-c)%:M); rewrite monicE lead_coefC => /eqP ->; apply: det_mx00.
-have addn1n n : (n + 1 = 1 + n)%N by rewrite addn1.
-exists (castmx (erefl _, addn1n _)
- (block_mx (\row_(i < sp) - p`_(sp - i)) (-p`_0)%:M
- 1%:M 0)).
-elim/poly_ind: p sp Hsp (addn1n _) => [|p c IHp] sp; first by rewrite size_poly0.
-rewrite size_MXaddC.
-have [->|p_neq0] //= := altP eqP; first by rewrite size_poly0; case: ifP.
-move=> [Hsp] eq_cast.
-rewrite monicE lead_coefDl ?size_polyC ?size_mul ?polyX_eq0 //; last first.
- by rewrite size_polyX addn2 Hsp ltnS (leq_trans (leq_b1 _)).
-rewrite lead_coefMX -monicE => p_monic.
-rewrite -/_`_0 coefD coefMX coefC eqxx add0r.
-case: sp => [|sp] in Hsp p_neq0 p_monic eq_cast *.
- move: Hsp p_monic => /eqP/size_poly1P [l l_neq0 ->].
- rewrite monicE lead_coefC => /eqP ->; rewrite mul1r.
- rewrite /char_poly /char_poly_mx thinmx0 flatmx0 castmx_id.
- set b := (block_mx _ _ _ _); rewrite [map_mx _ b]map_block_mx => {b}.
- rewrite !map_mx0 map_scalar_mx (@opp_block_mx _ 1 0 0 1) !oppr0.
- set b := block_mx _ _ _ _; rewrite (_ : b = c%:P%:M); last first.
- apply/matrixP => i j; rewrite !mxE; case: splitP => k /= Hk; last first.
- by move: (ltn_ord i); rewrite Hk.
- rewrite !ord1 !mxE; case: splitP => {k Hk} k /= Hk; first by move: (ltn_ord k).
- by rewrite ord1 !mxE mulr1n rmorphN opprK.
- by rewrite -rmorphD det_scalar.
-rewrite /char_poly /char_poly_mx (expand_det_col _ ord_max).
-rewrite big_ord_recr /= big_ord_recl //= big1 ?simp; last first.
- move=> i _; rewrite !simp.
- case: splitP => k /=; first by rewrite /bump leq0n ord1.
- rewrite /bump leq0n => [] [Hik]; rewrite !simp.
- case: splitP => l /=; first by move/eqP; rewrite gtn_eqF.
- rewrite !ord1 addn0 => _ {l}; rewrite !simp -!val_eqE /=.
- by rewrite /bump leq0n ltn_eqF ?ltnS ?add1n // mulr0n subrr mul0r.
-case: splitP => i //=; rewrite !ord1 !simp => _ {i}.
-case: splitP => i //=; first by move/eqP; rewrite gtn_eqF.
-rewrite ord1 !simp => {i}.
-case: splitP => i //=; rewrite ?ord1 ?simp // => /esym [eq_i_sp] _.
-case: splitP => j //=; first by move/eqP; rewrite gtn_eqF.
-rewrite ord1 !simp => {j} _.
-rewrite eqxx mulr0n ?mulr1n rmorphN ?opprK !add0r !addr0 subr0 /=.
-rewrite -[c%:P in X in _ = X]mulr1 addrC mulrC.
-rewrite /cofactor -signr_odd addnn odd_double expr0 mul1r /=.
-rewrite !linearB /= -!map_col' -!map_row'.
-congr (_ * 'X + c%:P * _).
- have coefE := (coefD, coefMX, coefC, eqxx, add0r, addr0).
- rewrite -[X in _ = X](IHp sp Hsp _ p_monic) /char_poly /char_poly_mx.
- congr (\det (_ - _)).
- apply/matrixP => k l; rewrite !simp -val_eqE /=;
- by rewrite /bump ![(sp < _)%N]ltnNge ?leq_ord.
- apply/matrixP => k l; rewrite !simp.
- case: splitP => k' /=; rewrite ?ord1 /bump ltnNge leq_ord add0n.
- case: splitP => [k'' /= |k'' -> //]; rewrite ord1 !simp => k_eq0 _.
- case: splitP => l' /=; rewrite ?ord1 /bump ltnNge leq_ord add0n !simp;
- last by move/eqP; rewrite ?addn0 ltn_eqF.
- move<-; case: splitP => l'' /=; rewrite ?ord1 ?addn0 !simp.
- by move<-; rewrite subSn ?leq_ord ?coefE.
- move->; rewrite eqxx mulr1n ?coefE subSn ?subrr //=.
- by rewrite !rmorphN ?subnn addr0.
- case: splitP => k'' /=; rewrite ?ord1 => -> // []; rewrite !simp.
- case: splitP => l' /=; rewrite /bump ltnNge leq_ord add0n !simp -?val_eqE /=;
- last by rewrite ord1 addn0 => /eqP; rewrite ltn_eqF.
- by case: splitP => l'' /= -> <- <-; rewrite !simp // ?ord1 ?addn0 ?ltn_eqF.
-move=> {IHp Hsp p_neq0 p_monic}; rewrite add0n; set s := _ ^+ _;
-apply: (@mulfI _ s); first by rewrite signr_eq0.
-rewrite mulrA -expr2 sqrr_sign mulr1 mul1r /s.
-pose fix D n : 'M[{poly K}]_n.+1 :=
- if n is n'.+1 then block_mx (-1 :'M_1) ('X *: pid_mx 1)
- 0 (D n') else -1.
-pose D' n : 'M[{poly K}]_n.+1 := \matrix_(i, j) ('X *+ (i.+1 == j) - (i == j)%:R).
-set M := (_ - _); have -> : M = D' sp.
- apply/matrixP => k l; rewrite !simp.
- case: splitP => k' /=; rewrite ?ord1 !simp // /bump leq0n add1n; case.
- case: splitP => l' /=; rewrite /bump ltnNge leq_ord add0n; last first.
- by move/eqP; rewrite ord1 addn0 ltn_eqF.
- rewrite !simp -!val_eqE /= /bump leq0n ltnNge leq_ord [(true + _)%N]add1n ?add0n.
- by move=> -> ->; rewrite polyC_muln.
-have -> n : D' n = D n.
- clear -simp; elim: n => [|n IHn] //=; apply/matrixP => i j; rewrite !simp.
- by rewrite !ord1 /= ?mulr0n sub0r.
- case: splitP => i' /=; rewrite -!val_eqE /= ?ord1 !simp => -> /=.
- case: splitP => j' /=; rewrite ?ord1 !simp => -> /=; first by rewrite sub0r.
- by rewrite eqSS andbT subr0 mulr_natr.
- by case: splitP => j' /=; rewrite ?ord1 -?IHn ?simp => -> //=; rewrite subr0.
-elim: sp {eq_cast i M eq_i_sp s} => [|n IHn].
- by rewrite /= (_ : -1 = (-1)%:M) ?det_scalar // rmorphN.
-rewrite /= (@det_ublock _ 1 n.+1) IHn.
-by rewrite (_ : -1 = (-1)%:M) ?det_scalar // rmorphN.
-Qed.
-
-Definition companion (p : {poly K}) : 'M[K]_((size p).-1) :=
- projT1 (companion_subproof p).
-
-Lemma companionK (p : {poly K}) : p \is monic -> char_poly (companion p) = p.
-Proof. exact: projT2 (companion_subproof _). Qed.
-
-End Companion.
-
-Section Restriction.
-
-Variable K : fieldType.
-Variable m : nat.
-Variables (V : 'M[K]_m).
-
-Implicit Types f : 'M[K]_m.
-
-Definition restrict f : 'M_(\rank V) := row_base V *m f *m (pinvmx (row_base V)).
-
-Lemma stable_row_base f :
- (row_base V *m f <= row_base V)%MS = (V *m f <= V)%MS.
-Proof.
-rewrite eq_row_base.
-by apply/idP/idP=> /(submx_trans _) ->; rewrite ?submxMr ?eq_row_base.
-Qed.
-
-Lemma eigenspace_restrict f : (V *m f <= V)%MS ->
- forall n a (W : 'M_(n, \rank V)),
- (W <= eigenspace (restrict f) a)%MS =
- (W *m row_base V <= eigenspace f a)%MS.
-Proof.
-move=> f_stabV n a W; apply/eigenspaceP/eigenspaceP; rewrite scalemxAl.
- by move<-; rewrite -mulmxA -[X in _ = X]mulmxA mulmxKpV ?stable_row_base.
-move/(congr1 (mulmx^~ (pinvmx (row_base V)))).
-rewrite -2!mulmxA [_ *m (f *m _)]mulmxA => ->.
-by apply: (row_free_inj (row_base_free V)); rewrite mulmxKpV ?submxMl.
-Qed.
-
-Lemma eigenvalue_restrict f : (V *m f <= V)%MS ->
- {subset eigenvalue (restrict f) <= eigenvalue f}.
-Proof.
-move=> f_stabV a /eigenvalueP [x /eigenspaceP]; rewrite eigenspace_restrict //.
-move=> /eigenspaceP Hf x_neq0; apply/eigenvalueP.
-by exists (x *m row_base V); rewrite ?mul_mx_rowfree_eq0 ?row_base_free.
-Qed.
-
-Lemma restrictM : {in [pred f | (V *m f <= V)%MS] &,
- {morph restrict : f g / f *m g}}.
-Proof.
-move=> f g; rewrite !inE => Vf Vg /=.
-by rewrite /restrict 2!mulmxA mulmxA mulmxKpV ?stable_row_base.
-Qed.
-
-End Restriction.
-
-End extramx.
-Notation skew K n := (@skew_def _ (Phant K) n).
-
-Section Paper_HarmDerksen.
-
-(* Following http://www.math.lsa.umich.edu/~hderksen/preprints/linalg.pdf *)
-(* quite literally except for Lemma5 where we don't use hermitian matrices. *)
-(* Instead we encode the morphism by hand in 'M[R]_(n * n), which turns out *)
-(* to be very clumsy for formalizing commutation and the end of Lemma 4. *)
-(* Moreover, the Qed takes time, so it would be far much better to formalize *)
-(* Herm C n and use it instead ! *)
-
-Implicit Types (K : fieldType).
-
-Definition CommonEigenVec_def K (phK : phant K) (d r : nat) :=
- forall (m : nat) (V : 'M[K]_m), ~~ (d %| \rank V) ->
- forall (sf : seq 'M_m), size sf = r ->
- {in sf, forall f, (V *m f <= V)%MS} ->
- {in sf &, forall f g, f *m g = g *m f} ->
- exists2 v : 'rV_m, (v != 0) & forall f, f \in sf ->
- exists a, (v <= eigenspace f a)%MS.
-Notation CommonEigenVec K d r := (@CommonEigenVec_def _ (Phant K) d r).
-
-Definition Eigen1Vec_def K (phK : phant K) (d : nat) :=
- forall (m : nat) (V : 'M[K]_m), ~~ (d %| \rank V) ->
- forall (f : 'M_m), (V *m f <= V)%MS -> exists a, eigenvalue f a.
-Notation Eigen1Vec K d := (@Eigen1Vec_def _ (Phant K) d).
-
-Lemma Eigen1VecP (K : fieldType) (d : nat) :
- CommonEigenVec K d 1%N <-> Eigen1Vec K d.
-Proof.
-split=> [Hd m V HV f|Hd m V HV [] // f [] // _ /(_ _ (mem_head _ _))] f_stabV.
- have [] := Hd _ _ HV [::f] (erefl _).
- + by move=> ?; rewrite in_cons orbF => /eqP ->.
- + by move=> ? ?; rewrite /= !in_cons !orbF => /eqP -> /eqP ->.
- move=> v v_neq0 /(_ f (mem_head _ _)) [a /eigenspaceP].
- by exists a; apply/eigenvalueP; exists v.
-have [a /eigenvalueP [v /eigenspaceP v_eigen v_neq0]] := Hd _ _ HV _ f_stabV.
-by exists v => // ?; rewrite in_cons orbF => /eqP ->; exists a.
-Qed.
-
-Lemma Lemma3 K d : Eigen1Vec K d -> forall r, CommonEigenVec K d r.+1.
-Proof.
-move=> E1V_K_d; elim=> [|r IHr m V]; first exact/Eigen1VecP.
-move: (\rank V) {-2}V (leqnn (\rank V)) => n {V}.
-elim: n m => [|n IHn] m V.
- by rewrite leqn0 => /eqP ->; rewrite dvdn0.
-move=> le_rV_Sn HrV [] // f sf /= [] ssf f_sf_stabV f_sf_comm.
-have [->|f_neq0] := altP (f =P 0).
- have [||v v_neq0 Hsf] := (IHr _ _ HrV _ ssf).
- + by move=> g f_sf /=; rewrite f_sf_stabV // in_cons f_sf orbT.
- + move=> g h g_sf h_sf /=.
- by apply: f_sf_comm; rewrite !in_cons ?g_sf ?h_sf ?orbT.
- exists v => // g; rewrite in_cons => /orP [/eqP->|]; last exact: Hsf.
- by exists 0; apply/eigenspaceP; rewrite mulmx0 scale0r.
-have f_stabV : (V *m f <= V)%MS by rewrite f_sf_stabV ?mem_head.
-have sf_stabV : {in sf, forall f, (V *m f <= V)%MS}.
- by move=> g g_sf /=; rewrite f_sf_stabV // in_cons g_sf orbT.
-pose f' := restrict V f; pose sf' := map (restrict V) sf.
-have [||a a_eigen_f'] := E1V_K_d _ 1%:M _ f'; do ?by rewrite ?mxrank1 ?submx1.
-pose W := (eigenspace f' a)%MS; pose Z := (f' - a%:M).
-have rWZ : (\rank W + \rank Z)%N = \rank V.
- by rewrite (mxrank_ker (f' - a%:M)) subnK // rank_leq_row.
-have f'_stabW : (W *m f' <= W)%MS.
- by rewrite (eigenspaceP (submx_refl _)) scalemx_sub.
-have f'_stabZ : (Z *m f' <= Z)%MS.
- rewrite (submx_trans _ (submxMl f' _)) //.
- by rewrite mulmxDl mulmxDr mulmxN mulNmx scalar_mxC.
-have sf'_comm : {in [::f' & sf'] &, forall f g, f *m g = g *m f}.
- move=> g' h' /=; rewrite -!map_cons.
- move=> /mapP [g g_s_sf -> {g'}] /mapP [h h_s_sf -> {h'}].
- by rewrite -!restrictM ?inE /= ?f_sf_stabV // f_sf_comm.
-have sf'_stabW : {in sf', forall f, (W *m f <= W)%MS}.
- move=> g g_sf /=; apply/eigenspaceP.
- rewrite -mulmxA -[g *m _]sf'_comm ?(mem_head, in_cons, g_sf, orbT) //.
- by rewrite mulmxA scalemxAl (eigenspaceP (submx_refl _)).
-have sf'_stabZ : {in sf', forall f, (Z *m f <= Z)%MS}.
- move=> g g_sf /=.
- rewrite mulmxBl sf'_comm ?(mem_head, in_cons, g_sf, orbT) //.
- by rewrite -scalar_mxC -mulmxBr submxMl.
-have [eqWV|neqWV] := altP (@eqmxP _ _ _ _ W 1%:M).
- have [] // := IHr _ W _ sf'; do ?by rewrite ?eqWV ?mxrank1 ?size_map.
- move=> g h g_sf' h_sf'; apply: sf'_comm;
- by rewrite in_cons (g_sf', h_sf') orbT.
- move=> v v_neq0 Hv; exists (v *m row_base V).
- by rewrite mul_mx_rowfree_eq0 ?row_base_free.
- move=> g; rewrite in_cons => /orP [/eqP ->|g_sf]; last first.
- have [|b] := Hv (restrict V g); first by rewrite map_f.
- by rewrite eigenspace_restrict // ?sf_stabV //; exists b.
- by exists a; rewrite -eigenspace_restrict // eqWV submx1.
-have lt_WV : (\rank W < \rank V)%N.
- rewrite -[X in (_ < X)%N](@mxrank1 K) rank_ltmx //.
- by rewrite ltmxEneq neqWV // submx1.
-have ltZV : (\rank Z < \rank V)%N.
- rewrite -[X in (_ < X)%N]rWZ -subn_gt0 addnK lt0n mxrank_eq0 -lt0mx.
- move: a_eigen_f' => /eigenvalueP [v /eigenspaceP] sub_vW v_neq0.
- by rewrite (ltmx_sub_trans _ sub_vW) // lt0mx.
-have [] // := IHn _ (if d %| \rank Z then W else Z) _ _ [:: f' & sf'].
-+ by rewrite -ltnS (@leq_trans (\rank V)) //; case: ifP.
-+ by apply: contra HrV; case: ifP => [*|-> //]; rewrite -rWZ dvdn_add.
-+ by rewrite /= size_map ssf.
-+ move=> g; rewrite in_cons => /= /orP [/eqP -> {g}|g_sf']; case: ifP => _ //;
- by rewrite (sf'_stabW, sf'_stabZ).
-move=> v v_neq0 Hv; exists (v *m row_base V).
- by rewrite mul_mx_rowfree_eq0 ?row_base_free.
-move=> g Hg; have [|b] := Hv (restrict V g); first by rewrite -map_cons map_f.
-rewrite eigenspace_restrict //; first by exists b.
-by move: Hg; rewrite in_cons => /orP [/eqP -> //|/sf_stabV].
-Qed.
-
-Lemma Lemma4 r : CommonEigenVec R 2 r.+1.
-Proof.
-apply: Lemma3=> m V hV f f_stabV.
-have [|a] := @odd_poly_root _ (char_poly (restrict V f)).
- by rewrite size_char_poly /= -dvdn2.
-rewrite -eigenvalue_root_char => /eigenvalueP [v] /eigenspaceP v_eigen v_neq0.
-exists a; apply/eigenvalueP; exists (v *m row_base V).
- by apply/eigenspaceP; rewrite -eigenspace_restrict.
-by rewrite mul_mx_rowfree_eq0 ?row_base_free.
-Qed.
-
-Notation toC := (real_complex R).
-Notation MtoC := (map_mx toC).
-
-Lemma Lemma5 : Eigen1Vec R[i] 2.
-Proof.
-move=> m V HrV f f_stabV.
-suff: exists a, eigenvalue (restrict V f) a.
- by move=> [a /eigenvalue_restrict Hf]; exists a; apply: Hf.
-move: (\rank V) (restrict V f) => {f f_stabV V m} n f in HrV *.
-pose u := map_mx (@Re R) f; pose v := map_mx (@Im R) f.
-have fE : f = MtoC u + 'i%C *: MtoC v.
- rewrite /u /v [f]lock; apply/matrixP => i j; rewrite !mxE /=.
- by case: (locked f i j) => a b; simpc.
-move: u v => u v in fE *.
-pose L1fun : 'M[R]_n -> _ :=
- 2%:R^-1 \*: (mulmxr u \+ (mulmxr v \o trmx)
- \+ ((mulmx (u^T)) \- (mulmx (v^T) \o trmx))).
-pose L1 := lin_mx [linear of L1fun].
-pose L2fun : 'M[R]_n -> _ :=
- 2%:R^-1 \*: (((@GRing.opp _) \o (mulmxr u \o trmx) \+ mulmxr v)
- \+ ((mulmx (u^T) \o trmx) \+ (mulmx (v^T)))).
-pose L2 := lin_mx [linear of L2fun].
-have [] := @Lemma4 _ _ 1%:M _ [::L1; L2] (erefl _).
-+ by move: HrV; rewrite mxrank1 !dvdn2 ?negbK odd_mul andbb.
-+ by move=> ? _ /=; rewrite submx1.
-+ suff {f fE}: L1 *m L2 = L2 *m L1.
- move: L1 L2 => L1 L2 commL1L2 La Lb.
- rewrite !{1}in_cons !{1}in_nil !{1}orbF.
- by move=> /orP [] /eqP -> /orP [] /eqP -> //; symmetry.
- apply/eqP/mulmxP => x; rewrite [X in X = _]mulmxA [X in _ = X]mulmxA.
- rewrite 4!mul_rV_lin !mxvecK /= /L1fun /L2fun /=; congr (mxvec (_ *: _)).
- move=> {L1 L2 L1fun L2fun}.
- case: n {x} (vec_mx x) => [//|n] x in HrV u v *.
- do ?[rewrite -(scalemxAl, scalemxAr, scalerN, scalerDr)
- |rewrite (mulmxN, mulNmx, trmxK, trmx_mul)
- |rewrite ?[(_ *: _)^T]linearZ ?[(_ + _)^T]linearD ?[(- _)^T]linearN /=].
- congr (_ *: _).
- rewrite !(mulmxDr, mulmxDl, mulNmx, mulmxN, mulmxA, opprD, opprK).
- do ![move: (_ *m _ *m _)] => t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12.
- rewrite [X in X + _ + _]addrC [X in X + _ = _]addrACA.
- rewrite [X in _ = (_ + _ + X) + _]addrC [X in _ = X + _]addrACA.
- rewrite [X in _ + (_ + _ + X)]addrC [X in _ + X = _]addrACA.
- rewrite [X in _ = _ + (X + _)]addrC [X in _ = _ + X]addrACA.
- rewrite [X in X = _]addrACA [X in _ = X]addrACA; congr (_ + _).
- by rewrite addrC [X in X + _ = _]addrACA [X in _ + X = _]addrACA.
-move=> g g_neq0 Hg; have [] := (Hg L1, Hg L2).
-rewrite !(mem_head, in_cons, orbT) => [].
-move=> [//|a /eigenspaceP g_eigenL1] [//|b /eigenspaceP g_eigenL2].
-rewrite !mul_rV_lin /= /L1fun /L2fun /= in g_eigenL1 g_eigenL2.
-do [move=> /(congr1 vec_mx); rewrite mxvecK linearZ /=] in g_eigenL1.
-do [move=> /(congr1 vec_mx); rewrite mxvecK linearZ /=] in g_eigenL2.
-move=> {L1 L2 L1fun L2fun Hg HrV}.
-set vg := vec_mx g in g_eigenL1 g_eigenL2.
-exists (a +i* b); apply/eigenvalueP.
-pose w := (MtoC vg - 'i%C *: MtoC vg^T).
-exists (nz_row w); last first.
- rewrite nz_row_eq0 subr_eq0; apply: contraNneq g_neq0 => Hvg.
- rewrite -vec_mx_eq0; apply/eqP/matrixP => i j; rewrite !mxE /=.
- move: Hvg => /matrixP /(_ i j); rewrite !mxE /=; case.
- by rewrite !(mul0r, mulr0, add0r, mul1r, oppr0) => ->.
-apply/eigenspaceP.
-case: n f => [|n] f in u v g g_neq0 vg w fE g_eigenL1 g_eigenL2 *.
- by rewrite thinmx0 eqxx in g_neq0.
-rewrite (submx_trans (nz_row_sub _)) //; apply/eigenspaceP.
-rewrite fE [a +i* b]complexE /=.
-rewrite !(mulmxDr, mulmxBl, =^~scalemxAr, =^~scalemxAl) -!map_mxM.
-rewrite !(scalerDl, scalerDr, scalerN, =^~scalemxAr, =^~scalemxAl).
-rewrite !scalerA /= mulrAC ['i%C * _]sqr_i ?mulN1r scaleN1r scaleNr !opprK.
-rewrite [_ * 'i%C]mulrC -!scalerA -!map_mxZ /=.
-do 2!rewrite [X in (_ - _) + X]addrC [_ - 'i%C *: _ + _]addrACA.
-rewrite ![- _ + _]addrC -!scalerBr -!(rmorphB, rmorphD) /=.
-congr (_ + 'i%C *: _); congr map_mx; rewrite -[_ *: _^T]linearZ /=;
-rewrite -g_eigenL1 -g_eigenL2 linearZ -(scalerDr, scalerBr);
-do ?rewrite ?trmxK ?trmx_mul ?[(_ + _)^T]linearD ?[(- _)^T]linearN /=;
-rewrite -[in X in _ *: (_ + X)]addrC 1?opprD 1?opprB ?mulmxN ?mulNmx;
-rewrite [X in _ *: X]addrACA.
- rewrite -mulr2n [X in _ *: (_ + X)]addrACA subrr addNr !addr0.
- by rewrite -scaler_nat scalerA mulVf ?pnatr_eq0 // scale1r.
-rewrite subrr addr0 addrA addrAC -addrA -mulr2n addrC.
-by rewrite -scaler_nat scalerA mulVf ?pnatr_eq0 // scale1r.
-Qed.
-
-Lemma Lemma6 k r : CommonEigenVec R[i] (2^k.+1) r.+1.
-Proof.
-elim: k {-2}k (leqnn k) r => [|k IHk] l.
- by rewrite leqn0 => /eqP ->; apply: Lemma3; apply: Lemma5.
-rewrite leq_eqVlt ltnS => /orP [/eqP ->|/IHk //] r {l}.
-apply: Lemma3 => m V Hn f f_stabV {r}.
-have [dvd2n|Ndvd2n] := boolP (2 %| \rank V); last first.
- exact: @Lemma5 _ _ Ndvd2n _ f_stabV.
-suff: exists a, eigenvalue (restrict V f) a.
- by move=> [a /eigenvalue_restrict Hf]; exists a; apply: Hf.
-case: (\rank V) (restrict V f) => {f f_stabV V m} [|n] f in Hn dvd2n *.
- by rewrite dvdn0 in Hn.
-pose L1 := lin_mx [linear of mulmxr f \+ (mulmx f^T)].
-pose L2 := lin_mx [linear of mulmxr f \o mulmx f^T].
-have [] /= := IHk _ (leqnn _) _ _ (skew R[i] n.+1) _ [::L1; L2] (erefl _).
-+ rewrite rank_skew; apply: contra Hn.
- rewrite -(@dvdn_pmul2r 2) //= -expnSr muln2 -[_.*2]add0n.
- have n_odd : odd n by rewrite dvdn2 /= ?negbK in dvd2n *.
- have {2}<- : odd (n.+1 * n) = 0%N :> nat by rewrite odd_mul /= andNb.
- by rewrite odd_double_half Gauss_dvdl // coprime_pexpl // coprime2n.
-+ move=> L; rewrite 2!in_cons in_nil orbF => /orP [] /eqP ->;
- apply/rV_subP => v /submxP [s -> {v}]; rewrite mulmxA; apply/skewP;
- set u := _ *m skew _ _;
- do [have /skewP : (u <= skew R[i] n.+1)%MS by rewrite submxMl];
- rewrite mul_rV_lin /= !mxvecK => skew_u.
- by rewrite opprD linearD /= !trmx_mul skew_u mulmxN mulNmx addrC trmxK.
- by rewrite !trmx_mul trmxK skew_u mulNmx mulmxN mulmxA.
-+ suff commL1L2: L1 *m L2 = L2 *m L1.
- move=> La Lb; rewrite !in_cons !in_nil !orbF.
- by move=> /orP [] /eqP -> /orP [] /eqP -> //; symmetry.
- apply/eqP/mulmxP => u; rewrite !mulmxA !mul_rV_lin ?mxvecK /=.
- by rewrite !(mulmxDr, mulmxDl, mulmxA).
-move=> v v_neq0 HL1L2; have [] := (HL1L2 L1, HL1L2 L2).
-rewrite !(mem_head, in_cons) orbT => [] [] // a vL1 [] // b vL2 {HL1L2}.
-move/eigenspaceP in vL1; move/eigenspaceP in vL2.
-move: vL2 => /(congr1 vec_mx); rewrite linearZ mul_rV_lin /= mxvecK.
-move: vL1 => /(congr1 vec_mx); rewrite linearZ mul_rV_lin /= mxvecK.
-move=> /(canRL (addKr _)) ->; rewrite mulmxDl mulNmx => Hv.
-pose p := 'X^2 + (- a) *: 'X + b%:P.
-have : vec_mx v *m (horner_mx f p) = 0.
- rewrite !(rmorphN, rmorphB, rmorphD, rmorphM) /= linearZ /=.
- rewrite horner_mx_X horner_mx_C !mulmxDr mul_mx_scalar -Hv.
- rewrite addrAC addrA mulmxA addrN add0r.
- by rewrite -scalemxAl -scalemxAr scaleNr addrN.
-rewrite [p]monic_canonical_form; move: (_ / 2%:R) (_ / 2%:R).
-move=> r2 r1 {Hv p a b L1 L2 Hn}.
-rewrite rmorphM !rmorphB /= horner_mx_X !horner_mx_C mulmxA => Hv.
-have: exists2 w : 'M_n.+1, w != 0 & exists a, (w <= eigenspace f a)%MS.
- move: Hv; set w := vec_mx _ *m _.
- have [w_eq0 _|w_neq0 r2_eigen] := altP (w =P 0).
- exists (vec_mx v); rewrite ?vec_mx_eq0 //; exists r1.
- apply/eigenspaceP/eqP.
- by rewrite -mul_mx_scalar -subr_eq0 -mulmxBr -/w w_eq0.
- exists w => //; exists r2; apply/eigenspaceP/eqP.
- by rewrite -mul_mx_scalar -subr_eq0 -mulmxBr r2_eigen.
-move=> [w w_neq0 [a /(submx_trans (nz_row_sub _)) /eigenspaceP Hw]].
-by exists a; apply/eigenvalueP; exists (nz_row w); rewrite ?nz_row_eq0.
-Qed.
-
-(* We enunciate a corollary of Theorem 7 *)
-Corollary Theorem7' (m : nat) (f : 'M[R[i]]_m) : (0 < m)%N -> exists a, eigenvalue f a.
-Proof.
-case: m f => // m f _; have /Eigen1VecP := @Lemma6 m 0.
-move=> /(_ m.+1 1 _ f) []; last by move=> a; exists a.
-+ by rewrite mxrank1 (contra (dvdn_leq _)) // -ltnNge ltn_expl.
-+ by rewrite submx1.
-Qed.
-
-Lemma complex_acf_axiom : GRing.ClosedField.axiom [ringType of R[i]].
-Proof.
-move=> n c n_gt0; pose p := 'X^n - \poly_(i < n) c i.
-suff [x rpx] : exists x, root p x.
- exists x; move: rpx; rewrite /root /p hornerD hornerN hornerXn subr_eq0.
- by move=> /eqP ->; rewrite horner_poly.
-have p_monic : p \is monic.
- rewrite qualifE lead_coefDl ?lead_coefXn //.
- by rewrite size_opp size_polyXn ltnS size_poly.
-have sp_gt1 : (size p > 1)%N.
- by rewrite size_addl size_polyXn // size_opp ltnS size_poly.
-case: n n_gt0 p => //= n _ p in p_monic sp_gt1 *.
-have [] := Theorem7' (companion p); first by rewrite -(subnK sp_gt1) addn2.
-by move=> x; rewrite eigenvalue_root_char companionK //; exists x.
-Qed.
-
-Definition complex_decFieldMixin := closed_fields_QEMixin complex_acf_axiom.
-Canonical complex_decField := DecFieldType R[i] complex_decFieldMixin.
-Canonical complex_closedField := ClosedFieldType R[i] complex_acf_axiom.
-
-Definition complex_numClosedFieldMixin :=
- ImaginaryMixin (sqr_i R) (fun x=> esym (sqr_normc x)).
-
-Canonical complex_numClosedFieldType :=
- NumClosedFieldType R[i] complex_numClosedFieldMixin.
-
-End Paper_HarmDerksen.
-
-End ComplexClosed.
-
-(* End ComplexInternal. *)
-
-(* Canonical ComplexInternal.complex_eqType. *)
-(* Canonical ComplexInternal.complex_choiceType. *)
-(* Canonical ComplexInternal.complex_countType. *)
-(* Canonical ComplexInternal.complex_ZmodType. *)
-(* Canonical ComplexInternal.complex_Ring. *)
-(* Canonical ComplexInternal.complex_comRing. *)
-(* Canonical ComplexInternal.complex_unitRing. *)
-(* Canonical ComplexInternal.complex_comUnitRing. *)
-(* Canonical ComplexInternal.complex_iDomain. *)
-(* Canonical ComplexInternal.complex_fieldType. *)
-(* Canonical ComplexInternal.ComplexField.real_complex_rmorphism. *)
-(* Canonical ComplexInternal.ComplexField.real_complex_additive. *)
-(* Canonical ComplexInternal.ComplexField.Re_additive. *)
-(* Canonical ComplexInternal.ComplexField.Im_additive. *)
-(* Canonical ComplexInternal.complex_numDomainType. *)
-(* Canonical ComplexInternal.complex_numFieldType. *)
-(* Canonical ComplexInternal.conjc_rmorphism. *)
-(* Canonical ComplexInternal.conjc_additive. *)
-(* Canonical ComplexInternal.complex_decField. *)
-(* Canonical ComplexInternal.complex_closedField. *)
-(* Canonical ComplexInternal.complex_numClosedFieldType. *)
-
-(* Definition complex_algebraic_trans := ComplexInternal.complex_algebraic_trans. *)
-
-Section ComplexClosedTheory.
-
-Variable R : rcfType.
-
-Lemma complexiE : 'i%C = 'i%R :> R[i].
-Proof. by []. Qed.
-
-Lemma complexRe (x : R[i]) : (Re x)%:C = 'Re x.
-Proof.
-rewrite {1}[x]Crect raddfD /= mulrC ReiNIm rmorphB /=.
-by rewrite ?RRe_real ?RIm_real ?Creal_Im ?Creal_Re // subr0.
-Qed.
-
-Lemma complexIm (x : R[i]) : (Im x)%:C = 'Im x.
-Proof.
-rewrite {1}[x]Crect raddfD /= mulrC ImiRe rmorphD /=.
-by rewrite ?RRe_real ?RIm_real ?Creal_Im ?Creal_Re // add0r.
-Qed.
-
-End ComplexClosedTheory.
-
-Definition complexalg := realalg[i].
-
-Canonical complexalg_eqType := [eqType of complexalg].
-Canonical complexalg_choiceType := [choiceType of complexalg].
-Canonical complexalg_countype := [choiceType of complexalg].
-Canonical complexalg_zmodType := [zmodType of complexalg].
-Canonical complexalg_ringType := [ringType of complexalg].
-Canonical complexalg_comRingType := [comRingType of complexalg].
-Canonical complexalg_unitRingType := [unitRingType of complexalg].
-Canonical complexalg_comUnitRingType := [comUnitRingType of complexalg].
-Canonical complexalg_idomainType := [idomainType of complexalg].
-Canonical complexalg_fieldType := [fieldType of complexalg].
-Canonical complexalg_decDieldType := [decFieldType of complexalg].
-Canonical complexalg_closedFieldType := [closedFieldType of complexalg].
-Canonical complexalg_numDomainType := [numDomainType of complexalg].
-Canonical complexalg_numFieldType := [numFieldType of complexalg].
-Canonical complexalg_numClosedFieldType := [numClosedFieldType of complexalg].
-
-Lemma complexalg_algebraic : integralRange (@ratr [unitRingType of complexalg]).
-Proof.
-move=> x; suff [p p_monic] : integralOver (real_complex _ \o realalg_of _) x.
- by rewrite (eq_map_poly (fmorph_eq_rat _)); exists p.
-by apply: complex_algebraic_trans; apply: realalg_algebraic.
-Qed.
diff --git a/mathcomp/real_closed/descr b/mathcomp/real_closed/descr
deleted file mode 100644
index b51ecf9..0000000
--- a/mathcomp/real_closed/descr
+++ /dev/null
@@ -1,7 +0,0 @@
-Mathematical Components Library on real closed fields
-
-This library contains definitions and theorems about real closed
-fields, with a construction of the real closure and the algebraic
-closure (including a proof of the fundamental theorem of algebra). It
-also contains a proof of decidability of the first order theory of
-real closed field, through quantifier elimination.
diff --git a/mathcomp/real_closed/mxtens.v b/mathcomp/real_closed/mxtens.v
deleted file mode 100644
index 792e223..0000000
--- a/mathcomp/real_closed/mxtens.v
+++ /dev/null
@@ -1,316 +0,0 @@
-(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-(* Distributed under the terms of CeCILL-B. *)
-Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp
-Require Import ssrfun ssrbool eqtype ssrnat seq choice fintype.
-From mathcomp
-Require Import bigop ssralg matrix zmodp div.
-
-Set Implicit Arguments.
-Unset Strict Implicit.
-Unset Printing Implicit Defensive.
-
-Import GRing.Theory.
-Local Open Scope nat_scope.
-Local Open Scope ring_scope.
-
-Section ExtraBigOp.
-
-Lemma sumr_add : forall (R : ringType) m n (F : 'I_(m + n) -> R),
- \sum_(i < m + n) F i = \sum_(i < m) F (lshift _ i)
- + \sum_(i < n) F (rshift _ i).
-Proof.
-move=> R; elim=> [|m ihm] n F.
- rewrite !big_ord0 add0r; apply: congr_big=> // [[i hi]] _.
- by rewrite /rshift /=; congr F; apply: val_inj.
-rewrite !big_ord_recl ihm -addrA.
-congr (_ + _); first by congr F; apply: val_inj.
-congr (_ + _); by apply: congr_big=> // i _ /=; congr F; apply: val_inj.
-Qed.
-
-Lemma mxtens_index_proof m n (ij : 'I_m * 'I_n) : ij.1 * n + ij.2 < m * n.
-Proof.
-case: m ij=> [[[] //]|] m ij; rewrite mulSn addnC -addSn leq_add //.
-by rewrite leq_mul2r; case: n ij=> // n ij; rewrite leq_ord orbT.
-Qed.
-
-Definition mxtens_index m n ij := Ordinal (@mxtens_index_proof m n ij).
-
-Lemma mxtens_index_proof1 m n (k : 'I_(m * n)) : k %/ n < m.
-Proof. by move: m n k=> [_ [] //|m] [|n] k; rewrite ?divn0 // ltn_divLR. Qed.
-Lemma mxtens_index_proof2 m n (k : 'I_(m * n)) : k %% n < n.
-Proof. by rewrite ltn_mod; case: n k=> //; rewrite muln0=> [] []. Qed.
-
-Definition mxtens_unindex m n k :=
- (Ordinal (@mxtens_index_proof1 m n k), Ordinal (@mxtens_index_proof2 m n k)).
-
-Arguments mxtens_index {m n}.
-Arguments mxtens_unindex {m n}.
-
-Lemma mxtens_indexK m n : cancel (@mxtens_index m n) (@mxtens_unindex m n).
-Proof.
-case: m=> [[[] //]|m]; case: n=> [[_ [] //]|n].
-move=> [i j]; congr (_, _); apply: val_inj=> /=.
- by rewrite divnMDl // divn_small.
-by rewrite modnMDl // modn_small.
-Qed.
-
-Lemma mxtens_unindexK m n : cancel (@mxtens_unindex m n) (@mxtens_index m n).
-Proof.
-case: m=> [[[] //]|m]. case: n=> [|n] k.
- by suff: False by []; move: k; rewrite muln0=> [] [].
-by apply: val_inj=> /=; rewrite -divn_eq.
-Qed.
-
-CoInductive is_mxtens_index (m n : nat) : 'I_(m * n) -> Type :=
- IsMxtensIndex : forall (i : 'I_m) (j : 'I_n),
- is_mxtens_index (mxtens_index (i, j)).
-
-Lemma mxtens_indexP (m n : nat) (k : 'I_(m * n)) : is_mxtens_index k.
-Proof. by rewrite -[k]mxtens_unindexK; constructor. Qed.
-
-Lemma mulr_sum (R : ringType) m n (Fm : 'I_m -> R) (Fn : 'I_n -> R) :
- (\sum_(i < m) Fm i) * (\sum_(i < n) Fn i)
- = \sum_(i < m * n) ((Fm (mxtens_unindex i).1) * (Fn (mxtens_unindex i).2)).
-Proof.
-rewrite mulr_suml; transitivity (\sum_i (\sum_(j < n) Fm i * Fn j)).
- by apply: eq_big=> //= i _; rewrite -mulr_sumr.
-rewrite pair_big; apply: reindex=> //=.
-by exists mxtens_index=> i; rewrite (mxtens_indexK, mxtens_unindexK).
-Qed.
-
-End ExtraBigOp.
-
-Section ExtraMx.
-
-Lemma castmx_mul (R : ringType)
- (m m' n p p': nat) (em : m = m') (ep : p = p')
- (M : 'M[R]_(m, n)) (N : 'M[R]_(n, p)) :
- castmx (em, ep) (M *m N) = castmx (em, erefl _) M *m castmx (erefl _, ep) N.
-Proof. by case: m' / em; case: p' / ep. Qed.
-
-Lemma mulmx_cast (R : ringType)
- (m n n' p p' : nat) (en : n' = n) (ep : p' = p)
- (M : 'M[R]_(m, n)) (N : 'M[R]_(n', p')) :
- M *m (castmx (en, ep) N) =
- (castmx (erefl _, (esym en)) M) *m (castmx (erefl _, ep) N).
-Proof. by case: n / en in M *; case: p / ep in N *. Qed.
-
-Lemma castmx_row (R : Type) (m m' n1 n2 n1' n2' : nat)
- (eq_n1 : n1 = n1') (eq_n2 : n2 = n2') (eq_n12 : (n1 + n2 = n1' + n2')%N)
- (eq_m : m = m') (A1 : 'M[R]_(m, n1)) (A2 : 'M_(m, n2)) :
- castmx (eq_m, eq_n12) (row_mx A1 A2) =
- row_mx (castmx (eq_m, eq_n1) A1) (castmx (eq_m, eq_n2) A2).
-Proof.
-case: _ / eq_n1 in eq_n12 *; case: _ / eq_n2 in eq_n12 *.
-by case: _ / eq_m; rewrite castmx_id.
-Qed.
-
-Lemma castmx_col (R : Type) (m m' n1 n2 n1' n2' : nat)
- (eq_n1 : n1 = n1') (eq_n2 : n2 = n2') (eq_n12 : (n1 + n2 = n1' + n2')%N)
- (eq_m : m = m') (A1 : 'M[R]_(n1, m)) (A2 : 'M_(n2, m)) :
- castmx (eq_n12, eq_m) (col_mx A1 A2) =
- col_mx (castmx (eq_n1, eq_m) A1) (castmx (eq_n2, eq_m) A2).
-Proof.
-case: _ / eq_n1 in eq_n12 *; case: _ / eq_n2 in eq_n12 *.
-by case: _ / eq_m; rewrite castmx_id.
-Qed.
-
-Lemma castmx_block (R : Type) (m1 m1' m2 m2' n1 n2 n1' n2' : nat)
- (eq_m1 : m1 = m1') (eq_n1 : n1 = n1') (eq_m2 : m2 = m2') (eq_n2 : n2 = n2')
- (eq_m12 : (m1 + m2 = m1' + m2')%N) (eq_n12 : (n1 + n2 = n1' + n2')%N)
- (ul : 'M[R]_(m1, n1)) (ur : 'M[R]_(m1, n2))
- (dl : 'M[R]_(m2, n1)) (dr : 'M[R]_(m2, n2)) :
- castmx (eq_m12, eq_n12) (block_mx ul ur dl dr) =
- block_mx (castmx (eq_m1, eq_n1) ul) (castmx (eq_m1, eq_n2) ur)
- (castmx (eq_m2, eq_n1) dl) (castmx (eq_m2, eq_n2) dr).
-Proof.
-case: _ / eq_m1 in eq_m12 *; case: _ / eq_m2 in eq_m12 *.
-case: _ / eq_n1 in eq_n12 *; case: _ / eq_n2 in eq_n12 *.
-by rewrite !castmx_id.
-Qed.
-
-End ExtraMx.
-
-Section MxTens.
-
-Variable R : ringType.
-
-Definition tensmx {m n p q : nat}
- (A : 'M_(m, n)) (B : 'M_(p, q)) : 'M[R]_(_,_) := nosimpl
- (\matrix_(i, j) (A (mxtens_unindex i).1 (mxtens_unindex j).1
- * B (mxtens_unindex i).2 (mxtens_unindex j).2)).
-
-Notation "A *t B" := (tensmx A B)
- (at level 40, left associativity, format "A *t B").
-
-Lemma tensmxE {m n p q} (A : 'M_(m, n)) (B : 'M_(p, q)) i j k l :
- (A *t B) (mxtens_index (i, j)) (mxtens_index (k, l)) = A i k * B j l.
-Proof. by rewrite !mxE !mxtens_indexK. Qed.
-
-Lemma tens0mx {m n p q} (M : 'M[R]_(p,q)) : (0 : 'M_(m,n)) *t M = 0.
-Proof. by apply/matrixP=> i j; rewrite !mxE mul0r. Qed.
-
-Lemma tensmx0 {m n p q} (M : 'M[R]_(m,n)) : M *t (0 : 'M_(p,q)) = 0.
-Proof. by apply/matrixP=> i j; rewrite !mxE mulr0. Qed.
-
-Lemma tens_scalar_mx (m n : nat) (c : R) (M : 'M_(m,n)):
- c%:M *t M = castmx (esym (mul1n _), esym (mul1n _)) (c *: M).
-Proof.
-apply/matrixP=> i j.
-case: (mxtens_indexP i)=> i0 i1; case: (mxtens_indexP j)=> j0 j1.
-rewrite tensmxE [i0]ord1 [j0]ord1 !castmxE !mxE /= mulr1n.
-by congr (_ * M _ _); apply: val_inj.
-Qed.
-
-Lemma tens_scalar1mx (m n : nat) (M : 'M_(m,n)) :
- 1 *t M = castmx (esym (mul1n _), esym (mul1n _)) M.
-Proof. by rewrite tens_scalar_mx scale1r. Qed.
-
-Lemma tens_scalarN1mx (m n : nat) (M : 'M_(m,n)) :
- (-1) *t M = castmx (esym (mul1n _), esym (mul1n _)) (-M).
-Proof. by rewrite [-1]mx11_scalar /= tens_scalar_mx !mxE scaleNr scale1r. Qed.
-
-Lemma trmx_tens {m n p q} (M :'M[R]_(m,n)) (N : 'M[R]_(p,q)) :
- (M *t N)^T = M^T *t N^T.
-Proof. by apply/matrixP=> i j; rewrite !mxE. Qed.
-
-Lemma tens_col_mx {m n p q} (r : 'rV[R]_n)
- (M :'M[R]_(m, n)) (N : 'M[R]_(p, q)) :
- (col_mx r M) *t N =
- castmx (esym (mulnDl _ _ _), erefl _) (col_mx (r *t N) (M *t N)).
-Proof.
-apply/matrixP=> i j.
-case: (mxtens_indexP i)=> i0 i1; case: (mxtens_indexP j)=> j0 j1.
-rewrite !tensmxE castmxE /= cast_ord_id esymK !mxE /=.
-case: splitP=> i0' /= hi0'; case: splitP=> k /= hk.
-+ case: (mxtens_indexP k) hk=> k0 k1 /=; rewrite tensmxE.
- move=> /(f_equal (edivn^~ p)); rewrite !edivn_eq // => [] [h0 h1].
- by congr (r _ _ * N _ _); apply: val_inj; rewrite /= -?h0 ?h1.
-+ move: hk (ltn_ord i1); rewrite hi0'.
- by rewrite [i0']ord1 mul0n mul1n add0n ltnNge=> ->; rewrite leq_addr.
-+ move: (ltn_ord k); rewrite -hk hi0' ltnNge {1}mul1n.
- by rewrite mulnDl {1}mul1n -addnA leq_addr.
-case: (mxtens_indexP k) hk=> k0 k1 /=; rewrite tensmxE.
-rewrite hi0' mulnDl -addnA=> /addnI.
- move=> /(f_equal (edivn^~ p)); rewrite !edivn_eq // => [] [h0 h1].
-by congr (M _ _ * N _ _); apply: val_inj; rewrite /= -?h0 ?h1.
-Qed.
-
-Lemma tens_row_mx {m n p q} (r : 'cV[R]_m) (M :'M[R]_(m,n)) (N : 'M[R]_(p,q)) :
- (row_mx r M) *t N =
- castmx (erefl _, esym (mulnDl _ _ _)) (row_mx (r *t N) (M *t N)).
-Proof.
-rewrite -[_ *t _]trmxK trmx_tens tr_row_mx tens_col_mx.
-apply/eqP; rewrite -(can2_eq (castmxKV _ _) (castmxK _ _)); apply/eqP.
-by rewrite trmx_cast castmx_comp castmx_id tr_col_mx -!trmx_tens !trmxK.
-Qed.
-
-Lemma tens_block_mx {m n p q}
- (ul : 'M[R]_1) (ur : 'rV[R]_n) (dl : 'cV[R]_m)
- (M :'M[R]_(m,n)) (N : 'M[R]_(p,q)) :
- (block_mx ul ur dl M) *t N =
- castmx (esym (mulnDl _ _ _), esym (mulnDl _ _ _))
- (block_mx (ul *t N) (ur *t N) (dl *t N) (M *t N)).
-Proof.
-rewrite !block_mxEv tens_col_mx !tens_row_mx -!cast_col_mx castmx_comp.
-by congr (castmx (_,_)); apply nat_irrelevance.
-Qed.
-
-
-Fixpoint ntensmx_rec {m n} (A : 'M_(m,n)) k : 'M_(m ^ k.+1,n ^ k.+1) :=
- if k is k'.+1 then (A *t (ntensmx_rec A k')) else A.
-
-Definition ntensmx {m n} (A : 'M_(m, n)) k := nosimpl
- (if k is k'.+1 return 'M[R]_(m ^ k,n ^ k) then ntensmx_rec A k' else 1).
-
-Notation "A ^t k" := (ntensmx A k)
- (at level 39, left associativity, format "A ^t k").
-
-Lemma ntensmx0 : forall {m n} (A : 'M_(m,n)) , A ^t 0 = 1.
-Proof. by []. Qed.
-
-Lemma ntensmx1 : forall {m n} (A : 'M_(m,n)) , A ^t 1 = A.
-Proof. by []. Qed.
-
-Lemma ntensmx2 : forall {m n} (A : 'M_(m,n)) , A ^t 2 = A *t A.
-Proof. by []. Qed.
-
-Lemma ntensmxSS : forall {m n} (A : 'M_(m,n)) k, A ^t k.+2 = A *t A ^t k.+1.
-Proof. by []. Qed.
-
-Definition ntensmxS := (@ntensmx1, @ntensmx2, @ntensmxSS).
-
-End MxTens.
-
-Notation "A *t B" := (tensmx A B)
- (at level 40, left associativity, format "A *t B").
-
-Notation "A ^t k" := (ntensmx A k)
- (at level 39, left associativity, format "A ^t k").
-
-Section MapMx.
-Variables (aR rR : ringType).
-Hypothesis f : {rmorphism aR -> rR}.
-Local Notation "A ^f" := (map_mx f A) : ring_scope.
-
-Variables m n p q: nat.
-Implicit Type A : 'M[aR]_(m, n).
-Implicit Type B : 'M[aR]_(p, q).
-
-Lemma map_mxT A B : (A *t B)^f = A^f *t B^f :> 'M_(m*p, n*q).
-Proof. by apply/matrixP=> i j; rewrite !mxE /= rmorphM. Qed.
-
-End MapMx.
-
-Section Misc.
-
-Lemma tensmx_mul (R : comRingType) m n p q r s
- (A : 'M[R]_(m,n)) (B : 'M[R]_(p,q)) (C : 'M[R]_(n, r)) (D : 'M[R]_(q, s)) :
- (A *t B) *m (C *t D) = (A *m C) *t (B *m D).
-Proof.
-apply/matrixP=> /= i j.
-case (mxtens_indexP i)=> [im ip] {i}; case (mxtens_indexP j)=> [jr js] {j}.
-rewrite !mxE !mxtens_indexK mulr_sum; apply: congr_big=> // k _.
-by rewrite !mxE !mxtens_indexK mulrCA !mulrA [C _ _ * A _ _]mulrC.
-Qed.
-
-(* Todo : move to div ? *)
-Lemma eq_addl_mul q q' m m' d : m < d -> m' < d ->
- (q * d + m == q' * d + m')%N = ((q, m) == (q', m')).
-Proof.
-move=> lt_md lt_m'd; apply/eqP/eqP; last by move=> [-> ->].
-by move=> /(f_equal (edivn^~ d)); rewrite !edivn_eq.
-Qed.
-
-Lemma tensmx_unit (R : fieldType) m n (A : 'M[R]_m%N) (B : 'M[R]_n%N) :
- m != 0%N -> n != 0%N -> A \in unitmx -> B \in unitmx -> (A *t B) \in unitmx.
-Proof.
-move: m n A B => [|m] [|n] // A B _ _ uA uB.
-suff : (A^-1 *t B^-1) *m (A *t B) = 1 by case/mulmx1_unit.
-rewrite tensmx_mul !mulVmx //; apply/matrixP=> /= i j.
-rewrite !mxE /=; symmetry; rewrite -natrM -!val_eqE /=.
-rewrite {1}(divn_eq i n.+1) {1}(divn_eq j n.+1).
-by rewrite eq_addl_mul ?ltn_mod // xpair_eqE mulnb.
-Qed.
-
-
-Lemma tens_mx_scalar : forall (R : comRingType)
- (m n : nat) (c : R) (M : 'M[R]_(m,n)),
- M *t c%:M = castmx (esym (muln1 _), esym (muln1 _)) (c *: M).
-Proof.
-move=> R0 m n c M; apply/matrixP=> i j.
-case: (mxtens_indexP i)=> i0 i1; case: (mxtens_indexP j)=> j0 j1.
-rewrite tensmxE [i1]ord1 [j1]ord1 !castmxE !mxE /= mulr1n mulrC.
-by congr (_ * M _ _); apply: val_inj=> /=; rewrite muln1 addn0.
-Qed.
-
-Lemma tensmx_decr : forall (R : comRingType) m n (M :'M[R]_m) (N : 'M[R]_n),
- M *t N = (M *t 1%:M) *m (1%:M *t N).
-Proof. by move=> R0 m n M N; rewrite tensmx_mul mul1mx mulmx1. Qed.
-
-Lemma tensmx_decl : forall (R : comRingType) m n (M :'M[R]_m) (N : 'M[R]_n),
- M *t N = (1%:M *t N) *m (M *t 1%:M).
-Proof. by move=> R0 m n M N; rewrite tensmx_mul mul1mx mulmx1. Qed.
-
-End Misc.
diff --git a/mathcomp/real_closed/opam b/mathcomp/real_closed/opam
deleted file mode 100644
index 52d18b2..0000000
--- a/mathcomp/real_closed/opam
+++ /dev/null
@@ -1,16 +0,0 @@
-opam-version: "1.2"
-name: "coq-mathcomp-real_closed"
-version: "dev"
-maintainer: "Mathematical Components <mathcomp-dev@sympa.inria.fr>"
-
-homepage: "http://math-comp.github.io/math-comp/"
-bug-reports: "Mathematical Components <mathcomp-dev@sympa.inria.fr>"
-license: "CeCILL-B"
-
-build: [ make "-j" "%{jobs}%" ]
-install: [ make "install" ]
-remove: [ "sh" "-c" "rm -rf '%{lib}%/coq/user-contrib/mathcomp/real_closed'" ]
-depends: [ "coq-mathcomp-field" { = "dev" } ]
-
-tags: [ "keyword:real closed field" "keyword:Feit Thompson theorem" "keyword:small scale reflection" "keyword:mathematical components" "keyword:odd order theorem" ]
-authors: [ "Jeremy Avigad <>" "Andrea Asperti <>" "Stephane Le Roux <>" "Yves Bertot <>" "Laurence Rideau <>" "Enrico Tassi <>" "Ioana Pasca <>" "Georges Gonthier <>" "Sidi Ould Biha <>" "Cyril Cohen <>" "Francois Garillot <>" "Alexey Solovyev <>" "Russell O'Connor <>" "Laurent Théry <>" "Assia Mahboubi <>" ]
diff --git a/mathcomp/real_closed/ordered_qelim.v b/mathcomp/real_closed/ordered_qelim.v
deleted file mode 100644
index e9f15f9..0000000
--- a/mathcomp/real_closed/ordered_qelim.v
+++ /dev/null
@@ -1,1185 +0,0 @@
-(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-(* Distributed under the terms of CeCILL-B. *)
-Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp
-Require Import ssrfun ssrbool eqtype ssrnat seq div choice fintype.
-From mathcomp
-Require Import bigop ssralg finset fingroup zmodp.
-From mathcomp
-Require Import poly ssrnum.
-
-
-Set Implicit Arguments.
-Unset Strict Implicit.
-Unset Printing Implicit Defensive.
-
-Local Open Scope ring_scope.
-Import GRing.
-
-Reserved Notation "p <% q" (at level 70, no associativity).
-Reserved Notation "p <=% q" (at level 70, no associativity).
-
-(* Set Printing Width 30. *)
-
-Module ord.
-
-Section Formulas.
-
-Variable T : Type.
-
-Inductive formula : Type :=
-| Bool of bool
-| Equal of (term T) & (term T)
-| Lt of (term T) & (term T)
-| Le of (term T) & (term T)
-| Unit of (term T)
-| And of formula & formula
-| Or of formula & formula
-| Implies of formula & formula
-| Not of formula
-| Exists of nat & formula
-| Forall of nat & formula.
-
-End Formulas.
-
-Fixpoint term_eq (T : eqType)(t1 t2 : term T) :=
- match t1, t2 with
- | Var n1, Var n2 => n1 == n2
- | Const r1, Const r2 => r1 == r2
- | NatConst n1, NatConst n2 => n1 == n2
- | Add r1 s1, Add r2 s2 => (term_eq r1 r2) && (term_eq s1 s2)
- | Opp r1, Opp r2 => term_eq r1 r2
- | NatMul r1 n1, NatMul r2 n2 => (term_eq r1 r2) && (n1 == n2)
- | Mul r1 s1, Mul r2 s2 => (term_eq r1 r2) && (term_eq s1 s2)
- | Inv r1, Inv r2 => term_eq r1 r2
- | Exp r1 n1, Exp r2 n2 => (term_eq r1 r2) && (n1 == n2)
- |_, _ => false
- end.
-
-Lemma term_eqP (T : eqType) : Equality.axiom (@term_eq T).
-Proof.
-move=> t1 t2; apply: (iffP idP) => [|<-]; last first.
- by elim: t1 {t2} => //= t -> // n; rewrite eqxx.
-elim: t1 t2.
-- by move=> n1 /= [] // n2 /eqP ->.
-- by move=> r1 /= [] // r2 /eqP ->.
-- by move=> n1 /= [] // n2 /eqP ->.
-- by move=> r1 hr1 r2 hr2 [] //= s1 s2 /andP [] /hr1 -> /hr2 ->.
-- by move=> r1 hr1 [] //= s1 /hr1 ->.
-- by move=> s1 hs1 n1 [] //= s2 n2 /andP [] /hs1 -> /eqP ->.
-- by move=> r1 hr1 r2 hr2 [] //= s1 s2 /andP [] /hr1 -> /hr2 ->.
-- by move=> r1 hr1 [] //= s1 /hr1 ->.
-- by move=> s1 hs1 n1 [] //= s2 n2 /andP [] /hs1 -> /eqP ->.
-Qed.
-
-Canonical term_eqMixin (T : eqType) := EqMixin (@term_eqP T).
-Canonical term_eqType (T : eqType) :=
- Eval hnf in EqType (term T) (@term_eqMixin T).
-
-Arguments term_eqP T [x y].
-Prenex Implicits term_eq.
-
-
-Bind Scope oterm_scope with term.
-Bind Scope oterm_scope with formula.
-Delimit Scope oterm_scope with oT.
-Arguments Add _ _%oT _%oT.
-Arguments Opp _ _%oT.
-Arguments NatMul _ _%oT _%N.
-Arguments Mul _ _%oT _%oT.
-Arguments Mul _ _%oT _%oT.
-Arguments Inv _ _%oT.
-Arguments Exp _ _%oT _%N.
-Arguments Equal _ _%oT _%oT.
-Arguments Unit _ _%oT.
-Arguments And _ _%oT _%oT.
-Arguments Or _ _%oT _%oT.
-Arguments Implies _ _%oT _%oT.
-Arguments Not _ _%oT.
-Arguments Exists _ _%N _%oT.
-Arguments Forall _ _%N _%oT.
-
-Arguments Bool [T].
-Prenex Implicits Const Add Opp NatMul Mul Exp Bool Unit And Or Implies Not.
-Prenex Implicits Exists Forall Lt.
-
-Notation True := (Bool true).
-Notation False := (Bool false).
-
-Notation "''X_' i" := (Var _ i) : oterm_scope.
-Notation "n %:R" := (NatConst _ n) : oterm_scope.
-Notation "x %:T" := (Const x) : oterm_scope.
-Notation "0" := 0%:R%oT : oterm_scope.
-Notation "1" := 1%:R%oT : oterm_scope.
-Infix "+" := Add : oterm_scope.
-Notation "- t" := (Opp t) : oterm_scope.
-Notation "t - u" := (Add t (- u)) : oterm_scope.
-Infix "*" := Mul : oterm_scope.
-Infix "*+" := NatMul : oterm_scope.
-Notation "t ^-1" := (Inv t) : oterm_scope.
-Notation "t / u" := (Mul t u^-1) : oterm_scope.
-Infix "^+" := Exp : oterm_scope.
-Notation "t ^- n" := (t^-1 ^+ n)%oT : oterm_scope.
-Infix "==" := Equal : oterm_scope.
-Infix "<%" := Lt : oterm_scope.
-Infix "<=%" := Le : oterm_scope.
-Infix "/\" := And : oterm_scope.
-Infix "\/" := Or : oterm_scope.
-Infix "==>" := Implies : oterm_scope.
-Notation "~ f" := (Not f) : oterm_scope.
-Notation "x != y" := (Not (x == y)) : oterm_scope.
-Notation "''exists' ''X_' i , f" := (Exists i f) : oterm_scope.
-Notation "''forall' ''X_' i , f" := (Forall i f) : oterm_scope.
-
-Section Substitution.
-
-Variable T : Type.
-
-
-Fixpoint fsubst (f : formula T) (s : nat * term T) :=
- match f with
- | Bool _ => f
- | (t1 == t2) => (tsubst t1 s == tsubst t2 s)
- | (t1 <% t2) => (tsubst t1 s <% tsubst t2 s)
- | (t1 <=% t2) => (tsubst t1 s <=% tsubst t2 s)
- | (Unit t1) => Unit (tsubst t1 s)
- | (f1 /\ f2) => (fsubst f1 s /\ fsubst f2 s)
- | (f1 \/ f2) => (fsubst f1 s \/ fsubst f2 s)
- | (f1 ==> f2) => (fsubst f1 s ==> fsubst f2 s)
- | (~ f1) => (~ fsubst f1 s)
- | ('exists 'X_i, f1) => ('exists 'X_i, if i == s.1 then f1 else fsubst f1 s)
- | ('forall 'X_i, f1) => ('forall 'X_i, if i == s.1 then f1 else fsubst f1 s)
- end%oT.
-
-End Substitution.
-
-Section OrderedClause.
-
-Inductive oclause (R : Type) : Type :=
- Oclause : seq (term R) -> seq (term R) -> seq (term R) -> seq (term R) -> oclause R.
-
-Definition eq_of_oclause (R : Type)(x : oclause R) :=
- let: Oclause y _ _ _ := x in y.
-Definition neq_of_oclause (R : Type)(x : oclause R) :=
- let: Oclause _ y _ _ := x in y.
-Definition lt_of_oclause (R : Type) (x : oclause R) :=
- let: Oclause _ _ y _ := x in y.
-Definition le_of_oclause (R : Type) (x : oclause R) :=
- let: Oclause _ _ _ y := x in y.
-
-End OrderedClause.
-
-Delimit Scope oclause_scope with OCLAUSE.
-Open Scope oclause_scope.
-
-Notation "p .1" := (@eq_of_oclause _ p)
- (at level 2, left associativity, format "p .1") : oclause_scope.
-Notation "p .2" := (@neq_of_oclause _ p)
- (at level 2, left associativity, format "p .2") : oclause_scope.
-
-Notation "p .3" := (@lt_of_oclause _ p)
- (at level 2, left associativity, format "p .3") : oclause_scope.
-Notation "p .4" := (@le_of_oclause _ p)
- (at level 2, left associativity, format "p .4") : oclause_scope.
-
-Definition oclause_eq (T : eqType)(t1 t2 : oclause T) :=
- let: Oclause eq_l1 neq_l1 lt_l1 leq_l1 := t1 in
- let: Oclause eq_l2 neq_l2 lt_l2 leq_l2 := t2 in
- [&& eq_l1 == eq_l2, neq_l1 == neq_l2, lt_l1 == lt_l2 & leq_l1 == leq_l2].
-
-Lemma oclause_eqP (T : eqType) : Equality.axiom (@oclause_eq T).
-Proof.
-move=> t1 t2; apply: (iffP idP) => [|<-] /=; last first.
- by rewrite /oclause_eq; case: t1=> l1 l2 l3 l4; rewrite !eqxx.
-case: t1 => [l1 l2 l3 l4]; case: t2 => m1 m2 m3 m4 /=; case/and4P.
-by move/eqP=> -> /eqP -> /eqP -> /eqP ->.
-Qed.
-
-Canonical oclause_eqMixin (T : eqType) := EqMixin (@oclause_eqP T).
-Canonical oclause_eqType (T : eqType) :=
- Eval hnf in EqType (oclause T) (@oclause_eqMixin T).
-
-Arguments oclause_eqP T [x y].
-Prenex Implicits oclause_eq.
-
-Section EvalTerm.
-
-Variable R : realDomainType.
-
-(* Evaluation of a reified formula *)
-
-Fixpoint holds (e : seq R) (f : ord.formula R) {struct f} : Prop :=
- match f with
- | Bool b => b
- | (t1 == t2)%oT => eval e t1 = eval e t2
- | (t1 <% t2)%oT => eval e t1 < eval e t2
- | (t1 <=% t2)%oT => eval e t1 <= eval e t2
- | Unit t1 => eval e t1 \in unit
- | (f1 /\ f2)%oT => holds e f1 /\ holds e f2
- | (f1 \/ f2)%oT => holds e f1 \/ holds e f2
- | (f1 ==> f2)%oT => holds e f1 -> holds e f2
- | (~ f1)%oT => ~ holds e f1
- | ('exists 'X_i, f1)%oT => exists x, holds (set_nth 0 e i x) f1
- | ('forall 'X_i, f1)%oT => forall x, holds (set_nth 0 e i x) f1
- end.
-
-
-(* Extensionality of formula evaluation *)
-Lemma eq_holds e e' f : same_env e e' -> holds e f -> holds e' f.
-Proof.
-pose sv := set_nth (0 : R).
-have eq_i i v e1 e2: same_env e1 e2 -> same_env (sv e1 i v) (sv e2 i v).
- by move=> eq_e j; rewrite !nth_set_nth /= eq_e.
-elim: f e e' => //=.
-- by move=> t1 t2 e e' eq_e; rewrite !(eq_eval _ eq_e).
-- by move=> t1 t2 e e' eq_e; rewrite !(eq_eval _ eq_e).
-- by move=> t1 t2 e e' eq_e; rewrite !(eq_eval _ eq_e).
-- by move=> t e e' eq_e; rewrite (eq_eval _ eq_e).
-- by move=> f1 IH1 f2 IH2 e e' eq_e; move/IH2: (eq_e); move/IH1: eq_e; tauto.
-- by move=> f1 IH1 f2 IH2 e e' eq_e; move/IH2: (eq_e); move/IH1: eq_e; tauto.
-- by move=> f1 IH1 f2 IH2 e e' eq_e f12; move/IH1: (same_env_sym eq_e); eauto.
-- by move=> f1 IH1 e e'; move/same_env_sym; move/IH1; tauto.
-- by move=> i f1 IH1 e e'; move/(eq_i i)=> eq_e [x f_ex]; exists x; eauto.
-by move=> i f1 IH1 e e'; move/(eq_i i); eauto.
-Qed.
-
-(* Evaluation and substitution by a constant *)
-Lemma holds_fsubst e f i v :
- holds e (fsubst f (i, v%:T)%T) <-> holds (set_nth 0 e i v) f.
-Proof.
-elim: f e => //=; do [
- by move=> *; rewrite !eval_tsubst
-| move=> f1 IHf1 f2 IHf2 e; move: (IHf1 e) (IHf2 e); tauto
-| move=> f IHf e; move: (IHf e); tauto
-| move=> j f IHf e].
-- case eq_ji: (j == i); first rewrite (eqP eq_ji).
- by split=> [] [x f_x]; exists x; rewrite set_set_nth eqxx in f_x *.
- split=> [] [x f_x]; exists x; move: f_x; rewrite set_set_nth eq_sym eq_ji;
- have:= IHf (set_nth 0 e j x); tauto.
-case eq_ji: (j == i); first rewrite (eqP eq_ji).
- by split=> [] f_ x; move: (f_ x); rewrite set_set_nth eqxx.
-split=> [] f_ x; move: (IHf (set_nth 0 e j x)) (f_ x);
- by rewrite set_set_nth eq_sym eq_ji; tauto.
-Qed.
-
-(* Boolean test selecting formulas in the theory of rings *)
-Fixpoint rformula (f : formula R) :=
- match f with
- | Bool _ => true
- | t1 == t2 => rterm t1 && rterm t2
- | t1 <% t2 => rterm t1 && rterm t2
- | t1 <=% t2 => rterm t1 && rterm t2
- | Unit t1 => false
- | (f1 /\ f2) | (f1 \/ f2) | (f1 ==> f2) => rformula f1 && rformula f2
- | (~ f1) | ('exists 'X__, f1) | ('forall 'X__, f1) => rformula f1
- end%oT.
-
-(* An oformula stating that t1 is equal to 0 in the ring theory. *)
-Definition eq0_rform t1 :=
- let m := @ub_var R t1 in
- let: (t1', r1) := to_rterm t1 [::] m in
- let fix loop r i := match r with
- | [::] => t1' == 0
- | t :: r' =>
- let f := ('X_i * t == 1 /\ t * 'X_i == 1) in
- 'forall 'X_i, (f \/ 'X_i == t /\ ~ ('exists 'X_i, f)) ==> loop r' i.+1
- end%oT
- in loop r1 m.
-
-(* An oformula stating that t1 is less than 0 in the equational ring theory.
-Definition leq0_rform t1 :=
- let m := @ub_var R t1 in
- let: (t1', r1) := to_rterm t1 [::] m in
- let fix loop r i := match r with
- | [::] => 'exists 'X_m.+1, t1' == 'X_m.+1 * 'X_m.+1
- | t :: r' =>
- let f := ('X_i * t == 1 /\ t * 'X_i == 1) in
- 'forall 'X_i, (f \/ 'X_i == t /\ ~ ('exists 'X_i, f)) ==> loop r' i.+1
- end%oT
- in loop r1 m.
-*)
-Definition leq0_rform t1 :=
- let m := @ub_var R t1 in
- let: (t1', r1) := to_rterm t1 [::] m in
- let fix loop r i := match r with
- | [::] => t1' <=% 0
- | t :: r' =>
- let f := ('X_i * t == 1 /\ t * 'X_i == 1) in
- 'forall 'X_i, (f \/ 'X_i == t /\ ~ ('exists 'X_i, f)) ==> loop r' i.+1
- end%oT
- in loop r1 m.
-
-
-(* Definition lt0_rform t1 := *)
-(* let m := @ub_var R t1 in *)
-(* let: (t1', r1) := to_rterm t1 [::] m in *)
-(* let fix loop r i := match r with *)
-(* | [::] => 'exists 'X_m.+1, (t1' == 'X_m.+1 * 'X_m.+1 /\ ~ ('X_m.+1 == 0)) *)
-(* | t :: r' => *)
-(* let f := ('X_i * t == 1 /\ t * 'X_i == 1) in *)
-(* 'forall 'X_i, (f \/ 'X_i == t /\ ~ ('exists 'X_i, f)) ==> loop r' i.+1 *)
-(* end%oT *)
-(* in loop r1 m. *)
-
-Definition lt0_rform t1 :=
- let m := @ub_var R t1 in
- let: (t1', r1) := to_rterm t1 [::] m in
- let fix loop r i := match r with
- | [::] => t1' <% 0
- | t :: r' =>
- let f := ('X_i * t == 1 /\ t * 'X_i == 1) in
- 'forall 'X_i, (f \/ 'X_i == t /\ ~ ('exists 'X_i, f)) ==> loop r' i.+1
- end%oT
- in loop r1 m.
-
-(* Transformation of a formula in the theory of rings with units into an *)
-
-(* equivalent formula in the sub-theory of rings. *)
-Fixpoint to_rform f :=
- match f with
- | Bool b => f
- | t1 == t2 => eq0_rform (t1 - t2)
- | t1 <% t2 => lt0_rform (t1 - t2)
- | t1 <=% t2 => leq0_rform (t1 - t2)
- | Unit t1 => eq0_rform (t1 * t1^-1 - 1)
- | f1 /\ f2 => to_rform f1 /\ to_rform f2
- | f1 \/ f2 => to_rform f1 \/ to_rform f2
- | f1 ==> f2 => to_rform f1 ==> to_rform f2
- | ~ f1 => ~ to_rform f1
- | ('exists 'X_i, f1) => 'exists 'X_i, to_rform f1
- | ('forall 'X_i, f1) => 'forall 'X_i, to_rform f1
- end%oT.
-
-(* The transformation gives a ring formula. *)
-(* the last part of the proof consists in 3 cases that are exactly the same.
- how to factorize ? *)
-Lemma to_rform_rformula f : rformula (to_rform f).
-Proof.
-suffices [h1 h2 h3]:
- [/\ forall t1, rformula (eq0_rform t1),
- forall t1, rformula (lt0_rform t1) &
- forall t1, rformula (leq0_rform t1)].
- by elim: f => //= => f1 ->.
-split=> t1.
-- rewrite /eq0_rform; move: (ub_var t1) => m.
- set tr := _ m.
- suffices: all (@rterm R) (tr.1 :: tr.2)%PAIR.
- case: tr => {t1} t1 r /= /andP[t1_r].
- by elim: r m => [|t r IHr] m; rewrite /= ?andbT // => /andP[->]; apply: IHr.
- have: all (@rterm R) [::] by [].
- rewrite {}/tr; elim: t1 [::] => //=.
- + move=> t1 IHt1 t2 IHt2 r.
- move/IHt1; case: to_rterm => {t1 r IHt1} t1 r /= /andP[t1_r].
- move/IHt2; case: to_rterm => {t2 r IHt2} t2 r /= /andP[t2_r].
- by rewrite t1_r t2_r.
- + by move=> t1 IHt1 r /IHt1; case: to_rterm.
- + by move=> t1 IHt1 n r /IHt1; case: to_rterm.
- + move=> t1 IHt1 t2 IHt2 r.
- move/IHt1; case: to_rterm => {t1 r IHt1} t1 r /= /andP[t1_r].
- move/IHt2; case: to_rterm => {t2 r IHt2} t2 r /= /andP[t2_r].
- by rewrite t1_r t2_r.
- + move=> t1 IHt1 r.
- by move/IHt1; case: to_rterm => {t1 r IHt1} t1 r /=; rewrite all_rcons.
- + by move=> t1 IHt1 n r /IHt1; case: to_rterm.
-- rewrite /lt0_rform; move: (ub_var t1) => m; set tr := _ m.
- suffices: all (@rterm R) (tr.1 :: tr.2)%PAIR.
- case: tr => {t1} t1 r /= /andP[t1_r].
- by elim: r m => [|t r IHr] m; rewrite /= ?andbT // => /andP[->]; apply: IHr.
- have: all (@rterm R) [::] by [].
- rewrite {}/tr; elim: t1 [::] => //=.
- + move=> t1 IHt1 t2 IHt2 r.
- move/IHt1; case: to_rterm => {t1 r IHt1} t1 r /= /andP[t1_r].
- move/IHt2; case: to_rterm => {t2 r IHt2} t2 r /= /andP[t2_r].
- by rewrite t1_r t2_r.
- + by move=> t1 IHt1 r /IHt1; case: to_rterm.
- + by move=> t1 IHt1 n r /IHt1; case: to_rterm.
- + move=> t1 IHt1 t2 IHt2 r.
- move/IHt1; case: to_rterm => {t1 r IHt1} t1 r /= /andP[t1_r].
- move/IHt2; case: to_rterm => {t2 r IHt2} t2 r /= /andP[t2_r].
- by rewrite t1_r t2_r.
- + move=> t1 IHt1 r.
- by move/IHt1; case: to_rterm => {t1 r IHt1} t1 r /=; rewrite all_rcons.
- + by move=> t1 IHt1 n r /IHt1; case: to_rterm.
-- rewrite /leq0_rform; move: (ub_var t1) => m; set tr := _ m.
- suffices: all (@rterm R) (tr.1 :: tr.2)%PAIR.
- case: tr => {t1} t1 r /= /andP[t1_r].
- by elim: r m => [|t r IHr] m; rewrite /= ?andbT // => /andP[->]; apply: IHr.
- have: all (@rterm R) [::] by [].
- rewrite {}/tr; elim: t1 [::] => //=.
- + move=> t1 IHt1 t2 IHt2 r.
- move/IHt1; case: to_rterm => {t1 r IHt1} t1 r /= /andP[t1_r].
- move/IHt2; case: to_rterm => {t2 r IHt2} t2 r /= /andP[t2_r].
- by rewrite t1_r t2_r.
- + by move=> t1 IHt1 r /IHt1; case: to_rterm.
- + by move=> t1 IHt1 n r /IHt1; case: to_rterm.
- + move=> t1 IHt1 t2 IHt2 r.
- move/IHt1; case: to_rterm => {t1 r IHt1} t1 r /= /andP[t1_r].
- move/IHt2; case: to_rterm => {t2 r IHt2} t2 r /= /andP[t2_r].
- by rewrite t1_r t2_r.
- + move=> t1 IHt1 r.
- by move/IHt1; case: to_rterm => {t1 r IHt1} t1 r /=; rewrite all_rcons.
- + by move=> t1 IHt1 n r /IHt1; case: to_rterm.
-Qed.
-
-Import Num.Theory.
-
-(* Correctness of the transformation. *)
-Lemma to_rformP e f : holds e (to_rform f) <-> holds e f.
-Proof.
-suffices{e f} [equal0_equiv lt0_equiv le0_equiv]:
- [/\ forall e t1 t2, holds e (eq0_rform (t1 - t2)) <-> (eval e t1 == eval e t2),
- forall e t1 t2, holds e (lt0_rform (t1 - t2)) <-> (eval e t1 < eval e t2) &
- forall e t1 t2, holds e (leq0_rform (t1 - t2)) <-> (eval e t1 <= eval e t2)].
-- elim: f e => /=; try tauto.
- + move=> t1 t2 e.
- by split; [move/equal0_equiv/eqP | move/eqP/equal0_equiv].
- + by move=> t1 t2 e; split; move/lt0_equiv.
- + by move=> t1 t2 e; split; move/le0_equiv.
- + by move=> t1 e; rewrite unitrE; apply: equal0_equiv.
- + by move=> f1 IHf1 f2 IHf2 e; move: (IHf1 e) (IHf2 e); tauto.
- + by move=> f1 IHf1 f2 IHf2 e; move: (IHf1 e) (IHf2 e); tauto.
- + by move=> f1 IHf1 f2 IHf2 e; move: (IHf1 e) (IHf2 e); tauto.
- + by move=> f1 IHf1 e; move: (IHf1 e); tauto.
- + by move=> n f1 IHf1 e; split=> [] [x] /IHf1; exists x.
- + by move=> n f1 IHf1 e; split=> Hx x; apply/IHf1.
-suffices h e t1 t2 :
- [/\ holds e (eq0_rform (t1 - t2)) <-> (eval e t1 == eval e t2),
- holds e (lt0_rform (t1 - t2)) <-> (eval e t1 < eval e t2) &
- holds e (leq0_rform (t1 - t2)) <-> (eval e t1 <= eval e t2)].
- by split => e t1 t2; case: (h e t1 t2).
-rewrite -{1}(add0r (eval e t2)) -(can2_eq (subrK _) (addrK _)).
-rewrite -subr_lt0 -subr_le0 -/(eval e (t1 - t2)); move: {t1 t2}(t1 - t2)%T => t.
-have sub_var_tsubst s t0: (s.1%PAIR >= ub_var t0)%N -> tsubst t0 s = t0.
- elim: t0 {t} => //=.
- - by move=> n; case: ltngtP.
- - by move=> t1 IHt1 t2 IHt2; rewrite geq_max => /andP[/IHt1-> /IHt2->].
- - by move=> t1 IHt1 /IHt1->.
- - by move=> t1 IHt1 n /IHt1->.
- - by move=> t1 IHt1 t2 IHt2; rewrite geq_max => /andP[/IHt1-> /IHt2->].
- - by move=> t1 IHt1 /IHt1->.
- - by move=> t1 IHt1 n /IHt1->.
-pose fix rsub t' m r : term R :=
- if r is u :: r' then tsubst (rsub t' m.+1 r') (m, u^-1)%T else t'.
-pose fix ub_sub m r : Prop :=
- if r is u :: r' then (ub_var u <= m)%N /\ ub_sub m.+1 r' else true.
-suffices{t} rsub_to_r t r0 m: (m >= ub_var t)%N -> ub_sub _ m r0 ->
- let: (t', r) := to_rterm t r0 m in
- [/\ take (size r0) r = r0,
- ub_var t' <= m + size r, ub_sub _ m r & rsub t' m r = t]%N.
-- have:= rsub_to_r t [::] _ (leqnn _); rewrite /eq0_rform /lt0_rform /leq0_rform.
- case: (to_rterm _ _ _) => [t1' r1] /= [//| _ _ ub_r1 def_t].
- rewrite -{2 4 6}def_t {def_t}.
- elim: r1 (ub_var t) e ub_r1 => [|u r1 IHr1] m e /= => [_|[ub_u ub_r1]].
- by split => //; split=> /eqP.
- rewrite eval_tsubst /=; set y := eval e u; split; split => //= t_h0.
- + case: (IHr1 m.+1 (set_nth 0 e m y^-1) ub_r1) => h _ _; apply/h.
- apply: t_h0.
- rewrite nth_set_nth /= eqxx -(eval_tsubst e u (m, Const _)).
- rewrite sub_var_tsubst //= -/y.
- case Uy: (y \in unit); [left | right]; first by rewrite mulVr ?divrr.
- split=> [|[z]]; first by rewrite invr_out ?Uy.
- rewrite nth_set_nth /= eqxx.
- rewrite -!(eval_tsubst _ _ (m, Const _)) !sub_var_tsubst // -/y => yz1.
- by case/unitrP: Uy; exists z.
- + move=> x def_x.
- case: (IHr1 m.+1 (set_nth 0 e m x) ub_r1) => h _ _. apply/h.
- suff ->: x = y^-1 by []; move: def_x.
- rewrite nth_set_nth /= eqxx -(eval_tsubst e u (m, Const _)).
- rewrite sub_var_tsubst //= -/y; case=> [[xy1 yx1] | [xy nUy]].
- by rewrite -[y^-1]mul1r -[1]xy1 mulrK //; apply/unitrP; exists x.
- rewrite invr_out //; apply/unitrP=> [[z yz1]]; case: nUy; exists z.
- rewrite nth_set_nth /= eqxx -!(eval_tsubst _ _ (m, _%:T)%T).
- by rewrite !sub_var_tsubst.
- + case: (IHr1 m.+1 (set_nth 0 e m y^-1) ub_r1) => _ h _. apply/h.
- apply: t_h0.
- rewrite nth_set_nth /= eqxx -(eval_tsubst e u (m, Const _)).
- rewrite sub_var_tsubst //= -/y.
- case Uy: (y \in unit); [left | right]; first by rewrite mulVr ?divrr.
- split=> [|[z]]; first by rewrite invr_out ?Uy.
- rewrite nth_set_nth /= eqxx.
- rewrite -!(eval_tsubst _ _ (m, Const _)) !sub_var_tsubst // -/y => yz1.
- by case/unitrP: Uy; exists z.
- + move=> x def_x.
- case: (IHr1 m.+1 (set_nth 0 e m x) ub_r1) => _ h _. apply/h.
- suff ->: x = y^-1 by []; move: def_x.
- rewrite nth_set_nth /= eqxx -(eval_tsubst e u (m, Const _)).
- rewrite sub_var_tsubst //= -/y; case=> [[xy1 yx1] | [xy nUy]].
- by rewrite -[y^-1]mul1r -[1]xy1 mulrK //; apply/unitrP; exists x.
- rewrite invr_out //; apply/unitrP=> [[z yz1]]; case: nUy; exists z.
- rewrite nth_set_nth /= eqxx -!(eval_tsubst _ _ (m, _%:T)%T).
- by rewrite !sub_var_tsubst.
- + case: (IHr1 m.+1 (set_nth 0 e m y^-1) ub_r1) => _ _ h. apply/h.
- apply: t_h0.
- rewrite nth_set_nth /= eqxx -(eval_tsubst e u (m, Const _)).
- rewrite sub_var_tsubst //= -/y.
- case Uy: (y \in unit); [left | right]; first by rewrite mulVr ?divrr.
- split=> [|[z]]; first by rewrite invr_out ?Uy.
- rewrite nth_set_nth /= eqxx.
- rewrite -!(eval_tsubst _ _ (m, Const _)) !sub_var_tsubst // -/y => yz1.
- by case/unitrP: Uy; exists z.
- + move=> x def_x.
- case: (IHr1 m.+1 (set_nth 0 e m x) ub_r1) => _ _ h. apply/h.
- suff ->: x = y^-1 by []; move: def_x.
- rewrite nth_set_nth /= eqxx -(eval_tsubst e u (m, Const _)).
- rewrite sub_var_tsubst //= -/y; case=> [[xy1 yx1] | [xy nUy]].
- by rewrite -[y^-1]mul1r -[1]xy1 mulrK //; apply/unitrP; exists x.
- rewrite invr_out //; apply/unitrP=> [[z yz1]]; case: nUy; exists z.
- rewrite nth_set_nth /= eqxx -!(eval_tsubst _ _ (m, _%:T)%T).
- by rewrite !sub_var_tsubst.
-have rsub_id r t0 n: (ub_var t0 <= n)%N -> rsub t0 n r = t0.
- by elim: r n => //= t1 r IHr n let0n; rewrite IHr ?sub_var_tsubst ?leqW.
-have rsub_acc r s t1 m1:
- (ub_var t1 <= m1 + size r)%N -> rsub t1 m1 (r ++ s) = rsub t1 m1 r.
- elim: r t1 m1 => [|t1 r IHr] t2 m1 /=; first by rewrite addn0; apply: rsub_id.
- by move=> letmr; rewrite IHr ?addSnnS.
-elim: t r0 m => /=; try do [
- by move=> n r m hlt hub; rewrite take_size (ltn_addr _ hlt) rsub_id
-| by move=> n r m hlt hub; rewrite leq0n take_size rsub_id
-| move=> t1 IHt1 t2 IHt2 r m; rewrite geq_max; case/andP=> hub1 hub2 hmr;
- case: to_rterm {IHt1 hub1 hmr}(IHt1 r m hub1 hmr) => t1' r1;
- case=> htake1 hub1' hsub1 <-;
- case: to_rterm {IHt2 hub2 hsub1}(IHt2 r1 m hub2 hsub1) => t2' r2 /=;
- rewrite geq_max; case=> htake2 -> hsub2 /= <-;
- rewrite -{1 2}(cat_take_drop (size r1) r2) htake2; set r3 := drop _ _;
- rewrite size_cat addnA (leq_trans _ (leq_addr _ _)) //;
- split=> {hsub2}//;
- first by [rewrite takel_cat // -htake1 size_take geq_minr];
- rewrite -(rsub_acc r1 r3 t1') {hub1'}// -{htake1}htake2 {r3}cat_take_drop;
- by elim: r2 m => //= u r2 IHr2 m; rewrite IHr2
-| do [ move=> t1 IHt1 r m; do 2!move/IHt1=> {IHt1}IHt1
- | move=> t1 IHt1 n r m; do 2!move/IHt1=> {IHt1}IHt1];
- case: to_rterm IHt1 => t1' r1 [-> -> hsub1 <-]; split=> {hsub1}//;
- by elim: r1 m => //= u r1 IHr1 m; rewrite IHr1].
-move=> t1 IH r m letm /IH {IH} /(_ letm) {letm}.
-case: to_rterm => t1' r1 /= [def_r ub_t1' ub_r1 <-].
-rewrite size_rcons addnS leqnn -{1}cats1 takel_cat ?def_r; last first.
- by rewrite -def_r size_take geq_minr.
-elim: r1 m ub_r1 ub_t1' {def_r} => /= [|u r1 IHr1] m => [_|[->]].
- by rewrite addn0 eqxx.
-by rewrite -addSnnS => /IHr1 IH /IH[_ _ ub_r1 ->].
-Qed.
-
-(* The above proof is ugly but is in fact copypaste *)
-
-(* Boolean test selecting formulas which describe a constructible set, *)
-(* i.e. formulas without quantifiers. *)
-
-(* The quantifier elimination check. *)
-Fixpoint qf_form (f : formula R) :=
- match f with
- | Bool _ | _ == _ | Unit _ | Lt _ _ | Le _ _ => true
- | f1 /\ f2 | f1 \/ f2 | f1 ==> f2 => qf_form f1 && qf_form f2
- | ~ f1 => qf_form f1
- | _ => false
- end%oT.
-
-(* Boolean holds predicate for quantifier free formulas *)
-Definition qf_eval e := fix loop (f : formula R) : bool :=
- match f with
- | Bool b => b
- | t1 == t2 => (eval e t1 == eval e t2)%bool
- | t1 <% t2 => (eval e t1 < eval e t2)%bool
- | t1 <=% t2 => (eval e t1 <= eval e t2)%bool
- | Unit t1 => eval e t1 \in unit
- | f1 /\ f2 => loop f1 && loop f2
- | f1 \/ f2 => loop f1 || loop f2
- | f1 ==> f2 => (loop f1 ==> loop f2)%bool
- | ~ f1 => ~~ loop f1
- |_ => false
- end%oT.
-
-(* qf_eval is equivalent to holds *)
-Lemma qf_evalP e f : qf_form f -> reflect (holds e f) (qf_eval e f).
-Proof.
-elim: f => //=; try by move=> *; apply: idP.
-- by move=> t1 t2 _; apply: eqP.
-- move=> f1 IHf1 f2 IHf2 /= /andP[/IHf1[] f1T]; last by right; case.
- by case/IHf2; [left | right; case].
-- move=> f1 IHf1 f2 IHf2 /= /andP[/IHf1[] f1F]; first by do 2 left.
- by case/IHf2; [left; right | right; case].
-- move=> f1 IHf1 f2 IHf2 /= /andP[/IHf1[] f1T]; last by left.
- by case/IHf2; [left | right; move/(_ f1T)].
-by move=> f1 IHf1 /IHf1[]; [right | left].
-Qed.
-
-(* Quantifier-free formula are normalized into DNF. A DNF is *)
-(* represented by the type seq (seq (term R) * seq (term R)), where we *)
-(* separate positive and negative literals *)
-
-
-(* DNF preserving conjunction *)
-
-Definition and_odnf (bcs1 bcs2 : seq (oclause R)) :=
- \big[cat/nil]_(bc1 <- bcs1)
- map (fun bc2 : oclause R =>
- (Oclause (bc1.1 ++ bc2.1) (bc1.2 ++ bc2.2) (bc1.3 ++ bc2.3) (bc1.4 ++ bc2.4)))%OCLAUSE bcs2.
-
-(* Computes a DNF from a qf ring formula *)
-Fixpoint qf_to_odnf (f : formula R) (neg : bool) {struct f} : seq (oclause R) :=
- match f with
- | Bool b => if b (+) neg then [:: (Oclause [::] [::] [::] [::])] else [::]
- | t1 == t2 =>
- [:: if neg then (Oclause [::] [:: t1 - t2] [::] [::]) else (Oclause [:: t1 - t2] [::] [::] [::])]
- | t1 <% t2 =>
- [:: if neg then (Oclause [::] [::] [::] [:: t1 - t2]) else (Oclause [::] [::] [:: t2 - t1] [::])]
- | t1 <=% t2 =>
- [:: if neg then (Oclause [::] [::] [:: t1 - t2] [::]) else (Oclause [::] [::] [::] [:: t2 - t1])]
- | f1 /\ f2 => (if neg then cat else and_odnf) [rec f1, neg] [rec f2, neg]
- | f1 \/ f2 => (if neg then and_odnf else cat) [rec f1, neg] [rec f2, neg]
- | f1 ==> f2 => (if neg then and_odnf else cat) [rec f1, ~~ neg] [rec f2, neg]
- | ~ f1 => [rec f1, ~~ neg]
- | _ => if neg then [:: (Oclause [::] [::] [::] [::])] else [::]
- end%oT where "[ 'rec' f , neg ]" := (qf_to_odnf f neg).
-
-(* Conversely, transforms a DNF into a formula *)
-Definition odnf_to_oform :=
- let pos_lit t := And (t == 0)%oT in let neg_lit t := And (t != 0)%oT in
- let lt_lit t := And (0 <% t)%oT in let le_lit t := And (0 <=% t)%oT in
- let ocls (bc : oclause R) :=
- Or
- (foldr pos_lit True bc.1 /\ foldr neg_lit True bc.2 /\
- foldr lt_lit True bc.3 /\ foldr le_lit True bc.4) in
- foldr ocls False.
-
-(* Catenation of dnf is the Or of formulas *)
-Lemma cat_dnfP e bcs1 bcs2 :
- qf_eval e (odnf_to_oform (bcs1 ++ bcs2))
- = qf_eval e (odnf_to_oform bcs1 \/ odnf_to_oform bcs2).
-Proof.
-by elim: bcs1 => //= bc1 bcs1 IH1; rewrite -orbA; congr orb; rewrite IH1.
-Qed.
-
-
-
-(* and_dnf is the And of formulas *)
-Lemma and_odnfP e bcs1 bcs2 :
- qf_eval e (odnf_to_oform (and_odnf bcs1 bcs2))
- = qf_eval e (odnf_to_oform bcs1 /\ odnf_to_oform bcs2).
-Proof.
-elim: bcs1 => [|bc1 bcs1 IH1] /=; first by rewrite /and_odnf big_nil.
-rewrite /and_odnf big_cons -/(and_odnf bcs1 bcs2) cat_dnfP /=.
-rewrite {}IH1 /= andb_orl; congr orb.
-elim: bcs2 bc1 {bcs1} => [|bc2 bcs2 IH] bc1 /=; first by rewrite andbF.
-rewrite {}IH /= andb_orr; congr orb => {bcs2}.
-suffices aux (l1 l2 : seq (term R)) g : let redg := foldr (And \o g) True in
- qf_eval e (redg (l1 ++ l2)) = qf_eval e (redg l1 /\ redg l2)%oT.
-+ rewrite !aux /= !andbA; congr (_ && _); rewrite -!andbA; congr (_ && _).
- rewrite -andbCA; congr (_ && _); bool_congr; rewrite andbCA; bool_congr.
- by rewrite andbA andbC !andbA.
-by elim: l1 => [| t1 l1 IHl1] //=; rewrite -andbA IHl1.
-Qed.
-
-Lemma qf_to_dnfP e :
- let qev f b := qf_eval e (odnf_to_oform (qf_to_odnf f b)) in
- forall f, qf_form f && rformula f -> qev f false = qf_eval e f.
-Proof.
-move=> qev; have qevT f: qev f true = ~~ qev f false.
- rewrite {}/qev; elim: f => //=; do [by case | move=> f1 IH1 f2 IH2 | ].
- - by move=> t1 t2; rewrite !andbT !orbF.
- - by move=> t1 t2; rewrite !andbT !orbF; rewrite !subr_gte0 -lerNgt.
- - by move=> t1 t2; rewrite !andbT !orbF; rewrite !subr_gte0 -ltrNge.
- - by rewrite and_odnfP cat_dnfP negb_and -IH1 -IH2.
- - by rewrite and_odnfP cat_dnfP negb_or -IH1 -IH2.
- - by rewrite and_odnfP cat_dnfP /= negb_or IH1 -IH2 negbK.
- by move=> t1 ->; rewrite negbK.
-rewrite /qev; elim=> //=; first by case.
-- by move=> t1 t2 _; rewrite subr_eq0 !andbT orbF.
-- by move=> t1 t2 _; rewrite orbF !andbT subr_gte0.
-- by move=> t1 t2 _; rewrite orbF !andbT subr_gte0.
-- move=> f1 IH1 f2 IH2; rewrite andbCA -andbA andbCA andbA; case/andP.
- by rewrite and_odnfP /= => /IH1-> /IH2->.
-- move=> f1 IH1 f2 IH2; rewrite andbCA -andbA andbCA andbA; case/andP.
- by rewrite cat_dnfP /= => /IH1-> => /IH2->.
-- move=> f1 IH1 f2 IH2; rewrite andbCA -andbA andbCA andbA; case/andP.
- by rewrite cat_dnfP /= [qf_eval _ _]qevT -implybE => /IH1 <- /IH2->.
-by move=> f1 IH1 /IH1 <-; rewrite -qevT.
-Qed.
-
-Lemma dnf_to_form_qf bcs : qf_form (odnf_to_oform bcs).
-Proof.
-elim: bcs => //= [[clT clF] clLt clLe ? ->] /=; elim: clT => //=.
-by rewrite andbT; elim: clF; elim: clLt => //; elim: clLe.
-Qed.
-
-Definition dnf_rterm (cl : oclause R) :=
- [&& all (@rterm R) cl.1, all (@rterm R) cl.2,
- all (@rterm R) cl.3 & all (@rterm R) cl.4].
-
-Lemma qf_to_dnf_rterm f b : rformula f -> all dnf_rterm (qf_to_odnf f b).
-Proof.
-set ok := all dnf_rterm.
-have cat_ok bcs1 bcs2: ok bcs1 -> ok bcs2 -> ok (bcs1 ++ bcs2).
- by move=> ok1 ok2; rewrite [ok _]all_cat; apply/andP.
-have and_ok bcs1 bcs2: ok bcs1 -> ok bcs2 -> ok (and_odnf bcs1 bcs2).
- rewrite /and_odnf unlock; elim: bcs1 => //= cl1 bcs1 IH1; rewrite -andbA.
- case/and3P=> ok11 ok12 ok1 ok2; rewrite cat_ok ?{}IH1 {bcs1 ok1}//.
- elim: bcs2 ok2 => //= cl2 bcs2 IH2 /andP[ok2 /IH2->].
- by rewrite /dnf_rterm /= !all_cat andbT ok11; case/and3P: ok12=> -> -> ->.
-elim: f b => //=; try by [move=> _ ? ? [] | move=> ? ? ? ? [] /= /andP[]; auto].
-- by do 2!case.
-- by rewrite /dnf_rterm => ? ? [] /= ->.
-- by rewrite /dnf_rterm => ? ? [] /=; rewrite andbC !andbT.
-- by rewrite /dnf_rterm => ? ? [] /=; rewrite andbC !andbT.
-by auto.
-Qed.
-
-Lemma dnf_to_rform bcs : rformula (odnf_to_oform bcs) = all dnf_rterm bcs.
-Proof.
-elim: bcs => //= [[cl1 cl2 cl3 cl4] bcs ->]; rewrite {2}/dnf_rterm /=; congr (_ && _).
-congr andb; first by elim: cl1 => //= t cl ->; rewrite andbT.
-congr andb; first by elim: cl2 => //= t cl ->; rewrite andbT.
-congr andb; first by elim: cl3 => //= t cl ->.
-by elim: cl4 => //= t cl ->.
-Qed.
-
-Implicit Type f : formula R.
-
-Fixpoint leq_elim_aux (eq_l lt_l le_l : seq (term R)) :=
- match le_l with
- [::] => [:: (eq_l, lt_l)]
- |le1 :: le_l' =>
- let res := leq_elim_aux eq_l lt_l le_l' in
- let as_eq := map (fun x => (le1 :: x.1%PAIR, x.2%PAIR)) res in
- let as_lt := map (fun x => (x.1%PAIR, le1 :: x.2%PAIR)) res in
- as_eq ++ as_lt
- end.
-
-Definition oclause_leq_elim oc : seq (oclause R) :=
- let: Oclause eq_l neq_l lt_l le_l := oc in
- map (fun x => Oclause x.1%PAIR neq_l x.2%PAIR [::])
- (leq_elim_aux eq_l lt_l le_l).
-
-Definition terms_of_oclause (oc : oclause R) :=
- let: Oclause eq_l neq_l lt_l le_l := oc in
- eq_l ++ neq_l ++ lt_l ++ le_l.
-
-Lemma terms_of_leq_elim oc1 oc2:
- oc2 \in (oclause_leq_elim oc1) ->
- (terms_of_oclause oc2) =i (terms_of_oclause oc1).
-case: oc1 => eq1 neq1 lt1 leq1 /=.
-elim: leq1 eq1 lt1 oc2 => [|t1 leq1 ih] eq1 lt1 [eq2 neq2 lt2 leq2] /=.
- by rewrite inE; case/eqP=> -> -> -> -> ?.
-rewrite map_cat /= mem_cat -!map_comp; set f := fun _ => _.
-rewrite -/f in ih; case/orP.
- case/mapP=> [[y1 y2]] yin ye.
- move: (ih eq1 lt1 (f (y1, y2))); rewrite mem_map //; last first.
- by move=> [u1 u2] [v1 v2]; rewrite /f /=; case=> -> ->.
- move/(_ yin); move: ye; rewrite /f /=; case=> -> -> -> -> /= h.
- move=> u; rewrite in_cons (h u) !mem_cat in_cons.
- by rewrite orbC !orbA; set x := _ || (u \in lt1); rewrite orbAC.
-case/mapP=> [[y1 y2]] yin ye.
-move: (ih eq1 lt1 (f (y1, y2))); rewrite mem_map //; last first.
- by move=> [u1 u2] [v1 v2]; rewrite /f /=; case=> -> ->.
-move/(_ yin); move: ye; rewrite /f /=; case=> -> -> -> -> /= h u.
-rewrite !mem_cat !in_cons orbA orbCA -!orbA; move: (h u); rewrite !mem_cat=> ->.
-by rewrite orbC !orbA; set x := _ || (u \in lt1); rewrite orbAC.
-Qed.
-
-Lemma odnf_to_oform_cat e c d : holds e (odnf_to_oform (c ++ d))
- <-> holds e ((odnf_to_oform c) \/ (odnf_to_oform d))%oT.
-Proof.
-elim: c d => [| tc c ihc] d /=; first by split => // hd; [right | case: hd].
-rewrite ihc /=; split.
- case; first by case=> ?; case=> ?; case=> ? ?; left; left.
- case; first by move=> ?; left; right.
- by move=> ?; right.
-case; last by move=> ?; right; right.
-case; last by move=> ?; right; left.
-by do 3!case=> ?; move=> ?; left.
-Qed.
-
-Lemma oclause_leq_elimP oc e :
- holds e (odnf_to_oform [:: oc]) <->
- holds e (odnf_to_oform (oclause_leq_elim oc)).
-Proof.
-case: oc => eq_l neq_l lt_l le_l; rewrite /oclause_leq_elim.
-elim: le_l eq_l neq_l lt_l => [|t le_l ih] eq_l neq_l lt_l //=.
-move: (ih eq_l neq_l lt_l) => /= {ih}.
-set x1 := foldr _ _ _; set x2 := foldr _ _ _; set x3 := foldr _ _ _.
-set x4 := foldr _ _ _ => h.
-have -> : (holds e x1 /\ holds e x2 /\ holds e x3 /\ 0%:R <= eval e t /\
- holds e x4 \/ false) <->
- (0%:R <= eval e t) /\ (holds e x1 /\ holds e x2 /\ holds e x3 /\
- holds e x4 \/ false).
- split; first by case=> //; do 4!(case=> ?); move=> ?; split => //; left.
- by case=> ?; case=> //; do 3!(case=> ?); move=> ?; left.
-rewrite h {h} /= !map_cat /= -!map_comp.
-set s1 := [seq _ | _ <- _]; set s2 := [seq _ | _ <- _].
-set s3 := [seq _ | _ <- _]. rewrite odnf_to_oform_cat.
-suff {x1 x2 x3 x4} /= -> :
- holds e (odnf_to_oform s2) <-> eval e t == 0%:R /\ holds e (odnf_to_oform s1).
- suff /= -> :
- holds e (odnf_to_oform s3) <-> 0%:R < eval e t /\ holds e (odnf_to_oform s1).
- rewrite ler_eqVlt eq_sym; split; first by case; case/orP=> -> ?; [left|right].
- by case; [case=> -> ? /= |case=> ->; rewrite orbT].
- rewrite /s1 /s3.
- elim: (leq_elim_aux eq_l lt_l le_l) => /= [| t1 l ih]; first by split=> // [[]].
- rewrite /= ih; split.
- case; last by case=> -> ?; split=> //; right.
- by do 2!case=> ?; case; case=> -> ? _; split => //; auto.
- by case=> ->; case; [do 3!case=> ?; move=> _; left | right].
-rewrite /s2 /s1.
-elim: (leq_elim_aux eq_l lt_l le_l) => /= [| t1 l ih]; first by split=> // [[]].
-rewrite /= ih; split.
- case; last by case=> -> ?; split=> //; right.
- by case; case=> /eqP ? ?; do 2!case=> ?; move=> _; split=> //; left.
-case=> /eqP ?; case; first by do 3!case=> ?; move=> _; left.
-by right; split=> //; apply/eqP.
-Qed.
-
-Fixpoint neq_elim_aux (lt_l neq_l : seq (term R)) :=
- match neq_l with
- [::] => [:: lt_l]
- |neq1 :: neq_l' =>
- let res := neq_elim_aux lt_l neq_l' in
- let as_pos := map (fun x => neq1 :: x) res in
- let as_neg := map (fun x => Opp neq1 :: x) res in
- as_pos ++ as_neg
- end.
-
-Definition oclause_neq_elim oc : seq (oclause R) :=
- let: Oclause eq_l neq_l lt_l le_l := oc in
- map (fun x => Oclause eq_l [::] x le_l) (neq_elim_aux lt_l neq_l).
-
-Lemma terms_of_neq_elim oc1 oc2:
- oc2 \in (oclause_neq_elim oc1) ->
- {subset (terms_of_oclause oc2) <= (terms_of_oclause oc1) ++ (map Opp oc1.2)}.
-Proof.
-case: oc1 => eq1 neq1 lt1 leq1 /=.
-elim: neq1 lt1 oc2 => [|t1 neq1 ih] lt1 [eq2 neq2 lt2 leq2] /=.
- by rewrite inE; case/eqP=> -> -> -> ->; rewrite !cats0 !cat0s.
-rewrite map_cat /= mem_cat -!map_comp; set f := fun _ => _.
-rewrite -/f in ih; case/orP.
- case/mapP=> y yin ye.
- move: (ih lt1 (f y)); rewrite mem_map //; last first.
- by move=> u v; rewrite /f /=; case.
- move/(_ yin); move: ye; rewrite /f /=; case=> -> -> -> -> /= h.
- move=> u. rewrite !mem_cat !in_cons orbAC orbC mem_cat -!orbA.
- case/orP; first by move->; rewrite !orbT.
- rewrite !orbA [_ || (_ \in eq1)]orbC; move: (h u); rewrite !mem_cat=> hu.
- by move/hu; do 2!(case/orP; last by move->; rewrite !orbT); move->.
-case/mapP=> y yin ye.
-move: (ih lt1 (f y)); rewrite mem_map //; last first.
- by move=> u v; rewrite /f /=; case.
-move/(_ yin); move: ye; rewrite /f /=; case=> -> -> -> -> /= h.
-move=> u; rewrite !mem_cat !in_cons orbAC orbC mem_cat -!orbA.
-case/orP; first by move->; rewrite !orbT.
-rewrite !orbA [_ || (_ \in eq1)]orbC; move: (h u); rewrite !mem_cat=> hu.
-by move/hu; do 2!(case/orP; last by move->; rewrite !orbT); move->.
-Qed.
-
-
-Lemma oclause_neq_elimP oc e :
- holds e (odnf_to_oform [:: oc]) <->
- holds e (odnf_to_oform (oclause_neq_elim oc)).
-Proof.
-case: oc => eq_l neq_l lt_l le_l; rewrite /oclause_neq_elim.
-elim: neq_l lt_l => [|t neq_l ih] lt_l //=.
-move: (ih lt_l) => /= {ih}.
-set x1 := foldr _ _ _; set x2 := foldr _ _ _; set x3 := foldr _ _ _.
-set x4 := foldr _ _ _ => h /=.
-have -> : holds e x1 /\
- (eval e t <> 0%:R /\
- holds e x2) /\
- holds e x3 /\ holds e x4 \/
- false <->
- (eval e t <> 0%:R) /\ (holds e x1 /\ holds e x2 /\ holds e x3 /\
- holds e x4 \/ false).
- split; case=> //.
- - by case=> ?; case; case=> ? ? [] ? ?; split=> //; left.
- - by move=> ?; case=> //; do 3!case=> ?; move=> ?; left.
-rewrite h {h} /= !map_cat /= -!map_comp.
-set s1 := [seq _ | _ <- _]; set s2 := [seq _ | _ <- _].
-set s3 := [seq _ | _ <- _]; rewrite odnf_to_oform_cat.
-suff {x1 x2 x3 x4} /= -> :
- holds e (odnf_to_oform s2) <-> 0%:R < eval e t/\ holds e (odnf_to_oform s1).
- suff /= -> :
- holds e (odnf_to_oform s3) <-> 0%:R < - eval e t /\ holds e (odnf_to_oform s1).
- rewrite oppr_gt0; split.
- by case; move/eqP; rewrite neqr_lt; case/orP=> -> h1; [right | left].
- by case; case=> h ?; split=> //; apply/eqP; rewrite neqr_lt h ?orbT.
- rewrite /s1 /s3.
- elim: (neq_elim_aux lt_l neq_l) => /= [| t1 l ih] /=; first by split => //; case.
- set y1 := foldr _ _ _; set y2 := foldr _ _ _; set y3 := foldr _ _ _.
- rewrite ih; split.
- case; first by case=> ?; case=> _; case; case=> -> ? ?; split=> //; left.
- by case=> ? ?; split=> //; right.
- by case=> ->; case; [case=> ?; case=> _; case=> ? ?; left| move=> ?; right].
-rewrite /s1 /s2.
-elim: (neq_elim_aux lt_l neq_l) => /= [| t1 l ih] /=; first by split => //; case.
-set y1 := foldr _ _ _; set y2 := foldr _ _ _; set y3 := foldr _ _ _.
-rewrite ih; split.
- case; first by case=> ? [] _ [] [] ? ? ?; split=> //; left.
- by case=> ? ?; split=> //; right.
-case=> ? []; last by right.
-by case=> ? [] _ [] ? ?; left.
-Qed.
-
-Definition oclause_neq_leq_elim oc :=
- flatten (map oclause_neq_elim (oclause_leq_elim oc)).
-
-Lemma terms_of_neq_leq_elim oc1 oc2:
- oc2 \in (oclause_neq_leq_elim oc1) ->
- {subset (terms_of_oclause oc2) <= (terms_of_oclause oc1) ++ map Opp oc1.2}.
-Proof.
-rewrite /oclause_neq_leq_elim/flatten; rewrite foldr_map.
-suff : forall oc3,
- oc3 \in (oclause_leq_elim oc1) ->
- (terms_of_oclause oc3 =i terms_of_oclause oc1) /\ oc3.2 = oc1.2.
- elim: (oclause_leq_elim oc1) => [| t l ih] //= h1.
- rewrite mem_cat; case/orP.
- - move/terms_of_neq_elim=> h u; move/(h u); rewrite !mem_cat.
- by case: (h1 t (mem_head _ _)); move/(_ u)=> -> ->.
- - by move=> h; apply: (ih _ h) => ? loc3; apply: h1; rewrite in_cons loc3 orbT.
-move=> {oc2} oc3 hoc3; split; first exact: terms_of_leq_elim.
-case: oc3 hoc3=> eq2 neq2 lt2 leq2 /=; case: oc1=> eq1 neq1 lt1 leq1 /=.
-elim: leq1 => [| t1 le1 ih] //=; first by rewrite inE; case/eqP=> _ ->.
-rewrite map_cat mem_cat; move: ih.
-elim: (leq_elim_aux eq1 lt1 le1) => [| t2 l2 ih2] //=; rewrite !in_cons.
-move=> h1; case/orP=> /=.
- case/orP; first by case/eqP.
- by move=> h2; apply: ih2; rewrite ?h2 // => - h3; apply: h1; rewrite h3 orbT.
-case/orP; first by case/eqP.
-move=> h3; apply: ih2; last by rewrite h3 orbT.
-by move=> h2; apply: h1; rewrite h2 orbT.
-Qed.
-
-Lemma oclause_neq_leq_elimP oc e :
- holds e (odnf_to_oform [:: oc]) <->
- holds e (odnf_to_oform (oclause_neq_leq_elim oc)).
-Proof.
-rewrite /oclause_neq_leq_elim.
-rewrite oclause_leq_elimP; elim: (oclause_leq_elim oc) => [| t l ih] //=.
-rewrite odnf_to_oform_cat /= ih -oclause_neq_elimP /=.
-suff -> : forall A, A \/ false <-> A by [].
-by intuition.
-Qed.
-
-Definition oclause_to_w oc :=
- let s := oclause_neq_leq_elim oc in
- map (fun x => let: Oclause eq_l neq_l lt_l leq_l := x in (eq_l, lt_l)) s.
-
-Definition w_to_oclause (t : seq (term R) * seq (term R)) :=
- Oclause t.1%PAIR [::] t.2%PAIR [::].
-
-Lemma oclause_leq_elim4 bc oc : oc \in (oclause_leq_elim bc) -> oc.4 == [::].
-Proof.
-case: bc => bc1 bc2 bc3 bc4; elim: bc4 bc1 bc3 oc => [|t bc4 ih] bc1 bc3 /= oc.
- by rewrite inE; move/eqP; case: oc => ? ? ? oc4 /=; case=> _ _ _ /eqP.
-rewrite map_cat; move: (ih bc1 bc3 oc) => /= {ih}.
-elim: (leq_elim_aux bc1 bc3 bc4) => [| t2 l2 ih2] //= ih1.
-rewrite in_cons; case/orP.
- by move/eqP; case: oc {ih1 ih2} => ? ? ? ? [] /= _ _ _ /eqP.
-rewrite mem_cat; case/orP=> [hoc1|].
- apply: ih2; first by move=> hoc2; apply: ih1; rewrite in_cons hoc2 orbT.
- by rewrite mem_cat hoc1.
-rewrite in_cons; case/orP=> [| hoc1].
- by move/eqP; case: {ih1 ih2} oc=> ? ? ? ? [] /= _ _ _ /eqP.
-apply: ih2; first by move=> hoc2; apply: ih1; rewrite in_cons hoc2 orbT.
-by rewrite mem_cat hoc1 orbT.
-Qed.
-
-Lemma oclause_neq_elim2 bc oc :
- oc \in (oclause_neq_elim bc) -> (oc.2 == [::]) && (oc.4 == bc.4).
-Proof.
-case: bc => bc1 bc2 bc3 bc4; elim: bc2 bc4 oc => [|t bc2 /= ih] bc4 /= oc.
- by rewrite inE; move/eqP; case: oc => ? ? ? oc4 /=; case=> _ /eqP -> _ /eqP.
-rewrite map_cat; move: (ih bc4 oc) => /= {ih}.
-elim: (neq_elim_aux bc3 bc2) => [| t2 l2 ih2] //= ih1.
-rewrite in_cons; case/orP.
- by move/eqP; case: oc {ih1 ih2} => ? ? ? ? [] /= _ -> _ ->; rewrite !eqxx.
-rewrite mem_cat; case/orP=> [hoc1|].
- apply: ih2; first by move=> hoc2; apply: ih1; rewrite in_cons hoc2 orbT.
- by rewrite mem_cat hoc1.
-rewrite in_cons; case/orP=> [| hoc1].
- by move/eqP; case: {ih1 ih2} oc=> ? ? ? ? [] /= _ -> _ ->; rewrite !eqxx.
-apply: ih2; first by move=> hoc2; apply: ih1; rewrite in_cons hoc2 orbT.
-by rewrite mem_cat hoc1 orbT.
-Qed.
-
-Lemma oclause_to_wP e bc :
- holds e (odnf_to_oform (oclause_neq_leq_elim bc)) <->
- holds e (odnf_to_oform (map w_to_oclause (oclause_to_w bc))).
-Proof.
-rewrite /oclause_to_w /oclause_neq_leq_elim.
-move: (@oclause_leq_elim4 bc).
-elim: (oclause_leq_elim bc) => [| t1 l1 ih1] //= h4.
-rewrite !map_cat !odnf_to_oform_cat.
-rewrite -[holds e (_ \/ _)]/(holds e _ \/ holds e _).
-suff <- : (oclause_neq_elim t1) = map w_to_oclause
- [seq (let: Oclause eq_l _ lt_l _ := x in (eq_l, lt_l))
- | x <- oclause_neq_elim t1].
- by rewrite ih1 // => - oc hoc; apply: h4; rewrite in_cons hoc orbT.
-have : forall oc, oc \in (oclause_neq_elim t1) -> oc.2 = [::] /\ oc.4 = [::].
- move=> oc hoc; move/oclause_neq_elim2: (hoc); case/andP=> /eqP -> /eqP ->.
- by move/eqP: (h4 _ (mem_head _ _))->.
-elim: (oclause_neq_elim t1) => [| [teq1 tneq1 tleq1 tlt1] l2 ih2] h24 //=.
-rewrite /w_to_oclause /=; move: (h24 _ (mem_head _ _ ))=> /= [] -> ->.
-by congr (_ :: _); apply: ih2 => oc hoc; apply: h24; rewrite in_cons hoc orbT.
-Qed.
-
-Variable wproj : nat -> (seq (term R) * seq (term R)) -> formula R.
-
-Definition proj (n : nat)(oc : oclause R) :=
- foldr Or False (map (wproj n) (oclause_to_w oc)).
-
-Hypothesis wf_QE_wproj : forall i bc (bc_i := wproj i bc),
- dnf_rterm (w_to_oclause bc) -> qf_form bc_i && rformula bc_i.
-
-Lemma dnf_rterm_subproof bc : dnf_rterm bc ->
- all (dnf_rterm \o w_to_oclause) (oclause_to_w bc).
-Proof.
-case: bc => leq lneql llt lle; rewrite /dnf_rterm /=; case/and4P=> req rneq rlt rle.
-rewrite /oclause_to_w /= !all_map.
-apply/allP => [] [oc_eq oc_neq oc_le oc_lt] hoc; rewrite /dnf_rterm /= andbT.
-rewrite -all_cat; apply/allP=> u hu; move/terms_of_neq_leq_elim: hoc => /=.
-move/(_ u); rewrite !mem_cat.
-have {hu} hu : [|| u \in oc_eq, u \in oc_neq, u \in oc_le | u \in oc_lt].
- by move: hu; rewrite mem_cat; case/orP=> ->; rewrite ?orbT.
-move/(_ hu); case/orP; last first.
- move: rneq.
- have <- : (all (@rterm R) (map Opp lneql)) = all (@rterm R) lneql.
- by elim: lneql => [| t l] //= ->.
- by move/allP; apply.
-case/orP; first by apply: (allP req).
-case/orP; first by apply: (allP rneq).
-case/orP; first by apply: (allP rlt).
-exact: (allP rle).
-Qed.
-
-
-Lemma wf_QE_proj i : forall bc (bc_i := proj i bc),
- dnf_rterm bc -> qf_form bc_i && rformula bc_i.
-Proof.
-case=> leq lneql llt lle /= hdnf; move: (hdnf).
-rewrite /dnf_rterm /=; case/and4P=> req rneq rlt rle; rewrite /proj; apply/andP.
-move: (dnf_rterm_subproof hdnf).
-elim: (oclause_to_w _ ) => //= [a t] ih /andP [h1 h2].
-by case: (ih h2)=> -> ->; case/andP: (wf_QE_wproj i h1) => -> ->.
-Qed.
-
-Hypothesis valid_QE_wproj :
- forall i bc (bc' := w_to_oclause bc)
- (ex_i_bc := ('exists 'X_i, odnf_to_oform [:: bc'])%oT) e,
- dnf_rterm bc' ->
- reflect (holds e ex_i_bc) (qf_eval e (wproj i bc)).
-
-Lemma valid_QE_proj e i : forall bc (bc_i := proj i bc)
- (ex_i_bc := ('exists 'X_i, odnf_to_oform [:: bc])%oT),
- dnf_rterm bc -> reflect (holds e ex_i_bc) (qf_eval e (proj i bc)).
-Proof.
-move=> bc; rewrite /dnf_rterm => hdnf; rewrite /proj; apply: (equivP idP).
-have -> : holds e ('exists 'X_i, odnf_to_oform [:: bc]) <->
- (exists x : R, holds (set_nth 0 e i x)
- (odnf_to_oform (oclause_neq_leq_elim bc))).
- split; case=> x h; exists x; first by rewrite -oclause_neq_leq_elimP.
- by rewrite oclause_neq_leq_elimP.
-have -> :
- (exists x : R,
- holds (set_nth 0 e i x) (odnf_to_oform (oclause_neq_leq_elim bc))) <->
- (exists x : R,
- holds (set_nth 0 e i x) (odnf_to_oform (map w_to_oclause (oclause_to_w bc)))).
- by split; case=> x; move/oclause_to_wP=> h; exists x.
-move: (dnf_rterm_subproof hdnf).
-rewrite /oclause_to_w; elim: (oclause_neq_leq_elim bc) => /= [|a l ih].
- by split=> //; case.
-case/andP=> h1 h2; have {ih h2} ih := (ih h2); split.
-- case/orP.
- move/(valid_QE_wproj i e h1)=> /= [x /=] [] // [] h2 [] _ [] h3 _; exists x.
- by left.
- by case/ih => x h; exists x; right.
-- case=> x [] /=.
- + case=> h2 [] _ h3; apply/orP; left; apply/valid_QE_wproj => //=.
- by exists x; left.
- + by move=> hx; apply/orP; right; apply/ih; exists x.
-Qed.
-
-Let elim_aux f n := foldr Or False (map (proj n) (qf_to_odnf f false)).
-
-Fixpoint quantifier_elim f :=
- match f with
- | f1 /\ f2 => (quantifier_elim f1) /\ (quantifier_elim f2)
- | f1 \/ f2 => (quantifier_elim f1) \/ (quantifier_elim f2)
- | f1 ==> f2 => (~ quantifier_elim f1) \/ (quantifier_elim f2)
- | ~ f => ~ quantifier_elim f
- | ('exists 'X_n, f) => elim_aux (quantifier_elim f) n
- | ('forall 'X_n, f) => ~ elim_aux (~ quantifier_elim f) n
- | _ => f
- end%oT.
-
-Lemma quantifier_elim_wf f :
- let qf := quantifier_elim f in rformula f -> qf_form qf && rformula qf.
-Proof.
-suffices aux_wf f0 n : let qf := elim_aux f0 n in
- rformula f0 -> qf_form qf && rformula qf.
-- by elim: f => //=; do ?[ move=> f1 IH1 f2 IH2;
- case/andP=> rf1 rf2;
- case/andP:(IH1 rf1)=> -> ->;
- case/andP:(IH2 rf2)=> -> -> //
- | move=> n f1 IH rf1;
- case/andP: (IH rf1)=> qff rf;
- rewrite aux_wf ].
-rewrite /elim_aux => rf.
-suffices or_wf fs : let ofs := foldr Or False fs in
- all qf_form fs && all rformula fs -> qf_form ofs && rformula ofs.
-- apply: or_wf.
- suffices map_proj_wf bcs: let mbcs := map (proj n) bcs in
- all dnf_rterm bcs -> all qf_form mbcs && all rformula mbcs.
- by apply: map_proj_wf; apply: qf_to_dnf_rterm.
- elim: bcs => [|bc bcs ihb] bcsr //= /andP[rbc rbcs].
- by rewrite andbAC andbA wf_QE_proj //= andbC ihb.
-elim: fs => //= g gs ihg; rewrite -andbA => /and4P[-> qgs -> rgs] /=.
-by apply: ihg; rewrite qgs rgs.
-Qed.
-
-Lemma quantifier_elim_rformP e f :
- rformula f -> reflect (holds e f) (qf_eval e (quantifier_elim f)).
-Proof.
-pose rc e n f := exists x, qf_eval (set_nth 0 e n x) f.
-have auxP f0 e0 n0: qf_form f0 && rformula f0 ->
- reflect (rc e0 n0 f0) (qf_eval e0 (elim_aux f0 n0)).
-+ rewrite /elim_aux => cf; set bcs := qf_to_odnf f0 false.
- apply: (@iffP (rc e0 n0 (odnf_to_oform bcs))); last first.
- - by case=> x; rewrite -qf_to_dnfP //; exists x.
- - by case=> x; rewrite qf_to_dnfP //; exists x.
- have: all dnf_rterm bcs by case/andP: cf => _; apply: qf_to_dnf_rterm.
- elim: {f0 cf}bcs => [|bc bcs IHbcs] /=; first by right; case.
- case/andP=> r_bc /IHbcs {IHbcs}bcsP.
- have f_qf := dnf_to_form_qf [:: bc].
- case: valid_QE_proj => //= [ex_x|no_x].
- left; case: ex_x => x /(qf_evalP _ f_qf); rewrite /= orbF => bc_x.
- by exists x; rewrite /= bc_x.
- apply: (iffP bcsP) => [[x bcs_x] | [x]] /=.
- by exists x; rewrite /= bcs_x orbT.
- case/orP => [bc_x|]; last by exists x.
- by case: no_x; exists x; apply/(qf_evalP _ f_qf); rewrite /= bc_x.
-elim: f e => //.
-- by move=> b e _; apply: idP.
-- by move=> t1 t2 e _; apply: eqP.
-- by move=> t1 t2 e _; apply: idP.
-- by move=> t1 t2 e _; apply: idP.
-- move=> f1 IH1 f2 IH2 e /= /andP[/IH1[] f1e]; last by right; case.
- by case/IH2; [left | right; case].
-- move=> f1 IH1 f2 IH2 e /= /andP[/IH1[] f1e]; first by do 2!left.
- by case/IH2; [left; right | right; case].
-- move=> f1 IH1 f2 IH2 e /= /andP[/IH1[] f1e]; last by left.
- by case/IH2; [left | right; move/(_ f1e)].
-- by move=> f IHf e /= /IHf[]; [right | left].
-- move=> n f IHf e /= rf; have rqf := quantifier_elim_wf rf.
- by apply: (iffP (auxP _ _ _ rqf)) => [] [x]; exists x; apply/IHf.
-move=> n f IHf e /= rf; have rqf := quantifier_elim_wf rf.
-case: auxP => // [f_x|no_x]; first by right=> no_x; case: f_x => x /IHf[].
-by left=> x; apply/IHf=> //; apply/idPn=> f_x; case: no_x; exists x.
-Qed.
-
-Definition proj_sat e f := qf_eval e (quantifier_elim (to_rform f)).
-
-Lemma proj_satP : forall e f, reflect (holds e f) (proj_sat e f).
-Proof.
-move=> e f; have fP := quantifier_elim_rformP e (to_rform_rformula f).
-by apply: (iffP fP); move/to_rformP.
-Qed.
-
-End EvalTerm.
-
-End ord. \ No newline at end of file
diff --git a/mathcomp/real_closed/polyorder.v b/mathcomp/real_closed/polyorder.v
deleted file mode 100644
index 4a96dcc..0000000
--- a/mathcomp/real_closed/polyorder.v
+++ /dev/null
@@ -1,274 +0,0 @@
-(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-(* Distributed under the terms of CeCILL-B. *)
-Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp
-Require Import ssrfun ssrbool eqtype ssrnat seq choice fintype.
-From mathcomp
-Require Import ssralg poly ssrnum zmodp polydiv interval.
-
-Import GRing.Theory.
-Import Num.Theory.
-
-Import Pdiv.Idomain.
-
-Set Implicit Arguments.
-Unset Strict Implicit.
-Unset Printing Implicit Defensive.
-
-Local Open Scope ring_scope.
-
-Section Multiplicity.
-
-Variable R : idomainType.
-Implicit Types x y c : R.
-Implicit Types p q r d : {poly R}.
-
-(* Definition multiplicity (x : R) (p : {poly R}) : nat := *)
-(* (odflt ord0 (pick (fun i : 'I_(size p).+1 => ((('X - x%:P) ^+ i %| p)) *)
-(* && (~~ (('X - x%:P) ^+ i.+1 %| p))))). *)
-
-(* Notation "'\mu_' x" := (multiplicity x) *)
-(* (at level 8, format "'\mu_' x") : ring_scope. *)
-
-(* Lemma mu0 : forall x, \mu_x 0 = 0%N. *)
-(* Proof. *)
-(* by move=> x; rewrite /multiplicity; case: pickP=> //= i; rewrite !dvdp0. *)
-(* Qed. *)
-
-(* Lemma muP : forall p x, p != 0 -> *)
-(* (('X - x%:P) ^+ (\mu_x p) %| p) && ~~(('X - x%:P) ^+ (\mu_x p).+1 %| p). *)
-(* Proof. *)
-(* move=> p x np0; rewrite /multiplicity; case: pickP=> //= hp. *)
-(* have {hp} hip: forall i, i <= size p *)
-(* -> (('X - x%:P) ^+ i %| p) -> (('X - x%:P) ^+ i.+1 %| p). *)
-(* move=> i; rewrite -ltnS=> hi; move/negbT: (hp (Ordinal hi)). *)
-(* by rewrite -negb_imply negbK=> /implyP. *)
-(* suff: forall i, i <= size p -> ('X - x%:P) ^+ i %| p. *)
-(* move=> /(_ _ (leqnn _)) /(size_dvdp np0). *)
-(* rewrite -[size _]prednK; first by rewrite size_exp size_XsubC mul1n ltnn. *)
-(* by rewrite lt0n size_poly_eq0 expf_eq0 polyXsubC_eq0 lt0n size_poly_eq0 np0. *)
-(* elim=> [|i ihi /ltnW hsp]; first by rewrite expr0 dvd1p. *)
-(* by rewrite hip // ihi. *)
-(* Qed. *)
-
-(* Lemma cofactor_XsubC : forall p a, p != 0 -> *)
-(* exists2 q : {poly R}, (~~ root q a) & p = q * ('X - a%:P) ^+ (\mu_a p). *)
-(* Proof. *)
-(* move=> p a np0. *)
-
-Definition multiplicity (x : R) (p : {poly R}) :=
- if p == 0 then 0%N else sval (multiplicity_XsubC p x).
-
-Notation "'\mu_' x" := (multiplicity x)
- (at level 8, format "'\mu_' x") : ring_scope.
-
-Lemma mu_spec p a : p != 0 ->
- { q : {poly R} & (~~ root q a)
- & ( p = q * ('X - a%:P) ^+ (\mu_a p)) }.
-Proof.
-move=> nz_p; rewrite /multiplicity -if_neg.
-by case: (_ p a) => m /=/sig2_eqW[q]; rewrite nz_p; exists q.
-Qed.
-
-Lemma mu0 x : \mu_x 0 = 0%N.
-Proof. by rewrite /multiplicity {1}eqxx. Qed.
-
-Lemma root_mu p x : ('X - x%:P) ^+ (\mu_x p) %| p.
-Proof.
-case p0: (p == 0); first by rewrite (eqP p0) mu0 expr0 dvd1p.
-case: (@mu_spec p x); first by rewrite p0.
-by move=> q qn0 hp //=; rewrite {2}hp dvdp_mulIr.
-Qed.
-
-(* Lemma size_exp_XsubC : forall x n, size (('X - x%:P) ^+ n) = n.+1. *)
-(* Proof. *)
-(* move=> x n; rewrite -[size _]prednK ?size_exp ?size_XsubC ?mul1n //. *)
-(* by rewrite ltnNge leqn0 size_poly_eq0 expf_neq0 // polyXsubC_eq0. *)
-(* Qed. *)
-
-Lemma root_muN p x : p != 0 ->
- (('X - x%:P)^+(\mu_x p).+1 %| p) = false.
-Proof.
-move=> pn0; case: (mu_spec x pn0)=> q qn0 hp /=.
-rewrite {2}hp exprS dvdp_mul2r; last first.
- by rewrite expf_neq0 // polyXsubC_eq0.
-apply: negbTE; rewrite -eqp_div_XsubC; apply: contra qn0.
-by move/eqP->; rewrite rootM root_XsubC eqxx orbT.
-Qed.
-
-Lemma root_le_mu p x n : p != 0 -> ('X - x%:P)^+n %| p = (n <= \mu_x p)%N.
-Proof.
-move=> pn0; case: leqP=> hn; last apply/negP=> hp.
- apply: (@dvdp_trans _ (('X - x%:P) ^+ (\mu_x p))); last by rewrite root_mu.
- by rewrite dvdp_Pexp2l // size_XsubC.
-suff : ('X - x%:P) ^+ (\mu_x p).+1 %| p by rewrite root_muN.
-by apply: dvdp_trans hp; rewrite dvdp_Pexp2l // size_XsubC.
-Qed.
-
-Lemma muP p x n : p != 0 ->
- (('X - x%:P)^+n %| p) && ~~(('X - x%:P)^+n.+1 %| p) = (n == \mu_x p).
-Proof.
-by move=> hp0; rewrite !root_le_mu//; case: (ltngtP n (\mu_x p)).
-Qed.
-
-Lemma mu_gt0 p x : p != 0 -> (0 < \mu_x p)%N = root p x.
-Proof. by move=> pn0; rewrite -root_le_mu// expr1 root_factor_theorem. Qed.
-
-Lemma muNroot p x : ~~ root p x -> \mu_x p = 0%N.
-Proof.
-case p0: (p == 0); first by rewrite (eqP p0) rootC eqxx.
-by move=> pnx0; apply/eqP; rewrite -leqn0 leqNgt mu_gt0 ?p0.
-Qed.
-
-Lemma mu_polyC c x : \mu_x (c%:P) = 0%N.
-Proof.
-case c0: (c == 0); first by rewrite (eqP c0) mu0.
-by apply: muNroot; rewrite rootC c0.
-Qed.
-
-Lemma cofactor_XsubC_mu x p n :
- ~~ root p x -> \mu_x (p * ('X - x%:P) ^+ n) = n.
-Proof.
-move=> p0; apply/eqP; rewrite eq_sym -muP//; last first.
- apply: contra p0; rewrite mulf_eq0 expf_eq0 polyXsubC_eq0 andbF orbF.
- by move/eqP->; rewrite root0.
-rewrite dvdp_mulIr /= exprS dvdp_mul2r -?root_factor_theorem //.
-by rewrite expf_eq0 polyXsubC_eq0 andbF //.
-Qed.
-
-Lemma mu_mul p q x : p * q != 0 ->
- \mu_x (p * q) = (\mu_x p + \mu_x q)%N.
-Proof.
-move=> hpqn0; apply/eqP; rewrite eq_sym -muP//.
-rewrite exprD dvdp_mul ?root_mu//=.
-move: hpqn0; rewrite mulf_eq0 negb_or; case/andP=> hp0 hq0.
-move: (mu_spec x hp0)=> [qp qp0 hp].
-move: (mu_spec x hq0)=> [qq qq0 hq].
-rewrite {2}hp {2}hq exprS exprD !mulrA [qp * _ * _]mulrAC.
-rewrite !dvdp_mul2r ?expf_neq0 ?polyXsubC_eq0 // -eqp_div_XsubC.
-move: (mulf_neq0 qp0 qq0); rewrite -hornerM; apply: contra; move/eqP->.
-by rewrite hornerM hornerXsubC subrr mulr0.
-Qed.
-
-Lemma mu_XsubC x : \mu_x ('X - x%:P) = 1%N.
-Proof.
-apply/eqP; rewrite eq_sym -muP; last by rewrite polyXsubC_eq0.
-by rewrite expr1 dvdpp/= -{2}[_ - _]expr1 dvdp_Pexp2l // size_XsubC.
-Qed.
-
-Lemma mu_mulC c p x : c != 0 -> \mu_x (c *: p) = \mu_x p.
-Proof.
-move=> cn0; case p0: (p == 0); first by rewrite (eqP p0) scaler0.
-by rewrite -mul_polyC mu_mul ?mu_polyC// mulf_neq0 ?p0 ?polyC_eq0.
-Qed.
-
-Lemma mu_opp p x : \mu_x (-p) = \mu_x p.
-Proof.
-rewrite -mulN1r -polyC1 -polyC_opp mul_polyC mu_mulC //.
-by rewrite -oppr0 (inj_eq (inv_inj (@opprK _))) oner_eq0.
-Qed.
-
-Lemma mu_exp p x n : \mu_x (p ^+ n) = (\mu_x p * n)%N.
-Proof.
-elim: n p => [|n ihn] p; first by rewrite expr0 mu_polyC muln0.
-case p0: (p == 0); first by rewrite (eqP p0) exprS mul0r mu0 mul0n.
-by rewrite exprS mu_mul ?ihn ?mulnS// mulf_eq0 expf_eq0 p0 andbF.
-Qed.
-
-Lemma mu_addr p q x : p != 0 -> (\mu_x p < \mu_x q)%N ->
- \mu_x (p + q) = \mu_x p.
-Proof.
-move=> pn0 mupq.
-have pqn0 : p + q != 0.
- move: mupq; rewrite ltnNge; apply: contra.
- by rewrite -[q]opprK subr_eq0; move/eqP->; rewrite opprK mu_opp leqnn.
-have qn0: q != 0 by move: mupq; apply: contraL; move/eqP->; rewrite mu0 ltn0.
-case: (mu_spec x pn0)=> [qqp qqp0] hp.
-case: (mu_spec x qn0)=> [qqq qqq0] hq.
-rewrite hp hq -(subnK (ltnW mupq)).
-rewrite mu_mul ?mulf_eq0; last first.
- rewrite expf_eq0 polyXsubC_eq0 andbF orbF.
- by apply: contra qqp0; move/eqP->; rewrite root0.
-rewrite mu_exp mu_XsubC mul1n [\mu_x qqp]muNroot // add0n.
-rewrite exprD mulrA -mulrDl mu_mul; last first.
- by rewrite mulrDl -mulrA -exprD subnK 1?ltnW // -hp -hq.
-rewrite muNroot ?add0n ?mu_exp ?mu_XsubC ?mul1n //.
-rewrite rootE !hornerE horner_exp hornerXsubC subrr.
-by rewrite -subnSK // subnS exprS mul0r mulr0 addr0.
-Qed.
-
-Lemma mu_addl p q x : q != 0 -> (\mu_x p > \mu_x q)%N ->
- \mu_x (p + q) = \mu_x q.
-Proof. by move=> q0 hmu; rewrite addrC mu_addr. Qed.
-
-Lemma mu_div p x n : (n <= \mu_x p)%N ->
- \mu_x (p %/ ('X - x%:P) ^+ n) = (\mu_x p - n)%N.
-Proof.
-move=> hn.
-case p0: (p == 0); first by rewrite (eqP p0) div0p mu0 sub0n.
-case: (@mu_spec p x); rewrite ?p0 // => q hq hp.
-rewrite {1}hp -{1}(subnK hn) exprD mulrA.
-rewrite Pdiv.IdomainMonic.mulpK; last by apply: monic_exp; apply: monicXsubC.
-rewrite mu_mul ?mulf_eq0 ?expf_eq0 ?polyXsubC_eq0 ?andbF ?orbF; last first.
- by apply: contra hq; move/eqP->; rewrite root0.
-by rewrite mu_exp muNroot // add0n mu_XsubC mul1n.
-Qed.
-
-End Multiplicity.
-
-Notation "'\mu_' x" := (multiplicity x)
- (at level 8, format "'\mu_' x") : ring_scope.
-
-
-Section PolyrealIdomain.
-
- (*************************************************************************)
- (* This should be replaced by a 0-characteristic condition + integrality *)
- (* and merged into poly and polydiv *)
- (*************************************************************************)
-
-Variable R : realDomainType.
-
-Lemma size_deriv (p : {poly R}) : size p^`() = (size p).-1.
-Proof.
-have [lep1|lt1p] := leqP (size p) 1.
- by rewrite {1}[p]size1_polyC // derivC size_poly0 -subn1 (eqnP lep1).
-rewrite size_poly_eq // mulrn_eq0 -subn2 -subSn // subn2.
-by rewrite lead_coef_eq0 -size_poly_eq0 -(subnKC lt1p).
-Qed.
-
-Lemma derivn_poly0 : forall (p : {poly R}) n, (size p <= n)%N = (p^`(n) == 0).
-Proof.
-move=> p n; apply/idP/idP.
- move=> Hpn; apply/eqP; apply/polyP=>i; rewrite coef_derivn.
- rewrite nth_default; first by rewrite mul0rn coef0.
- by apply: leq_trans Hpn _; apply leq_addr.
-elim: n {-2}n p (leqnn n) => [m | n ihn [| m]] p.
-- by rewrite leqn0; move/eqP->; rewrite derivn0 leqn0 -size_poly_eq0.
-- by move=> _; apply: ihn; rewrite leq0n.
-- rewrite derivSn => hmn hder; case e: (size p) => [|sp] //.
- rewrite -(prednK (ltn0Sn sp)) [(_.-1)%N]lock -e -lock -size_deriv ltnS.
- exact: ihn.
-Qed.
-
-Lemma mu_deriv : forall x (p : {poly R}), root p x ->
- \mu_x (p^`()) = (\mu_x p - 1)%N.
-Proof.
-move=> x p px0; have [-> | nz_p] := eqVneq p 0; first by rewrite derivC mu0.
-have [q nz_qx Dp] := mu_spec x nz_p.
-case Dm: (\mu_x p) => [|m]; first by rewrite Dp Dm mulr1 (negPf nz_qx) in px0.
-rewrite subn1 Dp Dm !derivCE exprS mul1r mulrnAr -mulrnAl mulrA -mulrDl.
-rewrite cofactor_XsubC_mu // rootE !(hornerE, hornerMn) subrr mulr0 add0r.
-by rewrite mulrn_eq0.
-Qed.
-
-Lemma mu_deriv_root : forall x (p : {poly R}), p != 0 -> root p x ->
- \mu_x p = (\mu_x (p^`()) + 1)%N.
-Proof.
-by move=> x p p0 rpx; rewrite mu_deriv // subn1 addn1 prednK // mu_gt0.
-Qed.
-
-End PolyrealIdomain.
-
-
-
diff --git a/mathcomp/real_closed/polyrcf.v b/mathcomp/real_closed/polyrcf.v
deleted file mode 100644
index 8aaeb97..0000000
--- a/mathcomp/real_closed/polyrcf.v
+++ /dev/null
@@ -1,1811 +0,0 @@
-(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-(* Distributed under the terms of CeCILL-B. *)
-Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp
-Require Import ssrfun ssrbool eqtype ssrnat seq choice fintype.
-From mathcomp
-Require Import bigop ssralg poly polydiv ssrnum zmodp.
-From mathcomp
-Require Import polyorder path interval ssrint.
-
-(****************************************************************************)
-(* This files contains basic (and unformatted) theory for polynomials *)
-(* over a realclosed fields. From the IVT (contained in the rcfType *)
-(* structure), we derive Rolle's Theorem, the Mean Value Theorem, a root *)
-(* isolation procedure and the notion of neighborhood. *)
-(* *)
-(* sgp_minfty p == the sign of p in -oo *)
-(* sgp_pinfty p == the sign of p in +oo *)
-(* cauchy_bound p == the cauchy bound of p *)
-(* (this strictly bounds the norm of roots of p) *)
-(* roots p a b == the ordered list of roots of p in `[a, b] *)
-(* defaults to [::] when p == 0 *)
-(* rootsR p == the ordered list of all roots of p, ([::] if p == 0). *)
-(* next_root p x b == the smallest root of p contained in `[x, maxn x b] *)
-(* if p has no root on `[x, maxn x b], we pick maxn x b. *)
-(* prev_root p x a == the smallest root of p contained in `[minn x a, x] *)
-(* if p has no root on `[minn x a, x], we pick minn x a. *)
-(* neighpr p a b := `]a, next_root p a b[. *)
-(* == an open interval of the form `]a, x[, with x <= b *)
-(* in which p has no root. *)
-(* neighpl p a b := `]prev_root p a b, b[. *)
-(* == an open interval of the form `]x, b[, with a <= x *)
-(* in which p has no root. *)
-(* sgp_right p a == the sign of p on the right of a. *)
-(****************************************************************************)
-
-
-Import GRing.Theory Num.Theory Num.Def.
-Import Pdiv.Idomain.
-
-Set Implicit Arguments.
-Unset Strict Implicit.
-Unset Printing Implicit Defensive.
-
-Local Open Scope nat_scope.
-Local Open Scope ring_scope.
-
-Local Notation noroot p := (forall x, ~~ root p x).
-Local Notation mid x y := ((x + y) / 2%:R).
-
-Section more.
-Section SeqR.
-
-Lemma last1_neq0 (R : ringType) (s : seq R) (c : R) :
- c != 0 -> (last c s != 0) = (last 1 s != 0).
-Proof. by elim: s c => [|t s ihs] c cn0 //; rewrite oner_eq0 cn0. Qed.
-
-End SeqR.
-
-Section poly.
-Import Pdiv.Ring Pdiv.ComRing.
-
-Variable R : idomainType.
-
-Implicit Types p q : {poly R}.
-
-Lemma lead_coefDr p q :
- (size q > size p)%N -> lead_coef (p + q) = lead_coef q.
-Proof. by move/lead_coefDl<-; rewrite addrC. Qed.
-
-Lemma leq1_size_polyC (c : R) : (size c%:P <= 1)%N.
-Proof. by rewrite size_polyC; case: (c == 0). Qed.
-
-Lemma my_size_exp p n :
- p != 0 -> (size (p ^+ n)) = ((size p).-1 * n).+1%N.
-Proof.
-by move=> hp; rewrite -size_exp prednK // lt0n size_poly_eq0 expf_neq0.
-Qed.
-
-Lemma coef_comp_poly p q n :
- (p \Po q)`_n = \sum_(i < size p) p`_i * (q ^+ i)`_n.
-Proof.
-rewrite comp_polyE coef_sum.
-by elim/big_ind2: _ => [//|? ? ? ? -> -> //|i]; rewrite coefZ.
-Qed.
-
-Lemma gt_size_poly p n : (size p > n)%N -> p != 0.
-Proof.
-by move=> h; rewrite -size_poly_eq0 lt0n_neq0 //; apply: leq_ltn_trans h.
-Qed.
-
-Lemma lead_coef_comp_poly p q :
- (size q > 1)%N ->
- lead_coef (p \Po q) = (lead_coef p) * (lead_coef q) ^+ (size p).-1.
-Proof.
-move=> sq; rewrite !lead_coefE coef_comp_poly size_comp_poly.
-case hp: (size p) => [|n].
- move/eqP: hp; rewrite size_poly_eq0 => /eqP ->.
- by rewrite big_ord0 coef0 mul0r.
-rewrite big_ord_recr /= big1 => [|i _].
- by rewrite add0r -lead_coefE -lead_coef_exp lead_coefE size_exp mulnC.
-rewrite [X in _ * X]nth_default ?mulr0 ?(leq_trans (size_exp_leq _ _)) //.
-by rewrite mulnC ltn_mul2r -subn1 subn_gt0 sq /=.
-Qed.
-
-End poly.
-End more.
-
-(******************************************************************)
-(* Definitions and properties for polynomials in a numDomainType. *)
-(******************************************************************)
-Section PolyNumDomain.
-
-Variable R : numDomainType.
-Implicit Types (p q : {poly R}).
-
-Definition sgp_pinfty (p : {poly R}) := sgr (lead_coef p).
-Definition sgp_minfty (p : {poly R}) :=
- sgr ((-1) ^+ (size p).-1 * (lead_coef p)).
-
-End PolyNumDomain.
-
-(******************************************************************)
-(* Definitions and properties for polynomials in a realFieldType. *)
-(******************************************************************)
-Section PolyRealField.
-
-Variable R : realFieldType.
-Implicit Types (p q : {poly R}).
-
-Section SgpInfty.
-
-Lemma sgp_pinfty_sym p : sgp_pinfty (p \Po -'X) = sgp_minfty p.
-Proof.
-rewrite /sgp_pinfty /sgp_minfty lead_coef_comp_poly ?size_opp ?size_polyX //.
-by rewrite lead_coef_opp lead_coefX mulrC.
-Qed.
-
-Lemma poly_pinfty_gt_lc p :
- lead_coef p > 0 ->
- exists n, forall x, x >= n -> p.[x] >= lead_coef p.
-Proof.
-elim/poly_ind: p => [| q c IHq]; first by rewrite lead_coef0 ltrr.
-have [->|q_neq0] := eqVneq q 0.
- by rewrite mul0r add0r lead_coefC => c_gt0; exists 0 => x _; rewrite hornerC.
-rewrite lead_coefDl ?size_mul ?polyX_eq0 // ?lead_coefMX; last first.
- rewrite size_polyX addn2 size_polyC /= ltnS.
- by rewrite (leq_trans (leq_b1 _)) // size_poly_gt0.
-move=> lq_gt0; have [y Hy] := IHq lq_gt0.
-pose z := (1 + (lead_coef q) ^-1 * `|c|); exists (maxr y z) => x.
-have z_gt0 : 0 < z by rewrite ltr_spaddl ?ltr01 ?mulr_ge0 ?invr_ge0 // ltrW.
-rewrite !hornerE ler_maxl => /andP[/Hy Hq Hc].
-rewrite (@ler_trans _ (lead_coef q * z + c)) //; last first.
- rewrite ler_add2r (@ler_trans _ (q.[x] * z)) // ?ler_pmul2r //.
- by rewrite ler_pmul2l // (ltr_le_trans _ Hq).
-rewrite mulrDr mulr1 -addrA ler_addl mulVKf ?gtr_eqF //.
-by rewrite -[c]opprK subr_ge0 normrN ler_norm.
-Qed.
-
-(* :REMARK: not necessary here ! *)
-Lemma poly_lim_infty p m :
- lead_coef p > 0 -> (size p > 1)%N ->
- exists n, forall x, x >= n -> p.[x] >= m.
-Proof.
-elim/poly_ind: p m => [| q c _] m; first by rewrite lead_coef0 ltrr.
-have [-> _|q_neq0] := eqVneq q 0.
- by rewrite mul0r add0r size_polyC ltnNge leq_b1.
-rewrite lead_coefDl ?size_mul ?polyX_eq0 // ?lead_coefMX; last first.
- rewrite size_polyX addn2 size_polyC /= ltnS.
- by rewrite (leq_trans (leq_b1 _)) // size_poly_gt0.
-move=> lq_gt0; have [y Hy _] := poly_pinfty_gt_lc lq_gt0.
-pose z := (1 + (lead_coef q) ^-1 * (`|m| + `|c|)); exists (maxr y z) => x.
-have z_gt0 : 0 < z.
- by rewrite ltr_spaddl ?ltr01 ?mulr_ge0 ?invr_ge0 ?addr_ge0 // ?ltrW.
-rewrite !hornerE ler_maxl => /andP[/Hy Hq Hc].
-rewrite (@ler_trans _ (lead_coef q * z + c)) //; last first.
- rewrite ler_add2r (@ler_trans _ (q.[x] * z)) // ?ler_pmul2r //.
- by rewrite ler_pmul2l // (ltr_le_trans _ Hq).
-rewrite mulrDr mulr1 mulVKf ?gtr_eqF // addrA -addrA ler_paddr //.
- by rewrite -[c]opprK subr_ge0 normrN ler_norm.
-by rewrite ler_paddl ?ler_norm // ?ltrW.
-Qed.
-
-End SgpInfty.
-
-Section CauchyBound.
-
-Definition cauchy_bound (p : {poly R}) :=
- 1 + `|lead_coef p|^-1 * \sum_(i < size p) `|p`_i|.
-
-(* Could be a sharp bound, and proof should shrink... *)
-Lemma cauchy_boundP (p : {poly R}) x :
- p != 0 -> p.[x] = 0 -> `| x | < cauchy_bound p.
-Proof.
-move=> np0 rpx; rewrite ltr_spaddl ?ltr01 //.
-case e: (size p) => [|n]; first by move: np0; rewrite -size_poly_eq0 e eqxx.
-have lcp : `|lead_coef p| > 0 by move: np0; rewrite -lead_coef_eq0 -normr_gt0.
-have lcn0 : `|lead_coef p| != 0 by rewrite normr_eq0 -normr_gt0.
-case: (lerP `|x| 1) => cx1.
- rewrite (ler_trans cx1) // /cauchy_bound ler_pdivl_mull // mulr1.
- by rewrite big_ord_recr /= /lead_coef e ler_addr sumr_ge0.
-case es: n e => [|m] e.
- suff p0 : p = 0 by rewrite p0 eqxx in np0.
- by move: rpx; rewrite (@size1_polyC _ p) ?e ?lerr // hornerC; move->.
-move: rpx; rewrite horner_coef e -es big_ord_recr /=; move/eqP; rewrite eq_sym.
-rewrite -subr_eq sub0r; move/eqP => h1.
-have {h1} h1 : `|p`_n| * `|x| ^+ n <= \sum_(i < n) `|p`_i * x ^+ i|.
- rewrite -normrX -normrM -normrN h1.
- by rewrite (ler_trans (ler_norm_sum _ _ _)) // lerr.
-have xp : `| x | > 0 by rewrite (ltr_trans _ cx1) ?ltr01.
-move: h1; rewrite {-1}es exprS mulrA -ler_pdivl_mulr ?exprn_gt0 //.
-rewrite big_distrl /= big_ord_recr /= normrM normrX -mulrA es mulfV; last first.
- by rewrite expf_eq0 negb_and eq_sym (ltr_eqF xp) orbT.
-have pnp : 0 < `|p`_n| by move: lcp; rewrite /lead_coef e es.
-rewrite mulr1 -es mulrC -ler_pdivl_mulr //.
-rewrite [_ / _]mulrC /cauchy_bound /lead_coef e -es /=.
-move=> h1; apply: (ler_trans h1) => //.
-rewrite ler_pmul2l ?invr_gt0 ?(ltrW pnp) // big_ord_recr /=.
-rewrite es [_ + `|p`_m.+1|]addrC ler_paddl // ?normr_ge0 //.
-rewrite big_ord_recr /= ler_add2r; apply: ler_sum => i.
-rewrite normrM normrX.
-rewrite -mulrA ler_pimulr ?normrE // ler_pdivr_mulr ?exprn_gt0 // mul1r.
-by rewrite ler_eexpn2l // 1?ltrW //; case: i=> i hi /=; rewrite ltnW.
-(* this could be improved a little bit with int exponents *)
-Qed.
-
-Lemma le_cauchy_bound p : p != 0 -> {in `]-oo, (- cauchy_bound p)], noroot p}.
-Proof.
-move=> p_neq0 x; rewrite inE /= lerNgt; apply: contra => /rootP.
-by move=> /(cauchy_boundP p_neq0) /ltr_normlP []; rewrite ltr_oppl.
-Qed.
-Hint Resolve le_cauchy_bound.
-
-Lemma ge_cauchy_bound p : p != 0 -> {in `[cauchy_bound p, +oo[, noroot p}.
-Proof.
-move=> p_neq0 x; rewrite inE andbT /= lerNgt; apply: contra => /rootP.
-by move=> /(cauchy_boundP p_neq0) /ltr_normlP []; rewrite ltr_oppl.
-Qed.
-Hint Resolve ge_cauchy_bound.
-
-Lemma cauchy_bound_gt0 p : cauchy_bound p > 0.
-Proof.
-rewrite ltr_spaddl ?ltr01 ?mulr_ge0 ?invr_ge0 ?normr_ge0 //.
-by rewrite sumr_ge0 // => i; rewrite normr_ge0.
-Qed.
-Hint Resolve cauchy_bound_gt0.
-
-Lemma cauchy_bound_ge0 p : cauchy_bound p >= 0.
-Proof. by rewrite ltrW. Qed.
-Hint Resolve cauchy_bound_ge0.
-
-End CauchyBound.
-
-End PolyRealField.
-
-(************************************************************)
-(* Definitions and properties for polynomials in a rcfType. *)
-(************************************************************)
-Section PolyRCF.
-
-Variable R : rcfType.
-
-Section Prelim.
-
-Implicit Types a b c : R.
-Implicit Types x y z t : R.
-Implicit Types p q r : {poly R}.
-
-(* we restate poly_ivt in a nicer way. Perhaps the def of PolyRCF should *)
-(* be moved in this file, juste above this section *)
-
-Lemma poly_ivt (p : {poly R}) (a b : R) :
- a <= b -> 0 \in `[p.[a], p.[b]] -> { x : R | x \in `[a, b] & root p x }.
-Proof. by move=> leab root_p_ab; apply/sig2W/poly_ivt. Qed.
-
-Lemma polyrN0_itv (i : interval R) (p : {poly R}) :
- {in i, noroot p} ->
- forall y x : R, y \in i -> x \in i -> sgr p.[x] = sgr p.[y].
-Proof.
-move=> hi y x hy hx; wlog xy: x y hx hy / x <= y=> [hwlog|].
- by case/orP: (ler_total x y)=> xy; [|symmetry]; apply: hwlog.
-have hxyi: {subset `[x, y] <= i}.
- move=> z; apply: subitvP=> /=.
- by case: i hx hy {hi}=> [[[] ?|] [[] ?|]] /=; do ?[move/itvP->|move=> ?].
-do 2![case: sgrP; first by move/rootP; rewrite (negPf (hi _ _))]=> //.
- move=> /ltrW py0 /ltrW p0x; case: (@poly_ivt (- p) x y)=> //.
- by rewrite inE !hornerN !oppr_cp0 p0x.
- by move=> z hz; rewrite rootN (negPf (hi z _)) // hxyi.
-move=> /ltrW p0y /ltrW px0; case: (@poly_ivt p x y); rewrite ?inE ?px0 //.
-by move=> z hz; rewrite (negPf (hi z _)) // hxyi.
-Qed.
-
-Lemma poly_div_factor (a : R) (P : {poly R} -> Prop) :
- (forall k, P k%:P) ->
- (forall p n k, p.[a] != 0 -> P p -> P (p * ('X - a%:P)^+(n.+1) + k%:P)%R)
- -> forall p, P p.
-Proof.
-move=> Pk Pq p.
-move: {-2}p (leqnn (size p)); elim: (size p)=> {p} [|n ihn] p spn.
- move: spn; rewrite leqn0 size_poly_eq0; move/eqP->; rewrite -polyC0.
- exact: Pk.
-case: (leqP (size p) 1)=> sp1; first by rewrite [p]size1_polyC ?sp1//.
-rewrite (Pdiv.IdomainMonic.divp_eq (monicXsubC a) p).
-rewrite [_ %% _]size1_polyC; last first.
- rewrite -ltnS.
- by rewrite (@leq_trans (size ('X - a%:P))) //
- ?ltn_modp ?polyXsubC_eq0 ?size_XsubC.
-have [n' [q hqa hp]] := multiplicity_XsubC (p %/ ('X - a%:P)) a.
-rewrite divpN0 ?size_XsubC ?polyXsubC_eq0 ?sp1 //= in hqa.
-rewrite hp -mulrA -exprSr; apply: Pq=> //; apply: ihn.
-rewrite (@leq_trans (size (q * ('X - a%:P) ^+ n'))) //.
- rewrite size_mul ?expf_eq0 ?polyXsubC_eq0 ?andbF //; last first.
- by apply: contra hqa; move/eqP->; rewrite root0.
- by rewrite size_exp_XsubC addnS leq_addr.
-by rewrite -hp size_divp ?polyXsubC_eq0 ?size_XsubC // leq_subLR.
-Qed.
-
-Lemma nth_root x n : x > 0 -> { y | y > 0 & y ^+ (n.+1) = x }.
-Proof.
-move=> l0x.
-case: (ltrgtP x 1)=> hx; last by exists 1; rewrite ?hx ?lter01// expr1n.
- case: (@poly_ivt ('X ^+ n.+1 - x%:P) 0 1); first by rewrite ler01.
- rewrite ?(hornerE,horner_exp) ?inE.
- by rewrite exprS mul0r sub0r expr1n oppr_cp0 subr_gte0/= !ltrW.
- move=> y; case/andP=> [l0y ly1]; rewrite rootE ?(hornerE,horner_exp).
- rewrite subr_eq0; move/eqP=> hyx; exists y=> //; rewrite lt0r l0y.
- rewrite andbT; apply/eqP=> y0; move: hyx; rewrite y0.
- by rewrite exprS mul0r=> x0; move: l0x; rewrite -x0 ltrr.
-case: (@poly_ivt ('X ^+ n.+1 - x%:P) 0 x); first by rewrite ltrW.
- rewrite ?(hornerE,horner_exp) exprS mul0r sub0r ?inE.
- by rewrite oppr_cp0 (ltrW l0x) subr_ge0 ler_eexpr // ltrW.
-move=> y; case/andP=> l0y lyx; rewrite rootE ?(hornerE,horner_exp).
-rewrite subr_eq0; move/eqP=> hyx; exists y=> //; rewrite lt0r l0y.
-rewrite andbT; apply/eqP=> y0; move: hyx; rewrite y0.
-by rewrite exprS mul0r=> x0; move: l0x; rewrite -x0 ltrr.
-Qed.
-
-Lemma poly_cont x p e :
- e > 0 -> exists2 d, d > 0 & forall y, `|y - x| < d -> `|p.[y] - p.[x]| < e.
-Proof.
-elim/(@poly_div_factor x): p e.
- move=> e ep; exists 1; rewrite ?ltr01// => y hy.
- by rewrite !hornerC subrr normr0.
-move=> p n k pxn0 Pp e ep.
-case: (Pp (`|p.[x]|/2%:R)).
- by rewrite pmulr_lgt0 ?invr_gte0//= ?ltr0Sn// normrE.
-move=> d' d'p He'.
-case: (@nth_root (e / ((3%:R / 2%:R) * `|p.[x]|)) n).
- by rewrite ltr_pdivl_mulr ?mul0r ?pmulr_rgt0 ?invr_gt0 ?normrE ?ltr0Sn.
-move=> d dp rootd.
-exists (minr d d'); first by rewrite ltr_minr dp.
-move=> y; rewrite ltr_minr; case/andP=> hxye hxye'.
-rewrite !(hornerE, horner_exp) subrr [0 ^+ _]exprS mul0r mulr0 add0r addrK.
-rewrite normrM (@ler_lt_trans _ (`|p.[y]| * d ^+ n.+1)) //.
- by rewrite ler_wpmul2l ?normrE // normrX ler_expn2r -?topredE /= ?normrE 1?ltrW.
-rewrite rootd mulrCA gtr_pmulr //.
-rewrite ltr_pdivr_mulr ?mul1r ?pmulr_rgt0 ?invr_gt0 ?ltr0Sn ?normrE //.
-rewrite mulrDl mulrDl divff; last by rewrite -mulr2n pnatr_eq0.
-rewrite !mul1r mulrC -ltr_subl_addr.
-by rewrite (ler_lt_trans _ (He' y _)) // ler_sub_dist.
-Qed.
-
-Lemma poly_ltsp_roots p (rs : seq R) :
- (size rs >= size p)%N -> uniq rs -> all (root p) rs -> p = 0.
-Proof.
-move=> hrs urs rrs; apply/eqP; apply: contraLR hrs=> np0.
-by rewrite -ltnNge; apply: max_poly_roots.
-Qed.
-
-Lemma ivt_sign (p : {poly R}) (a b : R) :
- a <= b -> sgr p.[a] * sgr p.[b] = -1 -> { x : R | x \in `]a, b[ & root p x}.
-Proof.
-move=> hab /eqP; rewrite mulrC mulr_sg_eqN1=> /andP [spb0 /eqP spb].
- case: (@poly_ivt (sgr p.[b] *: p) a b)=> //.
- by rewrite !hornerZ {1}spb mulNr -!normrEsg inE /= oppr_cp0 !normrE.
-move=> c hc; rewrite rootZ ?sgr_eq0 // => rpc; exists c=> //.
-(* need for a lemma reditvP *)
-rewrite inE /= !ltr_neqAle andbCA -!andbA [_ && (_ <= _)]hc andbT.
-rewrite eq_sym -negb_or.
-apply/negP=> /orP [] /eqP ec; move: rpc; rewrite -ec /root ?(negPf spb0) //.
-by rewrite -sgr_cp0 -[sgr _]opprK -spb eqr_oppLR oppr0 sgr_cp0 (negPf spb0).
-Qed.
-
-Let rolle_weak a b p :
- a < b -> p.[a] = 0 -> p.[b] = 0 ->
- {c | (c \in `]a, b[) & (p^`().[c] == 0) || (p.[c] == 0)}.
-Proof.
-move=> lab pa0 pb0; apply/sig2W.
-case p0: (p == 0).
- rewrite (eqP p0); exists (mid a b); first by rewrite mid_in_itv.
- by rewrite derivC horner0 eqxx.
-have [n [p' p'a0 hp]] := multiplicity_XsubC p a; rewrite p0 /= in p'a0.
-case: n hp pa0 p0 pb0 p'a0=> [ | n -> _ p0 pb0 p'a0].
- by rewrite {1}expr0 mulr1 rootE=> ->; move/eqP->.
-have [m [q qb0 hp']] := multiplicity_XsubC p' b.
-rewrite (contraNneq _ p'a0) /= in qb0 => [|->]; last exact: root0.
-case: m hp' pb0 p0 p'a0 qb0=> [|m].
- rewrite {1}expr0 mulr1=> ->; move/eqP.
- rewrite !(hornerE, horner_exp, mulf_eq0).
- by rewrite !expf_eq0 !subr_eq0 !(gtr_eqF lab) !andbF !orbF !rootE=> ->.
-move=> -> _ p0 p'a0 qb0; case: (sgrP (q.[a] * q.[b])); first 2 last.
-- move=> sqasb; case: (@ivt_sign q a b)=> //; first exact: ltrW.
- by apply/eqP; rewrite -sgrM sgr_cp0.
- move=> c lacb rqc; exists c=> //.
- by rewrite !hornerM (eqP rqc) !mul0r eqxx orbT.
-- move/eqP; rewrite mulf_eq0 (rootPf qb0) orbF; move/eqP=> qa0.
- by move: p'a0; rewrite ?rootM rootE qa0 eqxx.
-- move=> hspq; rewrite !derivCE /= !mul1r mulrDl !pmulrn.
- set xan := (('X - a%:P) ^+ n); set xbm := (('X - b%:P) ^+ m).
- have ->: ('X - a%:P) ^+ n.+1 = ('X - a%:P) * xan by rewrite exprS.
- have ->: ('X - b%:P) ^+ m.+1 = ('X - b%:P) * xbm by rewrite exprS.
- rewrite -mulrzl -[_ *~ n.+1]mulrzl.
- have fac : forall x y z : {poly R}, x * (y * xbm) * (z * xan)
- = (y * z * x) * (xbm * xan).
- by move=> x y z; rewrite mulrCA !mulrA [_ * y]mulrC mulrA.
- rewrite !fac -!mulrDl; set r := _ + _ + _.
- case: (@ivt_sign (sgr q.[b] *: r) a b); first exact: ltrW.
- rewrite !hornerZ !sgr_smul mulrACA -expr2 sqr_sg (rootPf qb0) mul1r.
- rewrite !(subrr, mul0r, mulr0, addr0, add0r, hornerC, hornerXsubC,
- hornerD, hornerN, hornerM, hornerMn).
- rewrite [_ * _%:R]mulrC -!mulrA !pmulrn !mulrzl !sgrMz -sgrM.
- rewrite mulrAC mulrA -mulrA sgrM -opprB mulNr sgrN sgrM.
- by rewrite !gtr0_sg ?subr_gt0 ?mulr1 // mulrC.
-move=> c lacb; rewrite rootE hornerZ mulf_eq0.
-rewrite sgr_cp0 (rootPf qb0) orFb=> rc0.
-by exists c=> //; rewrite !hornerM !mulf_eq0 rc0.
-Qed.
-
-Theorem rolle a b p :
- a < b -> p.[a] = p.[b] -> {c | c \in `]a, b[ & p^`().[c] = 0}.
-Proof.
-move=> lab pab.
-wlog pb0 : p pab / p.[b] = 0 => [hwlog|].
- case: (hwlog (p - p.[b]%:P)); rewrite ?hornerE ?pab ?subrr //.
- by move=> c acb; rewrite derivE derivC subr0=> hc; exists c.
-move: pab; rewrite pb0=> pa0.
-have: (forall rs : seq R, {subset rs <= `]a, b[} ->
- (size p <= size rs)%N -> uniq rs -> all (root p) rs -> p = 0).
- by move=> rs hrs; apply: poly_ltsp_roots.
-elim: (size p) a b lab pa0 pb0=> [|n ihn] a b lab pa0 pb0 max_roots.
- rewrite (@max_roots [::]) //=.
- by exists (mid a b); rewrite ?mid_in_itv // derivE horner0.
-case: (@rolle_weak a b p); rewrite // ?pa0 ?pb0 //=.
-move=> c hc; case: (altP (_ =P 0))=> //= p'c0 pc0; first by exists c.
-suff: { d : R | d \in `]a, c[ & (p^`()).[d] = 0 }.
- case=> [d hd] p'd0; exists d=> //.
- by apply: subitvPr hd; rewrite //= (itvP hc).
-apply: ihn=> //; first by rewrite (itvP hc).
- exact/eqP.
-move=> rs hrs srs urs rrs; apply: (max_roots (c :: rs))=> //=; last exact/andP.
- move=> x; rewrite in_cons; case/predU1P=> hx; first by rewrite hx.
- have: x \in `]a, c[ by apply: hrs.
- by apply: subitvPr; rewrite /= (itvP hc).
-by rewrite urs andbT; apply/negP; move/hrs; rewrite bound_in_itv.
-Qed.
-
-Theorem mvt a b p :
- a < b -> {c | c \in `]a, b[ & p.[b] - p.[a] = p^`().[c] * (b - a)}.
-Proof.
-move=> lab.
-pose q := (p.[b] - p.[a])%:P * ('X - a%:P) - (b - a)%:P * (p - p.[a]%:P).
-case: (@rolle a b q)=> //.
- by rewrite /q !hornerE !(subrr,mulr0) mulrC subrr.
-move=> c lacb q'x0; exists c=> //.
-move: q'x0; rewrite /q !derivE !(mul0r,add0r,subr0,mulr1).
-by move/eqP; rewrite !hornerE mulrC subr_eq0; move/eqP.
-Qed.
-
-Lemma deriv_sign a b p :
- (forall x, x \in `]a, b[ -> p^`().[x] >= 0)
- -> (forall x y, (x \in `]a, b[) && (y \in `]a, b[)
- -> x < y -> p.[x] <= p.[y] ).
-Proof.
-move=> Pab x y; case/andP=> hx hy xy.
-rewrite -subr_gte0; case: (@mvt x y p)=> //.
-move=> c hc ->; rewrite pmulr_lge0 ?subr_gt0 ?Pab //.
-by apply: subitvP hc; rewrite //= ?(itvP hx) ?(itvP hy).
-Qed.
-
-End Prelim.
-
-Section MonotonictyAndRoots.
-
-Section NoRoot.
-
-Variable (p : {poly R}).
-
-Variables (a b : R).
-
-Hypothesis der_pos : forall x, x \in `]a, b[ -> (p^`()).[x] > 0.
-
-Lemma derp0r : 0 <= p.[a] -> forall x, x \in `]a, b] -> p.[x] > 0.
-Proof.
-move=> pa0 x; case/itv_dec=> ax xb; case: (mvt p ax) => c acx.
-move/(canRL (@subrK _ _))->; rewrite ltr_paddr //.
-by rewrite pmulr_rgt0 ?subr_gt0 // der_pos //; apply: subitvPr acx.
-Qed.
-
-Lemma derppr : 0 < p.[a] -> forall x, x \in `[a, b] -> p.[x] > 0.
-Proof.
-move=> pa0 x hx; case exa: (x == a); first by rewrite (eqP exa).
-case: (@mvt a x p); first by rewrite ltr_def exa (itvP hx).
-move=> c hc; move/eqP; rewrite subr_eq; move/eqP->; rewrite ltr_spsaddr //.
-rewrite pmulr_rgt0 ?subr_gt0 //; first by rewrite ltr_def exa (itvP hx).
-by rewrite der_pos // (subitvPr _ hc) //= ?(itvP hx).
-Qed.
-
-Lemma derp0l : p.[b] <= 0 -> forall x, x \in `[a, b[ -> p.[x] < 0.
-Proof.
-move=> pb0 x hx; rewrite -oppr_gte0 /=.
-case: (@mvt x b p)=> //; first by rewrite (itvP hx).
-move=> c hc; move/(canRL (@addKr _ _))->; rewrite ltr_spaddr ?oppr_ge0 //.
-rewrite pmulr_rgt0 // ?subr_gt0 ?(itvP hx) //.
-by rewrite der_pos // (subitvPl _ hc) //= (itvP hx).
-Qed.
-
-Lemma derpnl : p.[b] < 0 -> forall x, x \in `[a, b] -> p.[x] < 0.
-Proof.
-move=> pbn x hx; case xb: (b == x) pbn; first by rewrite -(eqP xb).
-case: (@mvt x b p); first by rewrite ltr_def xb ?(itvP hx).
-move=> y hy; move/eqP; rewrite subr_eq; move/eqP->.
-rewrite !ltrNge; apply: contra=> hpx; rewrite ler_paddr // ltrW //.
-rewrite pmulr_rgt0 ?subr_gt0 ?(itvP hy) //.
-by rewrite der_pos // (subitvPl _ hy) //= (itvP hx).
-Qed.
-
-End NoRoot.
-
-Section NoRoot_sg.
-
-Variable (p : {poly R}).
-
-Variables (a b c : R).
-
-Hypothesis derp_neq0 : {in `]a, b[, noroot p^`()}.
-Hypothesis acb : c \in `]a, b[.
-
-Local Notation sp'c := (sgr p^`().[c]).
-Local Notation q := (sp'c *: p).
-
-Fact derq_pos x : x \in `]a, b[ -> (q^`()).[x] > 0.
-Proof.
-move=> hx; rewrite derivZ hornerZ -sgr_cp0.
-rewrite sgrM sgr_id mulr_sg_eq1 derp_neq0 //=.
-by apply/eqP; apply: (@polyrN0_itv `]a, b[).
-Qed.
-
-Fact sgp x : sgr p.[x] = sp'c * sgr q.[x].
-Proof.
-by rewrite hornerZ sgr_smul mulrA -expr2 sqr_sg derp_neq0 ?mul1r.
-Qed.
-
-Fact hsgp x : 0 < q.[x] -> sgr p.[x] = sp'c.
-Proof. by rewrite -sgr_cp0 sgp => /eqP->; rewrite mulr1. Qed.
-
-Fact hsgpN x : q.[x] < 0 -> sgr p.[x] = - sp'c.
-Proof. by rewrite -sgr_cp0 sgp => /eqP->; rewrite mulrN1. Qed.
-
-Lemma ders0r : p.[a] = 0 -> forall x, x \in `]a, b] -> sgr p.[x] = sp'c.
-Proof.
-move=> pa0 x hx; rewrite hsgp // (@derp0r _ a b) //; first exact: derq_pos.
-by rewrite hornerZ pa0 mulr0.
-Qed.
-
-Lemma derspr : sgr p.[a] = sp'c -> forall x, x \in `[a, b] -> sgr p.[x] = sp'c.
-Proof.
-move=> spa x hx; rewrite hsgp // (@derppr _ a b) //; first exact: derq_pos.
-by rewrite -sgr_cp0 hornerZ sgrM sgr_id spa -expr2 sqr_sg derp_neq0.
-Qed.
-
-Lemma ders0l : p.[b] = 0 -> forall x, x \in `[a, b[ -> sgr p.[x] = -sp'c.
-Proof.
-move=> pa0 x hx; rewrite hsgpN // (@derp0l _ a b) //; first exact: derq_pos.
-by rewrite hornerZ pa0 mulr0.
-Qed.
-
-Lemma derspl :
- sgr p.[b] = -sp'c -> forall x, x \in `[a, b] -> sgr p.[x] = -sp'c.
-Proof.
-move=> spb x hx; rewrite hsgpN // (@derpnl _ a b) //; first exact: derq_pos.
-by rewrite -sgr_cp0 hornerZ sgr_smul spb mulrN -expr2 sqr_sg derp_neq0.
-Qed.
-
-End NoRoot_sg.
-
-Variable (p : {poly R}).
-
-Variables (a b : R).
-
-Section der_root.
-
-Hypothesis der_pos : forall x, x \in `]a, b[ -> (p^`()).[x] > 0.
-
-Lemma derp_root : a <= b -> 0 \in `]p.[a], p.[b][ ->
- { r : R |
- [/\ forall x, x \in `[a, r[ -> p.[x] < 0,
- p.[r] = 0,
- r \in `]a, b[ &
- forall x, x \in `]r, b] -> p.[x] > 0] }.
-Proof.
-move=> leab hpab.
-have /eqP hs : sgr p.[a] * sgr p.[b] == -1.
- by rewrite -sgrM sgr_cp0 pmulr_llt0 ?(itvP hpab).
-case: (ivt_sign leab hs) => r arb pr0; exists r; split => //; last 2 first.
-- by move/eqP: pr0.
-- move=> x rxb; have hd : forall t, t \in `]r, b[ -> 0 < (p^`()).[t].
- by move=> t ht; rewrite der_pos // ?(subitvPl _ ht) //= ?(itvP arb).
- by rewrite (derp0r hd) ?(eqP pr0).
-- move=> x rxb; have hd : forall t, t \in `]a, r[ -> 0 < (p^`()).[t].
- by move=> t ht; rewrite der_pos // ?(subitvPr _ ht) //= ?(itvP arb).
- by rewrite (derp0l hd) ?(eqP pr0).
-Qed.
-
-End der_root.
-
-(* Section der_root_sg. *)
-
-(* Hypothesis der_pos : forall x, x \in `]a, b[ -> (p^`()).[x] != 0. *)
-
-(* Lemma derp_root : a <= b -> sgr p.[a] != sgr p.[b] -> *)
-(* { r : R | *)
-(* [/\ forall x, x \in `[a, r[ -> p.[x] < 0, *)
-(* p.[r] = 0, *)
-(* r \in `]a, b[ & *)
-(* forall x, x \in `]r, b] -> p.[x] > 0] }. *)
-(* Proof. *)
-(* move=> leab hpab. *)
-(* have hs : sgr p.[a] * sgr p.[b] == -1. *)
-(* by rewrite -sgrM sgr_cp0 mulr_lt0_gt0 ?(itvP hpab). *)
-(* case: (ivt_sign ivt leab hs) => r arb pr0; exists r; split => //; last 2 first. *)
-(* - by move/eqP: pr0. *)
-(* - move=> x rxb; have hd : forall t, t \in `]r, b[ -> 0 < (p^`()).[t]. *)
-(* by move=> t ht; rewrite der_pos // ?(subitvPl _ ht) //= ?(itvP arb). *)
-(* by rewrite (derp0r hd) ?(eqP pr0). *)
-(* - move=> x rxb; have hd : forall t, t \in `]a, r[ -> 0 < (p^`()).[t]. *)
-(* by move=> t ht; rewrite der_pos // ?(subitvPr _ ht) //= ?(itvP arb). *)
-(* by rewrite (derp0l hd) ?(eqP pr0). *)
-(* Qed. *)
-
-(* End der_root. *)
-
-End MonotonictyAndRoots.
-
-Section RootsOn.
-
-Variable T : predType R.
-
-Definition roots_on (p : {poly R}) (i : T) (s : seq R) :=
- forall x, (x \in i) && (root p x) = (x \in s).
-
-Lemma roots_onP p i s : roots_on p i s -> {in i, root p =1 mem s}.
-Proof. by move=> hp x hx; move: (hp x); rewrite hx. Qed.
-
-Lemma roots_on_in p i s :
- roots_on p i s -> forall x, x \in s -> x \in i.
-Proof. by move=> hp x; rewrite -hp; case/andP. Qed.
-
-Lemma roots_on_root p i s :
- roots_on p i s -> forall x, x \in s -> root p x.
-Proof. by move=> hp x; rewrite -hp; case/andP. Qed.
-
-Lemma root_roots_on p i s :
- roots_on p i s -> forall x, x \in i -> root p x -> x \in s.
-Proof. by move=> hp x; rewrite -hp=> ->. Qed.
-
-Lemma roots_on_opp p i s : roots_on (- p) i s -> roots_on p i s.
-Proof. by move=> hp x; rewrite -hp rootN. Qed.
-
-Lemma roots_on_nil p i : roots_on p i [::] -> {in i, noroot p}.
-Proof. by move=> hp x hx; move: (hp x); rewrite in_nil hx /=; move->. Qed.
-
-Lemma roots_on_same s' p i s : s =i s' -> (roots_on p i s <-> roots_on p i s').
-Proof. by move=> hss'; split=> hs x; rewrite (hss', (I, hss')). Qed.
-
-End RootsOn.
-
-
-(* (* Symmetry of center a *) *)
-(* Definition symr (a x : R) := a - x. *)
-
-(* Lemma symr_inv : forall a, involutive (symr a). *)
-(* Proof. by move=> a y; rewrite /symr opprD addrA subrr opprK add0r. Qed. *)
-
-(* Lemma symr_inj : forall a, injective (symr a). *)
-(* Proof. by move=> a; apply: inv_inj; apply: symr_inv. Qed. *)
-
-(* Lemma ltr_sym : forall a x y, (symr a x < symr a y) = (y < x). *)
-(* Proof. by move=> a x y; rewrite lter_add2r lter_oppr opprK. Qed. *)
-
-(* Lemma symr_add_itv : forall a b x, *)
-(* (a < symr (a + b) x < b) = (a < x < b). *)
-(* Proof. *)
-(* move=> a b x; rewrite andbC. *)
-(* by rewrite lter_subrA lter_add2r -lter_addlA lter_add2l. *)
-(* Qed. *)
-
-Lemma roots_on_comp p a b s :
- roots_on (p \Po (-'X)) `](-b), (-a)[ (map (-%R) s) <-> roots_on p `]a, b[ s.
-Proof.
-split=> /= hs x; rewrite ?root_comp ?hornerE.
- move: (hs (-x)); rewrite mem_map; last exact: (inv_inj (@opprK _)).
- by rewrite root_comp ?hornerE oppr_itv !opprK.
-rewrite -[x]opprK oppr_itv /= mem_map; last exact: (inv_inj (@opprK _)).
-by move: (hs (-x)); rewrite !opprK.
-Qed.
-
-Lemma min_roots_on p a b x s :
- all (> x) s -> roots_on p `]a, b[ (x :: s) ->
- [/\ x \in `]a, b[, roots_on p `]a, x[ [::], root p x & roots_on p `]x, b[ s].
-Proof.
-move=> lxs hxs.
-have hx: x \in `]a, b[ by rewrite (roots_on_in hxs) ?mem_head.
-rewrite hx (roots_on_root hxs) ?mem_head //.
-split=> // y; move: (hxs y); rewrite ?in_nil ?in_cons /=.
- case hy: (y \in `]a, x[)=> //=.
- rewrite (subitvPr _ hy) //= ?(itvP hx) //= => ->.
- rewrite ltr_eqF ?(itvP hy) //=; apply/negP.
- by move/allP: lxs=> lxs /lxs; rewrite ltrNge ?(itvP hy).
-move/allP:lxs=>lxs; case eyx: (y == _)=> /=.
- case/andP=> hy _; rewrite (eqP eyx).
- rewrite boundl_in_itv /=; symmetry.
- by apply/negP; move/lxs; rewrite ltrr.
-case py0: root; rewrite !(andbT, andbF) //.
-case ys: (y \in s); first by move/lxs:ys; rewrite ?inE => ->; case/andP.
-move/negP; move/negP=> nhy; apply: negbTE; apply: contra nhy.
-by apply: subitvPl; rewrite //= ?(itvP hx).
-Qed.
-
-Lemma max_roots_on p a b x s :
- all (< x) s -> roots_on p `]a, b[ (x :: s) ->
- [/\ x \in `]a, b[, roots_on p `]x, b[ [::], root p x & roots_on p `]a, x[ s].
-Proof.
-move/allP=> lsx /roots_on_comp/=/min_roots_on[].
- apply/allP=> y; rewrite -[y]opprK mem_map.
- by move/lsx; rewrite ltr_oppr opprK.
- exact: (inv_inj (@opprK _)).
-rewrite oppr_itv root_comp !hornerE !opprK=> -> rxb -> rax.
-by split=> //; apply/roots_on_comp.
-Qed.
-
-Lemma roots_on_cons p a b r s :
- sorted <%R (r :: s) -> roots_on p `]a, b[ (r :: s) -> roots_on p `]r, b[ s.
-Proof.
-move=> /= hrs hr.
-have:= (order_path_min (@ltr_trans _) hrs)=> allrs.
-by case: (min_roots_on allrs hr).
-Qed.
-(* move=> p a b r s hp hr x; apply/andP/idP. *)
-(* have:= (order_path_min (@ltr_trans _) hp) => /=; case/andP=> ar1 _. *)
-(* case; move/ooitvP=> rxb rpx; move: (hr x); rewrite in_cons rpx andbT. *)
-(* by rewrite rxb andbT (ltr_trans ar1) 1?eq_sym ?ltr_eqF ?rxb. *)
-(* move=> spx. *)
-(* have xrsp: x \in r :: s by rewrite in_cons spx orbT. *)
-(* rewrite (roots_on_root hr) //. *)
-(* rewrite (roots_on_in hr xrsp); move: hp => /=; case/andP=> _. *)
-(* by move/(order_path_min (@ltr_trans _)); move/allP; move/(_ _ spx)->. *)
-(* Qed. *)
-
-Lemma roots_on_rcons : forall p a b r s,
- sorted <%R (rcons s r) -> roots_on p `]a, b[ (rcons s r)
- -> roots_on p `]a, r[ s.
-Proof.
-move=> p a b r s; rewrite -{1}[s]revK -!rev_cons rev_sorted /=.
-move=> hrs hr.
-have := (order_path_min (rev_trans (@ltr_trans _)) hrs)=> allrrs.
-have allrs: (all (< r) s).
- by apply/allP=> x hx; move/allP:allrrs; apply; rewrite mem_rev.
-move/(@roots_on_same _ _ _ _ (r::s)):hr=>hr.
-case: (max_roots_on allrs (hr _))=> //.
-by move=> x; rewrite mem_rcons.
-Qed.
-
-
-(* move=> p a b r s; rewrite -{1}[s]revK -!rev_cons rev_sorted. *)
-(* rewrite [r :: _]lock /=; unlock; move=> hp hr x; apply/andP/idP. *)
-(* have:= (order_path_min (rev_trans (@ltr_trans _)) hp) => /=. *)
-(* case/andP=> ar1 _; case; move/ooitvP=> axr rpx. *)
-(* move: (hr x); rewrite mem_rcons in_cons rpx andbT axr andTb. *)
-(* by rewrite ((rev_trans (@ltr_trans _) ar1)) ?ltr_eqF ?axr. *)
-(* move=> spx. *)
-(* have xrsp: x \in rcons s r by rewrite mem_rcons in_cons spx orbT. *)
-(* rewrite (roots_on_root hr) //. *)
-(* rewrite (roots_on_in hr xrsp); move: hp => /=; case/andP=> _. *)
-(* move/(order_path_min (rev_trans (@ltr_trans _))); move/allP. *)
-(* by move/(_ x)=> -> //; rewrite mem_rev. *)
-(* Qed. *)
-
-Lemma no_roots_on (p : {poly R}) a b :
- {in `]a, b[, noroot p} -> roots_on p `]a, b[ [::].
-Proof.
-move=> hr x; rewrite in_nil; case hx: (x \in _) => //=.
-by apply: negPf; apply: hr hx.
-Qed.
-
-Lemma monotonic_rootN (p : {poly R}) (a b : R) :
- {in `]a, b[, noroot p^`()} ->
- ((roots_on p `]a, b[ [::]) + ({r : R | roots_on p `]a, b[ [:: r]}))%type.
-Proof.
-move=> hp'; case: (ltrP a b); last first => leab.
- by left => x; rewrite in_nil itv_gte.
-wlog {hp'} hp'sg: p / forall x, x \in `]a, b[ -> sgr (p^`()).[x] = 1.
- move=> hwlog. have := (polyrN0_itv hp').
- move: (mid_in_itvoo leab)=> hm /(_ _ _ hm).
- case: (sgrP _.[mid a b])=> hpm.
- - by move=> norm; move: (hp' _ hm); rewrite rootE hpm eqxx.
- - by move/(hwlog p).
- - move=> hp'N; case: (hwlog (-p))=> [x|h|[r hr]].
- * by rewrite derivE hornerN sgrN=> /hp'N->; rewrite opprK.
- * by left; apply: roots_on_opp.
- * by right; exists r; apply: roots_on_opp.
-have hp'pos: forall x, x \in `]a, b[ -> (p^`()).[x] > 0.
- by move=> x; move/hp'sg; move/eqP; rewrite sgr_cp0.
-case: (lerP 0 p.[a]) => ha.
-- left; apply: no_roots_on => x axb.
- by rewrite rootE gtr_eqF // (@derp0r _ a b) // (subitvPr _ axb) /=.
-- case: (lerP p.[b] 0) => hb.
- + left => x; rewrite in_nil; apply: negbTE; case axb: (x \in `]a, b[) => //=.
- by rewrite rootE ltr_eqF // (@derp0l _ a b) // (subitvPl _ axb) /=.
- + case: (derp_root hp'pos (ltrW leab) _).
- by rewrite ?inE; apply/andP.
- move=> r [h1 h2 h3] h4; right.
- exists r => x; rewrite in_cons in_nil (itv_splitU2 h3).
- case exr: (x == r); rewrite ?(andbT, orbT, andbF, orbF) /=.
- by rewrite rootE (eqP exr) h2 eqxx.
- case px0: root; rewrite (andbT, andbF) //.
- move/eqP: px0=> px0; apply/negP; case/orP=> hx.
- by move: (h1 x); rewrite (subitvPl _ hx) //= px0 ltrr; move/implyP.
- by move: (h4 x); rewrite (subitvPr _ hx) //= px0 ltrr; move/implyP.
-Qed.
-
-(* Inductive polN0 : Type := PolN0 : forall p : {poly R}, p != 0 -> polN0. *)
-
-(* Coercion pol_of_polN0 i := let: PolN0 p _ := i in p. *)
-
-(* Canonical Structure polN0_subType := [subType for pol_of_polN0]. *)
-(* Definition polN0_eqMixin := Eval hnf in [eqMixin of polN0 by <:]. *)
-(* Canonical Structure polN0_eqType := *)
-(* Eval hnf in EqType polN0 polN0_eqMixin. *)
-(* Definition polN0_choiceMixin := [choiceMixin of polN0 by <:]. *)
-(* Canonical Structure polN0_choiceType := *)
-(* Eval hnf in ChoiceType polN0 polN0_choiceMixin. *)
-
-(* Todo : Lemmas about operations of intervall :
- itversection, restriction and splitting *)
-Lemma cat_roots_on (p : {poly R}) a b x :
- x \in `]a, b[ -> ~~ (root p x) ->
- forall s s', sorted <%R s -> sorted <%R s' ->
- roots_on p `]a, x[ s -> roots_on p `]x, b[ s' ->
- roots_on p `]a, b[ (s ++ s').
-Proof.
-move=> hx /= npx0 s; elim: s a hx => [|y s ihs] a hx s' //= ss ss'.
- move/roots_on_nil=> hax hs' y.
- rewrite -hs'; case py0: root; rewrite ?(andbT, andbF) //.
- rewrite (itv_splitU2 hx); case: (y \in `]x, b[); rewrite ?orbF ?orbT //=.
- apply/negP; case/orP; first by move/hax; rewrite py0.
- by move/eqP=> exy; rewrite -exy py0 in npx0.
-move/min_roots_on; rewrite order_path_min //; last exact: ltr_trans.
-case=> // hy hay py0 hs hs' z.
-rewrite in_cons; case ezy: (z == y)=> /=.
- by rewrite (eqP ezy) py0 andbT (subitvPr _ hy) //= ?(itvP hx).
-rewrite -(ihs y) //; last exact: path_sorted ss; last first.
- by rewrite inE /= (itvP hx) (itvP hy).
-case pz0: root; rewrite ?(andbT, andbF) //.
-rewrite (@itv_splitU2 _ y); last by rewrite (subitvPr _ hy) //= (itvP hx).
-rewrite ezy /=; case: (z \in `]y, b[); rewrite ?orbF ?orbT //.
-by apply/negP=> hz; move: (hay z); rewrite hz pz0 in_nil.
-Qed.
-
-CoInductive roots_spec (p : {poly R}) (i : pred R) (s : seq R) :
- {poly R} -> bool -> seq R -> Type :=
-| Roots0 of p = 0 :> {poly R} & s = [::] : roots_spec p i s 0 true [::]
-| Roots of p != 0 & roots_on p i s
- & sorted <%R s : roots_spec p i s p false s.
-
-(* still much too long *)
-Lemma itv_roots (p :{poly R}) (a b : R) :
- {s : seq R & roots_spec p (topred `]a, b[) s p (p == 0) s}.
-Proof.
-case p0: (_ == 0).
- by rewrite (eqP p0); exists [::]; constructor.
-elim: (size p) {-2}p (leqnn (size p)) p0 a b => {p} [| n ihn] p sp p0 a b.
- by exists [::]; move: p0; rewrite -size_poly_eq0 -leqn0 sp.
-move/negbT: (p0)=> np0.
-case p'0 : (p^`() == 0).
- move: p'0; rewrite -derivn1 -derivn_poly0; move/size1_polyC => pC.
- exists [::]; constructor=> // x; rewrite in_nil pC rootC; apply: negPf.
- by rewrite negb_and -polyC_eq0 -pC p0 orbT.
-move/negbT: (p'0) => np'0.
-have sizep' : (size p^`() <= n)%N.
- rewrite -ltnS; apply: leq_trans sp; rewrite size_deriv prednK // lt0n.
- by rewrite size_poly_eq0 p0.
-case: (ihn _ sizep' p'0 a b) => sp' ih {ihn}.
-case ltab : (a < b); last first.
- exists [::]; constructor=> // x; rewrite in_nil.
- case axb : (x \in _) => //=.
- by case/andP: axb => ax xb; move: ltab; rewrite (ltr_trans ax xb).
-elim: sp' a b ltab ih => [|r1 sp' hsp'] a b ltab hp'.
- case: hp' np'0; rewrite ?eqxx // => np'0 hroots' _ _.
- move/roots_on_nil : hroots' => hroots'.
- case: (monotonic_rootN hroots') => [h| [r rh]].
- by exists [::]; constructor.
- by exists [:: r]; constructor=> //=; rewrite andbT.
-case: hp' np'0; rewrite ?eqxx // => np'0 hroots' /= hpath' _.
-case: (min_roots_on _ hroots').
- by rewrite order_path_min //; apply: ltr_trans.
-move=> hr1 har1 p'r10 hr1b.
-case: (hsp' r1 b); first by rewrite (itvP hr1).
- by constructor=> //; rewrite (path_sorted hpath').
-move=> s spec_s.
-case: spec_s np0; rewrite ?eqxx //.
-move=> np0 hroot hsort _.
-move: (roots_on_nil har1).
-case pr1 : (root p r1); case/monotonic_rootN => hrootsl; last 2 first.
-- exists s; constructor=> //.
- by rewrite -[s]cat0s; apply: (cat_roots_on hr1)=> //; rewrite pr1.
-- case: hrootsl=> r hr; exists (r::s); constructor=> //=.
- by rewrite -cat1s; apply: (cat_roots_on hr1)=> //; rewrite pr1.
- rewrite path_min_sorted // => y; rewrite -hroot; case/andP=> hy _.
- rewrite (@ltr_trans _ r1) ?(itvP hy) //.
- by rewrite (itvP (roots_on_in hr (mem_head _ _))).
-- exists (r1::s); constructor=> //=; last first.
- rewrite path_min_sorted=> // y; rewrite -hroot.
- by case/andP; move/itvP->.
- move=> x; rewrite in_cons; case exr1: (x == r1)=> /=.
- by rewrite (eqP exr1) pr1 andbT.
- rewrite -hroot; case px: root; rewrite ?(andbT, andbF) //.
- rewrite (itv_splitU2 hr1) exr1 /=.
- case: (_ \in `]r1, _[); rewrite ?(orbT, orbF) //.
- by apply/negP=> hx; move: (hrootsl x); rewrite hx px in_nil.
-- case: hrootsl => r0 hrootsl.
- move/min_roots_on:hrootsl; case=> // hr0 har0 pr0 hr0r1.
- exists [:: r0, r1 & s]; constructor=> //=; last first.
- rewrite (itvP hr0) /= path_min_sorted // => y.
- by rewrite -hroot; case/andP; move/itvP->.
- move=> y; rewrite !in_cons (itv_splitU2 hr1) (itv_splitU2 hr0).
- case eyr0: (y == r0); rewrite ?(orbT, orbF, orTb, orFb).
- by rewrite (eqP eyr0) pr0.
- case eyr1: (y == r1); rewrite ?(orbT, orbF, orTb, orFb).
- by rewrite (eqP eyr1) pr1.
- rewrite -hroot; case py0: root; rewrite ?(andbF, andbT) //.
- case: (_ \in `]r1, _[); rewrite ?(orbT, orbF) //.
- apply/negP; case/orP=> hy; first by move: (har0 y); rewrite hy py0 in_nil.
- by move: (hr0r1 y); rewrite hy py0 in_nil.
-Qed.
-
-Definition roots (p : {poly R}) a b := projT1 (itv_roots p a b).
-
-Lemma rootsP p a b :
- roots_spec p (topred `]a, b[) (roots p a b) p (p == 0) (roots p a b).
-Proof. by rewrite /roots; case hp: itv_roots. Qed.
-
-Lemma roots0 a b : roots 0 a b = [::].
-Proof. by case: rootsP=> //=; rewrite eqxx. Qed.
-
-Lemma roots_on_roots : forall p a b, p != 0 ->
- roots_on p `]a, b[ (roots p a b).
-Proof. by move=> a b p; case: rootsP. Qed.
-Hint Resolve roots_on_roots.
-
-Lemma sorted_roots a b p : sorted <%R (roots p a b).
-Proof. by case: rootsP. Qed.
-Hint Resolve sorted_roots.
-
-Lemma path_roots p a b : path <%R a (roots p a b).
-Proof.
-case: rootsP=> //= p0 hp sp; rewrite path_min_sorted //.
-by move=> y; rewrite -hp; case/andP; move/itvP->.
-Qed.
-Hint Resolve path_roots.
-
-Lemma root_is_roots (p : {poly R}) (a b : R) :
- p != 0 -> forall x, x \in `]a, b[ -> root p x = (x \in roots p a b).
-Proof. by case: rootsP=> // p0 hs ps _ y hy /=; rewrite -hs hy. Qed.
-
-Lemma root_in_roots (p : {poly R}) a b :
- p != 0 -> forall x, x \in `]a, b[ -> root p x -> x \in (roots p a b).
-Proof. by move=> p0 x axb rpx; rewrite -root_is_roots. Qed.
-
-Lemma root_roots p a b x : x \in roots p a b -> root p x.
-Proof. by case: rootsP=> // p0 <- _; case/andP. Qed.
-
-Lemma roots_nil p a b : p != 0 ->
- roots p a b = [::] -> {in `]a, b[, noroot p}.
-Proof.
-case: rootsP => // p0 hs ps _ s0 x axb.
-by move: (hs x); rewrite s0 in_nil !axb /= => ->.
-Qed.
-
-Lemma roots_in p a b x : x \in roots p a b -> x \in `]a, b[.
-Proof. by case: rootsP=> //= np0 ron_p *; apply: (roots_on_in ron_p). Qed.
-
-Lemma rootsEba p a b : b <= a -> roots p a b = [::].
-Proof.
-case: rootsP=> // p0; case: (roots _ _ _) => [|x s] hs ps ba //;
-by move: (hs x); rewrite itv_gte //= mem_head.
-Qed.
-
-Lemma roots_on_uniq p a b s1 s2 :
- sorted <%R s1 -> sorted <%R s2 ->
- roots_on p `]a, b[ s1 -> roots_on p `]a, b[ s2 -> s1 = s2.
-Proof.
-elim: s1 p a b s2 => [| r1 s1 ih] p a b [| r2 s2] ps1 ps2 rs1 rs2 //.
-- have rpr2 : root p r2 by apply: (roots_on_root rs2); rewrite mem_head.
- have abr2 : r2 \in `]a, b[ by apply: (roots_on_in rs2); rewrite mem_head.
- by have:= (rs1 r2); rewrite rpr2 !abr2 in_nil.
-- have rpr1 : root p r1 by apply: (roots_on_root rs1); rewrite mem_head.
- have abr1 : r1 \in `]a, b[ by apply: (roots_on_in rs1); rewrite mem_head.
- by have:= (rs2 r1); rewrite rpr1 !abr1 in_nil.
-- have er1r2 : r1 = r2.
- move: (rs1 r2); rewrite (roots_on_root rs2) ?mem_head //.
- rewrite !(roots_on_in rs2) ?mem_head //= in_cons.
- move/(@sym_eq _ true); case/orP => hr2; first by rewrite (eqP hr2).
- move: ps1=> /=; move/(order_path_min (@ltr_trans R)); move/allP.
- move/(_ r2 hr2) => h1.
- move: (rs2 r1); rewrite (roots_on_root rs1) ?mem_head //.
- rewrite !(roots_on_in rs1) ?mem_head //= in_cons.
- move/(@sym_eq _ true); case/orP => hr1; first by rewrite (eqP hr1).
- move: ps2=> /=; move/(order_path_min (@ltr_trans R)); move/allP.
- by move/(_ r1 hr1); rewrite ltrNge ltrW.
-congr (_ :: _) => //; rewrite er1r2 in ps1 rs1.
-have h3 := (roots_on_cons ps1 rs1).
-have h4 := (roots_on_cons ps2 rs2).
-move: ps1 ps2=> /=; move/path_sorted=> hs1; move/path_sorted=> hs2.
-exact: (ih p _ b _ hs1 hs2 h3 h4).
-Qed.
-
-Lemma roots_eq (p q : {poly R}) (a b : R) :
- p != 0 -> q != 0 ->
- ({in `]a, b[, root p =1 root q} <-> roots p a b = roots q a b).
-Proof.
-move=> p0 q0.
-case hab : (a < b); last first.
- split; first by rewrite !rootsEba // lerNgt hab.
- move=> _ x. rewrite !inE; case/andP=> ax xb.
- by move: hab; rewrite (@ltr_trans _ x) /=.
-split=> hpq.
- apply: (@roots_on_uniq p a b); rewrite ?path_roots ?p0 ?q0 //.
- by apply: roots_on_roots.
- rewrite /roots_on => x; case hx: (_ \in _).
- by rewrite -hx hpq //; apply: roots_on_roots.
- by rewrite /= -(andFb (q.[x] == 0)) -hx; apply: roots_on_roots.
-move=> x axb /=.
-by rewrite (@root_is_roots q a b) // (@root_is_roots p a b) // hpq.
-Qed.
-
-Lemma roots_opp p : roots (- p) =2 roots p.
-Proof.
-move=> a b; case p0 : (p == 0); first by rewrite (eqP p0) oppr0.
-by apply/roots_eq=> [||x]; rewrite ?oppr_eq0 ?p0 ?rootN.
-Qed.
-
-Lemma no_root_roots (p : {poly R}) a b :
- {in `]a, b[ , noroot p} -> roots p a b = [::].
-Proof.
-move=> hr; case: rootsP => // p0 hs ps.
-apply: (@roots_on_uniq p a b)=> // x; rewrite in_nil.
-by apply/negP; case/andP; move/hr; move/negPf->.
-Qed.
-
-Lemma head_roots_on_ge p a b s :
- a < b -> roots_on p `]a, b[ s -> a < head b s.
-Proof.
-case: s => [|x s] ab // /(_ x).
-by rewrite in_cons eqxx; case/andP; case/andP.
-Qed.
-
-Lemma head_roots_ge : forall p a b, a < b -> a < head b (roots p a b).
-Proof.
-by move=> p a b; case: rootsP=> // *; apply: head_roots_on_ge.
-Qed.
-
-Lemma last_roots_on_le p a b s :
- a < b -> roots_on p `]a, b[ s -> last a s < b.
-Proof.
-case: s => [|x s] ab rs //.
-by rewrite (itvP (roots_on_in rs _)) //= mem_last.
-Qed.
-
-Lemma last_roots_le p a b : a < b -> last a (roots p a b) < b.
-Proof. by case: rootsP=> // *; apply: last_roots_on_le. Qed.
-
-Lemma roots_uniq p a b s :
- p != 0 -> roots_on p `]a, b[ s -> sorted <%R s -> s = roots p a b.
-Proof.
-case: rootsP=> // p0 hs' ps' _ hs ss.
-exact: (@roots_on_uniq p a b)=> //.
-Qed.
-
-Lemma roots_cons p a b x s :
- (roots p a b == x :: s)
- = [&& p != 0, x \in `]a, b[,
- roots p a x == [::], root p x & roots p x b == s].
-Proof.
-case: rootsP=> // p0 hs' ps' /=.
-apply/idP/idP.
- move/eqP=> es'; move: ps' hs'; rewrite es' /= => sxs.
- case/min_roots_on; first by apply: order_path_min=> //; apply: ltr_trans.
- move=> -> rax px0 rxb.
- rewrite px0 (@roots_uniq p a x [::]) // (@roots_uniq p x b s) ?eqxx //=.
- by move/path_sorted:sxs.
-case: rootsP p0=> // p0 rax sax _.
-case/and3P=> hx hax; rewrite (eqP hax) in rax sax.
-case: rootsP p0=> // p0 rxb sxb _.
-case/andP=> px0 hxb; rewrite (eqP hxb) in rxb sxb.
-rewrite [_ :: _](@roots_uniq p a b) //; last first.
- rewrite /= path_min_sorted // => y.
- by rewrite -(eqP hxb); move/roots_in; move/itvP->.
-move=> y; rewrite (itv_splitU2 hx) !andb_orl in_cons.
-case hy: (y == x); first by rewrite (eqP hy) px0 orbT.
-by rewrite andFb orFb rax rxb in_nil.
-Qed.
-
-Lemma roots_rcons p a b x s :
- (roots p a b == rcons s x) =
- [&& p != 0, x \in `]a , b[,
- roots p x b == [::], root p x & roots p a x == s].
-Proof.
-case: rootsP; first by case: s.
-move=> // p0 hs' ps' /=.
-apply/idP/idP.
- move/eqP=> es'; move: ps' hs'; rewrite es' /= => sxs.
- have hsx: rcons s x =i x :: rev s.
- by move=> y; rewrite mem_rcons !in_cons mem_rev.
- move/(roots_on_same _ _ hsx).
- case/max_roots_on.
- move: sxs; rewrite -[rcons _ _]revK rev_sorted rev_rcons.
- by apply: order_path_min=> u v w /=; move/(ltr_trans _); apply.
- move=> -> rax px0 rxb.
- move/(@roots_on_same _ s): rxb; move/(_ (mem_rev _))=> rxb.
- rewrite px0 (@roots_uniq p x b [::]) // (@roots_uniq p a x s) ?eqxx //=.
- move: sxs; rewrite -[rcons _ _]revK rev_sorted rev_rcons.
- by move/path_sorted; rewrite -rev_sorted revK.
-case: rootsP p0=> // p0 rax sax _.
-case/and3P=> hx hax; rewrite (eqP hax) in rax sax.
-case: rootsP p0=> // p0 rxb sxb _.
-case/andP=> px0 hxb; rewrite (eqP hxb) in rxb sxb.
-rewrite [rcons _ _](@roots_uniq p a b) //; last first.
- rewrite -[rcons _ _]revK rev_sorted rev_rcons /= path_min_sorted.
- by rewrite -rev_sorted revK.
- move=> y; rewrite mem_rev; rewrite -(eqP hxb).
- by move/roots_in; move/itvP->.
-move=> y; rewrite (itv_splitU2 hx) mem_rcons in_cons !andb_orl.
-case hy: (y == x); first by rewrite (eqP hy) px0 orbT.
-by rewrite rxb rax in_nil !orbF.
-Qed.
-
-Section NeighborHood.
-
-Implicit Types a b : R.
-
-Implicit Types p : {poly R}.
-
-Definition next_root (p : {poly R}) x b :=
- if p == 0 then x else head (maxr b x) (roots p x b).
-
-Lemma next_root0 a b : next_root 0 a b = a.
-Proof. by rewrite /next_root eqxx. Qed.
-
-CoInductive next_root_spec (p : {poly R}) x b : bool -> R -> Type :=
-| NextRootSpec0 of p = 0 : next_root_spec p x b true x
-| NextRootSpecRoot y of p != 0 & p.[y] = 0 & y \in `]x, b[
- & {in `]x, y[, forall z, ~~(root p z)} : next_root_spec p x b true y
-| NextRootSpecNoRoot c of p != 0 & c = maxr b x
- & {in `]x, b[, forall z, ~~(root p z)} : next_root_spec p x b (p.[c] == 0) c.
-
-Lemma next_rootP (p : {poly R}) a b :
- next_root_spec p a b (p.[next_root p a b] == 0) (next_root p a b).
-Proof.
-rewrite /next_root /=; case hs: roots => [|x s] /=.
- case: (altP (p =P 0))=> p0.
- by rewrite {2}p0 hornerC eqxx; constructor; rewrite p0.
- by constructor=> // y hy; apply: (roots_nil p0 hs).
-move/eqP: hs; rewrite roots_cons; case/and5P=> p0 hx; move/eqP=> rap rpx rx.
-rewrite (negPf p0) (rootPt rpx); constructor=> //; first by move/eqP: rpx.
-by move=> y hy /=; move/(roots_nil p0): (rap); apply.
-Qed.
-
-Lemma next_root_in p a b : next_root p a b \in `[a, maxr b a].
-Proof.
-case: next_rootP => [p0|y np0 py0 hy _|c np0 hc _].
-* by rewrite bound_in_itv /= ler_maxr lerr orbT.
-* by apply: subitvP hy=> /=; rewrite ler_maxr !lerr.
-* by rewrite hc bound_in_itv /= ler_maxr lerr orbT.
-Qed.
-
-Lemma next_root_gt p a b : a < b -> p != 0 -> next_root p a b > a.
-Proof.
-move=> ab np0; case: next_rootP=> [p0|y _ py0 hy _|c _ -> _].
-* by rewrite p0 eqxx in np0.
-* by rewrite (itvP hy).
-* by rewrite maxr_l // ltrW.
-Qed.
-
-Lemma next_noroot p a b : {in `]a, (next_root p a b)[, noroot p}.
-Proof.
-move=> z; case: next_rootP; first by rewrite itv_xx.
- by move=> y np0 py0 hy hp hz; rewrite (negPf (hp _ _)).
-move=> c p0 -> hp hz; rewrite (negPf (hp _ _)) //.
-by case: maxrP hz; last by rewrite itv_xx.
-Qed.
-
-Lemma is_next_root p a b x :
- next_root_spec p a b (root p x) x -> x = next_root p a b.
-Proof.
-case; first by move->; rewrite /next_root eqxx.
- move=> y; case: next_rootP; first by move->; rewrite eqxx.
- move=> y' np0 py'0 hy' hp' _ py0 hy hp.
- wlog: y y' hy' hy hp' hp py0 py'0 / y <= y'.
- by case/orP: (ler_total y y')=> lyy' hw; [|symmetry]; apply: hw.
- case: ltrgtP=> // hyy' _; move: (hp' y).
- by rewrite rootE py0 eqxx inE /= (itvP hy) hyy'; move/(_ isT).
- move=> c p0 ->; case: maxrP=> hab; last by rewrite itv_gte //= ltrW.
- by move=> hpz _ py0 hy; move/hpz:hy; rewrite rootE py0 eqxx.
-case: next_rootP => //; first by move->; rewrite eqxx.
- by move=> y np0 py0 hy _ c _ _; move/(_ _ hy); rewrite rootE py0 eqxx.
-by move=> c _ -> _ c' _ ->.
-Qed.
-
-Definition prev_root (p : {poly R}) a x :=
- if p == 0 then x else last (minr a x) (roots p a x).
-
-Lemma prev_root0 a b : prev_root 0 a b = b.
-Proof. by rewrite /prev_root eqxx. Qed.
-
-CoInductive prev_root_spec (p : {poly R}) a x : bool -> R -> Type :=
-| PrevRootSpec0 of p = 0 : prev_root_spec p a x true x
-| PrevRootSpecRoot y of p != 0 & p.[y] = 0 & y \in`]a, x[
- & {in `]y, x[, forall z, ~~(root p z)} : prev_root_spec p a x true y
-| PrevRootSpecNoRoot c of p != 0 & c = minr a x
- & {in `]a, x[, forall z, ~~(root p z)} : prev_root_spec p a x (p.[c] == 0) c.
-
-Lemma prev_rootP (p : {poly R}) a b :
- prev_root_spec p a b (p.[prev_root p a b] == 0) (prev_root p a b).
-Proof.
-rewrite /prev_root /=; move hs: (roots _ _ _)=> s.
-case: (lastP s) hs=> {s} [|s x] hs /=.
- case: (altP (p =P 0))=> p0.
- by rewrite {2}p0 hornerC eqxx; constructor; rewrite p0.
- by constructor=> // y hy; apply: (roots_nil p0 hs).
-rewrite last_rcons; move/eqP: hs.
-rewrite roots_rcons; case/and5P=> p0 hx; move/eqP=> rap rpx rx.
-rewrite (negPf p0) (rootPt rpx); constructor=> //; first by move/eqP: rpx.
-by move=> y hy /=; move/(roots_nil p0): (rap); apply.
-Qed.
-
-Lemma prev_root_in p a b : prev_root p a b \in `[minr a b, b].
-Proof.
-case: prev_rootP => [p0|y np0 py0 hy _|c np0 hc _].
-* by rewrite bound_in_itv /= ler_minl lerr orbT.
-* by apply: subitvP hy=> /=; rewrite ler_minl !lerr.
-* by rewrite hc bound_in_itv /= ler_minl lerr orbT.
-Qed.
-
-Lemma prev_noroot p a b : {in `](prev_root p a b), b[, noroot p}.
-Proof.
-move=> z; case: prev_rootP; first by rewrite itv_xx.
- by move=> y np0 py0 hy hp hz; rewrite (negPf (hp _ _)).
-move=> c np0 ->; case: minrP=> hab; last by rewrite itv_xx.
-by move=> hp hz; rewrite (negPf (hp _ _)).
-Qed.
-
-Lemma prev_root_lt p a b : a < b -> p != 0 -> prev_root p a b < b.
-Proof.
-move=> ab np0; case: prev_rootP=> [p0|y _ py0 hy _|c _ -> _].
-* by rewrite p0 eqxx in np0.
-* by rewrite (itvP hy).
-* by rewrite minr_l // ltrW.
-Qed.
-
-Lemma is_prev_root p a b x :
- prev_root_spec p a b (root p x) x -> x = prev_root p a b.
-Proof.
-case; first by move->; rewrite /prev_root eqxx.
- move=> y; case: prev_rootP; first by move->; rewrite eqxx.
- move=> y' np0 py'0 hy' hp' _ py0 hy hp.
- wlog: y y' hy' hy hp' hp py0 py'0 / y <= y'.
- by case/orP: (ler_total y y')=> lyy' hw; [|symmetry]; apply: hw.
- case: ltrgtP=> // hyy' _; move/implyP: (hp y').
- by rewrite rootE py'0 eqxx inE /= (itvP hy') hyy'.
- by move=> c _ _ hpz _ py0 hy; move/hpz:hy; rewrite rootE py0 eqxx.
-case: prev_rootP=> //; first by move->; rewrite eqxx.
- move=> y ? py0 hy _ c _ ->; case: minrP hy=> hab; last first.
- by rewrite itv_gte //= ltrW.
- by move=> hy; move/(_ _ hy); rewrite rootE py0 eqxx.
-by move=> c _ -> _ c' _ ->.
-Qed.
-
-Definition neighpr p a b := `]a, (next_root p a b)[.
-
-Definition neighpl p a b := `](prev_root p a b), b[.
-
-Lemma neighpl_root p a x : {in neighpl p a x, noroot p}.
-Proof. exact: prev_noroot. Qed.
-
-Lemma sgr_neighplN p a x :
- ~~ root p x -> {in neighpl p a x, forall y, (sgr p.[y] = sgr p.[x])}.
-Proof.
-rewrite /neighpl=> nrpx /= y hy.
-apply: (@polyrN0_itv `[y, x]); do ?by rewrite bound_in_itv /= (itvP hy).
-move=> z; rewrite (@itv_splitU _ x false) ?itv_xx /=; last first.
-(* Todo : Lemma itv_splitP *)
- by rewrite bound_in_itv /= (itvP hy).
-rewrite orbC => /predU1P[-> // | hz].
-rewrite (@prev_noroot _ a x) //.
-by apply: subitvPl hz; rewrite /= (itvP hy).
-Qed.
-
-Lemma sgr_neighpl_same p a x :
- {in neighpl p a x &, forall y z, (sgr p.[y] = sgr p.[z])}.
-Proof.
-by rewrite /neighpl=> y z *; apply: (polyrN0_itv (@prev_noroot p a x)).
-Qed.
-
-Lemma neighpr_root p x b : {in neighpr p x b, noroot p}.
-Proof. exact: next_noroot. Qed.
-
-Lemma sgr_neighprN p x b :
- p.[x] != 0 -> {in neighpr p x b, forall y, (sgr p.[y] = sgr p.[x])}.
-Proof.
-rewrite /neighpr=> nrpx /= y hy; symmetry.
-apply: (@polyrN0_itv `[x, y]); do ?by rewrite bound_in_itv /= (itvP hy).
-move=> z; rewrite (@itv_splitU _ x true) ?itv_xx /=; last first.
-(* Todo : Lemma itv_splitP *)
- by rewrite bound_in_itv /= (itvP hy).
-case/orP=> [|hz]; first by rewrite inE /=; move/eqP->.
-rewrite (@next_noroot _ x b) //.
-by apply: subitvPr hz; rewrite /= (itvP hy).
-Qed.
-
-Lemma sgr_neighpr_same p x b :
- {in neighpr p x b &, forall y z, (sgr p.[y] = sgr p.[z])}.
-Proof.
-by rewrite /neighpl=> y z *; apply: (polyrN0_itv (@next_noroot p x b)).
-Qed.
-
-Lemma uniq_roots a b p : uniq (roots p a b).
-Proof.
-case p0: (p == 0); first by rewrite (eqP p0) roots0.
-by apply: (@sorted_uniq _ <%R); [apply: ltr_trans | apply: ltrr|].
-Qed.
-
-Hint Resolve uniq_roots.
-
-Lemma in_roots p (a b x : R) :
- (x \in roots p a b) = [&& root p x, x \in `]a, b[ & p != 0].
-Proof.
-case: rootsP=> //=; first by rewrite in_nil !andbF.
-by move=> p0 hr sr; rewrite andbT -hr andbC.
-Qed.
-
-(* Todo : move to polyorder => need char 0 *)
-Lemma gdcop_eq0 p q : (gdcop p q == 0) = (q == 0) && (p != 0).
-Proof.
-case: (eqVneq q 0) => [-> | q0].
- rewrite gdcop0 /= eqxx /=.
- by case: (eqVneq p 0) => [-> | pn0]; rewrite ?(negPf pn0) eqxx ?oner_eq0.
-rewrite /gdcop; move: {-1}(size q) (leqnn (size q))=> k hk.
-case: (eqVneq p 0) => [-> | p0].
- rewrite eqxx andbF; apply: negPf.
- elim: k q q0 {hk} => [|k ihk] q q0 /=; first by rewrite eqxx oner_eq0.
- case: ifP => _ //.
- by apply: ihk; rewrite gcdp0 divpp ?q0 // polyC_eq0; apply/lc_expn_scalp_neq0.
-rewrite p0 (negPf q0) /=; apply: negPf.
-elim: k q q0 hk => [|k ihk] /= q q0 hk.
- by move: hk q0; rewrite leqn0 size_poly_eq0; move->.
-case: ifP=> cpq; first by rewrite (negPf q0).
-apply: ihk.
- rewrite divpN0; last by rewrite gcdp_eq0 negb_and q0.
- by rewrite dvdp_leq // dvdp_gcdl.
-rewrite -ltnS; apply: leq_trans hk; move: (dvdp_gcdl q p); rewrite dvdp_eq.
-move/eqP=> eqq; move/(f_equal (fun x : {poly R} => size x)): (eqq).
-rewrite size_scale; last exact: lc_expn_scalp_neq0.
-have gcdn0 : gcdp q p != 0 by rewrite gcdp_eq0 negb_and q0.
-have qqn0 : q %/ gcdp q p != 0.
- apply: contraTneq q0; rewrite negbK => e.
- move: (scaler_eq0 (lead_coef (gcdp q p) ^+ scalp q (gcdp q p)) q).
- by rewrite (negPf (lc_expn_scalp_neq0 _ _)) /=; move<-; rewrite eqq e mul0r.
-move->; rewrite size_mul //; case sgcd: (size (gcdp q p)) => [|n].
- by move/eqP: sgcd gcdn0; rewrite size_poly_eq0; move->.
-case: n sgcd => [|n]; first by move/eqP; rewrite size_poly_eq1 gcdp_eqp1 cpq.
-by rewrite addnS /= -{1}[size (_ %/ _)]addn0 ltn_add2l.
-Qed.
-
-Lemma roots_mul a b : a < b -> forall p q,
- p != 0 -> q != 0 -> perm_eq (roots (p*q) a b)
- (roots p a b ++ roots ((gdcop p q)) a b).
-Proof.
-move=> hab p q np0 nq0.
-apply: uniq_perm_eq; first exact: uniq_roots.
- rewrite cat_uniq ?uniq_roots andbT /=; apply/hasPn=> x /=.
- move/root_roots; rewrite root_gdco //; case/andP=> _.
- by rewrite in_roots !negb_and=> ->.
-move=> x; rewrite mem_cat !in_roots root_gdco //.
-rewrite rootM mulf_eq0 gdcop_eq0 negb_and.
-case: (x \in `]_, _[); last by rewrite !andbF.
-by rewrite negb_or !np0 !nq0 !andbT /=; do 2?case: root=> //=.
-Qed.
-
-Lemma roots_mul_coprime a b :
- a < b ->
- forall p q, p != 0 -> q != 0 -> coprimep p q ->
- perm_eq (roots (p * q) a b)
- (roots p a b ++ roots q a b).
-Proof.
-move=> hab p q np0 nq0 cpq.
-rewrite (perm_eq_trans (roots_mul hab np0 nq0)) //.
-suff ->: roots (gdcop p q) a b = roots q a b by apply: perm_eq_refl.
-case: gdcopP=> r rq hrp; move/(_ q (dvdpp _)).
-rewrite coprimep_sym; move/(_ cpq)=> qr.
-have erq : r %= q by rewrite /eqp rq qr.
-(* Todo : relate eqp with roots *)
-apply/roots_eq=> // [|x hx]; last exact: eqp_root.
-by rewrite -size_poly_eq0 (eqp_size erq) size_poly_eq0.
-Qed.
-
-
-Lemma next_rootM a b (p q : {poly R}) :
- next_root (p * q) a b = minr (next_root p a b) (next_root q a b).
-Proof.
-symmetry; apply: is_next_root.
-wlog: p q / next_root p a b <= next_root q a b.
- case: minrP=> hpq; first by move/(_ _ _ hpq); case: minrP hpq.
- by move/(_ _ _ (ltrW hpq)); rewrite mulrC minrC; case: minrP hpq.
-case: minrP=> //; case: next_rootP=> [|y np0 py0 hy|c np0 ->] hp hpq _.
-* by rewrite hp mul0r root0; constructor.
-* rewrite rootM; move/rootP:(py0)->; constructor=> //.
- - by rewrite mulf_neq0 //; case: next_rootP hpq; rewrite // (itvP hy).
- - by rewrite hornerM py0 mul0r.
- - move=> z hz /=; rewrite rootM negb_or ?hp //.
- by rewrite (@next_noroot _ a b) //; apply: subitvPr hz.
-* case: (altP (q =P 0))=> q0.
- move: hpq; rewrite q0 mulr0 root0 next_root0 ler_maxl lerr andbT.
- by move=> hba; rewrite maxr_r //; constructor.
- constructor=> //; first by rewrite mulf_neq0.
- move=> z hz /=; rewrite rootM negb_or ?hp //.
- rewrite (@next_noroot _ a b) //; apply: subitvPr hz=> /=.
- by move: hpq; rewrite ler_maxl; case/andP.
-Qed.
-
-Lemma neighpr_mul a b p q :
- (neighpr (p * q) a b) =i [predI (neighpr p a b) & (neighpr q a b)].
-Proof.
-move=> x; rewrite inE /= !inE /= next_rootM.
-by case: (a < x); rewrite // ltr_minr.
-Qed.
-
-Lemma prev_rootM a b (p q : {poly R}) :
- prev_root (p * q) a b = maxr (prev_root p a b) (prev_root q a b).
-Proof.
-symmetry; apply: is_prev_root.
-wlog: p q / prev_root p a b >= prev_root q a b.
- case: maxrP=> hpq; first by move/(_ _ _ hpq); case: maxrP hpq.
- by move/(_ _ _ (ltrW hpq)); rewrite mulrC maxrC; case: maxrP hpq.
-case: maxrP=> //; case: (@prev_rootP p)=> [|y np0 py0 hy|c np0 ->] hp hpq _.
-* by rewrite hp mul0r root0; constructor.
-* rewrite rootM; move/rootP:(py0)->; constructor=> //.
- - by rewrite mulf_neq0 //; case: prev_rootP hpq; rewrite // (itvP hy).
- - by rewrite hornerM py0 mul0r.
- - move=> z hz /=; rewrite rootM negb_or ?hp //.
- by rewrite (@prev_noroot _ a b) //; apply: subitvPl hz.
-* case: (altP (q =P 0))=> q0.
- move: hpq; rewrite q0 mulr0 root0 prev_root0 ler_minr lerr andbT.
- by move=> hba; rewrite minr_r //; constructor.
- constructor=> //; first by rewrite mulf_neq0.
- move=> z hz /=; rewrite rootM negb_or ?hp //.
- rewrite (@prev_noroot _ a b) //; apply: subitvPl hz=> /=.
- by move: hpq; rewrite ler_minr; case/andP.
-Qed.
-
-Lemma neighpl_mul a b p q :
- (neighpl (p * q) a b) =i [predI (neighpl p a b) & (neighpl q a b)].
-Proof.
-move=> x; rewrite !inE /= prev_rootM.
-by case: (x < b); rewrite // ltr_maxl !(andbT, andbF).
-Qed.
-
-Lemma neighpr_wit p x b : x < b -> p != 0 -> {y | y \in neighpr p x b}.
-Proof.
-move=> xb; exists (mid x (next_root p x b)).
-by rewrite mid_in_itv //= next_root_gt.
-Qed.
-
-Lemma neighpl_wit p a x : a < x -> p != 0 -> {y | y \in neighpl p a x}.
-Proof.
-move=> xb; exists (mid (prev_root p a x) x).
-by rewrite mid_in_itv //= prev_root_lt.
-Qed.
-
-End NeighborHood.
-
-Section SignRight.
-
-Definition sgp_right (p : {poly R}) x :=
- let fix aux (p : {poly R}) n :=
- if n is n'.+1
- then if ~~ root p x
- then sgr p.[x]
- else aux p^`() n'
- else 0
- in aux p (size p).
-
-Lemma sgp_right0 x : sgp_right 0 x = 0.
-Proof. by rewrite /sgp_right size_poly0. Qed.
-
-Lemma sgr_neighpr b p x :
- {in neighpr p x b, forall y, (sgr p.[y] = sgp_right p x)}.
-Proof.
-elim: (size p) {-2}p (leqnn (size p))=> [|n ihn] {p} p.
- rewrite leqn0 size_poly_eq0 /neighpr; move/eqP=> -> /=.
- by move=> y; rewrite next_root0 itv_xx.
-rewrite leq_eqVlt ltnS; case/orP; last exact: ihn.
-move/eqP=> sp; rewrite /sgp_right sp /=.
-case px0: root=> /=; last first.
- move=> y; rewrite /neighpr => hy /=; symmetry.
- apply: (@polyrN0_itv `[x, y]); do ?by rewrite bound_in_itv /= (itvP hy).
- move=> z; rewrite (@itv_splitU _ x true) ?bound_in_itv /= ?(itvP hy) //.
- rewrite itv_xx /=; case/predU1P=> hz; first by rewrite hz px0.
- rewrite (@next_noroot p x b) //.
- by apply: subitvPr hz=> /=; rewrite (itvP hy).
-have <-: size p^`() = n by rewrite size_deriv sp.
-rewrite -/(sgp_right p^`() x).
-move=> y; rewrite /neighpr=> hy /=.
-case: (@neighpr_wit (p * p^`()) x b)=> [||m hm].
-* case: next_rootP hy; first by rewrite itv_xx.
- by move=> ? ? ?; move/itvP->.
- by move=> c p0 -> _; case: maxrP=> _; rewrite ?itv_xx //; move/itvP->.
-* rewrite mulf_neq0 //.
- by move/eqP:sp; apply: contraTneq=> ->; rewrite size_poly0.
- (* Todo : a lemma for this *)
- move: (size_deriv p); rewrite sp /=; move/eqP; apply: contraTneq=> ->.
- rewrite size_poly0; apply: contraTneq px0=> hn; rewrite -hn in sp.
- by move/eqP: sp; case/size_poly1P=> c nc0 ->; rewrite rootC.
-* move: hm; rewrite neighpr_mul /neighpr inE /=; case/andP=> hmp hmp'.
- rewrite (polyrN0_itv _ hmp) //; last exact: next_noroot.
- rewrite (@ders0r p x m (mid x m)) ?(eqP px0) ?mid_in_itv ?bound_in_itv //;
- rewrite /= ?(itvP hmp) //; last first.
- move=> u hu /=; rewrite (@next_noroot _ x b) //.
- by apply: subitvPr hu; rewrite /= (itvP hmp').
- rewrite ihn ?size_deriv ?sp /neighpr //.
- by rewrite (subitvP _ (@mid_in_itv _ true true _ _ _)) //= ?lerr (itvP hmp').
-Qed.
-
-Lemma sgr_neighpl a p x :
- {in neighpl p a x, forall y,
- (sgr p.[y] = (-1) ^+ (odd (\mu_x p)) * sgp_right p x)
- }.
-Proof.
-elim: (size p) {-2}p (leqnn (size p))=> [|n ihn] {p} p.
- rewrite leqn0 size_poly_eq0 /neighpl; move/eqP=> -> /=.
- by move=> y; rewrite prev_root0 itv_xx.
-rewrite leq_eqVlt ltnS; case/orP; last exact: ihn.
-move/eqP=> sp; rewrite /sgp_right sp /=.
-case px0: root=> /=; last first.
- move=> y; rewrite /neighpl => hy /=; symmetry.
- move: (negbT px0); rewrite -mu_gt0; last first.
- by apply: contraFN px0; move/eqP->; rewrite rootC.
- rewrite -leqNgt leqn0; move/eqP=> -> /=; rewrite expr0 mul1r.
- symmetry; apply: (@polyrN0_itv `[y, x]);
- do ?by rewrite bound_in_itv /= (itvP hy).
- move=> z; rewrite (@itv_splitU _ x false) ?bound_in_itv /= ?(itvP hy) //.
- rewrite itv_xx /= orbC; case/predU1P=> hz; first by rewrite hz px0.
- rewrite (@prev_noroot p a x) //.
- by apply: subitvPl hz=> /=; rewrite (itvP hy).
-have <-: size p^`() = n by rewrite size_deriv sp.
-rewrite -/(sgp_right p^`() x).
-move=> y; rewrite /neighpl=> hy /=.
-case: (@neighpl_wit (p * p^`()) a x)=> [||m hm].
-* case: prev_rootP hy; first by rewrite itv_xx.
- by move=> ? ? ?; move/itvP->.
- by move=> c p0 -> _; case: minrP=> _; rewrite ?itv_xx //; move/itvP->.
-* rewrite mulf_neq0 //.
- by move/eqP:sp; apply: contraTneq=> ->; rewrite size_poly0.
- (* Todo : a lemma for this *)
- move: (size_deriv p); rewrite sp /=; move/eqP; apply: contraTneq=> ->.
- rewrite size_poly0; apply: contraTneq px0=> hn; rewrite -hn in sp.
- by move/eqP: sp; case/size_poly1P=> c nc0 ->; rewrite rootC.
-* move: hm; rewrite neighpl_mul /neighpl inE /=; case/andP=> hmp hmp'.
- rewrite (polyrN0_itv _ hmp) //; last exact: prev_noroot.
- rewrite (@ders0l p m x (mid m x)) ?(eqP px0) ?mid_in_itv ?bound_in_itv //;
- rewrite /= ?(itvP hmp) //; last first.
- move=> u hu /=; rewrite (@prev_noroot _ a x) //.
- by apply: subitvPl hu; rewrite /= (itvP hmp').
- rewrite ihn ?size_deriv ?sp /neighpl //; last first.
- by rewrite (subitvP _ (@mid_in_itv _ true true _ _ _)) //=
- ?lerr (itvP hmp').
- rewrite mu_deriv // odd_sub ?mu_gt0 //=; last by rewrite -size_poly_eq0 sp.
- by rewrite signr_addb /= mulrN1 mulNr opprK.
-Qed.
-
-Lemma sgp_right_deriv (p : {poly R}) x :
- root p x -> sgp_right p x = sgp_right (p^`()) x.
-Proof.
-elim: (size p) {-2}p (erefl (size p)) x => {p} [p|sp hp p hsp x].
- by move/eqP; rewrite size_poly_eq0; move/eqP=> -> x _; rewrite derivC.
-by rewrite /sgp_right size_deriv hsp /= => ->.
-Qed.
-
-Lemma sgp_rightNroot (p : {poly R}) x :
- ~~ root p x -> sgp_right p x = sgr p.[x].
-Proof.
-move=> nrpx; rewrite /sgp_right; case hsp: (size _)=> [|sp].
- by move/eqP:hsp; rewrite size_poly_eq0; move/eqP->; rewrite hornerC sgr0.
-by rewrite nrpx.
-Qed.
-
-Lemma sgp_right_mul p q x : sgp_right (p * q) x = sgp_right p x * sgp_right q x.
-Proof.
-case: (altP (q =P 0))=> q0; first by rewrite q0 /sgp_right !(size_poly0,mulr0).
-case: (altP (p =P 0))=> p0; first by rewrite p0 /sgp_right !(size_poly0,mul0r).
-case: (@neighpr_wit (p * q) x (1 + x))=> [||m hpq]; do ?by rewrite mulf_neq0.
- by rewrite ltr_spaddl ?ltr01.
-rewrite -(@sgr_neighpr (1 + x) _ _ m) //.
-move: hpq; rewrite neighpr_mul inE /=; case/andP=> hp hq.
-by rewrite hornerM sgrM !(@sgr_neighpr (1 + x) _ x) /neighpr.
-Qed.
-
-Lemma sgp_right_scale c p x : sgp_right (c *: p) x = sgr c * sgp_right p x.
-Proof.
-case c0: (c == 0); first by rewrite (eqP c0) scale0r sgr0 mul0r sgp_right0.
-by rewrite -mul_polyC sgp_right_mul sgp_rightNroot ?hornerC ?rootC ?c0.
-Qed.
-
-Lemma sgp_right_square p x : p != 0 -> sgp_right p x * sgp_right p x = 1.
-Proof.
-move=> np0; case: (@neighpr_wit p x (1 + x))=> [||m hpq] //.
- by rewrite ltr_spaddl ?ltr01.
-rewrite -(@sgr_neighpr (1 + x) _ _ m) //.
-by rewrite -expr2 sqr_sg (@next_noroot _ x (1 + x)).
-Qed.
-
-Lemma sgp_right_rec p x :
- sgp_right p x =
- (if p == 0 then 0 else if ~~ root p x then sgr p.[x] else sgp_right p^`() x).
-Proof.
-rewrite /sgp_right; case hs: size => [|s]; rewrite -size_poly_eq0 hs //=.
-by rewrite size_deriv hs.
-Qed.
-
-Lemma sgp_right_addp0 (p q : {poly R}) x :
- q != 0 -> (\mu_x p > \mu_x q)%N -> sgp_right (p + q) x = sgp_right q x.
-Proof.
-move=> nq0; move hm: (\mu_x q)=> m.
-elim: m p q nq0 hm => [|mq ihmq] p q nq0 hmq; case hmp: (\mu_x p)=> // [mp];
- do[
- rewrite ltnS=> hm;
- rewrite sgp_right_rec {1}addrC;
- rewrite GRing.Theory.addr_eq0]. (* Todo : fix this ! *)
- case: (altP (_ =P _))=> hqp.
- move: (nq0); rewrite {1}hqp oppr_eq0=> np0.
- rewrite sgp_right_rec (negPf nq0) -mu_gt0 // hmq /=.
- apply/eqP; rewrite eq_sym hqp hornerN sgrN.
- by rewrite oppr_eq0 sgr_eq0 -[_ == _]mu_gt0 ?hmp.
- rewrite rootE hornerD.
- have ->: p.[x] = 0.
- apply/eqP; rewrite -[_ == _]mu_gt0 ?hmp //.
- by move/eqP: hmp; apply: contraTneq=> ->; rewrite mu0.
- symmetry; rewrite sgp_right_rec (negPf nq0) add0r.
- by rewrite -/(root _ _) -mu_gt0 // hmq.
-case: (altP (_ =P _))=> hqp.
- by move: hm; rewrite -ltnS -hmq -hmp hqp mu_opp ltnn.
-have px0: p.[x] = 0.
- apply/rootP; rewrite -mu_gt0 ?hmp //.
- by move/eqP: hmp; apply: contraTneq=> ->; rewrite mu0.
-have qx0: q.[x] = 0 by apply/rootP; rewrite -mu_gt0 ?hmq //.
-rewrite rootE hornerD px0 qx0 add0r eqxx /=; symmetry.
-rewrite sgp_right_rec rootE (negPf nq0) qx0 eqxx /=.
-rewrite derivD ihmq // ?mu_deriv ?rootE ?px0 ?qx0 ?hmp ?hmq ?subn1 //.
-apply: contra nq0; rewrite -size_poly_eq0 size_deriv.
-case hsq: size=> [|sq] /=.
- by move/eqP: hsq; rewrite size_poly_eq0.
-move/eqP=> sq0; move/eqP: hsq qx0; rewrite sq0; case/size_poly1P=> c c0 ->.
-by rewrite hornerC; move/eqP; rewrite (negPf c0).
-Qed.
-
-End SignRight.
-
-(* redistribute some of what follows with in the file *)
-Section PolyRCFPdiv.
-Import Pdiv.Ring Pdiv.ComRing.
-
-Lemma sgp_rightc (x c : R) : sgp_right c%:P x = sgr c.
-Proof.
-rewrite /sgp_right size_polyC.
-case cn0: (_ == 0)=> /=; first by rewrite (eqP cn0) sgr0.
-by rewrite rootC hornerC cn0.
-Qed.
-
-Lemma sgp_right_eq0 (x : R) p : (sgp_right p x == 0) = (p == 0).
-Proof.
-case: (altP (p =P 0))=> p0; first by rewrite p0 sgp_rightc sgr0 eqxx.
-rewrite /sgp_right.
-elim: (size p) {-2}p (erefl (size p)) p0=> {p} [|sp ihsp] p esp p0.
- by move/eqP:esp; rewrite size_poly_eq0 (negPf p0).
-rewrite esp /=; case px0: root=> //=; rewrite ?sgr_cp0 ?px0//.
-have hsp: sp = size p^`() by rewrite size_deriv esp.
-rewrite hsp ihsp // -size_poly_eq0 -hsp; apply/negP; move/eqP=> sp0.
-move: px0; rewrite root_factor_theorem.
-by move=> /rdvdp_leq // /(_ p0); rewrite size_XsubC esp sp0.
-Qed.
-
-(* :TODO: backport to polydiv *)
-Lemma lc_expn_rscalp_neq0 (p q : {poly R}): lead_coef q ^+ rscalp p q != 0.
-Proof.
-case: (eqVneq q 0) => [->|nzq]; last by rewrite expf_neq0 ?lead_coef_eq0.
-by rewrite /rscalp unlock /= eqxx /= expr0 oner_neq0.
-Qed.
-Notation lcn_neq0 := lc_expn_rscalp_neq0.
-
-Lemma sgp_right_mod p q x : (\mu_x p < \mu_x q)%N ->
- sgp_right (rmodp p q) x = (sgr (lead_coef q)) ^+ (rscalp p q) * sgp_right p x.
-Proof.
-move=> mupq; case p0: (p == 0).
- by rewrite (eqP p0) rmod0p !sgp_right0 mulr0.
-have qn0 : q != 0.
- by apply/negP; move/eqP=> q0; rewrite q0 mu0 ltn0 in mupq.
-move/eqP: (rdivp_eq q p).
-rewrite eq_sym (can2_eq (addKr _ ) (addNKr _)); move/eqP->.
-case qpq0: ((rdivp p q) == 0).
- by rewrite (eqP qpq0) mul0r oppr0 add0r sgp_right_scale // sgrX.
-rewrite sgp_right_addp0 ?sgp_right_scale ?sgrX //.
- by rewrite scaler_eq0 negb_or p0 lcn_neq0.
-rewrite mu_mulC ?lcn_neq0 // mu_opp mu_mul ?mulf_neq0 ?qpq0 //.
-by rewrite ltn_addl.
-Qed.
-
-Lemma rootsC (a b c : R) : roots c%:P a b = [::].
-Proof.
-case: (altP (c =P 0))=> hc; first by rewrite hc roots0.
-by apply: no_root_roots=> x hx; rewrite rootC.
-Qed.
-
-Lemma rootsZ a b c p : c != 0 -> roots (c *: p) a b = roots p a b.
-Proof.
-have [->|p_neq0 c_neq0] := eqVneq p 0; first by rewrite scaler0.
-by apply/roots_eq => [||x axb]; rewrite ?scaler_eq0 ?(negPf c_neq0) ?rootZ.
-Qed.
-
-Lemma root_bigrgcd (x : R) (ps : seq {poly R}) :
- root (\big[(@rgcdp _)/0]_(p <- ps) p) x = all (root^~ x) ps.
-Proof.
-elim: ps; first by rewrite big_nil root0.
-move=> p ps ihp; rewrite big_cons /=.
-by rewrite (eqp_root (eqp_rgcd_gcd _ _)) root_gcd ihp.
-Qed.
-
-Definition rootsR p := roots p (- cauchy_bound p) (cauchy_bound p).
-
-Lemma roots_on_rootsR p : p != 0 -> roots_on p `]-oo, +oo[ (rootsR p).
-Proof.
-rewrite /rootsR => p_neq0 x /=; rewrite -roots_on_roots // andbC.
-by have [/(cauchy_boundP p_neq0) /=|//] := altP rootP; rewrite ltr_norml.
-Qed.
-
-Lemma rootsR0 : rootsR 0 = [::]. Proof. exact: roots0. Qed.
-
-Lemma rootsRC c : rootsR c%:P = [::]. Proof. exact: rootsC. Qed.
-
-Lemma rootsRP p a b :
- {in `]-oo, a], noroot p} -> {in `[b , +oo[, noroot p} ->
- roots p a b = rootsR p.
-Proof.
-move=> rpa rpb.
-have [->|p_neq0] := eqVneq p 0; first by rewrite rootsR0 roots0.
-apply: (eq_sorted_irr (@ltr_trans _)); rewrite ?sorted_roots // => x.
-rewrite -roots_on_rootsR -?roots_on_roots //=.
-have [rpx|] := boolP (root _ _); rewrite ?(andbT, andbF) //.
-apply: contraLR rpx; rewrite inE negb_and -!lerNgt.
-by move=> /orP[/rpa //|xb]; rewrite rpb // inE andbT.
-Qed.
-
-Lemma sgp_pinftyP x (p : {poly R}) :
- {in `[x , +oo[, noroot p} ->
- {in `[x, +oo[, forall y, sgr p.[y] = sgp_pinfty p}.
-Proof.
-rewrite /sgp_pinfty; wlog lp_gt0 : x p / lead_coef p > 0 => [hwlog|rpx y Hy].
- have [|/(hwlog x p) //|/eqP] := ltrgtP (lead_coef p) 0; last first.
- by rewrite lead_coef_eq0 => /eqP -> ? ? ?; rewrite lead_coef0 horner0.
- rewrite -[p]opprK lead_coef_opp oppr_cp0 => /(hwlog x _) Hp HNp y Hy.
- by rewrite hornerN !sgrN Hp => // z /HNp; rewrite rootN.
-have [z Hz] := poly_pinfty_gt_lc lp_gt0.
-have {Hz} Hz u : u \in `[z, +oo[ -> Num.sg p.[u] = 1.
- by rewrite inE andbT => /Hz pu_ge1; rewrite gtr0_sg // (ltr_le_trans lp_gt0).
-rewrite (@polyrN0_itv _ _ rpx (maxr y z)) ?inE ?ler_maxr ?(itvP Hy) //.
-by rewrite Hz ?gtr0_sg // inE ler_maxr lerr orbT.
-Qed.
-
-Lemma sgp_minftyP x (p : {poly R}) :
- {in `]-oo, x], noroot p} ->
- {in `]-oo, x], forall y, sgr p.[y] = sgp_minfty p}.
-Proof.
-move=> rpx y Hy; rewrite -sgp_pinfty_sym.
-have -> : p.[y] = (p \Po -'X).[-y] by rewrite horner_comp !hornerE opprK.
-apply: (@sgp_pinftyP (- x)); last by rewrite inE ler_opp2 (itvP Hy).
-by move=> z Hz /=; rewrite root_comp !hornerE rpx // inE ler_oppl (itvP Hz).
-Qed.
-
-Lemma odd_poly_root (p : {poly R}) : ~~ odd (size p) -> {x | root p x}.
-Proof.
-move=> size_p_even.
-have [->|p_neq0] := altP (p =P 0); first by exists 0; rewrite root0.
-pose b := cauchy_bound p.
-have [] := @ivt_sign p (-b) b; last by move=> x _; exists x.
- by rewrite ge0_cp // ?cauchy_bound_ge0.
-rewrite (sgp_minftyP (le_cauchy_bound p_neq0)) ?bound_in_itv //.
-rewrite (sgp_pinftyP (ge_cauchy_bound p_neq0)) ?bound_in_itv //.
-move: size_p_even; rewrite polySpred //= negbK /sgp_minfty -signr_odd => ->.
-by rewrite expr1 mulN1r sgrN mulNr -expr2 sqr_sg lead_coef_eq0 p_neq0.
-Qed.
-End PolyRCFPdiv.
-
-End PolyRCF.
diff --git a/mathcomp/real_closed/qe_rcf.v b/mathcomp/real_closed/qe_rcf.v
deleted file mode 100644
index 743ca81..0000000
--- a/mathcomp/real_closed/qe_rcf.v
+++ /dev/null
@@ -1,1017 +0,0 @@
-(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-(* Distributed under the terms of CeCILL-B. *)
-Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp
-Require Import ssrfun ssrbool eqtype ssrnat seq choice fintype.
-From mathcomp
-Require Import finfun path matrix.
-From mathcomp
-Require Import bigop ssralg poly polydiv ssrnum zmodp div ssrint.
-From mathcomp
-Require Import polyorder polyrcf interval polyXY.
-From mathcomp
-Require Import qe_rcf_th ordered_qelim mxtens.
-
-Set Implicit Arguments.
-Unset Strict Implicit.
-Unset Printing Implicit Defensive.
-
-Import GRing.Theory Num.Theory.
-
-Local Open Scope nat_scope.
-Local Open Scope ring_scope.
-
-Definition grab (X Y : Type) (pattern : Y -> Prop) (P : Prop -> Prop)
- (y : X) (f : X -> Y) :
- (let F := f in P (forall x, y = x -> pattern (F x)))
- -> P (forall x : X, y = x -> pattern (f x)) := id.
-
-Definition grab_eq X Y u := @grab X Y (fun v => u = v :> Y).
-
-Tactic Notation "grab_eq" ident(f) open_constr(PAT1) :=
- let Edef := fresh "Edef" in
- let E := fresh "E" in
- move Edef: PAT1 => E;
- move: E Edef;
- elim/grab_eq: _ => f _ <-.
-
-Import ord.
-
-Section QF.
-
-Variable R : Type.
-
-Inductive term : Type :=
-| Var of nat
-| Const of R
-| NatConst of nat
-| Add of term & term
-| Opp of term
-| NatMul of term & nat
-| Mul of term & term
-| Exp of term & nat.
-
-Inductive formula : Type :=
-| Bool of bool
-| Equal of term & term
-| Lt of term & term
-| Le of term & term
-| And of formula & formula
-| Or of formula & formula
-| Implies of formula & formula
-| Not of formula.
-
-Coercion rterm_to_term := fix loop (t : term) : GRing.term R :=
- match t with
- | Var x => GRing.Var _ x
- | Const x => GRing.Const x
- | NatConst n => GRing.NatConst _ n
- | Add u v => GRing.Add (loop u) (loop v)
- | Opp u => GRing.Opp (loop u)
- | NatMul u n => GRing.NatMul (loop u) n
- | Mul u v => GRing.Mul (loop u) (loop v)
- | Exp u n => GRing.Exp (loop u) n
- end.
-
-Coercion qfr_to_formula := fix loop (f : formula) : ord.formula R :=
- match f with
- | Bool b => ord.Bool b
- | Equal x y => ord.Equal x y
- | Lt x y => ord.Lt x y
- | Le x y => ord.Le x y
- | And f g => ord.And (loop f) (loop g)
- | Or f g => ord.Or (loop f) (loop g)
- | Implies f g => ord.Implies (loop f) (loop g)
- | Not f => ord.Not (loop f)
- end.
-
-Definition to_rterm := fix loop (t : GRing.term R) : term :=
- match t with
- | GRing.Var x => Var x
- | GRing.Const x => Const x
- | GRing.NatConst n => NatConst n
- | GRing.Add u v => Add (loop u) (loop v)
- | GRing.Opp u => Opp (loop u)
- | GRing.NatMul u n => NatMul (loop u) n
- | GRing.Mul u v => Mul (loop u) (loop v)
- | GRing.Exp u n => Exp (loop u) n
- | _ => NatConst 0
- end.
-
-End QF.
-
-Bind Scope qf_scope with term.
-Bind Scope qf_scope with formula.
-Delimit Scope qf_scope with qfT.
-Arguments Add _ _%qfT _%qfT.
-Arguments Opp _ _%qfT.
-Arguments NatMul _ _%qfT _%N.
-Arguments Mul _ _%qfT _%qfT.
-Arguments Mul _ _%qfT _%qfT.
-Arguments Exp _ _%qfT _%N.
-Arguments Equal _ _%qfT _%qfT.
-Arguments And _ _%qfT _%qfT.
-Arguments Or _ _%qfT _%qfT.
-Arguments Implies _ _%qfT _%qfT.
-Arguments Not _ _%qfT.
-
-Arguments Bool [R].
-Prenex Implicits Const Add Opp NatMul Mul Exp Bool Unit And Or Implies Not Lt.
-Prenex Implicits to_rterm.
-
-Notation True := (Bool true).
-Notation False := (Bool false).
-
-Notation "''X_' i" := (Var _ i) : qf_scope.
-Notation "n %:R" := (NatConst _ n) : qf_scope.
-Notation "x %:T" := (Const x) : qf_scope.
-Notation "0" := 0%:R%qfT : qf_scope.
-Notation "1" := 1%:R%qfT : qf_scope.
-Infix "+" := Add : qf_scope.
-Notation "- t" := (Opp t) : qf_scope.
-Notation "t - u" := (Add t (- u)) : qf_scope.
-Infix "*" := Mul : qf_scope.
-Infix "*+" := NatMul : qf_scope.
-Infix "^+" := Exp : qf_scope.
-Notation "t ^- n" := (t^-1 ^+ n)%qfT : qf_scope.
-Infix "==" := Equal : qf_scope.
-Infix "<%" := Lt : qf_scope.
-Infix "<=%" := Le : qf_scope.
-Infix "/\" := And : qf_scope.
-Infix "\/" := Or : qf_scope.
-Infix "==>" := Implies : qf_scope.
-Notation "~ f" := (Not f) : qf_scope.
-Notation "x != y" := (Not (x == y)) : qf_scope.
-
-Section evaluation.
-
-Variable R : realDomainType.
-
-Fixpoint eval (e : seq R) (t : term R) {struct t} : R :=
- match t with
- | ('X_i)%qfT => e`_i
- | (x%:T)%qfT => x
- | (n%:R)%qfT => n%:R
- | (t1 + t2)%qfT => eval e t1 + eval e t2
- | (- t1)%qfT => - eval e t1
- | (t1 *+ n)%qfT => eval e t1 *+ n
- | (t1 * t2)%qfT => eval e t1 * eval e t2
- | (t1 ^+ n)%qfT => eval e t1 ^+ n
- end.
-
-Lemma evalE (e : seq R) (t : term R) : eval e t = GRing.eval e t.
-Proof. by elim: t=> /=; do ?[move->|move=> ?]. Qed.
-
-Definition qf_eval e := fix loop (f : formula R) : bool :=
- match f with
- | Bool b => b
- | t1 == t2 => (eval e t1 == eval e t2)%bool
- | t1 <% t2 => (eval e t1 < eval e t2)%bool
- | t1 <=% t2 => (eval e t1 <= eval e t2)%bool
- | f1 /\ f2 => loop f1 && loop f2
- | f1 \/ f2 => loop f1 || loop f2
- | f1 ==> f2 => (loop f1 ==> loop f2)%bool
- | ~ f1 => ~~ loop f1
- end%qfT.
-
-Lemma qf_evalE (e : seq R) (f : formula R) : qf_eval e f = ord.qf_eval e f.
-Proof. by elim: f=> /=; do ?[rewrite evalE|move->|move=> ?]. Qed.
-
-Lemma to_rtermE (t : GRing.term R) :
- GRing.rterm t -> to_rterm t = t :> GRing.term _.
-Proof.
-elim: t=> //=; do ?
- [ by move=> u hu v hv /andP[ru rv]; rewrite hu ?hv
- | by move=> u hu *; rewrite hu].
-Qed.
-
-End evaluation.
-
-Import Pdiv.Ring.
-
-Definition bind_def T1 T2 T3 (f : (T1 -> T2) -> T3) (k : T1 -> T2) := f k.
-Notation "'bind' x <- y ; z" :=
- (bind_def y (fun x => z)) (at level 99, x at level 0, y at level 0,
- format "'[hv' 'bind' x <- y ; '/' z ']'").
-
-Section ProjDef.
-
-Variable F : realFieldType.
-
-Notation fF := (formula F).
-Notation tF := (term F).
-Definition polyF := seq tF.
-
-Lemma qf_formF (f : fF) : qf_form f.
-Proof. by elim: f=> // *; apply/andP; split. Qed.
-
-Lemma rtermF (t : tF) : GRing.rterm t.
-Proof. by elim: t=> //=; do ?[move->|move=> ?]. Qed.
-
-Lemma rformulaF (f : fF) : rformula f.
-Proof. by elim: f=> /=; do ?[rewrite rtermF|move->|move=> ?]. Qed.
-
-Section If.
-
-Implicit Types (pf tf ef : formula F).
-
-Definition If pf tf ef := (pf /\ tf \/ ~ pf /\ ef)%qfT.
-
-End If.
-
-Notation "'If' c1 'Then' c2 'Else' c3" := (If c1 c2 c3)
- (at level 200, right associativity, format
-"'[hv ' 'If' c1 '/' '[' 'Then' c2 ']' '/' '[' 'Else' c3 ']' ']'").
-
-Notation cps T := ((T -> fF) -> fF).
-
-Section Pick.
-
-Variables (I : finType) (pred_f then_f : I -> fF) (else_f : fF).
-
-Definition Pick :=
- \big[Or/False]_(p : {ffun pred I})
- ((\big[And/True]_i (if p i then pred_f i else ~ pred_f i))
- /\ (if pick p is Some i then then_f i else else_f))%qfT.
-
-Lemma eval_Pick e (qev := qf_eval e) :
- let P i := qev (pred_f i) in
- qev Pick = (if pick P is Some i then qev (then_f i) else qev else_f).
-Proof.
-move=> P; rewrite ((big_morph qev) false orb) //= big_orE /=.
-apply/existsP/idP=> [[p] | true_at_P].
- rewrite ((big_morph qev) true andb) //= big_andE /=.
- case/andP=> /forallP eq_p_P.
- rewrite (@eq_pick _ _ P) => [|i]; first by case: pick.
- by move/(_ i): eq_p_P => /=; case: (p i) => //=; move/negbTE.
-exists [ffun i => P i] => /=; apply/andP; split.
- rewrite ((big_morph qev) true andb) //= big_andE /=.
- by apply/forallP=> i; rewrite /= ffunE; case Pi: (P i) => //=; apply: negbT.
-rewrite (@eq_pick _ _ P) => [|i]; first by case: pick true_at_P.
-by rewrite ffunE.
-Qed.
-
-End Pick.
-
-Fixpoint eval_poly (e : seq F) pf :=
- if pf is c :: qf then (eval_poly e qf) * 'X + (eval e c)%:P else 0.
-
-Lemma eval_polyP e p : eval_poly e p = Poly (map (eval e) p).
-Proof. by elim: p=> // a p /= ->; rewrite cons_poly_def. Qed.
-
-Fixpoint Size (p : polyF) : cps nat := fun k =>
- if p is c :: q then
- bind n <- Size q;
- if n is m.+1 then k m.+2
- else If c == 0 Then k 0%N Else k 1%N
- else k 0%N.
-
-Definition Isnull (p : polyF) : cps bool := fun k =>
- bind n <- Size p; k (n == 0%N).
-
-Definition LtSize (p q : polyF) : cps bool := fun k =>
- bind n <- Size p; bind m <- Size q; k (n < m)%N.
-
-Fixpoint LeadCoef p : cps tF := fun k =>
- if p is c :: q then
- bind l <- LeadCoef q; If l == 0 Then k c Else k l
- else k (Const 0).
-
-Fixpoint AmulXn (a : tF) (n : nat) : polyF:=
- if n is n'.+1 then (Const 0) :: (AmulXn a n') else [::a].
-
-Fixpoint AddPoly (p q : polyF) :=
- if p is a::p' then
- if q is b::q' then (a + b)%qfT :: (AddPoly p' q')
- else p
- else q.
-Local Infix "++" := AddPoly : qf_scope.
-
-Definition ScalPoly (c : tF) (p : polyF) : polyF := map (Mul c) p.
-Local Infix "*:" := ScalPoly : qf_scope.
-
-Fixpoint MulPoly (p q : polyF) := if p is a :: p'
- then (a *: q ++ (0 :: (MulPoly p' q)))%qfT else [::].
-Local Infix "**" := MulPoly (at level 40) : qf_scope.
-
-Lemma map_poly0 (R R' : ringType) (f : R -> R') : map_poly f 0 = 0.
-Proof. by rewrite map_polyE polyseq0. Qed.
-
-Definition ExpPoly p n := iterop n MulPoly p [::1%qfT].
-Local Infix "^^+" := ExpPoly (at level 29) : qf_scope.
-
-Definition OppPoly := ScalPoly (@Const F (-1)).
-Local Notation "-- p" := (OppPoly p) (at level 35) : qf_scope.
-Local Notation "p -- q" := (p ++ (-- q))%qfT (at level 50) : qf_scope.
-
-Definition NatMulPoly n := ScalPoly (NatConst F n).
-Local Infix "+**" := NatMulPoly (at level 40) : qf_scope.
-
-Fixpoint Horner (p : polyF) (x : tF) : tF :=
- if p is a :: p then (Horner p x * x + a)%qfT else 0%qfT.
-
-Fixpoint Deriv (p : polyF) : polyF :=
- if p is a :: q then (q ++ (0 :: Deriv q))%qfT else [::].
-
-Fixpoint Rediv_rec_loop (q : polyF) sq cq
- (c : nat) (qq r : polyF) (n : nat) {struct n} :
- cps (nat * polyF * polyF) := fun k =>
- bind sr <- Size r;
- if (sr < sq)%N then k (c, qq, r) else
- bind lr <- LeadCoef r;
- let m := AmulXn lr (sr - sq) in
- let qq1 := (qq ** [::cq] ++ m)%qfT in
- let r1 := (r ** [::cq] -- m ** q)%qfT in
- if n is n1.+1 then Rediv_rec_loop q sq cq c.+1 qq1 r1 n1 k
- else k (c.+1, qq1, r1).
-
- Definition Rediv (p : polyF) (q : polyF) : cps (nat * polyF * polyF) :=
- fun k =>
- bind b <- Isnull q;
- if b then k (0%N, [::Const 0], p)
- else bind sq <- Size q;
- bind sp <- Size p;
- bind lq <- LeadCoef q;
- Rediv_rec_loop q sq lq 0 [::Const 0] p sp k.
-
-Definition Rmod (p : polyF) (q : polyF) (k : polyF -> fF) : fF :=
- Rediv p q (fun d => k d.2)%PAIR.
-Definition Rdiv (p : polyF) (q : polyF) (k : polyF -> fF) : fF :=
- Rediv p q (fun d => k d.1.2)%PAIR.
-Definition Rscal (p : polyF) (q : polyF) (k : nat -> fF) : fF :=
- Rediv p q (fun d => k d.1.1)%PAIR.
-Definition Rdvd (p : polyF) (q : polyF) (k : bool -> fF) : fF :=
- bind r <- Rmod p q; bind r_null <- Isnull r; k r_null.
-
-Fixpoint rgcdp_loop n (pp qq : {poly F}) {struct n} :=
- if rmodp pp qq == 0 then qq
- else if n is n1.+1 then rgcdp_loop n1 qq (rmodp pp qq)
- else rmodp pp qq.
-
-Fixpoint Rgcd_loop n pp qq k {struct n} :=
- bind r <- Rmod pp qq; bind b <- Isnull r;
- if b then (k qq)
- else if n is n1.+1 then Rgcd_loop n1 qq r k else k r.
-
-Definition Rgcd (p : polyF) (q : polyF) : cps polyF := fun k =>
- let aux p1 q1 k := (bind b <- Isnull p1;
- if b then k q1 else bind n <- Size p1; Rgcd_loop n p1 q1 k) in
- bind b <- LtSize p q;
- if b then aux q p k else aux p q k.
-
-Fixpoint BigRgcd (ps : seq polyF) : cps (seq tF) := fun k =>
- if ps is p :: pr then bind r <- BigRgcd pr; Rgcd p r k else k [::Const 0].
-
-Fixpoint Changes (s : seq tF) : cps nat := fun k =>
- if s is a :: q then
- bind v <- Changes q;
- If (Lt (a * head 0 q) 0)%qfT Then k (1 + v)%N Else k v
- else k 0%N.
-
-Fixpoint SeqPInfty (ps : seq polyF) : cps (seq tF) := fun k =>
- if ps is p :: ps then
- bind lp <- LeadCoef p;
- bind lps <- SeqPInfty ps;
- k (lp :: lps)
- else k [::].
-
-Fixpoint SeqMInfty (ps : seq polyF) : cps (seq tF) := fun k =>
- if ps is p :: ps then
- bind lp <- LeadCoef p;
- bind sp <- Size p;
- bind lps <- SeqMInfty ps;
- k ((-1)%:T ^+ (~~ odd sp) * lp :: lps)%qfT
- else k [::].
-
-Definition ChangesPoly ps : cps int := fun k =>
- bind mps <- SeqMInfty ps;
- bind pps <- SeqPInfty ps;
- bind vm <- Changes mps; bind vp <- Changes pps; k (vm%:Z - vp%:Z).
-
-Definition NextMod (p q : polyF) : cps polyF := fun k =>
- bind lq <- LeadCoef q;
- bind spq <- Rscal p q;
- bind rpq <- Rmod p q; k (- lq ^+ spq *: rpq)%qfT.
-
-Fixpoint ModsAux (p q : polyF) n : cps (seq polyF) := fun k =>
- if n is m.+1
- then
- bind p_eq0 <- Isnull p;
- if p_eq0 then k [::]
- else
- bind npq <- NextMod p q;
- bind ps <- ModsAux q npq m;
- k (p :: ps)
- else k [::].
-
-Definition Mods (p q : polyF) : cps (seq polyF) := fun k =>
- bind sp <- Size p; bind sq <- Size q;
- ModsAux p q (maxn sp sq.+1) k.
-
-Definition PolyComb (sq : seq polyF) (sc : seq int) :=
- reducebig [::1%qfT] (iota 0 (size sq))
- (fun i => BigBody i MulPoly true (nth [::] sq i ^^+ comb_exp sc`_i)%qfT).
-
-Definition Pcq sq i := (nth [::] (map (PolyComb sq) (sg_tab (size sq))) i).
-
-Definition TaqR (p : polyF) (q : polyF) : cps int := fun k =>
- bind r <- Mods p (Deriv p ** q)%qfT; ChangesPoly r k.
-
-Definition TaqsR (p : polyF) (sq : seq polyF) (i : nat) : cps tF :=
- fun k => bind n <- TaqR p (Pcq sq i); k ((n%:~R) %:T)%qfT.
-
-Fixpoint ProdPoly T (s : seq T) (f : T -> cps polyF) : cps polyF := fun k =>
- if s is a :: s then
- bind fa <- f a;
- bind fs <- ProdPoly s f;
- k (fa ** fs)%qfT
- else k [::1%qfT].
-
-Definition BoundingPoly (sq : seq polyF) : polyF :=
- Deriv (reducebig [::1%qfT] sq (fun i => BigBody i MulPoly true i)).
-
-Definition Coefs (n i : nat) : tF :=
- Const (match n with
- | 0 => (i == 0%N)%:R
- | 1 => [:: 2%:R^-1; 2%:R^-1; 0]`_i
- | n => coefs _ n i
- end).
-
-Definition CcountWeak (p : polyF) (sq : seq polyF) : cps tF := fun k =>
- let fix aux s (i : nat) k := if i is i'.+1
- then bind x <- TaqsR p sq i';
- aux (x * (Coefs (size sq) i') + s)%qfT i' k
- else k s in
- aux 0%qfT (3 ^ size sq)%N k.
-
-Definition CcountGt0 (sp sq : seq polyF) : fF :=
- bind p <- BigRgcd sp; bind p0 <- Isnull p;
- if ~~ p0 then
- bind c <- CcountWeak p sq;
- Lt 0%qfT c
- else
- let bq := BoundingPoly sq in
- bind cw <- CcountWeak bq sq;
- ((reducebig True sq (fun q =>
- BigBody q And true (LeadCoef q (fun lq => Lt 0 lq))))
- \/ ((reducebig True sq (fun q =>
- BigBody q And true
- (bind sq <- Size q;
- bind lq <- LeadCoef q;
- Lt 0 ((Opp 1) ^+ (sq).-1 * lq)
- ))) \/ Lt 0 cw))%qfT.
-
-
-Fixpoint abstrX (i : nat) (t : tF) : polyF :=
- (match t with
- | 'X_n => if n == i then [::0; 1] else [::t]
- | - x => -- abstrX i x
- | x + y => abstrX i x ++ abstrX i y
- | x * y => abstrX i x ** abstrX i y
- | x *+ n => n +** abstrX i x
- | x ^+ n => abstrX i x ^^+ n
- | _ => [::t]
- end)%qfT.
-
-Definition wproj (n : nat) (s : seq (GRing.term F) * seq (GRing.term F)) :
- formula F :=
- let sp := map (abstrX n \o to_rterm) s.1%PAIR in
- let sq := map (abstrX n \o to_rterm) s.2%PAIR in
- CcountGt0 sp sq.
-
-Definition rcf_sat := proj_sat wproj.
-
-End ProjDef.
-
-Section ProjCorrect.
-
-Variable F : rcfType.
-Implicit Types (e : seq F).
-
-Notation fF := (formula F).
-Notation tF := (term F).
-Notation polyF := (polyF F).
-
-Notation "'If' c1 'Then' c2 'Else' c3" := (If c1 c2 c3)
- (at level 200, right associativity, format
-"'[hv ' 'If' c1 '/' '[' 'Then' c2 ']' '/' '[' 'Else' c3 ']' ']'").
-
-Notation cps T := ((T -> fF) -> fF).
-
-Local Infix "**" := MulPoly (at level 40) : qf_scope.
-Local Infix "+**" := NatMulPoly (at level 40) : qf_scope.
-Local Notation "-- p" := (OppPoly p) (at level 35) : qf_scope.
-Local Notation "p -- q" := (p ++ (-- q))%qfT (at level 50) : qf_scope.
-Local Infix "^^+" := ExpPoly (at level 29) : qf_scope.
-Local Infix "**" := MulPoly (at level 40) : qf_scope.
-Local Infix "*:" := ScalPoly : qf_scope.
-Local Infix "++" := AddPoly : qf_scope.
-
-Lemma eval_If e pf tf ef (ev := qf_eval e) :
- ev (If pf Then tf Else ef) = (if ev pf then ev tf else ev ef).
-Proof. by unlock (If _ Then _ Else _)=> /=; case: ifP => _; rewrite ?orbF. Qed.
-
-Lemma eval_Size k p e :
- qf_eval e (Size p k) = qf_eval e (k (size (eval_poly e p))).
-Proof.
-elim: p e k=> [|c p ihp] e k; first by rewrite size_poly0.
-rewrite ihp /= size_MXaddC -size_poly_eq0; case: size=> //.
-by rewrite eval_If /=; case: (_ == _).
-Qed.
-
-Lemma eval_Isnull k p e : qf_eval e (Isnull p k)
- = qf_eval e (k (eval_poly e p == 0)).
-Proof. by rewrite eval_Size size_poly_eq0. Qed.
-
-Lemma eval_LeadCoef e p k k' :
- (forall x, qf_eval e (k x) = (k' (eval e x))) ->
- qf_eval e (LeadCoef p k) = k' (lead_coef (eval_poly e p)).
-Proof.
-move=> Pk; elim: p k k' Pk=> [|a p ihp] k k' Pk //=.
- by rewrite lead_coef0 Pk.
-rewrite (ihp _ (fun l => if l == 0 then qf_eval e (k a) else (k' l))); last first.
- by move=> x; rewrite eval_If /= !Pk.
-rewrite lead_coef_eq0; have [->|p_neq0] := altP (_ =P 0).
- by rewrite mul0r add0r lead_coefC.
-rewrite lead_coefDl ?lead_coefMX ?size_mulX // ltnS size_polyC.
-by rewrite (leq_trans (leq_b1 _)) // size_poly_gt0.
-Qed.
-
-Arguments eval_LeadCoef [e p k].
-Prenex Implicits eval_LeadCoef.
-
-Lemma eval_AmulXn a n e : eval_poly e (AmulXn a n) = (eval e a)%:P * 'X^n.
-Proof.
-elim: n=> [|n] /=; first by rewrite expr0 mulr1 mul0r add0r.
-by move->; rewrite addr0 -mulrA -exprSr.
-Qed.
-
-Lemma eval_AddPoly p q e :
- eval_poly e (p ++ q)%qfT = (eval_poly e p) + (eval_poly e q).
-Proof.
-elim: p q => [|a p Hp] q /=; first by rewrite add0r.
-case: q => [|b q] /=; first by rewrite addr0.
-by rewrite Hp mulrDl rmorphD /= !addrA [X in _ = X + _]addrAC.
-Qed.
-
-Lemma eval_ScalPoly e t p :
- eval_poly e (ScalPoly t p) = (eval e t) *: (eval_poly e p).
-Proof.
-elim: p=> [|a p ihp] /=; first by rewrite scaler0.
-by rewrite ihp scalerDr scalerAl -!mul_polyC rmorphM.
-Qed.
-
-Lemma eval_MulPoly e p q :
- eval_poly e (p ** q)%qfT = (eval_poly e p) * (eval_poly e q).
-Proof.
-elim: p q=> [|a p Hp] q /=; first by rewrite mul0r.
-rewrite eval_AddPoly /= eval_ScalPoly Hp.
-by rewrite addr0 mulrDl addrC mulrAC mul_polyC.
-Qed.
-
-Lemma eval_ExpPoly e p n : eval_poly e (p ^^+ n)%qfT = (eval_poly e p) ^+ n.
-Proof.
-case: n=> [|n]; first by rewrite /= expr0 mul0r add0r.
-rewrite /ExpPoly iteropS exprSr; elim: n=> [|n ihn] //=.
- by rewrite expr0 mul1r.
-by rewrite eval_MulPoly ihn exprS mulrA.
-Qed.
-
-Lemma eval_NatMulPoly p n e :
- eval_poly e (n +** p)%qfT = (eval_poly e p) *+ n.
-Proof.
-elim: p; rewrite //= ?mul0rn // => c p ->.
-rewrite mulrnDl mulr_natl polyC_muln; congr (_+_).
-by rewrite -mulr_natl mulrAC -mulrA mulr_natl mulrC.
-Qed.
-
-Lemma eval_OppPoly p e : eval_poly e (-- p)%qfT = - eval_poly e p.
-Proof.
-elim: p; rewrite //= ?oppr0 // => t ts ->.
-by rewrite !mulNr !opprD polyC_opp mul1r.
-Qed.
-
-Lemma eval_Horner e p x : eval e (Horner p x) = (eval_poly e p).[eval e x].
-Proof. by elim: p => /= [|a p ihp]; rewrite !(horner0, hornerE) // ihp. Qed.
-
-Lemma eval_ConstPoly e c : eval_poly e [::c] = (eval e c)%:P.
-Proof. by rewrite /= mul0r add0r. Qed.
-
-Lemma eval_Deriv e p : eval_poly e (Deriv p) = (eval_poly e p)^`().
-Proof.
-elim: p=> [|a p ihp] /=; first by rewrite deriv0.
-by rewrite eval_AddPoly /= addr0 ihp !derivE.
-Qed.
-
-Definition eval_OpPoly :=
- (eval_MulPoly, eval_AmulXn, eval_AddPoly, eval_OppPoly, eval_NatMulPoly,
- eval_ConstPoly, eval_Horner, eval_ExpPoly, eval_Deriv, eval_ScalPoly).
-
-Lemma eval_Changes e s k : qf_eval e (Changes s k)
- = qf_eval e (k (changes (map (eval e) s))).
-Proof.
-elim: s k=> //= a q ihq k; rewrite ihq eval_If /= -nth0.
-by case: q {ihq}=> /= [|b q]; [rewrite /= mulr0 ltrr add0n | case: ltrP].
-Qed.
-
-Lemma eval_SeqPInfty e ps k k' :
- (forall xs, qf_eval e (k xs) = k' (map (eval e) xs)) ->
- qf_eval e (SeqPInfty ps k)
- = k' (map lead_coef (map (eval_poly e) ps)).
-Proof.
-elim: ps k k' => [|p ps ihps] k k' Pk /=; first by rewrite Pk.
-set X := lead_coef _; grab_eq k'' X; apply: (eval_LeadCoef k'') => lp {X}.
-rewrite (ihps _ (fun ps => k' (eval e lp :: ps))) => //= lps.
-by rewrite Pk.
-Qed.
-
-Arguments eval_SeqPInfty [e ps k].
-Prenex Implicits eval_SeqPInfty.
-
-Lemma eval_SeqMInfty e ps k k' :
- (forall xs, qf_eval e (k xs) = k' (map (eval e) xs)) ->
- qf_eval e (SeqMInfty ps k)
- = k' (map (fun p : {poly F} => (-1) ^+ (~~ odd (size p)) * lead_coef p)
- (map (eval_poly e) ps)).
-Proof.
-elim: ps k k' => [|p ps ihps] k k' Pk /=; first by rewrite Pk.
-set X := lead_coef _; grab_eq k'' X; apply: eval_LeadCoef => lp {X}.
-rewrite eval_Size /= /k'' {k''}.
-by set X := map _ _; grab_eq k'' X; apply: ihps => {X} lps; rewrite Pk.
-Qed.
-
-Arguments eval_SeqMInfty [e ps k].
-Prenex Implicits eval_SeqMInfty.
-
-Lemma eval_ChangesPoly e ps k : qf_eval e (ChangesPoly ps k) =
- qf_eval e (k (changes_poly (map (eval_poly e) ps))).
-Proof.
-rewrite (eval_SeqMInfty (fun mps =>
- qf_eval e (k ((changes mps)%:Z -
- (changes_pinfty [seq eval_poly e i | i <- ps])%:Z)))) => // mps.
-rewrite (eval_SeqPInfty (fun pps =>
- qf_eval e (k ((changes (map (eval e) mps))%:Z - (changes pps)%:Z)))) => // pps.
-by rewrite !eval_Changes.
-Qed.
-
-Fixpoint redivp_rec_loop (q : {poly F}) sq cq
- (k : nat) (qq r : {poly F})(n : nat) {struct n} :=
- if (size r < sq)%N then (k, qq, r) else
- let m := (lead_coef r) *: 'X^(size r - sq) in
- let qq1 := qq * cq%:P + m in
- let r1 := r * cq%:P - m * q in
- if n is n1.+1 then redivp_rec_loop q sq cq k.+1 qq1 r1 n1 else (k.+1, qq1, r1).
-
-Lemma redivp_rec_loopP q c qq r n : redivp_rec q c qq r n
- = redivp_rec_loop q (size q) (lead_coef q) c qq r n.
-Proof. by elim: n c qq r => [| n Pn] c qq r //=; rewrite Pn. Qed.
-
-Lemma eval_Rediv_rec_loop e q sq cq c qq r n k k'
- (d := redivp_rec_loop (eval_poly e q) sq (eval e cq)
- c (eval_poly e qq) (eval_poly e r) n) :
- (forall c qq r, qf_eval e (k (c, qq, r))
- = k' (c, eval_poly e qq, eval_poly e r)) ->
- qf_eval e (Rediv_rec_loop q sq cq c qq r n k) = k' d.
-Proof.
-move=> Pk; elim: n c qq r k Pk @d=> [|n ihn] c qq r k Pk /=.
- rewrite eval_Size /=; have [//=|gtq] := ltnP.
- set X := lead_coef _; grab_eq k'' X; apply: eval_LeadCoef => {X}.
- by move=> x /=; rewrite Pk /= !eval_OpPoly /= !mul_polyC.
-rewrite eval_Size /=; have [//=|gtq] := ltnP.
-set X := lead_coef _; grab_eq k'' X; apply: eval_LeadCoef => {X}.
-by move=> x; rewrite ihn // !eval_OpPoly /= !mul_polyC.
-Qed.
-
-Arguments eval_Rediv_rec_loop [e q sq cq c qq r n k].
-Prenex Implicits eval_Rediv_rec_loop.
-
-Lemma eval_Rediv e p q k k' (d := (redivp (eval_poly e p) (eval_poly e q))) :
- (forall c qq r, qf_eval e (k (c, qq, r)) = k' (c, eval_poly e qq, eval_poly e r)) ->
- qf_eval e (Rediv p q k) = k' d.
-Proof.
-move=> Pk; rewrite eval_Isnull /d unlock.
-have [_|p_neq0] /= := boolP (_ == _); first by rewrite Pk /= mul0r add0r.
-rewrite !eval_Size; set p' := eval_poly e p; set q' := eval_poly e q.
-rewrite (eval_LeadCoef (fun lq =>
- k' (redivp_rec_loop q' (size q') lq 0 0 p' (size p')))) /=; last first.
- by move=> x; rewrite (eval_Rediv_rec_loop k') //= mul0r add0r.
-by rewrite redivp_rec_loopP.
-Qed.
-
-Arguments eval_Rediv [e p q k].
-Prenex Implicits eval_Rediv.
-
-Lemma eval_NextMod e p q k k' :
- (forall p, qf_eval e (k p) = k' (eval_poly e p)) ->
- qf_eval e (NextMod p q k) =
- k' (next_mod (eval_poly e p) (eval_poly e q)).
-Proof.
-move=> Pk; set p' := eval_poly e p; set q' := eval_poly e q.
-rewrite (eval_LeadCoef (fun lq =>
- k' (- lq ^+ rscalp p' q' *: rmodp p' q'))) => // lq.
-rewrite (eval_Rediv (fun spq =>
- k' (- eval e lq ^+ spq.1.1%PAIR *: rmodp p' q'))) => //= spq _ _.
-rewrite (eval_Rediv (fun mpq =>
- k' (- eval e lq ^+ spq *: mpq.2%PAIR))) => //= _ _ mpq.
-by rewrite Pk !eval_OpPoly.
-Qed.
-
-Arguments eval_NextMod [e p q k].
-Prenex Implicits eval_NextMod.
-
-Lemma eval_Rgcd_loop e n p q k k' :
- (forall p, qf_eval e (k p) = k' (eval_poly e p))
- -> qf_eval e (Rgcd_loop n p q k) =
- k' (rgcdp_loop n (eval_poly e p) (eval_poly e q)).
-Proof.
-elim: n p q k k'=> [|n ihn] p q k k' Pk /=.
- rewrite (eval_Rediv (fun r =>
- if r.2%PAIR == 0 then k' (eval_poly e q) else k' r.2%PAIR)) /=.
- by case: eqP.
- by move=> _ _ r; rewrite eval_Isnull; case: eqP.
-pose q' := eval_poly e q.
-rewrite (eval_Rediv (fun r =>
- if r.2%PAIR == 0 then k' q' else k' (rgcdp_loop n q' r.2%PAIR))) /=.
- by case: eqP.
-move=> _ _ r; rewrite eval_Isnull; case: eqP; first by rewrite Pk.
-by rewrite (ihn _ _ _ k').
-Qed.
-
-Lemma eval_Rgcd e p q k k' :
- (forall p, qf_eval e (k p) = k' (eval_poly e p)) ->
- qf_eval e (Rgcd p q k) =
- k' (rgcdp (eval_poly e p) (eval_poly e q)).
-Proof.
-move=> Pk; rewrite /Rgcd /LtSize !eval_Size /rgcdp.
-case: ltnP=> _; rewrite !eval_Isnull; case: eqP=> // _;
-by rewrite eval_Size; apply: eval_Rgcd_loop.
-Qed.
-
-
-Lemma eval_BigRgcd e ps k k' :
- (forall p, qf_eval e (k p) = k' (eval_poly e p)) ->
- qf_eval e (BigRgcd ps k) =
- k' (\big[@rgcdp _/0%:P]_(i <- ps) (eval_poly e i)).
-Proof.
-elim: ps k k'=> [|p sp ihsp] k k' Pk /=.
- by rewrite big_nil Pk /= mul0r add0r.
-rewrite big_cons (ihsp _ (fun r => k' (rgcdp (eval_poly e p) r))) //.
-by move=> r; apply: eval_Rgcd.
-Qed.
-
-Arguments eval_Rgcd [e p q k].
-Prenex Implicits eval_Rgcd.
-
-
-Fixpoint mods_aux (p q : {poly F}) (n : nat) : seq {poly F} :=
- if n is m.+1
- then if p == 0 then [::]
- else p :: (mods_aux q (next_mod p q) m)
- else [::].
-
-Lemma eval_ModsAux e p q n k k' :
- (forall sp, qf_eval e (k sp) = k' (map (eval_poly e) sp)) ->
- qf_eval e (ModsAux p q n k) =
- k' (mods_aux (eval_poly e p) (eval_poly e q) n).
-Proof.
-elim: n p q k k'=> [|n ihn] p q k k' Pk; first by rewrite /= Pk.
-rewrite /= eval_Isnull; have [|ep_neq0] := altP (_ =P _); first by rewrite Pk.
-set q' := eval_poly e q; set p' := eval_poly e p.
-rewrite (eval_NextMod (fun npq => k' (p' :: mods_aux q' npq n))) => // npq.
-by rewrite (ihn _ _ _ (fun ps => k' (p' :: ps))) => // ps; rewrite Pk.
-Qed.
-
-Arguments eval_ModsAux [e p q n k].
-Prenex Implicits eval_ModsAux.
-
-Lemma eval_Mods e p q k k' :
- (forall sp, qf_eval e (k sp) = k' (map (eval_poly e) sp)) ->
- qf_eval e (Mods p q k) = k' (mods (eval_poly e p) (eval_poly e q)).
-Proof. by move=> Pk; rewrite !eval_Size; apply: eval_ModsAux. Qed.
-
-Arguments eval_Mods [e p q k].
-Prenex Implicits eval_Mods.
-
-Lemma eval_TaqR e p q k :
- qf_eval e (TaqR p q k) =
- qf_eval e (k (taqR (eval_poly e p) (eval_poly e q))).
-Proof.
-rewrite (eval_Mods (fun r => qf_eval e (k (changes_poly r)))).
- by rewrite !eval_OpPoly.
-by move=> sp; rewrite !eval_ChangesPoly.
-Qed.
-
-Lemma eval_PolyComb e sq sc :
- eval_poly e (PolyComb sq sc) = poly_comb (map (eval_poly e) sq) sc.
-Proof.
-rewrite /PolyComb /poly_comb size_map.
-rewrite -BigOp.bigopE -val_enum_ord -filter_index_enum !big_map.
-apply: (big_ind2 (fun u v => eval_poly e u = v)).
-+ by rewrite /= mul0r add0r.
-+ by move=> x x' y y'; rewrite eval_MulPoly=> -> ->.
-by move=> i _; rewrite eval_ExpPoly /= (nth_map [::]).
-Qed.
-
-Definition pcq (sq : seq {poly F}) i :=
- (map (poly_comb sq) (sg_tab (size sq)))`_i.
-
-Lemma eval_Pcq e sq i :
- eval_poly e (Pcq sq i) = pcq (map (eval_poly e) sq) i.
-Proof.
-rewrite /Pcq /pcq size_map; move: (sg_tab _)=> s.
-have [ge_is|lt_is] := leqP (size s) i.
- by rewrite !nth_default ?size_map // /=.
-rewrite -(nth_map _ 0) ?size_map //; congr _`_i; rewrite -map_comp.
-by apply: eq_map=> x /=; rewrite eval_PolyComb.
-Qed.
-
-Lemma eval_TaqsR e p sq i k k' :
- (forall x, qf_eval e (k x) = k' (eval e x)) ->
- qf_eval e (TaqsR p sq i k) =
- k' (taqsR (eval_poly e p) (map (eval_poly e) sq) i).
-Proof. by move=> Pk; rewrite /TaqsR /taqsR eval_TaqR Pk /= eval_Pcq. Qed.
-
-Arguments eval_TaqsR [e p sq i k].
-Prenex Implicits eval_TaqsR.
-
-Fact invmx_ctmat1 : invmx (map_mx (intr : int -> F) ctmat1) =
- \matrix_(i, j)
- (nth [::] [:: [:: 2%:R^-1; - 2%:R^-1; 0];
- [:: 2%:R^-1; 2%:R^-1; -1];
- [:: 0; 0; 1]] i)`_j :> 'M[F]_3.
-Proof.
-rewrite -[lhs in lhs = _]mul1r; apply: (canLR (mulrK _)).
- exact: ctmat1_unit.
-symmetry; rewrite /ctmat1.
-apply/matrixP => i j; rewrite !(big_ord_recl, big_ord0, mxE) /=.
-have halfP (K : numFieldType) : 2%:R^-1 + 2%:R^-1 = 1 :> K.
- by rewrite -mulr2n -[_ *+ 2]mulr_natl mulfV // pnatr_eq0.
-move: i; do ?[case=> //=]; move: j; do ?[case=> //=] => _ _;
-rewrite !(mulr1, mul1r, mulrN1, mulN1r, mulr0, mul0r, opprK);
-by rewrite !(addr0, add0r, oppr0, subrr, addrA, halfP).
-Qed.
-
-Lemma eval_Coefs e n i : eval e (Coefs F n i) = coefs F n i.
-Proof.
-case: n => [|[|n]] //=; rewrite /coefs /=.
- case: i => [|i]; last first.
- by rewrite nth_default // size_map size_enum_ord expn0.
- rewrite (nth_map 0) ?size_enum_ord //.
- set O := _`_0; rewrite (_ : O = ord0).
- by rewrite ?castmxE ?cast_ord_id map_mx1 invmx1 mxE.
- by apply: val_inj => /=; rewrite nth_enum_ord.
-have [lt_i3|le_3i] := ltnP i 3; last first.
- by rewrite !nth_default // size_map size_enum_ord.
-rewrite /ctmat /= ?ntensmx1 invmx_ctmat1 /=.
-rewrite (nth_map 0) ?size_enum_ord // castmxE /=.
-rewrite !mxE !cast_ord_id //= nth_enum_ord //=.
-by move: i lt_i3; do 3?case.
-Qed.
-
-Lemma eval_CcountWeak e p sq k k' :
- (forall x, qf_eval e (k x) = k' (eval e x)) ->
- qf_eval e (CcountWeak p sq k) =
- k' (ccount_weak (eval_poly e p) (map (eval_poly e) sq)).
-Proof.
-move=> Pk; rewrite /CcountWeak /ccount_weak.
-set Aux := (fix Aux s i k := match i with 0 => _ | _ => _ end).
-set aux := (fix aux s i := match i with 0 => _ | _ => _ end).
-rewrite size_map -[0]/(eval e 0%qfT); move: 0%qfT=> x.
-elim: (_ ^ _)%N k k' Pk x=> /= [|n ihn] k k' Pk x.
- by rewrite Pk.
-rewrite (eval_TaqsR
- (fun y => k' (aux (y * (coefs F (size sq) n) + eval e x) n))).
- by rewrite size_map.
-by move=> y; rewrite (ihn _ k') // -(eval_Coefs e).
-Qed.
-
-Arguments eval_CcountWeak [e p sq k].
-Prenex Implicits eval_CcountWeak.
-
-Lemma eval_ProdPoly e T s f k f' k' :
- (forall x k k', (forall p, (qf_eval e (k p) = k' (eval_poly e p))) ->
- qf_eval e (f x k) = k' (f' x)) ->
- (forall p, qf_eval e (k p) = k' (eval_poly e p)) ->
- qf_eval e (@ProdPoly _ T s f k) = k' (\prod_(x <- s) f' x).
-Proof.
-move=> Pf; elim: s k k'=> [|a s ihs] k k' Pk /=.
- by rewrite big_nil Pk /= !(mul0r, add0r).
-rewrite (Pf _ _ (fun fa => k' (fa * \prod_(x <- s) f' x))).
- by rewrite big_cons.
-move=> fa; rewrite (ihs _ (fun fs => k' (eval_poly e fa * fs))) //.
-by move=> fs; rewrite Pk eval_OpPoly.
-Qed.
-
-Arguments eval_ProdPoly [e T s f k].
-Prenex Implicits eval_ProdPoly.
-
-Lemma eval_BoundingPoly e sq :
- eval_poly e (BoundingPoly sq) = bounding_poly (map (eval_poly e) sq).
-Proof.
-rewrite eval_Deriv -BigOp.bigopE; congr _^`(); rewrite big_map.
-by apply: big_morph => [p q | ]/=; rewrite ?eval_MulPoly // mul0r add0r.
-Qed.
-
-Lemma eval_CcountGt0 e sp sq : qf_eval e (CcountGt0 sp sq) =
- ccount_gt0 (map (eval_poly e) sp) (map (eval_poly e) sq).
-Proof.
-pose sq' := map (eval_poly e) sq; rewrite /ccount_gt0.
-rewrite (@eval_BigRgcd _ _ _ (fun p => if p != 0
- then 0 < ccount_weak p sq'
- else let bq := bounding_poly sq' in
- [|| \big[andb/true]_(q <- sq') (0 < lead_coef q),
- \big[andb/true]_(q <- sq') (0 < (-1) ^+ (size q).-1 * lead_coef q)
- | 0 < ccount_weak bq sq'])).
- by rewrite !big_map.
-move=> p; rewrite eval_Isnull; case: eqP=> _ /=; last first.
- by rewrite (eval_CcountWeak (> 0)).
-rewrite (eval_CcountWeak (fun n =>
- [|| \big[andb/true]_(q <- sq') (0 < lead_coef q),
- \big[andb/true]_(q <- sq') (0 < (-1) ^+ (size q).-1 * lead_coef q)
- | 0 < n ])).
- by rewrite eval_BoundingPoly.
-move=> n /=; rewrite -!BigOp.bigopE !big_map; congr [|| _, _| _].
- apply: (big_ind2 (fun u v => qf_eval e u = v))=> //=.
- by move=> u v u' v' -> ->.
- by move=> i _; rewrite (eval_LeadCoef (> 0)).
-apply: (big_ind2 (fun u v => qf_eval e u = v))=> //=.
- by move=> u v u' v' -> ->.
-by move=> i _; rewrite eval_Size (eval_LeadCoef (fun lq =>
- (0 < (-1) ^+ (size (eval_poly e i)).-1 * lq))).
-Qed.
-
-Lemma abstrXP e i t x :
- (eval_poly e (abstrX i t)).[x] = eval (set_nth 0 e i x) t.
-Proof.
-elim: t.
-- move=> n /=; case ni: (_ == _);
- rewrite //= ?(mul0r,add0r,addr0,polyC1,mul1r,hornerX,hornerC);
- by rewrite // nth_set_nth /= ni.
-- by move=> r; rewrite /= mul0r add0r hornerC.
-- by move=> r; rewrite /= mul0r add0r hornerC.
-- by move=> t tP s sP; rewrite /= eval_AddPoly hornerD tP ?sP.
-- by move=> t tP; rewrite /= eval_OppPoly hornerN tP.
-- by move=> t tP n; rewrite /= eval_NatMulPoly hornerMn tP.
-- by move=> t tP s sP; rewrite /= eval_MulPoly hornerM tP ?sP.
-- by move=> t tP n; rewrite /= eval_ExpPoly horner_exp tP.
-Qed.
-
-Lemma wf_QE_wproj i bc (bc_i := @wproj F i bc) :
- dnf_rterm (w_to_oclause bc) -> qf_form bc_i && rformula bc_i.
-Proof.
-case: bc @bc_i=> sp sq /=; rewrite /dnf_rterm /= /wproj andbT=> /andP[rsp rsq].
-by rewrite qf_formF rformulaF.
-Qed.
-
-Lemma valid_QE_wproj i bc (bc' := w_to_oclause bc)
- (ex_i_bc := ('exists 'X_i, odnf_to_oform [:: bc'])%oT) e :
- dnf_rterm bc' -> reflect (holds e ex_i_bc) (ord.qf_eval e (wproj i bc)).
-Proof.
-case: bc @bc' @ex_i_bc=> sp sq /=; rewrite /dnf_rterm /wproj /= andbT.
-move=> /andP[rsp rsq]; rewrite -qf_evalE.
-rewrite eval_CcountGt0 /=; apply: (equivP (ccount_gt0P _ _)).
-set P1 := (fun x => _); set P2 := (fun x => _).
-suff: forall x, P1 x <-> P2 x.
- by move=> hP; split=> [] [x Px]; exists x; rewrite (hP, =^~ hP).
-move=> x; rewrite /P1 /P2 {P1 P2} !big_map !(big_seq_cond xpredT) /=.
-rewrite (eq_bigr (fun t => GRing.eval (set_nth 0 e i x) t == 0)); last first.
- by move=> t /andP[t_in_sp _]; rewrite abstrXP evalE to_rtermE ?(allP rsp).
-rewrite [X in _ && X](eq_bigr (fun t => 0 < GRing.eval (set_nth 0 e i x) t));
- last by move=> t /andP[tsq _]; rewrite abstrXP evalE to_rtermE ?(allP rsq).
-rewrite -!big_seq_cond !(rwP (qf_evalP _ _)); first last.
-+ elim: sp rsp => //= p sp ihsp /andP[rp rsp]; first by rewrite ihsp.
-+ elim: sq rsq => //= q sq ihsq /andP[rq rsq]; first by rewrite ihsq.
-rewrite !(rwP andP) (rwP orP) orbF !andbT /=.
-have unfoldr P s : foldr (fun t => ord.And (P t)) ord.True s =
- \big[ord.And/ord.True]_(t <- s) P t by rewrite unlock /reducebig.
-rewrite !unfoldr; set e' := set_nth _ _ _ _.
-by rewrite !(@big_morph _ _ (ord.qf_eval _) true andb).
-Qed.
-
-Lemma rcf_satP e f : reflect (holds e f) (rcf_sat e f).
-Proof. exact: (proj_satP wf_QE_wproj valid_QE_wproj). Qed.
-
-End ProjCorrect.
-
-(* Section Example. *)
-(* no chances it computes *)
-
-(* From mathcomp
-Require Import rat. *)
-
-(* Eval vm_compute in (54%:R / 289%:R + 2%:R^-1 :rat). *)
-
-(* Local Open Scope qf_scope. *)
-
-(* Notation polyF := (polyF [realFieldType of rat]). *)
-(* Definition p : polyF := [::'X_2; 'X_1; 'X_0]. *)
-(* Definition q : polyF := [:: 0; 1]. *)
-(* Definition sq := [::q]. *)
-
-(* Eval vm_compute in MulPoly p q. *)
-
-(* Eval vm_compute in Rediv ([:: 1] : polyF) [::1]. *)
-
-(* Definition fpq := Eval vm_compute in (CcountWeak p [::q]). *)
-
-(* End Example. *)
diff --git a/mathcomp/real_closed/qe_rcf_th.v b/mathcomp/real_closed/qe_rcf_th.v
deleted file mode 100644
index b125997..0000000
--- a/mathcomp/real_closed/qe_rcf_th.v
+++ /dev/null
@@ -1,1298 +0,0 @@
-(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-(* Distributed under the terms of CeCILL-B. *)
-Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp
-Require Import ssrfun ssrbool eqtype ssrnat seq choice path fintype.
-From mathcomp
-Require Import div bigop ssralg poly polydiv ssrnum perm zmodp ssrint.
-From mathcomp
-Require Import polyorder polyrcf interval matrix mxtens.
-
-Set Implicit Arguments.
-Unset Strict Implicit.
-Unset Printing Implicit Defensive.
-
-Import GRing.Theory Num.Theory Num.Def Pdiv.Ring Pdiv.ComRing.
-
-Local Open Scope nat_scope.
-Local Open Scope ring_scope.
-
-Section extra.
-
-Variable R : rcfType.
-Implicit Types (p q : {poly R}).
-
-
-(* Proof. *)
-(* move=> sq; rewrite comp_polyE; case hp: (size p) => [|n]. *)
-(* move/eqP: hp; rewrite size_poly_eq0 => /eqP ->. *)
-(* by rewrite !big_ord0 mulr1 lead_coef0. *)
-(* rewrite big_ord_recr /= addrC lead_coefDl. *)
-(* by rewrite lead_coefZ lead_coef_exp // !lead_coefE hp. *)
-(* rewrite (leq_ltn_trans (size_sum _ _ _)) // size_scale; last first. *)
-(* rewrite -[n]/(n.+1.-1) -hp -lead_coefE ?lead_coef_eq0 //. *)
-(* by rewrite -size_poly_eq0 hp. *)
-(* rewrite polySpred ?ltnS ?expf_eq0; last first. *)
-(* by rewrite andbC -size_poly_eq0 gtn_eqF // ltnW. *)
-(* apply/bigmax_leqP => i _; rewrite size_exp. *)
-(* have [->|/size_scale->] := eqVneq p`_i 0; first by rewrite scale0r size_poly0. *)
-(* by rewrite (leq_trans (size_exp_leq _ _)) // ltn_mul2l -subn1 subn_gt0 sq /=. *)
-(* Qed. *)
-
-
-Lemma mul2n n : (2 * n = n + n)%N. Proof. by rewrite mulSn mul1n. Qed.
-Lemma mul3n n : (3 * n = n + (n + n))%N. Proof. by rewrite !mulSn addn0. Qed.
-Lemma exp3n n : (3 ^ n)%N = (3 ^ n).-1.+1.
-Proof. by elim: n => // n IHn; rewrite expnS IHn. Qed.
-
-Definition exp3S n : (3 ^ n.+1 = 3 ^ n + (3 ^ n + 3 ^ n))%N
- := etrans (expnS 3 n) (mul3n (3 ^ n)).
-
-Lemma tens_I3_mx (cR : comRingType) m n (M : 'M[cR]_(m,n)) :
- 1%:M *t M = castmx (esym (mul3n _ ), esym (mul3n _ ))
- (block_mx M 0
- 0 (block_mx M 0
- 0 M : 'M_(m+m,n+n)%N)).
-Proof.
-rewrite [1%:M : 'M_(1+2)%N]scalar_mx_block.
-rewrite [1%:M : 'M_(1+1)%N]scalar_mx_block.
-rewrite !tens_block_mx.
-apply/eqP; rewrite -(can2_eq (castmxKV _ _) (castmxK _ _)); apply/eqP.
-rewrite castmx_comp !tens_scalar_mx !tens0mx !scale1r.
-rewrite (castmx_block (mul1n _) (mul1n _) (mul2n _) (mul2n _)).
-rewrite !castmx_comp /= !castmx_id.
-rewrite (castmx_block (mul1n _) (mul1n _) (mul1n _) (mul1n _)).
-by rewrite !castmx_comp /= !castmx_id !castmx_const /=.
-Qed.
-
-Lemma mul_1tensmx (cR : comRingType) (m n p: nat)
- (e3n : (n + (n + n) = 3 * n)%N)
- (A B C : 'M[cR]_(m, n)) (M : 'M[cR]_(n, p)) :
- castmx (erefl _, e3n)
- (row_mx A (row_mx B C)) *m (1%:M *t M)
- = castmx (erefl _, esym (mul3n _))
- (row_mx (A *m M) (row_mx (B *m M) (C *m M))).
-Proof.
-apply/eqP; rewrite -(can2_eq (castmxKV _ _) (castmxK _ _)); apply/eqP.
-rewrite tens_I3_mx mulmx_cast castmx_mul !castmx_comp /= !castmx_id /=.
-by rewrite !mul_row_block /= !mulmx0 !addr0 !add0r.
-Qed.
-
-(* :TODO: backport to polydiv *)
-Lemma coprimep_rdiv_gcd p q : (p != 0) || (q != 0) ->
- coprimep (rdivp p (gcdp p q)) (rdivp q (gcdp p q)).
-Proof.
-move=> hpq.
-have gpq0: gcdp p q != 0 by rewrite gcdp_eq0 negb_and.
-rewrite -gcdp_eqp1 -(@eqp_mul2r _ (gcdp p q)) // mul1r.
-have: gcdp p q %| p by rewrite dvdp_gcdl.
-have: gcdp p q %| q by rewrite dvdp_gcdr.
-rewrite !dvdpE !rdvdp_eq eq_sym; move/eqP=> hq; rewrite eq_sym; move/eqP=> hp.
-rewrite (eqp_ltrans (mulp_gcdl _ _ _)) hq hp.
-have lcn0 k : (lead_coef (gcdp p q)) ^+ k != 0.
- by rewrite expf_neq0 ?lead_coef_eq0.
-by apply: eqp_gcd; rewrite ?eqp_scale.
-Qed.
-
-(* :TODO: generalize to non idomainTypes and backport to polydiv *)
-Lemma rgcdp_eq0 p q : rgcdp p q == 0 = (p == 0) && (q == 0).
-Proof. by rewrite -eqp0 (eqp_ltrans (eqp_rgcd_gcd _ _)) eqp0 gcdp_eq0. Qed.
-
-(* :TODO: : move in polyorder *)
-Lemma mu_eq0 : forall p x, p != 0 -> (\mu_x p == 0%N) = (~~ root p x).
-Proof. by move=> p x p0; rewrite -mu_gt0 // -leqNgt leqn0. Qed.
-
-Notation lcn_neq0 := lc_expn_rscalp_neq0.
-
-(* :TODO: : move to polyorder *)
-Lemma mu_mod p q x : (\mu_x p < \mu_x q)%N ->
- \mu_x (rmodp p q) = \mu_x p.
-Proof.
-move=> mupq; have [->|p0] := eqVneq p 0; first by rewrite rmod0p.
-have qn0 : q != 0 by apply: contraTneq mupq => ->; rewrite mu0 ltn0.
-have /(canLR (addKr _)) <- := (rdivp_eq q p).
-have [->|divpq_eq0] := eqVneq (rdivp p q) 0.
- by rewrite mul0r oppr0 add0r mu_mulC ?lcn_neq0.
-rewrite mu_addl ?mu_mulC ?scaler_eq0 ?negb_or ?mulf_neq0 ?lcn_neq0 //.
-by rewrite mu_opp mu_mul ?ltn_addl // ?mulf_neq0.
-Qed.
-
-(* :TODO: : move to polyorder *)
-Lemma mu_add p q x : p + q != 0 ->
- (minn (\mu_x p) (\mu_x q) <= \mu_x (p + q)%R)%N .
-Proof.
-have [->|p0] := eqVneq p 0; first by rewrite mu0 min0n add0r.
-have [->|q0] := eqVneq q 0; first by rewrite mu0 minn0 addr0.
-have [Hpq|Hpq|Hpq] := (ltngtP (\mu_x p) (\mu_x q)).
-+ by rewrite mu_addr ?geq_minl.
-+ by rewrite mu_addl ?geq_minr.
-have [//|p' nrp'x hp] := (@mu_spec _ p x).
-have [//|q' nrq'x hq] := (@mu_spec _ q x).
-rewrite Hpq minnn hp {1 3}hq Hpq -mulrDl => pq0.
-by rewrite mu_mul // mu_exp mu_XsubC mul1n leq_addl.
-Qed.
-
-(* :TODO: : move to polydiv *)
-Lemma mu_mod_leq : forall p q x, ~~ (q %| p) ->
- (\mu_x q <= \mu_x p)%N ->
- (\mu_x q <= \mu_x (rmodp p q)%R)%N.
-Proof.
-move=> p q x; rewrite dvdpE /rdvdp=> rn0 mupq.
-case q0: (q == 0); first by rewrite (eqP q0) mu0 leq0n.
-move/eqP: (rdivp_eq q p).
-rewrite eq_sym (can2_eq (addKr _ ) (addNKr _)); move/eqP=> hr.
-rewrite hr; case qpq0: (rdivp p q == 0).
- by rewrite (eqP qpq0) mul0r oppr0 add0r mu_mulC // lcn_neq0.
-rewrite (leq_trans _ (mu_add _ _)) // -?hr //.
-rewrite leq_min mu_opp mu_mul ?mulf_neq0 ?qpq0 ?q0 // leq_addl.
-by rewrite mu_mulC // lcn_neq0.
-Qed.
-
-(* Lemma sgp_right0 : forall (x : R), sgp_right 0 x = 0. *)
-(* Proof. by move=> x; rewrite /sgp_right size_poly0. Qed. *)
-
-End extra.
-
-Section ctmat.
-
-Variable R : numFieldType.
-
-Definition ctmat1 := \matrix_(i < 3, j < 3)
- (nth [::] [:: [:: 1%:Z ; 1 ; 1 ]
- ; [:: -1 ; 1 ; 1 ]
- ; [:: 0 ; 0 ; 1 ] ] i)`_j.
-
-Lemma det_ctmat1 : \det ctmat1 = 2.
-Proof.
-(* Developpement direct ? *)
-by do ?[rewrite (expand_det_row _ ord0) //=;
- rewrite ?(big_ord_recl,big_ord0) //= ?mxE //=;
- rewrite /cofactor /= ?(addn0, add0n, expr0, exprS);
- rewrite ?(mul1r,mulr1,mulN1r,mul0r,mul1r,addr0) /=;
- do ?rewrite [row' _ _]mx11_scalar det_scalar1 !mxE /=].
-Qed.
-
-Notation zmxR := ((map_mx ((intmul 1) : int -> R)) _ _).
-
-Lemma ctmat1_unit : zmxR ctmat1 \in unitmx.
-Proof.
-rewrite /mem /in_mem /= /unitmx det_map_mx //.
-by rewrite det_ctmat1 unitfE intr_eq0.
-Qed.
-
-Definition ctmat n := (ctmat1 ^t n).
-
-Lemma ctmat_unit : forall n, zmxR (ctmat n) \in unitmx.
-Proof.
-case=> [|n] /=; first by rewrite map_mx1 ?unitmx1//; apply: zinjR_morph.
-elim: n=> [|n ihn] /=; first by apply: ctmat1_unit.
-rewrite map_mxT //.
-apply: tensmx_unit=> //; last exact: ctmat1_unit.
-by elim: n {ihn}=> // n ihn; rewrite muln_eq0.
-Qed.
-
-Lemma ctmat1_blocks : ctmat1 = (block_mx
- 1 (row_mx 1 1)
- (col_mx (-1) 0) (block_mx 1 1 0 1 : 'M_(1+1)%N)).
-Proof.
-apply/matrixP=> i j; rewrite !mxE.
-by do 4?[case: splitP => ?; rewrite !mxE ?ord1=> ->].
-Qed.
-
-Lemma tvec_sub n : (3 * (3 ^ n).-1.+1 = 3 ^ (n.+1) )%N.
-Proof. by rewrite -exp3n expnS. Qed.
-
-Lemma tens_ctmat1_mx n (M : 'M_n) :
- ctmat1 *t M = castmx (esym (mul3n _ ), esym (mul3n _ ))
- (block_mx M (row_mx M M)
- (col_mx (-M) 0) (block_mx M M
- 0 M : 'M_(n+n)%N)).
-Proof.
-rewrite ctmat1_blocks !tens_block_mx !tens_row_mx !tens_col_mx.
-rewrite [-1]mx11_scalar !mxE /= !tens_scalar_mx !tens0mx scaleNr !scale1r.
-apply/eqP; rewrite -(can2_eq (castmxKV _ _) (castmxK _ _)); apply/eqP.
-rewrite !castmx_comp !esymK /=.
-rewrite !(castmx_block (mul1n _) (mul1n _) (mul2n _) (mul2n _)).
-rewrite !castmx_comp !castmx_id /=.
-rewrite !(castmx_row (mul1n _) (mul1n _)).
-rewrite !(castmx_block (mul1n _) (mul1n _) (mul1n _) (mul1n _)) /=.
-rewrite !(castmx_col (mul1n _) (mul1n _)) !castmx_comp !castmx_id /=.
-by rewrite !castmx_const.
-Qed.
-
-Definition coefs n i :=
- [seq (castmx (erefl _, exp3n _) (invmx (zmxR (ctmat n)))) i ord0
- | i <- enum 'I__]`_i.
-
-End ctmat.
-
-Section QeRcfTh.
-
-Variable R : rcfType.
-Implicit Types a b : R.
-Implicit Types p q : {poly R}.
-
-Notation zmxR := ((map_mx ((intmul 1) : int -> R)) _ _).
-Notation midf a b := ((a + b) / 2%:~R).
-
-(* Constraints and Tarski queries *)
-
-Local Notation sgp_is q s := (fun x => (sgr q.[x] == s)).
-
-Definition constraints (z : seq R) (sq : seq {poly R}) (sigma : seq int) :=
- (\sum_(x <- z) \prod_(i < size sq) (sgz (sq`_i).[x] == sigma`_i))%N.
-
-Definition taq (z : seq R) (q : {poly R}) : int := \sum_(x <- z) (sgz q.[x]).
-
-Lemma taq_constraint1 z q :
- taq z q = (constraints z [::q] [::1])%:~R - (constraints z [::q] [::-1])%:~R.
-Proof.
-rewrite /constraints /taq !sumMz -sumrB /=; apply: congr_big=> // x _.
-by rewrite !big_ord_recl big_ord0 !muln1 /=; case: sgzP.
-Qed.
-
-Lemma taq_constraint0 z q :
- taq z 1 = (constraints z [::q] [:: 0])%:~R
- + (constraints z [::q] [:: 1])%:~R
- + (constraints z [::q] [::-1])%:~R.
-Proof.
-rewrite /constraints /taq !sumMz //= -!big_split /=; apply: congr_big=> // x _.
-by rewrite hornerC sgz1 !big_ord_recl big_ord0 !muln1 /=; case: sgzP.
-Qed.
-
-Lemma taq_no_constraint z : taq z 1 = (constraints z [::] [::])%:~R.
-Proof.
-rewrite /constraints /taq !sumMz; apply: congr_big=> // x _.
-by rewrite hornerC sgz1 big_ord0.
-Qed.
-
-Lemma taq_constraint2 z q :
- taq z (q ^+ 2) = (constraints z [::q] [:: 1])%:~R
- + (constraints z [::q] [::-1])%:~R.
-Proof.
-rewrite /constraints /taq !sumMz -big_split /=; apply: congr_big=> // x _.
-rewrite !big_ord_recl big_ord0 !muln1 /= horner_exp sgzX.
-by case: (sgzP q.[x])=> _.
-Qed.
-
-Fixpoint sg_tab n : seq (seq int) :=
- if n is m.+1
- then flatten (map (fun x => map (fun l => x :: l) (sg_tab m)) [::1; -1; 0])
- else [::[::]].
-
-Lemma sg_tab_nil n : (sg_tab n == [::]) = false.
-Proof. by elim: n => //= n; case: sg_tab. Qed.
-
-Lemma size_sg_tab n : size (sg_tab n) = (3 ^ n)%N.
-Proof.
-by elim: n => [|n] // ihn; rewrite !size_cat !size_map ihn addn0 exp3S.
-Qed.
-
-Lemma size_sg_tab_neq0 n : size (sg_tab n) != 0%N.
-Proof. by rewrite size_sg_tab exp3n. Qed.
-
-
-Definition comb_exp (R : realDomainType) (s : R) :=
- match sgz s with Posz 1 => 1%N | Negz 0 => 2 | _ => 0%N end.
-
-Definition poly_comb (sq : seq {poly R}) (sc : seq int) : {poly R} :=
- \prod_(i < size sq) ((sq`_i) ^+ (comb_exp sc`_i)).
-
-(* Eval compute in sg_tab 4. *)
-
-Definition cvec z sq := let sg_tab := sg_tab (size sq) in
- \row_(i < 3 ^ size sq) ((constraints z sq (nth [::] sg_tab i))%:~R : int).
-Definition tvec z sq := let sg_tab := sg_tab (size sq) in
- \row_(i < 3 ^ size sq) (taq z (map (poly_comb sq) sg_tab)`_i).
-
-
-Lemma tvec_cvec1 z q : tvec z [::q] = (cvec z [::q]) *m ctmat1.
-Proof.
-apply/rowP => j.
-rewrite /tvec !mxE /poly_comb /= !big_ord_recl !big_ord0 //=.
-rewrite !(expr0,expr1,mulr1) /=.
-case: j=> [] [|[|[|j]]] hj //.
-* by rewrite !mxE /= mulr0 add0r mulr1 mulrN1 addr0 taq_constraint1.
-* by rewrite !mxE /= mulr0 !mulr1 add0r addr0 taq_constraint2.
-* by rewrite !mxE /= addrA (@taq_constraint0 _ q) !mulr1 addr0 -addrA addrC.
-Qed.
-
-Lemma cvec_rec z q sq :
- cvec z (q :: sq) = castmx (erefl _, esym (exp3S _))
- (row_mx (cvec (filter (sgp_is q 1) z) (sq))
- (row_mx (cvec (filter (sgp_is q (-1)) z) (sq))
- (cvec (filter (sgp_is q 0) z) (sq)))).
-Proof.
-apply/eqP; rewrite -(can2_eq (castmxKV _ _) (castmxK _ _)); apply/eqP.
-apply/rowP=> [] i; rewrite !(mxE, castmxE, esymK, cast_ord_id) /=.
-symmetry; case: splitP=> j hj /=; rewrite !mxE hj.
- case hst: sg_tab (sg_tab_nil (size sq))=> [|l st] // _.
- have sst: (size st).+1 = (3 ^ size sq)%N.
- transitivity (size (sg_tab (size sq))); first by rewrite hst //.
- by rewrite size_sg_tab.
- rewrite /constraints big_filter big_mkcond !sumMz; apply: congr_big=> // x _.
- rewrite nth_cat size_map ![size (_::_)]/= sst ltn_ord.
- rewrite (nth_map [::]) /= ?sst ?ltn_ord // big_ord_recl /=.
- by rewrite sgr_cp0 sgz_cp0; case: (_ < _); first by rewrite mul1n.
-case: splitP=> k hk; rewrite !mxE /= hk.
- case hst: sg_tab (sg_tab_nil (size sq))=> [|l st] // _.
- have sst: (size st).+1 = (3 ^ size sq)%N.
- transitivity (size (sg_tab (size sq))); first by rewrite hst //.
- by rewrite size_sg_tab.
- rewrite /constraints big_filter big_mkcond !sumMz; apply: congr_big=> // x _.
- rewrite nth_cat nth_cat !size_map ![size (_ :: _)]/= sst ltnNge leq_addr.
- rewrite (@nth_map _ [::] _ _ [eta cons (-1)] _ (l::st)) /= ?sst addKn ltn_ord //.
- rewrite big_ord_recl /= sgr_cp0 sgz_cp0.
- by case: (_ < _); first by rewrite mul1n.
-case hst: sg_tab (sg_tab_nil (size sq))=> [|l st] // _.
-have sst: (size st).+1 = (3 ^ size sq)%N.
- transitivity (size (sg_tab (size sq))); first by rewrite hst //.
- by rewrite size_sg_tab.
-rewrite /constraints big_filter big_mkcond !sumMz; apply: congr_big=> // x _.
-rewrite nth_cat nth_cat nth_cat !size_map ![size (_ :: _)]/= sst.
-rewrite (@nth_map _ [::] _ _ [eta cons 0] _ (l::st)) /=; last first.
- by rewrite !addKn sst ltn_ord.
-rewrite ltnNge leq_addr /= !addKn ltnNge leq_addr /= ltn_ord.
-rewrite big_ord_recl /= sgr_cp0 sgz_cp0.
-by case: (_ == _); first by rewrite mul1n.
-Qed.
-
-
-Lemma poly_comb_cons q sq s ss :
- poly_comb (q :: sq) (s :: ss) = (q ^ (comb_exp s)) * poly_comb sq ss.
-Proof. by rewrite /poly_comb /= big_ord_recl /=. Qed.
-
-Lemma comb_expE (rR : realDomainType):
- (comb_exp (1 : rR) = 1%N) * (comb_exp (-1 : rR) = 2%N) * (comb_exp (0 : rR) = 0%N).
-Proof. by rewrite /comb_exp sgzN sgz1 sgz0. Qed.
-
-Lemma tvec_rec z q sq :
- tvec z (q :: sq) =
- castmx (erefl _, esym (exp3S _)) (
- (row_mx (tvec (filter (sgp_is q 1) z) (sq))
- (row_mx (tvec (filter (sgp_is q (-1)) z) (sq))
- (tvec (filter (sgp_is q 0) z) (sq)))) *m
- (castmx (mul3n _, mul3n _) (ctmat1 *t 1%:M))).
-Proof.
-rewrite tens_ctmat1_mx !castmx_comp !castmx_id /=.
-rewrite !(mul_row_block, mul_row_col, mul_mx_row) !(mulmx1, mulmx0, mulmxN, addr0) /=.
-apply/eqP; rewrite -(can2_eq (castmxKV _ _) (castmxK _ _)); apply/eqP.
-apply/matrixP=> i j; rewrite !(castmxE, mxE) /=.
-symmetry; case: splitP=> l hl; rewrite !mxE hl.
- case hst: sg_tab (sg_tab_nil (size sq))=> [|s st] // _.
- have sst: (size st).+1 = (3 ^ size sq)%N.
- transitivity (size (sg_tab (size sq))); first by rewrite hst //.
- by rewrite size_sg_tab.
- rewrite /taq !big_filter !(big_mkcond (sgp_is _ _)) -sumrB.
- apply: congr_big=> // x _.
- rewrite cats0 !map_cat nth_cat !size_map /= sst ltn_ord /=.
- rewrite !poly_comb_cons /= !comb_expE expr1z.
- rewrite -!(nth_map _ 0 (fun p => p.[_])) /= ?size_map ?sst ?ltn_ord //.
- rewrite -!map_comp /= hornerM.
- set f := _ \o _; set g := _ \o _.
- set h := fun sc => q.[x] * (poly_comb sq sc).[x].
- have hg : g =1 h.
- by move=> sx; rewrite /g /h /= poly_comb_cons comb_expE expr1z hornerM.
- rewrite -/(h _) -hg -[g _ :: _]/(map g (_ ::_)).
- rewrite (nth_map [::]) /= ?sst ?ltn_ord // hg /h sgzM.
- rewrite -![(poly_comb _ _).[_]]/(f _) -[f _ :: _]/(map f (_ ::_)).
- rewrite (nth_map [::]) /= ?sst ?ltn_ord // !sgr_cp0.
- by case: (sgzP q.[x]); rewrite ?(mul0r, mul1r, mulN1r, subr0, sub0r).
-case: splitP=> k hk /=; rewrite !mxE hk.
- case hst: sg_tab (sg_tab_nil (size sq))=> [|s st] // _.
- have sst: (size st).+1 = (3 ^ size sq)%N.
- transitivity (size (sg_tab (size sq))); first by rewrite hst //.
- by rewrite size_sg_tab.
- rewrite /taq !big_filter !(big_mkcond (sgp_is _ _)) -big_split.
- apply: congr_big=> // x _.
- rewrite cats0 !map_cat !nth_cat !size_map /= sst.
- rewrite ltnNge leq_addr /= addKn ltn_ord /=.
- rewrite !poly_comb_cons /= !comb_expE.
- rewrite -!(nth_map _ 0 (fun p => p.[_])) /= ?size_map ?sst ?ltn_ord //.
- rewrite -!map_comp /= hornerM.
- set f := _ \o _; set g := _ \o _.
- set h := fun sc => (q ^ 2).[x] * (poly_comb sq sc).[x].
- have hg : g =1 h.
- by move=> sx; rewrite /g /h /= poly_comb_cons comb_expE hornerM.
- rewrite -/(h _) -hg -[g _ :: _]/(map g (_ ::_)).
- rewrite (nth_map [::]) /= ?sst ?ltn_ord // hg /h sgzM.
- rewrite -![(poly_comb _ _).[_]]/(f _) -[f _ :: _]/(map f (_ ::_)).
- rewrite (nth_map [::]) /= ?sst ?ltn_ord //.
- rewrite hornerM sgzM !sgr_cp0.
- by case: (sgzP q.[x]); rewrite ?(mul0r, mul1r, mulN1r, addr0, add0r).
-case hst: sg_tab (sg_tab_nil (size sq))=> [|s st] // _.
-have sst: (size st).+1 = (3 ^ size sq)%N.
- transitivity (size (sg_tab (size sq))); first by rewrite hst //.
- by rewrite size_sg_tab.
-rewrite /taq !big_filter !(big_mkcond (sgp_is _ _)) -!big_split.
-apply: congr_big=> // x _.
-rewrite cats0 !map_cat !nth_cat !size_map /= sst.
-rewrite !addKn 2!ltnNge !leq_addr /=.
-rewrite !poly_comb_cons /= !comb_expE expr0z mul1r.
-rewrite -!(nth_map _ 0 (fun p => p.[_])) /= ?size_map ?sst ?ltn_ord //.
-rewrite -!map_comp /=.
-set f := _ \o _; set g := _ \o _.
-have hg : g =1 f.
- by move=> sx; rewrite /g /f /= poly_comb_cons comb_expE expr0z mul1r.
-rewrite -[(poly_comb _ _).[_]]/(f _) -{4}hg.
-rewrite -[g s :: _]/(map _ (_ ::_)) (eq_map hg) !sgr_cp0.
-by case: (sgzP q.[x])=> _; rewrite ?(addr0, add0r).
-Qed.
-
-Lemma tvec_cvec z sq :
- tvec z sq = (cvec z sq) *m (ctmat (size sq)).
-Proof.
-elim: sq z => [|q sq ihsq] z /=.
- rewrite mulmx1; apply/rowP=> [] [i hi] /=; rewrite !mxE /=.
- move: hi; rewrite expn0 ltnS leqn0; move/eqP=> -> /=.
- rewrite /poly_comb big_ord0 /taq /constraints /=.
- rewrite sumMz; apply: (congr_big)=> //= x _.
- by rewrite hornerC sgz1 big_ord0.
-rewrite /ctmat /ntensmx /=. (* simpl in trunk is "weaker" here *)
-case: sq ihsq=> /= [|q' sq] ihsq; first by apply: tvec_cvec1.
-rewrite cvec_rec tensmx_decl mulmxA tvec_rec.
-apply/eqP; rewrite (can2_eq (castmxK _ _) (castmxKV _ _)); apply/eqP.
-rewrite !castmx_mul !castmx_id [row_mx _ _ *m _]mulmx_cast.
-congr (_ *m _); last by congr (castmx (_, _) _); apply: nat_irrelevance.
-rewrite /=; have->: forall n, exp3S n.+1 = mul3n (3^n.+1)%N.
- by move=> n; apply: nat_irrelevance.
-by rewrite mul_1tensmx !ihsq.
-Qed.
-
-Lemma cvec_tvec z sq :
- zmxR (cvec z (sq)) = (zmxR (tvec z (sq))) *m (invmx (zmxR (ctmat (size (sq))))).
-Proof.
-apply/eqP; set A := zmxR (ctmat _).
-rewrite -(@can2_eq _ _ (fun (x : 'rV_(_)) => x *m A) (fun x => x *m (invmx A))).
-* by rewrite /A -map_mxM ?tvec_cvec//; apply: zinjR_morph.
-* by apply: mulmxK; rewrite /A ctmat_unit.
-* by apply: mulmxKV; rewrite /A ctmat_unit.
-Qed.
-
-Lemma constraints1_tvec : forall z sq,
- (constraints z (sq) (nseq (size (sq)) 1))%:~R = (castmx (erefl _, exp3n _)
- (zmxR (tvec z (sq)) *m (invmx (zmxR (ctmat (size (sq))))))) ord0 ord0.
-Proof.
-move=> z sq.
-rewrite -cvec_tvec castmxE /= cast_ord_id /= /cvec !mxE //= intz.
-congr ((constraints _ _ _)%:~R); elim: sq=> //= _ s -> /=.
-set l := sg_tab _; suff: size l != 0%N by case: l.
-exact: size_sg_tab_neq0.
-Qed.
-
-(* Cauchy Index, relation with Tarski query*)
-
-Local Notation seq_mids a s b := (pairmap (fun x y => midf x y) a (rcons s b)).
-Local Notation noroot p := (forall x, ~~ root p x).
-Notation lcn_neq0 := lc_expn_rscalp_neq0.
-
-Definition jump q p x: int :=
- let non_null := (q != 0) && odd (\mu_x p - \mu_x q) in
- let sign := (sgp_right (q * p) x < 0)%R in
- (-1) ^+ sign *+ non_null.
-
-Definition cindex (a b : R) (q p : {poly R}) : int :=
- \sum_(x <- roots p a b) jump q p x.
-
-Definition cindexR q p := \sum_(x <- rootsR p) jump q p x.
-
-Definition sjump p x : int :=
- ((-1) ^+ (sgp_right p x < 0)%R) *+ odd (\mu_x p).
-
-Definition variation (x y : R) : int := (sgz y) * (x * y < 0).
-
-Definition cross p a b := variation p.[a] p.[b].
-
-Definition crossR p := variation (sgp_minfty p) (sgp_pinfty p).
-
-Definition sum_var (s : seq R) := \sum_(n <- pairmap variation 0 s) n.
-
-Lemma cindexEba a b : b <= a -> forall p q, cindex a b p q = 0.
-Proof. by move=> le_ba p q; rewrite /cindex rootsEba ?big_nil. Qed.
-
-Lemma jump0p q x : jump 0 q x = 0. Proof. by rewrite /jump eqxx mulr0n. Qed.
-
-Lemma taq_cindex a b p q : taq (roots p a b) q = cindex a b (p^`() * q) p.
-Proof.
-have [lt_ab|?] := ltrP a b; last by rewrite rootsEba ?cindexEba /taq ?big_nil.
-rewrite /taq /cindex !big_seq; apply: eq_bigr => x.
-have [->|p_neq0 /root_roots rpx] := eqVneq p 0; first by rewrite roots0 in_nil.
-have [->|q_neq0] := eqVneq q 0; first by rewrite mulr0 jump0p horner0 sgz0.
-have [p'0|p'_neq0] := eqVneq p^`() 0.
- move/(root_size_gt1 p_neq0): rpx.
- by rewrite -subn_gt0 subn1 -size_deriv p'0 size_poly0.
-have p'q0: p^`() * q != 0 by rewrite mulf_neq0.
-move: (p'q0); rewrite mulf_eq0 negb_or; case/andP=> p'0 q0.
-have p0: p != 0 by move: p'0; apply: contra; move/eqP->; rewrite derivC.
-rewrite /jump mu_mul// {1}(@mu_deriv_root _ _ p)// addn1 p'q0 /=.
-case emq: (\mu_(_) q)=> [|m].
- move/eqP: emq; rewrite -leqn0 leqNgt mu_gt0// => qxn0.
- rewrite addn0 subSnn mulr1n.
- rewrite !sgp_right_mul// (sgp_right_deriv rpx) mulrAC.
- rewrite sgp_right_square// mul1r sgp_rightNroot//.
- rewrite sgr_lt0 -sgz_cp0.
- by move: qxn0; rewrite -[root q x]sgz_cp0; case: sgzP.
-rewrite addnS subSS -{1}[\mu_(_) _]addn0 subnDl sub0n mulr0n.
-by apply/eqP; rewrite sgz_cp0 -[_ == 0]mu_gt0// emq.
-Qed.
-
-Lemma sum_varP s : 0 \notin s -> sum_var s = variation (head 0 s) (last 0 s).
-Proof.
-rewrite /sum_var /variation.
-case: s => /= [_|a s]; first by rewrite big_nil sgz0 mul0r.
-rewrite in_cons big_cons mul0r ltrr mulr0 add0r.
-elim: s a => [|b s IHs] a; first by rewrite big_nil ler_gtF ?mulr0 ?sqr_ge0.
-move=> /norP [neq_0a Hbs]; move: (Hbs); rewrite in_cons => /norP[neq_0b Hs].
-rewrite /= big_cons IHs ?negb_or ?neq_0b // -!sgz_cp0 !sgzM.
-have: (last b s) != 0 by apply: contra Hbs => /eqP <-; rewrite mem_last.
-by move: neq_0a neq_0b; do 3?case: sgzP => ? //.
-Qed.
-
-Lemma jump_coprime p q : p != 0 -> coprimep p q
- -> forall x, root p x -> jump q p x = sjump (q * p) x.
-Proof.
-move=> pn0 cpq x rpx; rewrite /jump /sjump.
-have q_neq0 : q != 0; last rewrite q_neq0 /=.
- apply: contraTneq cpq => ->; rewrite coprimep0.
- by apply: contraL rpx => /eqp_root ->; rewrite rootC oner_eq0.
-have := coprimep_root cpq rpx; rewrite -rootE -mu_eq0 => // /eqP muxq_eq0.
-by rewrite mu_mul ?mulf_neq0 ?muxq_eq0 ?subn0 ?add0n.
-Qed.
-
-Lemma sjump_neigh a b p x : p != 0 ->
- {in neighpl p a x & neighpr p x b,
- forall yl yr, sjump p x = cross p yl yr}.
-Proof.
-move=> pn0 yl yr yln yrn; rewrite /cross /variation.
-rewrite -sgr_cp0 sgrM /sjump (sgr_neighpl yln) -!(sgr_neighpr yrn).
-rewrite -mulrA -expr2 sqr_sg (rootPf (neighpr_root yrn)) mulr1.
-rewrite sgrEz ltrz0 -[in rhs in _ = rhs]intr_sign -[X in _ == X]mulrN1z eqr_int.
-by have /rootPf := neighpr_root yrn; case: sgzP; case: odd.
-Qed.
-
-Lemma jump_neigh a b p q x : q * p != 0 ->
- {in neighpl (q * p) a x & neighpr (q * p) x b, forall yl yr,
- jump q p x = cross (q * p) yl yr *+ ((q != 0) && (\mu_x p > \mu_x q)%N)}.
-Proof.
-move=> pqn0 yl yr hyl hyr; rewrite -(sjump_neigh pqn0 hyl hyr).
-rewrite /jump /sjump -mulrnA mulnb andbCA.
-have [muqp|/eqnP ->] := ltnP; rewrite (andbF, andbT) //.
-by rewrite mu_mul // odd_add addbC odd_sub // ltnW.
-Qed.
-
-Lemma jump_mul2l (p q r : {poly R}) :
- p != 0 -> jump (p * q) (p * r) =1 jump q r.
-Proof.
-move=> p0 x; rewrite /jump.
-case q0: (q == 0); first by rewrite (eqP q0) mulr0 eqxx.
-have ->: p * q != 0 by rewrite mulf_neq0 ?p0 ?q0.
-case r0: (r == 0); first by rewrite (eqP r0) !mulr0 mu0 !sub0n.
-rewrite !mu_mul ?mulf_neq0 ?andbT ?q0 ?r0 //; rewrite subnDl.
-rewrite mulrAC mulrA -mulrA.
-rewrite (@sgp_right_mul _ (p * p)) // sgp_right_mul // sgp_right_square //.
-by rewrite mul1r mulrC /=.
-Qed.
-
-Lemma jump_mul2r (p q r : {poly R}) :
- p != 0 -> jump (q * p) (r * p) =1 jump q r.
-Proof. by move=> p0 x; rewrite ![_ * p]mulrC jump_mul2l. Qed.
-
-Lemma jumppc p c x : jump p c%:P x = 0.
-Proof. by rewrite /jump mu_polyC sub0n !andbF. Qed.
-
-Lemma noroot_jump q p x : ~~ root p x -> jump q p x = 0.
-Proof.
-have [->|p_neq0] := eqVneq p 0; first by rewrite jumppc.
-by rewrite -mu_gt0 // lt0n negbK /jump => /eqP ->; rewrite andbF mulr0n.
-Qed.
-
-Lemma jump_mulCp c p q x : jump (c *: p) q x = (sgz c) * jump p q x.
-Proof.
-have [->|c0] := eqVneq c 0; first by rewrite sgz0 scale0r jump0p mul0r.
-have [->|p0] := eqVneq p 0; first by rewrite scaler0 jump0p mulr0.
-have [->|q0] := eqVneq q 0; first by rewrite !jumppc mulr0.
-(* :TODO: : rename mu_mulC *)
-rewrite /jump scale_poly_eq0 mu_mulC ?negb_or ?c0 ?p0 ?andTb //.
-rewrite -scalerAl sgp_right_scale //.
-case: sgzP c0 => // _ _; rewrite !(mul1r, mulN1r, =^~ mulNrn) //.
-by rewrite ?oppr_cp0 lt0r sgp_right_eq0 ?mulf_neq0 // andTb lerNgt signrN.
-Qed.
-
-Lemma jump_pmulC c p q x : jump p (c *: q) x = (sgz c) * jump p q x.
-Proof.
-have [->|c0] := eqVneq c 0; first by rewrite sgz0 scale0r mul0r jumppc.
-have [->|p0] := eqVneq p 0; first by rewrite !jump0p mulr0.
-have [->|q0] := eqVneq q 0; first by rewrite scaler0 !jumppc mulr0.
-rewrite /jump mu_mulC // -scalerAr sgp_right_scale //.
-case: sgzP c0 => // _ _; rewrite !(mul1r, mulN1r, =^~ mulNrn) //.
-by rewrite ?oppr_cp0 lt0r sgp_right_eq0 ?mulf_neq0 // andTb lerNgt signrN.
-Qed.
-
-Lemma jump_mod p q x :
- jump p q x = sgz (lead_coef q) ^+ (rscalp p q) * jump (rmodp p q) q x.
-Proof.
-case p0: (p == 0); first by rewrite (eqP p0) rmod0p jump0p mulr0.
-case q0: (q == 0); first by rewrite (eqP q0) rmodp0 jumppc mulr0.
-rewrite -sgzX; set s := sgz _.
-apply: (@mulfI _ s); first by rewrite /s sgz_eq0 lcn_neq0.
-rewrite mulrA mulz_sg lcn_neq0 mul1r -jump_mulCp rdivp_eq.
-have [->|rpq_eq0] := altP (rmodp p q =P 0).
- by rewrite addr0 jump0p -[X in jump _ X]mul1r jump_mul2r ?q0 // jumppc.
-rewrite /jump. set r := _ * q + _.
-have muxp : \mu_x p = \mu_x r by rewrite /r -rdivp_eq mu_mulC ?lcn_neq0.
-have r_neq0 : r != 0 by rewrite /r -rdivp_eq scaler_eq0 p0 orbF lcn_neq0.
-have [hpq|hpq] := leqP (\mu_x q) (\mu_x r).
- rewrite 2!(_ : _ - _ = 0)%N ?andbF //; apply/eqP; rewrite -/(_ <= _)%N //.
- by rewrite mu_mod_leq ?dvdpE // muxp.
-rewrite mu_mod ?muxp // rpq_eq0 (negPf r_neq0); congr (_ ^+ _ *+ _).
-rewrite !sgp_right_mul sgp_right_mod ?muxp // /r -rdivp_eq.
-by rewrite -mul_polyC sgp_right_mul sgp_rightc sgrX.
-Qed.
-
-Lemma cindexRP q p a b :
- {in `]-oo, a], noroot p} -> {in `[b , +oo[, noroot p} ->
- cindex a b q p = cindexR q p.
-Proof. by rewrite /cindex => rpa rpb; rewrite rootsRP. Qed.
-
-Lemma cindex0p a b q : cindex a b 0 q = 0.
-Proof.
-have [lt_ab|le_ba] := ltrP a b; last by rewrite cindexEba.
-by apply: big1_seq=> x; rewrite /jump eqxx mulr0n.
-Qed.
-
-Lemma cindexR0p p : cindexR 0 p = 0.
-Proof. by rewrite /cindexR big1 // => q _; rewrite jump0p. Qed.
-
-Lemma cindexpC a b p c : cindex a b p (c%:P) = 0.
-Proof.
-have [lt_ab|le_ba] := ltrP a b; last by rewrite cindexEba.
-by rewrite /cindex /jump rootsC big_nil.
-Qed.
-
-Lemma cindexRpC q c : cindexR q c%:P = 0.
-Proof. by rewrite /cindexR rootsRC big_nil. Qed.
-
-Lemma cindex_mul2r a b p q r : r != 0 ->
- cindex a b (p * r) (q * r) = cindex a b p q.
-Proof.
-have [lt_ab r0|le_ba] := ltrP a b; last by rewrite !cindexEba.
-have [->|p0] := eqVneq p 0; first by rewrite mul0r !cindex0p.
-have [->|q0] := eqVneq q 0; first by rewrite mul0r !cindexpC.
-rewrite /cindex (eq_big_perm _ (roots_mul _ _ _))//= big_cat/=.
-rewrite -[\sum_(x <- _) jump p _ _]addr0; congr (_+_).
- by rewrite !big_seq; apply: congr_big => // x hx; rewrite jump_mul2r.
-rewrite big1_seq//= => x hx; rewrite jump_mul2r // /jump.
-suff ->: \mu_x q = 0%N by rewrite andbF.
-apply/eqP; rewrite -leqn0 leqNgt mu_gt0 //.
-apply/negP; rewrite root_factor_theorem => rqx; move/root_roots:hx.
-case: gdcopP=> g hg; rewrite (negPf r0) orbF => cgq hdg.
-rewrite root_factor_theorem=> rgx.
-move/coprimepP:cgq rqx rgx=> cgq; rewrite -!dvdpE=> /cgq hgq /hgq.
-by rewrite -size_poly_eq1 size_XsubC.
-Qed.
-
-Lemma cindex_mulCp a b p q c :
- cindex a b (c *: p) q = (sgz c) * cindex a b p q.
-Proof.
-have [lt_ab|le_ba] := ltrP a b; last by rewrite !cindexEba ?mulr0.
-have [->|p0] := eqVneq p 0; first by rewrite !(cindex0p, scaler0, mulr0).
-have [->|q0] := eqVneq q 0; first by rewrite !(cindexpC, scaler0, mulr0).
-by rewrite /cindex big_distrr; apply: congr_big => //= x; rewrite jump_mulCp.
-Qed.
-
-Lemma cindex_pmulC a b p q c :
- cindex a b p (c *: q) = (sgz c) * cindex a b p q.
-Proof.
-have [lt_ab|le_ba] := ltrP a b; last by rewrite !cindexEba ?mulr0.
-have [->|p0] := eqVneq p 0; first by rewrite !(cindex0p, scaler0, mulr0).
-have [->|q0] := eqVneq q 0; first by rewrite !(cindexpC, scaler0, mulr0).
-have [->|c0] := eqVneq c 0; first by rewrite scale0r sgz0 mul0r cindexpC.
-rewrite /cindex big_distrr rootsZ //.
-by apply: congr_big => // x _; rewrite jump_pmulC.
-Qed.
-
-Lemma cindex_mod a b p q :
- cindex a b p q =
- (sgz (lead_coef q) ^+ rscalp p q) * cindex a b (rmodp p q) q.
-Proof.
-have [lt_ab|le_ba] := ltrP a b; last by rewrite !cindexEba ?mulr0.
-by rewrite /cindex big_distrr; apply: congr_big => // x; rewrite jump_mod.
-Qed.
-
-Lemma variation0r b : variation 0 b = 0.
-Proof. by rewrite /variation mul0r ltrr mulr0. Qed.
-
-Lemma variationC a b : variation a b = - variation b a.
-Proof. by rewrite /variation -!sgz_cp0 !sgzM; do 2?case: sgzP => _ //. Qed.
-
-Lemma variationr0 a : variation a 0 = 0.
-Proof. by rewrite variationC variation0r oppr0. Qed.
-
-Lemma variation_pmull a b c : c > 0 -> variation (a * c) (b) = variation a b.
-Proof. by move=> c_gt0; rewrite /variation mulrAC pmulr_llt0. Qed.
-
-Lemma variation_pmulr a b c : c > 0 -> variation a (b * c) = variation a b.
-Proof. by move=> c_gt0; rewrite variationC variation_pmull // -variationC. Qed.
-
-Lemma congr_variation a b a' b' : sgz a = sgz a' -> sgz b = sgz b' ->
- variation a b = variation a' b'.
-Proof. by rewrite /variation -!sgz_cp0 !sgzM => -> ->. Qed.
-
-Lemma crossRP p a b :
- {in `]-oo, a], noroot p} -> {in `[b , +oo[, noroot p} ->
- cross p a b = crossR p.
-Proof.
-move=> rpa rpb; rewrite /crossR /cross.
-rewrite -(@sgp_minftyP _ _ _ rpa a) ?boundr_in_itv //.
-rewrite -(@sgp_pinftyP _ _ _ rpb b) ?boundl_in_itv //.
-by rewrite /variation -sgrM sgr_lt0 sgz_sgr.
-Qed.
-
-Lemma noroot_cross p a b : a <= b ->
- {in `]a, b[, noroot p} -> cross p a b = 0.
-Proof.
-move=> le_ab noroot_ab; rewrite /cross /variation.
-have [] := ltrP; last by rewrite mulr0.
-rewrite mulr1 -sgr_cp0 sgrM => /eqP.
-by move=> /(ivt_sign le_ab) [x /noroot_ab /negPf->].
-Qed.
-
-Lemma cross_pmul p q a b : q.[a] > 0 -> q.[b] > 0 ->
- cross (p * q) a b = cross p a b.
-Proof.
-by move=> qa0 qb0; rewrite /cross !hornerM variation_pmull ?variation_pmulr.
-Qed.
-
-Lemma cross0 a b : cross 0 a b = 0.
-Proof. by rewrite /cross !horner0 variation0r. Qed.
-
-Lemma crossR0 : crossR 0 = 0.
-Proof.
-by rewrite /crossR /sgp_minfty /sgp_pinfty lead_coef0 mulr0 sgr0 variationr0.
-Qed.
-
-Lemma cindex_seq_mids a b : a < b ->
- forall p q, p != 0 -> q != 0 -> coprimep p q ->
- cindex a b q p + cindex a b p q =
- sum_var (map (horner (p * q)) (seq_mids a (roots (p * q) a b) b)).
-Proof.
-move=> hab p q p0 q0 cpq; rewrite /cindex /sum_var 2!big_seq.
-have pq_neq0 : p * q != 0 by rewrite mulf_neq0.
-have pq_eq0 := negPf pq_neq0.
-have jumpP : forall (p q : {poly R}), p != 0 -> coprimep p q ->
- forall x, x \in roots p a b -> jump q p x = sjump (q * p) x.
- by move=> ? ? ? ? ?; move/root_roots=> ?; rewrite jump_coprime.
-rewrite !(eq_bigr _ (jumpP _ _ _ _))// 1?coprimep_sym// => {jumpP}.
-have sjumpC x : sjump (q * p) x = sjump (p * q) x by rewrite mulrC.
-rewrite -!big_seq (eq_bigr _ (fun x _ => sjumpC x)).
-rewrite -big_cat /= -(eq_big_perm _ (roots_mul_coprime _ _ _ _)) //=.
-move: {1 2 5}a hab (erefl (roots (p * q) a b)) => //=.
-elim: roots => {a} [|x s /= ihs] a hab /eqP.
- by rewrite big_cons !big_nil variation0r.
-rewrite roots_cons; case/and5P => _ xab /eqP hax hx /eqP hs.
-rewrite !big_cons variation0r add0r (ihs _ _ hs) ?(itvP xab) // => {ihs}.
-pose y := (head b s); pose ax := midf a x; pose xy := midf x y.
-rewrite (@sjump_neigh a b _ _ _ ax xy) ?inE ?midf_lte//=; last 2 first.
-+ by rewrite /prev_root pq_eq0 hax minr_l ?(itvP xab, midf_lte).
-+ have hy: y \in `]x, b].
- rewrite /y; case: s hs {y xy} => /= [|u s] hu.
- by rewrite boundr_in_itv /= ?(itvP xab).
- have /roots_in: u \in roots (p * q) x b by rewrite hu mem_head.
- by apply: subitvP; rewrite /= !lerr.
- by rewrite /next_root pq_eq0 hs maxr_l ?(itvP hy, midf_lte).
-move: @y @xy {hs}; rewrite /cross.
-by case: s => /= [|y l]; rewrite ?(big_cons, big_nil, variation0r, add0r).
-Qed.
-
-Lemma cindex_inv a b : a < b -> forall p q,
- ~~ root (p * q) a -> ~~ root (p * q) b ->
- cindex a b q p + cindex a b p q = cross (p * q) a b.
-Proof.
-move=> hab p q hpqa hpqb.
-have hlab: a <= b by apply: ltrW.
-wlog cpq: p q hpqa hpqb / coprimep p q => [hwlog|].
- have p0: p != 0 by apply: contraNneq hpqa => ->; rewrite mul0r rootC.
- have q0: q != 0 by apply: contraNneq hpqa => ->; rewrite mulr0 rootC.
- set p' := p; rewrite -(divpK (dvdp_gcdr p q)) -[p'](divpK (dvdp_gcdl p q)).
- rewrite !cindex_mul2r ?gcdp_eq0 ?(negPf p0) //.
- have ga0 : (gcdp p q).[a] != 0.
- apply: contra hpqa; rewrite -rootE -!dvdp_XsubCl => /dvdp_trans -> //.
- by rewrite dvdp_mulr ?dvdp_gcdl.
- have gb0 : (gcdp p q).[b] != 0.
- apply: contra hpqb; rewrite -rootE -!dvdp_XsubCl => /dvdp_trans -> //.
- by rewrite dvdp_mulr ?dvdp_gcdl.
- rewrite mulrACA -expr2 cross_pmul ?horner_exp ?exprn_even_gt0 ?ga0 ?gb0 //.
- apply: hwlog; rewrite ?coprimep_div_gcd ?p0 // rootM.
- + apply: contra hpqa; rewrite -!dvdp_XsubCl => /orP.
- case=> /dvdp_trans-> //; rewrite (dvdp_trans (divp_dvd _));
- by rewrite ?(dvdp_gcdl, dvdp_gcdr) ?(dvdp_mulIl, dvdp_mulIr).
- + apply: contra hpqb; rewrite -!dvdp_XsubCl => /orP.
- case=> /dvdp_trans-> //; rewrite (dvdp_trans (divp_dvd _));
- by rewrite ?(dvdp_gcdl, dvdp_gcdr) ?(dvdp_mulIl, dvdp_mulIr).
-have p0: p != 0 by apply: contraNneq hpqa => ->; rewrite mul0r rootC.
-have q0: q != 0 by apply: contraNneq hpqa => ->; rewrite mulr0 rootC.
-have pq0 : p * q != 0 by rewrite mulf_neq0.
-rewrite cindex_seq_mids // sum_varP /cross.
- apply: congr_variation; apply: (mulrIz (oner_neq0 R)); rewrite -!sgrEz.
- case hr: roots => [|c s] /=; apply: (@sgr_neighprN _ _ a b) => //;
- rewrite /neighpr /next_root ?(negPf pq0) maxr_l // hr mid_in_itv //=.
- by move/eqP: hr; rewrite roots_cons => /and5P [_ /itvP ->].
- rewrite -cats1 pairmap_cat /= cats1 map_rcons last_rcons.
- apply: (@sgr_neighplN _ _ a b) => //.
- rewrite /neighpl /prev_root (negPf pq0) minr_l //.
- by rewrite mid_in_itv //= last_roots_le.
-elim: roots {-2 6}a (erefl (roots (p * q) a b))
- {hpqa hpqb} hab hlab => {a} [|c s IHs] a Hs hab hlab /=.
- rewrite in_cons orbF eq_sym. (* ; set x := (X in _.[X]). *)
- by rewrite -rootE (@roots_nil _ _ a b) // mid_in_itv.
-move/eqP: Hs; rewrite roots_cons => /and5P [_ cab /eqP rac rc /eqP rcb].
-rewrite in_cons eq_sym -rootE negb_or (roots_nil _ rac) //=; last first.
- by rewrite mid_in_itv //= (itvP cab).
-by rewrite IHs // (itvP cab).
-Qed.
-
-Definition next_mod p q := - (lead_coef q ^+ rscalp p q) *: rmodp p q.
-
-Lemma next_mod0p q : next_mod 0 q = 0.
-Proof. by rewrite /next_mod rmod0p scaler0. Qed.
-
-Lemma cindex_rec a b : a < b -> forall p q,
- ~~ root (p * q) a -> ~~ root (p * q) b ->
- cindex a b q p = cross (p * q) a b + cindex a b (next_mod p q) q.
-Proof.
-move=> lt_ab p q rpqa rpqb; have [->|p0] := eqVneq p 0.
- by rewrite cindexpC next_mod0p cindex0p mul0r cross0 add0r.
-have [->|q0] := eqVneq q 0.
- by rewrite cindex0p cindexpC mulr0 cross0 add0r.
-have /(canRL (addrK _)) -> := cindex_inv lt_ab rpqa rpqb.
-by rewrite cindex_mulCp cindex_mod sgzN mulNr sgzX.
-Qed.
-
-Lemma cindexR_rec p q :
- cindexR q p = crossR (p * q) + cindexR (next_mod p q) q.
-Proof.
-have [->|p_neq0] := eqVneq p 0.
- by rewrite cindexRpC mul0r next_mod0p cindexR0p crossR0.
-have [->|q_neq0] := eqVneq q 0.
- by rewrite cindexR0p mulr0 crossR0 cindexRpC.
-have pq_neq0 : p * q != 0 by rewrite mulf_neq0.
-pose b := cauchy_bound (p * q).
-have [lecb gecb] := pair (le_cauchy_bound pq_neq0) (ge_cauchy_bound pq_neq0).
-rewrite -?(@cindexRP _ _ (-b) b); do ?
- by [move=> x Hx /=; have: ~~ root (p * q) x by [apply: lecb|apply: gecb];
- rewrite rootM => /norP []].
-rewrite -(@crossRP _ (-b) b) 1?cindex_rec ?gt0_cp ?cauchy_bound_gt0 //.
- by rewrite lecb // boundr_in_itv.
-by rewrite gecb // boundl_in_itv.
-Qed.
-
-(* Computation of cindex through changes_mods *)
-
-Definition mods p q :=
- let fix aux p q n :=
- if n is m.+1
- then if p == 0 then [::] else p :: (aux q (next_mod p q) m)
- else [::] in aux p q (maxn (size p) (size q).+1).
-
-Lemma mods_rec p q : mods p q =
- if p == 0 then [::] else p :: (mods q (next_mod p q)).
-Proof.
-rewrite /mods; set aux := fix aux _ _ n := if n is _.+1 then _ else _.
-have aux0 u n : aux 0 u n = [::] by case: n => [//|n] /=; rewrite eqxx.
-pose m p q := maxn (size p) (size q).+1; rewrite -!/(m _ _).
-suff {p q} Hnext p q : q != 0 -> (m q (next_mod p q) < m p q)%N; last first.
- rewrite /m -maxnSS leq_max !geq_max !ltnS leqnn /= /next_mod.
- rewrite size_scale ?oppr_eq0 ?lcn_neq0 //=.
- by move=> q_neq0; rewrite ltn_rmodp ?q_neq0 ?orbT.
-suff {p q} m_gt0 p q : (0 < m p q)%N; last by rewrite leq_max orbT.
-rewrite -[m p q]prednK //=; have [//|p_neq0] := altP (p =P 0).
-have [->|q_neq0] := altP (q =P 0); first by rewrite !aux0.
-congr (_ :: _); suff {p q p_neq0 q_neq0} Haux p q n n' :
- (m p q <= n)%N -> (m p q <= n')%N -> aux p q n = aux p q n'.
- by apply: Haux => //; rewrite -ltnS prednK // Hnext.
-elim: n p q n' => [p q|n IHn p q n' Hn]; first by rewrite geq_max ltn0 andbF.
-case: n' => [|n' Hn' /=]; first by rewrite geq_max ltn0 andbF.
-have [//|p_neq0] := altP eqP; congr (_ :: _).
-have [->|q_neq0] := altP (q =P 0); first by rewrite !aux0.
-by apply: IHn; rewrite -ltnS (leq_trans _ Hn, leq_trans _ Hn') ?Hnext.
-Qed.
-
-Lemma mods_eq0 p q : (mods p q == [::]) = (p == 0).
-Proof. by rewrite mods_rec; have [] := altP (p =P 0). Qed.
-
-Lemma neq0_mods_rec p q : p != 0 -> mods p q = p :: mods q (next_mod p q).
-Proof. by rewrite mods_rec => /negPf ->. Qed.
-
-Lemma mods0p q : mods 0 q = [::].
-Proof. by apply/eqP; rewrite mods_eq0. Qed.
-
-Lemma modsp0 p : mods p 0 = if p == 0 then [::] else [::p].
-Proof. by rewrite mods_rec mods0p. Qed.
-
-Fixpoint changes (s : seq R) : nat :=
- (if s is a :: q then (a * (head 0 q) < 0)%R + changes q else 0)%N.
-
-Definition changes_pinfty (p : seq {poly R}) := changes (map lead_coef p).
-Definition changes_minfty (p : seq {poly R}) :=
- changes (map (fun p : {poly _} => (-1) ^+ (~~ odd (size p)) * lead_coef p) p).
-
-Definition changes_poly (p : seq {poly R}) :=
- (changes_minfty p)%:Z - (changes_pinfty p)%:Z.
-Definition changes_mods p q := changes_poly (mods p q).
-
-Lemma changes_mods0p q : changes_mods 0 q = 0.
-Proof. by rewrite /changes_mods /changes_poly mods0p. Qed.
-
-Lemma changes_modsp0 p : changes_mods p 0 = 0.
-Proof.
-rewrite /changes_mods /changes_poly modsp0; have [//|p_neq0] := altP eqP.
-by rewrite /changes_minfty /changes_pinfty /= !mulr0 ltrr.
-Qed.
-
-Lemma changes_mods_rec p q :
- changes_mods p q = crossR (p * q) + changes_mods q (next_mod p q).
-Proof.
-have [->|p0] := eqVneq p 0.
- by rewrite changes_mods0p mul0r crossR0 next_mod0p changes_modsp0.
-have [->|q0] := eqVneq q 0.
- by rewrite changes_modsp0 mulr0 crossR0 changes_mods0p.
-rewrite /changes_mods /changes_poly neq0_mods_rec //=.
-rewrite !PoszD opprD addrACA; congr (_ + _); rewrite neq0_mods_rec //=.
-rewrite /crossR /variation /sgp_pinfty /sgp_minfty.
-rewrite mulr_signM size_mul // !lead_coefM.
-rewrite polySpred // addSn [size q]polySpred // addnS /= !negbK.
-rewrite -odd_add signr_odd; set s := _ ^+ _.
-rewrite -!sgz_cp0 !(sgz_sgr, sgzM).
-have: s != 0 by rewrite signr_eq0.
-by move: p0 q0; rewrite -!lead_coef_eq0; do 3!case: sgzP=> _.
-Qed.
-
-Lemma changes_mods_cindex p q : changes_mods p q = cindexR q p.
-Proof.
-elim: mods {-2}p {-2}q (erefl (mods p q)) => [|r s IHs] {p q} p q hrpq.
- move/eqP: hrpq; rewrite mods_eq0 => /eqP ->.
- by rewrite changes_mods0p cindexRpC.
-rewrite changes_mods_rec cindexR_rec IHs //.
-by move: hrpq IHs; rewrite mods_rec; case: (p == 0) => // [] [].
-Qed.
-
-Definition taqR p q := changes_mods p (p^`() * q).
-
-Lemma taq_taqR p q : taq (rootsR p) q = taqR p q.
-Proof. by rewrite /taqR changes_mods_cindex taq_cindex. Qed.
-
-Section ChangesItvMod_USELESS.
-(* Not used anymore, but the content of this section is *)
-(* used in the LMCS 2012 paper and in Cyril's thesis *)
-
-Definition changes_horner (p : seq {poly R}) x :=
- changes (map (fun p => p.[x]) p).
-Definition changes_itv_poly a b (p : seq {poly R}) :=
- (changes_horner p a)%:Z - (changes_horner p b)%:Z.
-
-Definition changes_itv_mods a b p q := changes_itv_poly a b (mods p q).
-
-Lemma changes_itv_mods0p a b q : changes_itv_mods a b 0 q = 0.
-Proof.
-by rewrite /changes_itv_mods /changes_itv_poly mods0p /changes_horner /= subrr.
-Qed.
-
-Lemma changes_itv_modsp0 a b p : changes_itv_mods a b p 0 = 0.
-Proof.
-rewrite /changes_itv_mods /changes_itv_poly modsp0 /changes_horner /=.
-by have [//|p_neq0 /=] := altP eqP; rewrite !mulr0 ltrr.
-Qed.
-
-Lemma changes_itv_mods_rec a b : a < b -> forall p q,
- ~~ root (p * q) a -> ~~ root (p * q) b ->
- changes_itv_mods a b p q = cross (p * q) a b
- + changes_itv_mods a b q (next_mod p q).
-Proof.
-move=> lt_ab p q rpqa rpqb.
-have [->|p0] := eqVneq p 0.
- by rewrite changes_itv_mods0p mul0r next_mod0p changes_itv_modsp0 cross0.
-have [->|q0] := eqVneq q 0.
- by rewrite changes_itv_modsp0 mulr0 cross0 changes_itv_mods0p.
-rewrite /changes_itv_mods /changes_itv_poly /changes_horner neq0_mods_rec //=.
-rewrite !PoszD opprD addrACA; congr (_ + _); rewrite neq0_mods_rec //=.
-move: rpqa rpqb; rewrite -!hornerM !rootE; move: (p * q) => r {p q p0 q0}.
-by rewrite /cross /variation -![_ < _]sgz_cp0 sgzM; do 2!case: sgzP => _.
-Qed.
-
-Lemma changes_itv_mods_cindex a b : a < b -> forall p q,
- all (fun p => ~~ root p a) (mods p q) ->
- all (fun p => ~~ root p b) (mods p q) ->
- changes_itv_mods a b p q = cindex a b q p.
-Proof.
-move=> hab p q.
-elim: mods {-2}p {-2}q (erefl (mods p q)) => [|r s IHs] {p q} p q hrpq.
- move/eqP: hrpq; rewrite mods_eq0 => /eqP ->.
- by rewrite changes_itv_mods0p cindexpC.
-have p_neq0 : p != 0 by rewrite -(mods_eq0 p q) hrpq.
-move: hrpq IHs; rewrite neq0_mods_rec //.
-move=> [_ <-] IHs /= /andP[rpa Ha] /andP[rpb Hb].
-move=> /(_ _ _ (erefl _) Ha Hb) in IHs.
-have [->|q_neq0] := eqVneq q 0; first by rewrite changes_itv_modsp0 cindex0p.
-move: Ha Hb; rewrite neq0_mods_rec //= => /andP[rqa _] /andP[rqb _].
-rewrite cindex_rec 1?changes_itv_mods_rec;
-by rewrite ?rootM ?negb_or ?rpa ?rpb ?rqa ?rqb // IHs.
-Qed.
-
-Definition taq_itv a b p q := changes_itv_mods a b p (p^`() * q).
-
-Lemma taq_taq_itv a b : a < b -> forall p q,
- all (fun p => p.[a] != 0) (mods p (p^`() * q)) ->
- all (fun p => p.[b] != 0) (mods p (p^`() * q)) ->
- taq (roots p a b) q = taq_itv a b p q.
-Proof. by move=> *; rewrite /taq_itv changes_itv_mods_cindex // taq_cindex. Qed.
-
-End ChangesItvMod_USELESS.
-
-Definition tvecR p sq := let sg_tab := sg_tab (size sq) in
- \row_(i < 3^size sq) (taqR p (map (poly_comb sq) sg_tab)`_i).
-
-Lemma tvec_tvecR sq p : tvec (rootsR p) sq = tvecR p sq.
-Proof.
-by rewrite /tvec /tvecR; apply/matrixP=> i j; rewrite !mxE taq_taqR.
-Qed.
-
-Lemma all_prodn_gt0 : forall (I : finType) r (P : pred I) (F : I -> nat),
- (\prod_(i <- r | P i) F i > 0)%N ->
- forall i, i \in r -> P i -> (F i > 0)%N.
-Proof.
-move=> I r P F; elim: r => [_|a r hr] //.
-rewrite big_cons; case hPa: (P a).
- rewrite muln_gt0; case/andP=> Fa0; move/hr=> hF x.
- by rewrite in_cons; case/orP; [move/eqP-> | move/hF].
-move/hr=> hF x; rewrite in_cons; case/orP; last by move/hF.
-by move/eqP->; rewrite hPa.
-Qed.
-
-Definition taqsR p sq i : R :=
- (taqR p (map (poly_comb sq) (sg_tab (size sq)))`_i)%:~R.
-
-Definition ccount_weak p sq : R :=
- let fix aux s (i : nat) := if i is i'.+1
- then aux (taqsR p sq i' * coefs R (size sq) i' + s) i'
- else s in aux 0 (3 ^ size sq)%N.
-
-Lemma constraints1P (p : {poly R}) (sq : seq {poly R}) :
- (constraints (rootsR p) (sq) (nseq (size (sq)) 1))%:~R
- = ccount_weak p sq.
-Proof.
-rewrite constraints1_tvec; symmetry.
-rewrite castmxE mxE /= /ccount_weak.
-transitivity (\sum_(0 <= i < 3 ^ size sq) taqsR p sq i * coefs R (size sq) i).
- rewrite unlock /reducebig /= -foldr_map /= /index_iota subn0 foldr_map.
- elim: (3 ^ size sq)%N 0%R => [|n ihn] u //.
- by rewrite -[X in iota _ X]addn1 iota_add add0n /= foldr_cat ihn.
-rewrite big_mkord; apply: congr_big=> // i _.
-rewrite /taqsR /coefs /tvecR /=.
-have o : 'I_(3 ^ size sq) by rewrite exp3n; apply: ord0.
-rewrite (@nth_map _ o); last by rewrite size_enum_ord.
-by rewrite !castmxE !cast_ord_id !mxE /= nth_ord_enum taq_taqR.
-Qed.
-
-Lemma ccount_weakP p sq : p != 0 ->
- reflect (exists x, (p.[x] == 0) && \big[andb/true]_(q <- sq) (q.[x] > 0))
- (ccount_weak p sq > 0).
-Proof.
-move=> p_neq0; rewrite -constraints1P /constraints ltr0n lt0n.
-rewrite -(@pnatr_eq0 [numDomainType of int]) natr_sum psumr_eq0 //.
-rewrite -has_predC /=.
-apply: (iffP hasP) => [[x rpx /= prod_neq0]|[x /andP[rpx]]].
- exists x; rewrite -rootE [root _ _]roots_on_rootsR // rpx /=.
- rewrite big_seq big1 => // q Hq.
- move: prod_neq0; rewrite pnatr_eq0 -lt0n => /all_prodn_gt0.
- have := index_mem q sq; rewrite Hq => Hoq.
- pose oq := Ordinal Hoq => /(_ oq).
- rewrite mem_index_enum => /(_ isT isT) /=.
- by rewrite nth_nseq index_mem Hq nth_index // lt0b sgz_cp0.
-rewrite big_all => /allP Hsq.
-exists x => /=; first by rewrite -roots_on_rootsR.
-rewrite pnatr_eq0 -lt0n prodn_gt0 => // i; rewrite nth_nseq ltn_ord lt0b.
-by rewrite sgz_cp0 Hsq // mem_nth.
-Qed.
-
-Lemma myprodf_eq0 (S : idomainType)(I : eqType) (r : seq I) P (F : I -> S) :
- reflect (exists2 i, ((i \in r) && (P i)) & (F i == 0))
- (\prod_(i <- r| P i) F i == 0).
-Proof.
-apply: (iffP idP) => [|[i Pi /eqP Fi0]]; last first.
- by case/andP: Pi => ri Pi; rewrite (big_rem _ ri) /= Pi Fi0 mul0r.
-elim: r => [|i r IHr]; first by rewrite big_nil oner_eq0.
-rewrite big_cons /=; have [Pi | ?] := ifP.
- rewrite mulf_eq0; case/orP=> [Fi0|]; first by exists i => //; rewrite mem_head.
- by case/IHr=> j /andP [rj Pj] Fj; exists j; rewrite // in_cons rj orbT.
-by case/IHr=> j /andP [rj Pj] Fj; exists j; rewrite // in_cons rj orbT.
-Qed.
-
-Definition bounding_poly (sq : seq {poly R}) := (\prod_(q <- sq) q)^`().
-
-Lemma bounding_polyP (sq : seq {poly R}) :
- [\/ \big[andb/true]_(q <- sq) (lead_coef q > 0),
- \big[andb/true]_(q <- sq) ((-1)^+(size q).-1 * (lead_coef q) > 0) |
- exists x,
- ((bounding_poly sq).[x] == 0) && \big[andb/true]_(q <- sq) (q.[x] > 0)]
- <-> exists x, \big[andb/true]_(q <- sq) (q.[x] > 0).
-Proof.
-split=> [|[x]].
- case; last by move=> [x /andP [? h]]; exists x; rewrite h.
- rewrite big_all => /allP hsq.
- have sqn0 : {in sq, forall q, q != 0}.
- by move=> q' /= /hsq; apply: contraL=> /eqP->; rewrite lead_coef0 ltrr.
- pose qq := \prod_(q <- sq) q.
- have pn0 : qq != 0.
- by apply/negP=> /myprodf_eq0 [] q; rewrite andbT => /sqn0 /negPf ->.
- pose b := cauchy_bound qq; exists b.
- rewrite big_all; apply/allP=> r hr; have:= hsq r hr.
- rewrite -!sgr_cp0=> /eqP <-; apply/eqP.
- apply: (@sgp_pinftyP _ b); last by rewrite boundl_in_itv.
- move=> z Hz /=; have: ~~ root qq z by rewrite ge_cauchy_bound.
- by rewrite /root /qq horner_prod prodf_seq_neq0 => /allP /(_ _ hr).
- rewrite big_all => /allP hsq.
- have sqn0 : {in sq, forall q, q != 0}.
- move=> q' /= /hsq; apply: contraL=> /eqP->.
- by rewrite lead_coef0 mulr0 ltrr.
- pose qq := \prod_(q <- sq) q.
- have pn0 : qq != 0.
- by apply/negP=> /myprodf_eq0 [] q; rewrite andbT => /sqn0 /negPf ->.
- pose b := - cauchy_bound qq; exists b.
- rewrite big_all; apply/allP=> r hr; have:= hsq r hr.
- rewrite -!sgr_cp0=> /eqP <-; apply/eqP.
- apply: (@sgp_minftyP _ b); last by rewrite boundr_in_itv.
- move=> z Hz /=; have: ~~ root qq z by rewrite le_cauchy_bound.
- by rewrite /root /qq horner_prod prodf_seq_neq0 => /allP /(_ _ hr).
-rewrite /bounding_poly; set q := \prod_(q <- _) _.
-rewrite big_all => /allP hsq; set bnd := cauchy_bound q.
-have sqn0 : {in sq, forall q, q != 0}.
- by move=> q' /= /hsq; apply: contraL=> /eqP->; rewrite horner0 ltrr.
-have [/eqP|q_neq0] := eqVneq q 0.
- by rewrite prodf_seq_eq0=> /hasP [q' /= /sqn0 /negPf->].
-have genroot y : {in sq, forall r, ~~ root q y -> ~~ root r y}.
- rewrite /root /q => r r_sq.
- by rewrite horner_prod prodf_seq_neq0 => /allP /(_ _ r_sq).
-case: (next_rootP q x bnd) q_neq0; [by move->; rewrite eqxx| |]; last first.
- move=> _ q_neq0 _ Hq _.
- suff -> : \big[andb/true]_(q1 <- sq) (0 < lead_coef q1) by constructor.
- rewrite big_all; apply/allP=> r hr; have rxp := hsq r hr.
- rewrite -sgr_cp0 -/(sgp_pinfty _).
- rewrite -(@sgp_pinftyP _ x _ _ x) ?boundl_in_itv ?sgr_cp0 //.
- move=> z; rewrite (@itv_splitU _ x true) /= ?boundl_in_itv //.
- rewrite itv_xx /= inE => /orP [/eqP->|]; first by rewrite /root gtr_eqF.
- have [x_b|b_x] := ltrP x bnd.
- rewrite (@itv_splitU _ bnd false) /=; last by rewrite inE x_b.
- move=> /orP [] Hz; rewrite genroot //;
- by [rewrite Hq|rewrite ge_cauchy_bound].
- by move=> Hz; rewrite genroot // ge_cauchy_bound // (subitvP _ Hz) //= b_x.
-move=> y1 _ rqy1 hy1xb hy1.
-case: (prev_rootP q (- bnd) x); [by move->; rewrite eqxx| |]; last first.
- move=> _ q_neq0 _ Hq _. (* assia : what is the use of c ? *)
- suff -> : \big[andb/true]_(q1 <- sq) (0 < (-1) ^+ (size q1).-1 * lead_coef q1).
- by constructor 2.
- rewrite big_all; apply/allP=> r hr; have rxp := hsq r hr.
- rewrite -sgr_cp0 -/(sgp_minfty _).
- rewrite -(@sgp_minftyP _ x _ _ x) ?boundr_in_itv ?sgr_cp0 //.
- move=> z; rewrite (@itv_splitU _ x false) /= ?boundr_in_itv //.
- rewrite itv_xx => /orP [/=|/eqP->]; last by rewrite /root gtr_eqF.
- have [b_x|x_b] := ltrP (- bnd) x.
- rewrite (@itv_splitU _ (- bnd) true) /=; last by rewrite inE b_x.
- move=> /orP [] Hz; rewrite genroot //;
- by [rewrite Hq|rewrite le_cauchy_bound].
- by move=> Hz; rewrite genroot // le_cauchy_bound // (subitvP _ Hz) //= x_b.
-move=> y2 _ rqy2 hy2xb hy2 q_neq0.
-have lty12 : y2 < y1.
- by apply: (@ltr_trans _ x); rewrite 1?(itvP hy1xb) 1?(itvP hy2xb).
-have : q.[y2] = q.[y1] by rewrite rqy1 rqy2.
-case/(rolle lty12) => z hz rz; constructor 3; exists z.
-rewrite rz eqxx /= big_all; apply/allP => r r_sq.
-have xy : x \in `]y2, y1[ by rewrite inE 1?(itvP hy1xb) 1?(itvP hy2xb).
-rewrite -sgr_cp0 (@polyrN0_itv _ `]y2, y1[ _ _ x) ?sgr_cp0 ?hsq // => t.
-rewrite (@itv_splitU2 _ x) // => /or3P [/hy2|/eqP->|/hy1]; do ?exact: genroot.
-by rewrite rootE gtr_eqF ?hsq.
-Qed.
-
-Lemma size_prod_eq1 (sq : seq {poly R}) :
- reflect (forall q, q \in sq -> size q = 1%N) (size (\prod_(q0 <- sq) q0) == 1%N).
-Proof.
-apply: (iffP idP).
- elim: sq => [| q sq ih]; first by move=> _ q; rewrite in_nil.
- rewrite big_cons; case: (altP (q =P 0)) => [-> | qn0].
- by rewrite mul0r size_poly0.
- case: (altP ((\prod_(j <- sq) j) =P 0)) => [-> | pn0].
- by rewrite mulr0 size_poly0.
- rewrite size_mul //; case: (ltngtP (size q) 1).
- - by rewrite ltnS leqn0 size_poly_eq0 (negPf qn0).
- - case: (size q) => [|n] //; case: n => [|n] // _; rewrite !addSn /= eqSS.
- by rewrite addn_eq0 size_poly_eq0 (negPf pn0) andbF.
- - move=> sq1; case: (ltngtP (size (\prod_(j <- sq) j)) 1).
- + by rewrite ltnS leqn0 size_poly_eq0 (negPf pn0).
- + case: (size (\prod_(j <- sq) j)) => [|n] //; case: n => [|n] // _.
- by rewrite !addnS /= eqSS addn_eq0 size_poly_eq0 (negPf qn0).
- move=> sp1 _ p; rewrite in_cons; case/orP => [/eqP -> |] //; apply: ih.
- by apply/eqP.
-elim: sq => [| q sq ih] hs; first by rewrite big_nil size_poly1 eqxx.
-case: (altP (q =P 0)) => [ | qn0].
- by move/eqP; rewrite -size_poly_eq0 hs ?mem_head.
-case: (altP ((\prod_(q0 <- sq) q0) =P 0)) => [ | pn0].
- move/eqP; rewrite -size_poly_eq0 (eqP (ih _)) // => t ht; apply: hs.
- by rewrite in_cons ht orbT.
-rewrite big_cons size_mul // (eqP (ih _)) //; last first.
- by move=> t ht; apply: hs; rewrite in_cons ht orbT.
-by rewrite addnS addn0; apply/eqP; apply: hs; apply: mem_head.
-Qed.
-
-Definition ccount_gt0 (sp sq : seq {poly R}) :=
- let p := \big[@rgcdp _/0%R]_(p <- sp) p in
- if p != 0 then 0 < ccount_weak p sq
- else let bq := bounding_poly sq in
- [|| \big[andb/true]_(q <- sq)(lead_coef q > 0) ,
- \big[andb/true]_(q <- sq)((-1)^+(size q).-1 *(lead_coef q) > 0) |
- 0 < ccount_weak bq sq].
-
-Lemma ccount_gt0P (sp sq : seq {poly R}) :
- reflect (exists x, \big[andb/true]_(p <- sp) (p.[x] == 0)
- && \big[andb/true]_(q <- sq) (q.[x] > 0))
- (ccount_gt0 sp sq).
-Proof.
-rewrite /ccount_gt0; case: (boolP (_ == 0))=> hsp /=; last first.
- apply: (iffP (ccount_weakP _ _)) => // [] [x Hx]; exists x;
- by move: Hx; rewrite -rootE root_bigrgcd -big_all.
-apply: (@equivP (exists x, \big[andb/true]_(q <- sq) (0 < q.[x]))); last first.
- split=> [] [x Hx]; exists x; rewrite ?Hx ?andbT; do ?by case/andP: Hx.
- move: hsp; rewrite (big_morph _ (@rgcdp_eq0 _) (eqxx _)) !big_all.
- by move=> /allP Hsp; apply/allP => p /Hsp /eqP ->; rewrite horner0.
-have [|bq_neq0] := boolP (bounding_poly sq == 0).
- rewrite /bounding_poly -derivn1 -derivn_poly0 => ssq_le1.
- rewrite -constraints1P (size1_polyC ssq_le1) derivnC /= rootsRC.
- rewrite /constraints big_nil ltrr orbF.
- move: ssq_le1; rewrite leq_eqVlt ltnS leqn0 orbC.
- have [|_ /=] := boolP (_ == _).
- rewrite size_poly_eq0 => /eqP sq_eq0; move/eqP: (sq_eq0).
- rewrite prodf_seq_eq0 => /hasP /sig2W [q /= q_sq] /eqP q_eq0.
- move: q_sq; rewrite q_eq0 => sq0 _ {q q_eq0}.
- set f := _ || _; suff -> : f = false; move: @f => /=.
- constructor => [] [x]; rewrite big_all.
- by move=> /allP /(_ _ sq0); rewrite horner0 ltrr.
- apply: negbTE; rewrite !negb_or !big_all -!has_predC.
- apply/andP; split; apply/hasP;
- by exists 0; rewrite //= ?lead_coef0 ?mulr0 ltrr.
- move=> /size_prod_eq1 Hsq.
- have {Hsq} Hsq q : q \in sq -> q = (lead_coef q)%:P.
- by move=> /Hsq sq1; rewrite [q]size1_polyC ?sq1 // lead_coefC.
- apply: (@equivP (\big[andb/true]_(q <- sq) (0 < lead_coef q))); last first.
- split; [move=> sq0; exists 0; move: sq0|move=> [x]];
- rewrite !big_all => /allP H; apply/allP => q q_sq; have:= H _ q_sq;
- by rewrite [q]Hsq ?lead_coefC ?hornerC.
- have [] := boolP (\big[andb/true]_(q <- _) (0 < lead_coef q)).
- by constructor.
- rewrite !big_all -has_predC => /hasP sq0; apply: (iffP allP) => //=.
- move: sq0 => [q q_sq /= lq_gt0 /(_ _ q_sq)].
- rewrite [q]Hsq ?size_polyC ?lead_coefC //.
- by case: (_ != 0); rewrite /= expr0 mul1r ?(negPf lq_gt0).
-apply: (iffP or3P); rewrite -bounding_polyP;
-case; do ?by [constructor 1|constructor 2];
-by move/(ccount_weakP _ bq_neq0); constructor 3.
-Qed.
-
-End QeRcfTh.
diff --git a/mathcomp/real_closed/realalg.v b/mathcomp/real_closed/realalg.v
deleted file mode 100644
index 7d9d987..0000000
--- a/mathcomp/real_closed/realalg.v
+++ /dev/null
@@ -1,1537 +0,0 @@
-(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-(* Distributed under the terms of CeCILL-B. *)
-Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp
-Require Import ssrfun ssrbool eqtype ssrnat seq choice fintype.
-From mathcomp
-Require Import bigop ssralg ssrnum ssrint rat poly polydiv polyorder.
-From mathcomp
-Require Import perm matrix mxpoly polyXY binomial generic_quotient.
-From mathcomp
-Require Import cauchyreals separable zmodp bigenough.
-
-(*************************************************************************)
-(* This files constructs the real closure of an archimedian field in the *)
-(* way described in Cyril Cohen. Construction of real algebraic numbers *)
-(* in Coq. In Lennart Beringer and Amy Felty, editors, ITP - 3rd *)
-(* International Conference on Interactive Theorem Proving - 2012, *)
-(* Princeton, United States, August 2012. Springer *)
-(* *)
-(* The only definition one may want to use in this file is the operator *)
-(* {realclosure R} which constructs the real closure of the archimedian *)
-(* field R (for which rat is a prefect candidate) *)
-(*************************************************************************)
-
-Import GRing.Theory Num.Theory BigEnough.
-
-Set Implicit Arguments.
-Unset Strict Implicit.
-Unset Printing Implicit Defensive.
-
-Reserved Notation "{ 'realclosure' T }"
- (at level 0, format "{ 'realclosure' T }").
-Reserved Notation "{ 'alg' T }" (at level 0, format "{ 'alg' T }").
-
-Section extras.
-
-Local Open Scope ring_scope.
-Local Notation "p ^ f" := (map_poly f p) : ring_scope.
-
-Lemma map_comp_poly (aR : fieldType) (rR : idomainType)
- (f : {rmorphism aR -> rR})
- (p q : {poly aR}) : (p \Po q) ^ f = (p ^ f) \Po (q ^ f).
-Proof.
-rewrite !comp_polyE size_map_poly; apply: (big_ind2 (fun x y => x ^ f = y)).
-+ by rewrite rmorph0.
-+ by move=> u u' v v' /=; rewrite rmorphD /= => -> ->.
-move=> /= i _; rewrite -mul_polyC rmorphM /= map_polyC mul_polyC.
-by rewrite coef_map rmorphX.
-Qed.
-
-End extras.
-
-Module RealAlg.
-
-Local Open Scope ring_scope.
-Local Notation eval := horner_eval.
-
-Section RealAlg.
-
-Variable F : archiFieldType.
-Local Notation m0 := (fun _ => 0%N).
-
-(*********************************************************************)
-(* Construction of algebraic Cauchy reals : Cauchy real + polynomial *)
-(*********************************************************************)
-
-CoInductive algcreal := AlgCReal {
- creal_of_alg :> creal F;
- annul_creal : {poly F};
- _ : annul_creal \is monic;
- _ : (annul_creal.[creal_of_alg] == 0)%CR
-}.
-
-Lemma monic_annul_creal x : annul_creal x \is monic.
-Proof. by case: x. Qed.
-Hint Resolve monic_annul_creal.
-
-Lemma annul_creal_eq0 x : (annul_creal x == 0) = false.
-Proof. by rewrite (negPf (monic_neq0 _)). Qed.
-
-Lemma root_annul_creal x : ((annul_creal x).[x] == 0)%CR.
-Proof. by case: x. Qed.
-Hint Resolve root_annul_creal.
-
-Definition cst_algcreal (x : F) :=
- AlgCReal (monicXsubC _) (@root_cst_creal _ x).
-
-Local Notation zero_algcreal := (cst_algcreal 0).
-Local Notation one_algcreal := (cst_algcreal 1).
-
-Lemma size_annul_creal_gt1 (x : algcreal) :
- (1 < size (annul_creal x))%N.
-Proof.
-apply: (@has_root_creal_size_gt1 _ x).
- by rewrite monic_neq0 // monic_annul_creal.
-exact: root_annul_creal.
-Qed.
-
-Lemma is_root_annul_creal (x : algcreal) (y : creal F) :
- (x == y)%CR -> ((annul_creal x).[y] == 0)%CR.
-Proof. by move <-. Qed.
-
-Definition AlgCRealOf (p : {poly F}) (x : creal F)
- (p_neq0 : p != 0) (px_eq0 : (p.[x] == 0)%CR) :=
- AlgCReal (monic_monic_from_neq0 p_neq0) (root_monic_from_neq0 px_eq0).
-
-Lemma sub_annihilant_algcreal_neq0 (x y : algcreal) :
- sub_annihilant (annul_creal x) (annul_creal y) != 0.
-Proof. by rewrite sub_annihilant_neq0 ?monic_neq0. Qed.
-
-Lemma root_sub_algcreal (x y : algcreal) :
- ((sub_annihilant (annul_creal x) (annul_creal y)).[x - y] == 0)%CR.
-Proof. by rewrite root_sub_annihilant_creal ?root_annul_creal ?monic_neq0. Qed.
-
-Definition sub_algcreal (x y : algcreal) : algcreal :=
- AlgCRealOf (sub_annihilant_algcreal_neq0 x y) (@root_sub_algcreal x y).
-
-Lemma root_opp_algcreal (x : algcreal) :
- ((annul_creal (sub_algcreal (cst_algcreal 0) x)).[- x] == 0)%CR.
-Proof. by apply: is_root_annul_creal; rewrite /= add_0creal. Qed.
-
-Definition opp_algcreal (x : algcreal) : algcreal :=
- AlgCReal (@monic_annul_creal _) (@root_opp_algcreal x).
-
-Lemma root_add_algcreal (x y : algcreal) :
- ((annul_creal (sub_algcreal x (opp_algcreal y))).[x + y] == 0)%CR.
-Proof.
-apply: is_root_annul_creal; apply: eq_crealP.
-by exists m0=> * /=; rewrite opprK subrr normr0.
-Qed.
-
-Definition add_algcreal (x y : algcreal) : algcreal :=
- AlgCReal (@monic_annul_creal _) (@root_add_algcreal x y).
-
-Lemma div_annihilant_algcreal_neq0 (x y : algcreal) :
- (annul_creal y).[0] != 0 ->
- div_annihilant (annul_creal x) (annul_creal y) != 0.
-Proof. by move=> ?; rewrite div_annihilant_neq0 ?monic_neq0. Qed.
-
-Hint Resolve eq_creal_refl.
-Hint Resolve le_creal_refl.
-
-Lemma simplify_algcreal (x : algcreal) (x_neq0 : (x != 0)%CR) :
- {y | ((annul_creal y).[0] != 0) & ((y != 0)%CR * (x == y)%CR)%type}.
-Proof.
-elim: size {-3}x x_neq0 (leqnn (size (annul_creal x))) =>
- {x} [|n ihn] x x_neq0 hx.
- by move: hx; rewrite leqn0 size_poly_eq0 annul_creal_eq0.
-have [dvdX|ndvdX] := boolP ('X %| annul_creal x); last first.
- by exists x=> //; rewrite -rootE -dvdp_XsubCl subr0.
-have monic_p: @annul_creal x %/ 'X \is monic.
- by rewrite -(monicMr _ (@monicX _)) divpK //.
-have root_p: ((@annul_creal x %/ 'X).[x] == 0)%CR.
- have := @eq_creal_refl _ ((annul_creal x).[x])%CR.
- rewrite -{1}(divpK dvdX) horner_crealM // root_annul_creal.
- by case/poly_mul_creal_eq0=> //; rewrite horner_crealX.
-have [//|/=|y *] := ihn (AlgCReal monic_p root_p); last by exists y.
-by rewrite size_divp ?size_polyX ?polyX_eq0 ?leq_subLR ?add1n.
-Qed.
-
-(* Decidability of equality to 0 *)
-Lemma algcreal_eq0_dec (x : algcreal) : {(x == 0)%CR} + {(x != 0)%CR}.
-Proof.
-pose p := annul_creal x; move: {2}(size _)%N (leqnn (size p))=> n.
-elim: n x @p => [x p|n ihn x p le_sp_Sn].
- by rewrite leqn0 size_poly_eq0 /p annul_creal_eq0.
-move: le_sp_Sn; rewrite leq_eqVlt; have [|//|eq_sp_Sn _] := ltngtP.
- by rewrite ltnS=> /ihn ihnp _; apply: ihnp.
-have px0 : (p.[x] == 0)%CR by apply: root_annul_creal.
-have [cpX|ncpX] := boolP (coprimep p 'X).
- by right; move: (cpX)=> /coprimep_root /(_ px0); rewrite horner_crealX.
-have [eq_pX|] := altP (p =P 'X).
- by left; move: px0; rewrite eq_pX horner_crealX.
-rewrite -eqp_monic /p ?monicX // negb_and orbC.
-have:= ncpX; rewrite coprimepX -dvdp_XsubCl subr0 => /negPf-> /= ndiv_pX.
-have [r] := smaller_factor (monic_annul_creal _) px0 ndiv_pX ncpX.
-rewrite eq_sp_Sn ltnS => /andP[le_r_n monic_r] rx_eq0.
-exact: (ihn (AlgCReal monic_r rx_eq0)).
-Qed.
-
-Lemma eq_algcreal_dec (x y : algcreal) : {(x == y)%CR} + {(x != y)%CR}.
-Proof.
-have /= [d_eq0|d_neq0] := algcreal_eq0_dec (sub_algcreal x y); [left|right].
- apply: eq_crealP; exists_big_modulus m F.
- by move=> e i e_gt0 hi; rewrite (@eq0_modP _ _ d_eq0).
- by close.
-pose_big_enough i.
- apply: (@neq_crealP _ (lbound d_neq0) i i); do ?by rewrite ?lbound_gt0.
- by rewrite (@lbound0P _ _ d_neq0).
-by close.
-Qed.
-
-Definition eq_algcreal : rel algcreal := eq_algcreal_dec.
-
-Lemma eq_algcrealP (x y : algcreal) : reflect (x == y)%CR (eq_algcreal x y).
-Proof. by rewrite /eq_algcreal; case: eq_algcreal_dec=> /=; constructor. Qed.
-Arguments eq_algcrealP [x y].
-
-Lemma neq_algcrealP (x y : algcreal) : reflect (x != y)%CR (~~ eq_algcreal x y).
-Proof. by rewrite /eq_algcreal; case: eq_algcreal_dec=> /=; constructor. Qed.
-Arguments neq_algcrealP [x y].
-Prenex Implicits eq_algcrealP neq_algcrealP.
-
-Fact eq_algcreal_is_equiv : equiv_class_of eq_algcreal.
-Proof.
-split=> [x|x y|y x z]; first by apply/eq_algcrealP.
- by apply/eq_algcrealP/eq_algcrealP; symmetry.
-by move=> /eq_algcrealP /eq_creal_trans h /eq_algcrealP /h /eq_algcrealP.
-Qed.
-
-Canonical eq_algcreal_rel := EquivRelPack eq_algcreal_is_equiv.
-
-Lemma root_div_algcreal (x y : algcreal) (y_neq0 : (y != 0)%CR) :
- (annul_creal y).[0] != 0 ->
- ((div_annihilant (annul_creal x) (annul_creal y)).[x / y_neq0] == 0)%CR.
-Proof. by move=> hx; rewrite root_div_annihilant_creal ?monic_neq0. Qed.
-
-Definition div_algcreal (x y : algcreal) :=
- match eq_algcreal_dec y (cst_algcreal 0) with
- | left y_eq0 => cst_algcreal 0
- | right y_neq0 =>
- let: exist2 y' py'0_neq0 (y'_neq0, _) := simplify_algcreal y_neq0 in
- AlgCRealOf (div_annihilant_algcreal_neq0 x py'0_neq0)
- (@root_div_algcreal x y' y'_neq0 py'0_neq0)
- end.
-
-Lemma root_inv_algcreal (x : algcreal) (x_neq0 : (x != 0)%CR) :
- ((annul_creal (div_algcreal (cst_algcreal 1) x)).[x_neq0^-1] == 0)%CR.
-Proof.
-rewrite /div_algcreal; case: eq_algcreal_dec=> [/(_ x_neq0)|x_neq0'] //=.
-case: simplify_algcreal=> x' px'0_neq0 [x'_neq0 eq_xx'].
-apply: is_root_annul_creal; rewrite /= -(@eq_creal_inv _ _ _ x_neq0) //.
-by apply: eq_crealP; exists m0=> * /=; rewrite div1r subrr normr0.
-Qed.
-
-Definition inv_algcreal (x : algcreal) :=
- match eq_algcreal_dec x (cst_algcreal 0) with
- | left x_eq0 => cst_algcreal 0
- | right x_neq0 =>
- AlgCReal (@monic_annul_creal _) (@root_inv_algcreal _ x_neq0)
- end.
-
-Lemma div_creal_creal (y : creal F) (y_neq0 : (y != 0)%CR) :
- (y / y_neq0 == 1%:CR)%CR.
-Proof.
-apply: eq_crealP; exists_big_modulus m F.
- move=> e i e_gt0 hi; rewrite /= divff ?subrr ?normr0 //.
- by rewrite (@creal_neq_always _ _ 0%CR).
-by close.
-Qed.
-
-Lemma root_mul_algcreal (x y : algcreal) :
- ((annul_creal (div_algcreal x (inv_algcreal y))).[x * y] == 0)%CR.
-Proof.
-rewrite /div_algcreal /inv_algcreal.
-case: (eq_algcreal_dec y)=> [->|y_neq0]; apply: is_root_annul_creal.
- rewrite mul_creal0; case: eq_algcreal_dec=> // neq_00.
- by move: (eq_creal_refl neq_00).
-case: eq_algcreal_dec=> /= [yV_eq0|yV_neq0].
- have: (y * y_neq0^-1 == 0)%CR by rewrite yV_eq0 mul_creal0.
- by rewrite div_creal_creal=> /eq_creal_cst; rewrite oner_eq0.
-case: simplify_algcreal=> y' py'0_neq0 [y'_neq0 /= eq_yy'].
-rewrite -(@eq_creal_inv _ _ _ yV_neq0) //.
-by apply: eq_crealP; exists m0=> * /=; rewrite invrK subrr normr0.
-Qed.
-
-Definition mul_algcreal (x y : algcreal) :=
- AlgCReal (@monic_annul_creal _) (@root_mul_algcreal x y).
-
-Lemma le_creal_neqVlt (x y : algcreal) : (x <= y)%CR -> {(x == y)%CR} + {(x < y)%CR}.
-Proof.
-case: (eq_algcreal_dec x y); first by left.
-by move=> /neq_creal_ltVgt [|h /(_ h) //]; right.
-Qed.
-
-Lemma ltVge_algcreal_dec (x y : algcreal) : {(x < y)%CR} + {(y <= x)%CR}.
-Proof.
-have [eq_xy|/neq_creal_ltVgt [lt_xy|lt_yx]] := eq_algcreal_dec x y;
-by [right; rewrite eq_xy | left | right; apply: lt_crealW].
-Qed.
-
-Definition lt_algcreal : rel algcreal := ltVge_algcreal_dec.
-Definition le_algcreal : rel algcreal := fun x y => ~~ ltVge_algcreal_dec y x.
-
-Lemma lt_algcrealP (x y : algcreal) : reflect (x < y)%CR (lt_algcreal x y).
-Proof. by rewrite /lt_algcreal; case: ltVge_algcreal_dec; constructor. Qed.
-Arguments lt_algcrealP [x y].
-
-Lemma le_algcrealP (x y : algcreal) : reflect (x <= y)%CR (le_algcreal x y).
-Proof. by rewrite /le_algcreal; case: ltVge_algcreal_dec; constructor. Qed.
-Arguments le_algcrealP [x y].
-Prenex Implicits lt_algcrealP le_algcrealP.
-
-Definition exp_algcreal x n := iterop n mul_algcreal x one_algcreal.
-
-Lemma exp_algcrealE x n : (exp_algcreal x n == x ^+ n)%CR.
-Proof.
-case: n=> // n; rewrite /exp_algcreal /exp_creal !iteropS.
-by elim: n=> //= n ->.
-Qed.
-
-Definition horner_algcreal (p : {poly F}) x : algcreal :=
- \big[add_algcreal/zero_algcreal]_(i < size p)
- mul_algcreal (cst_algcreal p`_i) (exp_algcreal x i).
-
-Lemma horner_algcrealE p x : (horner_algcreal p x == p.[x])%CR.
-Proof.
-rewrite horner_coef_creal.
-apply: (big_ind2 (fun (u : algcreal) v => u == v)%CR)=> //.
- by move=> u u' v v' /= -> ->.
-by move=> i _ /=; rewrite exp_algcrealE.
-Qed.
-
-Definition norm_algcreal (x : algcreal) :=
- if le_algcreal zero_algcreal x then x else opp_algcreal x.
-
-Lemma norm_algcrealE (x : algcreal) : (norm_algcreal x == `| x |)%CR.
-Proof.
-rewrite /norm_algcreal /le_algcreal; case: ltVge_algcreal_dec => /=.
- move=> x_lt0; apply: eq_crealP; exists_big_modulus m F.
- move=> e i e_gt0 hi /=; rewrite [`|x i|]ler0_norm ?subrr ?normr0 //.
- by rewrite ltrW // [_ < 0%CR i]creal_lt_always.
- by close.
-move=> /(@le_creal_neqVlt zero_algcreal) /= [].
- by move<-; apply: eq_crealP; exists m0=> * /=; rewrite !(normr0, subrr).
-move=> x_gt0; apply: eq_crealP; exists_big_modulus m F.
- move=> e i e_gt0 hi /=; rewrite [`|x i|]ger0_norm ?subrr ?normr0 //.
- by rewrite ltrW // creal_gt0_always.
-by close.
-Qed.
-
-(**********************************************************************)
-(* Theory of the "domain" of algebraic numbers: polynomial + interval *)
-(**********************************************************************)
-CoInductive algdom := AlgDom {
- annul_algdom : {poly F};
- center_alg : F;
- radius_alg : F;
- _ : annul_algdom \is monic;
- _ : radius_alg >= 0;
- _ : annul_algdom.[center_alg - radius_alg]
- * annul_algdom.[center_alg + radius_alg] <= 0
-}.
-
-Lemma radius_alg_ge0 x : 0 <= radius_alg x. Proof. by case: x. Qed.
-
-Lemma monic_annul_algdom x : annul_algdom x \is monic. Proof. by case: x. Qed.
-Hint Resolve monic_annul_algdom.
-
-Lemma annul_algdom_eq0 x : (annul_algdom x == 0) = false.
-Proof. by rewrite (negPf (monic_neq0 _)). Qed.
-
-Lemma algdomP x : (annul_algdom x).[center_alg x - radius_alg x]
- * (annul_algdom x).[center_alg x + radius_alg x] <= 0.
-Proof. by case: x. Qed.
-
-Definition algdom' := seq F.
-
-Definition encode_algdom (x : algdom) : algdom' :=
- [:: center_alg x, radius_alg x & (annul_algdom x)].
-
-Definition decode_algdom (x : algdom') : option algdom :=
- if x is [::c, r & p']
- then let p := Poly p' in
- if ((p \is monic) =P true, (r >= 0) =P true,
- (p.[c - r] * p.[c + r] <= 0) =P true)
- is (ReflectT monic_p, ReflectT r_gt0, ReflectT hp)
- then Some (AlgDom monic_p r_gt0 hp)
- else None
- else None.
-
-Lemma encode_algdomK : pcancel encode_algdom decode_algdom.
-Proof.
-case=> p c r monic_p r_ge0 hp /=; rewrite polyseqK.
-do 3?[case: eqP; rewrite ?monic_p ?r_ge0 ?monic_p //] => monic_p' r_ge0' hp'.
-by congr (Some (AlgDom _ _ _)); apply: bool_irrelevance.
-Qed.
-
-Definition algdom_EqMixin := PcanEqMixin encode_algdomK.
-Canonical algdom_eqType := EqType algdom algdom_EqMixin.
-
-Definition algdom_ChoiceMixin := PcanChoiceMixin encode_algdomK.
-Canonical algdom_choiceType := ChoiceType algdom algdom_ChoiceMixin.
-
-Fixpoint to_algcreal_of (p : {poly F}) (c r : F) (i : nat) : F :=
- match i with
- | 0 => c
- | i.+1 =>
- let c' := to_algcreal_of p c r i in
- if p.[c' - r / 2%:R ^+ i] * p.[c'] <= 0
- then c' - r / 2%:R ^+ i.+1
- else c' + r / 2%:R ^+ i.+1
- end.
-
-
-Lemma to_algcreal_of_recP p c r i : 0 <= r ->
- `|to_algcreal_of p c r i.+1 - to_algcreal_of p c r i| <= r * 2%:R ^- i.+1.
-Proof.
-move=> r_ge0 /=; case: ifP=> _; rewrite addrAC subrr add0r ?normrN ger0_norm //;
-by rewrite mulr_ge0 ?invr_ge0 ?exprn_ge0 ?ler0n.
-Qed.
-
-Lemma to_algcreal_ofP p c r i j : 0 <= r -> (i <= j)%N ->
- `|to_algcreal_of p c r j - to_algcreal_of p c r i| <= r * 2%:R ^- i.
-Proof.
-move=> r_ge0 leij; pose r' := r * 2%:R ^- j * (2%:R ^+ (j - i) - 1).
-rewrite (@ler_trans _ r') //; last first.
- rewrite /r' -mulrA ler_wpmul2l // ler_pdivr_mull ?exprn_gt0 ?ltr0n //.
- rewrite -{2}(subnK leij) exprD mulfK ?gtr_eqF ?exprn_gt0 ?ltr0n //.
- by rewrite ger_addl lerN10.
-rewrite /r' subrX1 addrK mul1r -{1 2}(subnK leij); set f := _ c r.
-elim: (_ - _)%N=> [|k ihk]; first by rewrite subrr normr0 big_ord0 mulr0 lerr.
-rewrite addSn big_ord_recl /= mulrDr.
-rewrite (ler_trans (ler_dist_add (f (k + i)%N) _ _)) //.
-rewrite ler_add ?expr0 ?mulr1 ?to_algcreal_of_recP // (ler_trans ihk) //.
-rewrite exprSr invfM -!mulrA !ler_wpmul2l ?invr_ge0 ?exprn_ge0 ?ler0n //.
-by rewrite mulr_sumr ler_sum // => l _ /=; rewrite exprS mulKf ?pnatr_eq0.
-Qed.
-
-Lemma alg_to_crealP (x : algdom) :
- creal_axiom (to_algcreal_of (annul_algdom x) (center_alg x) (radius_alg x)).
-Proof.
-pose_big_modulus m F.
- exists m=> e i j e_gt0 hi hj.
- wlog leij : i j {hi} hj / (j <= i)%N.
- move=> hwlog; case/orP: (leq_total i j)=> /hwlog; last exact.
- by rewrite distrC; apply.
- rewrite (ler_lt_trans (to_algcreal_ofP _ _ _ _)) ?radius_alg_ge0 //.
- rewrite ltr_pdivr_mulr ?gtr0E // -ltr_pdivr_mull //.
- by rewrite upper_nthrootP.
-by close.
-Qed.
-
-Definition alg_to_creal x := CReal (alg_to_crealP x).
-
-Lemma exp2k_crealP : @creal_axiom F (fun i => 2%:R ^- i).
-Proof.
-pose_big_modulus m F.
- exists m=> e i j e_gt0 hi hj.
- wlog leij : i j {hj} hi / (i <= j)%N.
- move=> hwlog; case/orP: (leq_total i j)=> /hwlog; first exact.
- by rewrite distrC; apply.
- rewrite ger0_norm ?subr_ge0; last first.
- by rewrite ?lef_pinv -?topredE /= ?gtr0E // ler_eexpn2l ?ltr1n.
- rewrite -(@ltr_pmul2l _ (2%:R ^+ i )) ?gtr0E //.
- rewrite mulrBr mulfV ?gtr_eqF ?gtr0E //.
- rewrite (@ler_lt_trans _ 1) // ?ger_addl ?oppr_le0 ?mulr_ge0 ?ger0E //.
- by rewrite -ltr_pdivr_mulr // mul1r upper_nthrootP.
-by close.
-Qed.
-Definition exp2k_creal := CReal exp2k_crealP.
-
-Lemma exp2k_creal_eq0 : (exp2k_creal == 0)%CR.
-Proof.
-apply: eq_crealP; exists_big_modulus m F.
- move=> e i e_gt0 hi /=.
- rewrite subr0 gtr0_norm ?gtr0E // -ltf_pinv -?topredE /= ?gtr0E //.
- by rewrite invrK upper_nthrootP.
-by close.
-Qed.
-
-Notation lbound0_of p := (@lbound0P _ _ p _ _ _).
-
-Lemma to_algcrealP (x : algdom) : ((annul_algdom x).[alg_to_creal x] == 0)%CR.
-Proof.
-set u := alg_to_creal _; set p := annul_algdom _.
-pose r := radius_alg x; pose cr := cst_creal r.
-have: ((p).[u - cr * exp2k_creal] * (p).[u + cr * exp2k_creal] <= 0)%CR.
- apply: (@le_crealP _ 0%N)=> i _ /=.
- rewrite -/p -/r; set c := center_alg _.
- elim: i=> /= [|i].
- by rewrite !expr0 divr1 algdomP.
- set c' := to_algcreal_of _ _ _=> ihi.
- have [] := lerP (_ * p.[c' i]).
- rewrite addrNK -addrA -opprD -mulr2n -[_ / _ *+ _]mulr_natr.
- by rewrite -mulrA exprSr invfM mulfVK ?pnatr_eq0.
- rewrite addrK -addrA -mulr2n -[_ / _ *+ _]mulr_natr.
- rewrite -mulrA exprSr invfM mulfVK ?pnatr_eq0 // => /ler_pmul2l<-.
- rewrite mulr0 mulrCA !mulrA [X in X * _]mulrAC -mulrA.
- by rewrite mulr_ge0_le0 // -expr2 exprn_even_ge0.
-rewrite exp2k_creal_eq0 mul_creal0 opp_creal0 add_creal0.
-move=> hu pu0; apply: hu; pose e := (lbound pu0).
-pose_big_enough i.
- apply: (@lt_crealP _ (e * e) i i) => //.
- by rewrite !pmulr_rgt0 ?invr_gt0 ?ltr0n ?lbound_gt0.
- rewrite add0r [u]lock /= -!expr2.
- rewrite -[_.[_] ^+ _]ger0_norm ?exprn_even_ge0 // normrX.
- rewrite ler_pexpn2r -?topredE /= ?lbound_ge0 ?normr_ge0 //.
- by rewrite -lock (ler_trans _ (lbound0_of pu0)).
-by close.
-Qed.
-
-Definition to_algcreal_rec (x : algdom) :=
- AlgCReal (monic_annul_algdom x) (@to_algcrealP x).
-(* "Encoding" function from algdom to algcreal *)
-Definition to_algcreal := locked to_algcreal_rec.
-
-(* "Decoding" function, constructed interactively *)
-Lemma to_algdom_exists (x : algcreal) :
- { y : algdom | (to_algcreal y == x)%CR }.
-Proof.
-pose p := annul_creal x.
-move: {2}(size p) (leqnn (size p))=> n.
-elim: n x @p=> [x p|n ihn x p le_sp_Sn].
- by rewrite leqn0 size_poly_eq0 /p annul_creal_eq0.
-move: le_sp_Sn; rewrite leq_eqVlt.
-have [|//|eq_sp_Sn _] := ltngtP.
- by rewrite ltnS=> /ihn ihnp _; apply: ihnp.
-have px0 := @root_annul_creal x; rewrite -/p -/root in px0.
-have [|ncop] := boolP (coprimep p p^`()).
- move/coprimep_root => /(_ _ px0) /deriv_neq0_mono [r r_gt0 [i ir sm]].
- have p_chg_sign : p.[x i - r] * p.[x i + r] <= 0.
- have [/accr_pos_incr hp|/accr_neg_decr hp] := sm.
- have hpxj : forall j, (i <= j)%N ->
- (p.[x i - r] <= p.[x j]) * (p.[x j] <= p.[x i + r]).
- move=> j hj.
- suff: p.[x i - r] <= p.[x j] <= p.[x i + r] by case/andP=> -> ->.
- rewrite !hp 1?addrAC ?subrr ?add0r ?normrN;
- rewrite ?(gtr0_norm r_gt0) //;
- do ?by rewrite ltrW ?cauchymodP ?(leq_trans _ hj).
- by rewrite -ler_distl ltrW ?cauchymodP ?(leq_trans _ hj).
- rewrite mulr_le0_ge0 //; apply/le_creal_cst; rewrite -px0;
- by apply: (@le_crealP _ i)=> h hj /=; rewrite hpxj.
- have hpxj : forall j, (i <= j)%N ->
- (p.[x i + r] <= p.[x j]) * (p.[x j] <= p.[x i - r]).
- move=> j hj.
- suff: p.[x i + r] <= p.[x j] <= p.[x i - r] by case/andP=> -> ->.
- rewrite !hp 1?addrAC ?subrr ?add0r ?normrN;
- rewrite ?(gtr0_norm r_gt0) //;
- do ?by rewrite ltrW ?cauchymodP ?(leq_trans _ hj).
- by rewrite andbC -ler_distl ltrW ?cauchymodP ?(leq_trans _ hj).
- rewrite mulr_ge0_le0 //; apply/le_creal_cst; rewrite -px0;
- by apply: (@le_crealP _ i)=> h hj /=; rewrite hpxj.
- pose y := (AlgDom (monic_annul_creal x) (ltrW r_gt0) p_chg_sign).
- have eq_py_px: (p.[to_algcreal y] == p.[x])%CR.
- rewrite /to_algcreal -lock.
- by have := @to_algcrealP y; rewrite /= -/p=> ->; apply: eq_creal_sym.
- exists y.
- move: sm=> /strong_mono_bound [k k_gt0 hk].
- rewrite -/p; apply: eq_crealP.
- exists_big_modulus m F.
- move=> e j e_gt0 hj; rewrite (ler_lt_trans (hk _ _ _ _)) //.
- + rewrite /to_algcreal -lock.
- rewrite (ler_trans (to_algcreal_ofP _ _ _ (leq0n _))) ?(ltrW r_gt0) //.
- by rewrite expr0 divr1.
- + by rewrite ltrW // cauchymodP.
- rewrite -ltr_pdivl_mull //.
- by rewrite (@eq_modP _ _ _ eq_py_px) // ?pmulr_rgt0 ?invr_gt0.
- by close.
-case: (@smaller_factor _ p p^`() x); rewrite ?monic_annul_creal //.
- rewrite gtNdvdp // -?size_poly_eq0 size_deriv eq_sp_Sn //=.
- apply: contra ncop=> /eqP n_eq0; move: eq_sp_Sn; rewrite n_eq0.
- by move=> /eqP /size_poly1P [c c_neq0 ->]; rewrite derivC coprimep0 polyC_eqp1.
-move=> r /andP [hsr monic_r rx_eq0].
-apply: (ihn (AlgCReal monic_r rx_eq0))=> /=.
-by rewrite -ltnS -eq_sp_Sn.
-Qed.
-
-Definition to_algdom x := projT1 (to_algdom_exists x).
-
-Lemma to_algdomK x : (to_algcreal (to_algdom x) == x)%CR.
-Proof. by rewrite /to_algdom; case: to_algdom_exists. Qed.
-
-Lemma eq_algcreal_to_algdom x : eq_algcreal (to_algcreal (to_algdom x)) x.
-Proof. by apply/eq_algcrealP; apply: to_algdomK. Qed.
-
-(* Explicit encoding to a choice type *)
-Canonical eq_algcreal_encModRel := EncModRel eq_algcreal eq_algcreal_to_algdom.
-
-Local Open Scope quotient_scope.
-
-(***************************************************************************)
-(* Algebraic numbers are the quotient of algcreal by their setoid equality *)
-(***************************************************************************)
-Definition alg := {eq_quot eq_algcreal}.
-
-Definition alg_of of (phant F) := alg.
-Identity Coercion type_alg_of : alg_of >-> alg.
-
-Notation "{ 'alg' F }" := (alg_of (Phant F)).
-
-(* A lot of structure is inherited *)
-Canonical alg_eqType := [eqType of alg].
-Canonical alg_choiceType := [choiceType of alg].
-Canonical alg_quotType := [quotType of alg].
-Canonical alg_eqQuotType := [eqQuotType eq_algcreal of alg].
-Canonical alg_of_eqType := [eqType of {alg F}].
-Canonical alg_of_choiceType := [choiceType of {alg F}].
-Canonical alg_of_quotType := [quotType of {alg F}].
-Canonical alg_of_eqQuotType := [eqQuotType eq_algcreal of {alg F}].
-
-Definition to_alg_def (phF : phant F) : F -> {alg F} :=
- lift_embed {alg F} cst_algcreal.
-Notation to_alg := (@to_alg_def (Phant F)).
-Notation "x %:RA" := (to_alg x)
- (at level 2, left associativity, format "x %:RA").
-Local Notation "p ^ f" := (map_poly f p) : ring_scope.
-
-Canonical to_alg_pi_morph := PiEmbed to_alg.
-
-Local Notation zero_alg := 0%:RA.
-Local Notation one_alg := 1%:RA.
-
-Lemma equiv_alg (x y : algcreal) : (x == y)%CR <-> (x = y %[mod {alg F}]).
-Proof.
-split; first by move=> /eq_algcrealP /eqquotP ->.
-by move=> /eqquotP /eq_algcrealP.
-Qed.
-
-Lemma nequiv_alg (x y : algcreal) : reflect (x != y)%CR (x != y %[mod {alg F}]).
-Proof. by rewrite eqquotE; apply: neq_algcrealP. Qed.
-Arguments nequiv_alg [x y].
-Prenex Implicits nequiv_alg.
-
-Lemma pi_algK (x : algcreal) : (repr (\pi_{alg F} x) == x)%CR.
-Proof. by apply/equiv_alg; rewrite reprK. Qed.
-
-Definition add_alg := lift_op2 {alg F} add_algcreal.
-
-Lemma pi_add : {morph \pi_{alg F} : x y / add_algcreal x y >-> add_alg x y}.
-Proof. by unlock add_alg=> x y; rewrite -equiv_alg /= !pi_algK. Qed.
-
-Canonical add_pi_morph := PiMorph2 pi_add.
-
-Definition opp_alg := lift_op1 {alg F} opp_algcreal.
-
-Lemma pi_opp : {morph \pi_{alg F} : x / opp_algcreal x >-> opp_alg x}.
-Proof. by unlock opp_alg=> x; rewrite -equiv_alg /= !pi_algK. Qed.
-
-Canonical opp_pi_morph := PiMorph1 pi_opp.
-
-Definition mul_alg := lift_op2 {alg F} mul_algcreal.
-
-Lemma pi_mul : {morph \pi_{alg F} : x y / mul_algcreal x y >-> mul_alg x y}.
-Proof. by unlock mul_alg=> x y; rewrite -equiv_alg /= !pi_algK. Qed.
-
-Canonical mul_pi_morph := PiMorph2 pi_mul.
-
-Definition inv_alg := lift_op1 {alg F} inv_algcreal.
-
-Lemma pi_inv : {morph \pi_{alg F} : x / inv_algcreal x >-> inv_alg x}.
-Proof.
-unlock inv_alg=> x; symmetry; rewrite -equiv_alg /= /inv_algcreal.
-case: eq_algcreal_dec=> /= [|x'_neq0].
- by rewrite pi_algK; case: eq_algcreal_dec.
-move: x'_neq0 (x'_neq0); rewrite {1}pi_algK.
-case: eq_algcreal_dec=> // x'_neq0' x_neq0 x'_neq0 /=.
-by apply: eq_creal_inv; rewrite pi_algK.
-Qed.
-
-Canonical inv_pi_morph := PiMorph1 pi_inv.
-
-Lemma add_algA : associative add_alg.
-Proof.
-elim/quotW=> x; elim/quotW=> y; elim/quotW=> z; rewrite !piE -equiv_alg.
-by apply: eq_crealP; exists m0=> * /=; rewrite addrA subrr normr0.
-Qed.
-
-Lemma add_algC : commutative add_alg.
-Proof.
-elim/quotW=> x; elim/quotW=> y; rewrite !piE -equiv_alg /=.
-by apply: eq_crealP; exists m0=> * /=; rewrite [X in _ - X]addrC subrr normr0.
-Qed.
-
-Lemma add_0alg : left_id zero_alg add_alg.
-Proof. by elim/quotW=> x; rewrite !piE -equiv_alg /= add_0creal. Qed.
-
-Lemma add_Nalg : left_inverse zero_alg opp_alg add_alg.
-Proof.
-elim/quotW=> x; rewrite !piE -equiv_alg /=.
-by apply: eq_crealP; exists m0=> *; rewrite /= addNr subr0 normr0.
-Qed.
-
-Definition alg_zmodMixin := ZmodMixin add_algA add_algC add_0alg add_Nalg.
-Canonical alg_zmodType := Eval hnf in ZmodType alg alg_zmodMixin.
-Canonical alg_of_zmodType := Eval hnf in ZmodType {alg F} alg_zmodMixin.
-
-
-Lemma add_pi x y : \pi_{alg F} x + \pi_{alg F} y
- = \pi_{alg F} (add_algcreal x y).
-Proof. by rewrite [_ + _]piE. Qed.
-
-Lemma opp_pi x : - \pi_{alg F} x = \pi_{alg F} (opp_algcreal x).
-Proof. by rewrite [- _]piE. Qed.
-
-Lemma zeroE : 0 = \pi_{alg F} zero_algcreal.
-Proof. by rewrite [0]piE. Qed.
-
-Lemma sub_pi x y : \pi_{alg F} x - \pi_{alg F} y
- = \pi_{alg F} (add_algcreal x (opp_algcreal y)).
-Proof. by rewrite [_ - _]piE. Qed.
-
-Lemma mul_algC : commutative mul_alg.
-Proof.
-elim/quotW=> x; elim/quotW=> y; rewrite !piE -equiv_alg /=.
-by apply: eq_crealP; exists m0=> * /=; rewrite mulrC subrr normr0.
-Qed.
-
-Lemma mul_algA : associative mul_alg.
-Proof.
-elim/quotW=> x; elim/quotW=> y; elim/quotW=> z; rewrite !piE -equiv_alg /=.
-by apply: eq_crealP; exists m0=> * /=; rewrite mulrA subrr normr0.
-Qed.
-
-Lemma mul_1alg : left_id one_alg mul_alg.
-Proof. by elim/quotW=> x; rewrite piE -equiv_alg /= mul_1creal. Qed.
-
-Lemma mul_alg_addl : left_distributive mul_alg add_alg.
-Proof.
-elim/quotW=> x; elim/quotW=> y; elim/quotW=> z; rewrite !piE -equiv_alg /=.
-by apply: eq_crealP; exists m0=> * /=; rewrite mulrDl subrr normr0.
-Qed.
-
-Arguments neq_creal_cst [F x y].
-Prenex Implicits neq_creal_cst.
-
-Lemma nonzero1_alg : one_alg != zero_alg.
-Proof. by rewrite piE -(rwP neq_algcrealP) (rwP neq_creal_cst) oner_eq0. Qed.
-
-Definition alg_comRingMixin :=
- ComRingMixin mul_algA mul_algC mul_1alg mul_alg_addl nonzero1_alg.
-Canonical alg_Ring := Eval hnf in RingType alg alg_comRingMixin.
-Canonical alg_comRing := Eval hnf in ComRingType alg mul_algC.
-Canonical alg_of_Ring := Eval hnf in RingType {alg F} alg_comRingMixin.
-Canonical alg_of_comRing := Eval hnf in ComRingType {alg F} mul_algC.
-
-Lemma mul_pi x y : \pi_{alg F} x * \pi_{alg F} y
- = \pi_{alg F} (mul_algcreal x y).
-Proof. by rewrite [_ * _]piE. Qed.
-
-Lemma oneE : 1 = \pi_{alg F} one_algcreal.
-Proof. by rewrite [1]piE. Qed.
-
-Lemma mul_Valg (x : alg) : x != zero_alg -> mul_alg (inv_alg x) x = one_alg.
-Proof.
-elim/quotW: x=> x; rewrite piE -(rwP neq_algcrealP) /= => x_neq0.
-apply/eqP; rewrite piE; apply/eq_algcrealP; rewrite /= /inv_algcreal.
-case: eq_algcreal_dec=> [/(_ x_neq0) //|/= x_neq0'].
-apply: eq_crealP; exists_big_modulus m F.
- by move=> * /=; rewrite mulVf ?subrr ?normr0 ?creal_neq0_always.
-by close.
-Qed.
-
-Lemma inv_alg0 : inv_alg zero_alg = zero_alg.
-Proof.
-rewrite !piE -equiv_alg /= /inv_algcreal.
-by case: eq_algcreal_dec=> //= zero_neq0; move: (eq_creal_refl zero_neq0).
-Qed.
-
-Lemma to_alg_additive : additive to_alg.
-Proof.
-move=> x y /=; rewrite !piE sub_pi -equiv_alg /=.
-by apply: eq_crealP; exists m0=> * /=; rewrite subrr normr0.
-Qed.
-
-Canonical to_alg_is_additive := Additive to_alg_additive.
-
-Lemma to_alg_multiplicative : multiplicative to_alg.
-Proof.
-split=> [x y |] //; rewrite !piE mul_pi -equiv_alg.
-by apply: eq_crealP; exists m0=> * /=; rewrite subrr normr0.
-Qed.
-
-Canonical to_alg_is_rmorphism := AddRMorphism to_alg_multiplicative.
-
-Lemma expn_pi (x : algcreal) (n : nat) :
- (\pi_{alg F} x) ^+ n = \pi (exp_algcreal x n).
-Proof.
-rewrite /exp_algcreal; case: n=> [|n]; first by rewrite expr0 oneE.
-rewrite exprS iteropS; elim: n=> /= [|n ihn]; rewrite ?expr0 ?mulr1 //.
-by rewrite exprS ihn mul_pi.
-Qed.
-
-Lemma horner_pi (p : {poly F}) (x : algcreal) :
- (p ^ to_alg).[\pi_alg x] = \pi (horner_algcreal p x).
-Proof.
-rewrite horner_coef /horner_algcreal size_map_poly.
-apply: (big_ind2 (fun x y => x = \pi_alg y)).
-+ by rewrite zeroE.
-+ by move=> u u' v v' -> ->; rewrite [_ + _]piE.
-by move=> i /= _; rewrite expn_pi coef_map /= [_ * _]piE.
-Qed.
-
-(* Defining annihilating polynomials for algebraics *)
-Definition annul_alg : {alg F} -> {poly F} := locked (annul_creal \o repr).
-
-Lemma root_annul_algcreal (x : algcreal) : ((annul_alg (\pi x)).[x] == 0)%CR.
-Proof. by unlock annul_alg; rewrite /= -pi_algK root_annul_creal. Qed.
-
-Lemma root_annul_alg (x : {alg F}) : root ((annul_alg x) ^ to_alg) x.
-Proof.
-apply/rootP; rewrite -[x]reprK horner_pi /= zeroE -equiv_alg.
-by rewrite horner_algcrealE root_annul_algcreal.
-Qed.
-
-Lemma monic_annul_alg (x : {alg F}) : annul_alg x \is monic.
-Proof. by unlock annul_alg; rewrite monic_annul_creal. Qed.
-
-Lemma annul_alg_neq0 (x : {alg F}) : annul_alg x != 0.
-Proof. by rewrite monic_neq0 ?monic_annul_alg. Qed.
-
-Definition AlgFieldUnitMixin := FieldUnitMixin mul_Valg inv_alg0.
-Canonical alg_unitRing :=
- Eval hnf in UnitRingType alg AlgFieldUnitMixin.
-Canonical alg_comUnitRing := Eval hnf in [comUnitRingType of alg].
-Canonical alg_of_unitRing :=
- Eval hnf in UnitRingType {alg F} AlgFieldUnitMixin.
-Canonical alg_of_comUnitRing := Eval hnf in [comUnitRingType of {alg F}].
-
-Lemma field_axiom : GRing.Field.mixin_of alg_unitRing. Proof. exact. Qed.
-
-Definition AlgFieldIdomainMixin := (FieldIdomainMixin field_axiom).
-Canonical alg_iDomain :=
- Eval hnf in IdomainType alg (FieldIdomainMixin field_axiom).
-Canonical alg_fieldType := FieldType alg field_axiom.
-Canonical alg_of_iDomain :=
- Eval hnf in IdomainType {alg F} (FieldIdomainMixin field_axiom).
-Canonical alg_of_fieldType := FieldType {alg F} field_axiom.
-
-Lemma inv_pi x : (\pi_{alg F} x)^-1 = \pi_{alg F} (inv_algcreal x).
-Proof. by rewrite [_^-1]piE. Qed.
-
-Lemma div_pi x y : \pi_{alg F} x / \pi_{alg F} y
- = \pi_{alg F} (mul_algcreal x (inv_algcreal y)).
-Proof. by rewrite [_ / _]piE. Qed.
-
-Definition lt_alg := lift_fun2 {alg F} lt_algcreal.
-Definition le_alg := lift_fun2 {alg F} le_algcreal.
-
-Lemma lt_alg_pi : {mono \pi_{alg F} : x y / lt_algcreal x y >-> lt_alg x y}.
-Proof.
-move=> x y; unlock lt_alg; rewrite /lt_algcreal.
-by do 2!case: ltVge_algcreal_dec=> //=; rewrite !pi_algK.
-Qed.
-
-Canonical lt_alg_pi_mono := PiMono2 lt_alg_pi.
-
-Lemma le_alg_pi : {mono \pi_{alg F} : x y / le_algcreal x y >-> le_alg x y}.
-Proof.
-move=> x y; unlock le_alg; rewrite /le_algcreal.
-by do 2!case: ltVge_algcreal_dec=> //=; rewrite !pi_algK.
-Qed.
-
-Canonical le_alg_pi_mono := PiMono2 le_alg_pi.
-
-Definition norm_alg := lift_op1 {alg F} norm_algcreal.
-
-Lemma norm_alg_pi : {morph \pi_{alg F} : x / norm_algcreal x >-> norm_alg x}.
-Proof.
-move=> x; unlock norm_alg; rewrite /norm_algcreal /le_algcreal.
-by do 2!case: ltVge_algcreal_dec=> //=; rewrite !(pi_opp, pi_algK, reprK).
-Qed.
-
-Canonical norm_alg_pi_morph := PiMorph1 norm_alg_pi.
-
-(* begin hide *)
-(* Lemma norm_pi (x : algcreal) : `|\pi_{alg F} x| = \pi (norm_algcreal x). *)
-(* Proof. by rewrite /norm_algcreal -lt_pi -zeroE -lerNgt fun_if -opp_pi. Qed. *)
-(* end hide *)
-
-Lemma add_alg_gt0 x y : lt_alg zero_alg x -> lt_alg zero_alg y ->
- lt_alg zero_alg (x + y).
-Proof.
-rewrite -[x]reprK -[y]reprK !piE -!(rwP lt_algcrealP).
-move=> x_gt0 y_gt0; pose_big_enough i.
- apply: (@lt_crealP _ (diff x_gt0 + diff y_gt0) i i) => //.
- by rewrite addr_gt0 ?diff_gt0.
- by rewrite /= add0r ler_add // ?diff0P.
-by close.
-Qed.
-
-Lemma mul_alg_gt0 x y : lt_alg zero_alg x -> lt_alg zero_alg y ->
- lt_alg zero_alg (x * y).
-Proof.
-rewrite -[x]reprK -[y]reprK !piE -!(rwP lt_algcrealP).
-move=> x_gt0 y_gt0; pose_big_enough i.
- apply: (@lt_crealP _ (diff x_gt0 * diff y_gt0) i i) => //.
- by rewrite pmulr_rgt0 ?diff_gt0.
- rewrite /= add0r (@ler_trans _ (diff x_gt0 * (repr y) i)) //.
- by rewrite ler_wpmul2l ?(ltrW (diff_gt0 _)) // diff0P.
- by rewrite ler_wpmul2r ?diff0P ?ltrW ?creal_gt0_always.
-by close.
-Qed.
-
-Lemma gt0_alg_nlt0 x : lt_alg zero_alg x -> ~~ lt_alg x zero_alg.
-Proof.
-rewrite -[x]reprK !piE -!(rwP lt_algcrealP, rwP le_algcrealP).
-move=> hx; pose_big_enough i.
- apply: (@le_crealP _ i)=> j /= hj.
- by rewrite ltrW // creal_gt0_always.
-by close.
-Qed.
-
-Lemma sub_alg_gt0 x y : lt_alg zero_alg (y - x) = lt_alg x y.
-Proof.
-rewrite -[x]reprK -[y]reprK !piE; apply/lt_algcrealP/lt_algcrealP=> /= hxy.
- pose_big_enough i.
- apply: (@lt_crealP _ (diff hxy) i i); rewrite ?diff_gt0 //.
- by rewrite (monoLR (addNKr _) (ler_add2l _)) addrC diff0P.
- by close.
-pose_big_enough i.
- apply: (@lt_crealP _ (diff hxy) i i); rewrite ?diff_gt0 //.
- by rewrite (monoRL (addrK _) (ler_add2r _)) add0r addrC diffP.
-by close.
-Qed.
-
-Lemma lt0_alg_total (x : alg) : x != zero_alg ->
- lt_alg zero_alg x || lt_alg x zero_alg.
-Proof.
-rewrite -[x]reprK !piE => /neq_algcrealP /= x_neq0.
-apply/orP; rewrite -!(rwP lt_algcrealP).
-case/neq_creal_ltVgt: x_neq0=> /= [lt_x0|lt_0x]; [right|by left].
-pose_big_enough i.
- by apply: (@lt_crealP _ (diff lt_x0) i i); rewrite ?diff_gt0 ?diffP.
-by close.
-Qed.
-
-Lemma norm_algN x : norm_alg (- x) = norm_alg x.
-Proof.
-rewrite -[x]reprK !piE /= -equiv_alg !norm_algcrealE; apply: eq_crealP.
-exists_big_modulus m F=> [e i e_gt0 hi /=|].
- by rewrite normrN subrr normr0.
-by close.
-Qed.
-
-Lemma ge0_norm_alg x : le_alg 0 x -> norm_alg x = x.
-Proof. by rewrite -[x]reprK !piE /= /norm_algcreal => ->. Qed.
-
-Lemma lt_alg0N (x : alg) : lt_alg 0 (- x) = lt_alg x 0.
-Proof. by rewrite -sub0r sub_alg_gt0. Qed.
-
-Lemma lt_alg00 : lt_alg zero_alg zero_alg = false.
-Proof. by have /implyP := @gt0_alg_nlt0 0; case: lt_alg. Qed.
-
-Lemma le_alg_def x y : le_alg x y = (y == x) || lt_alg x y.
-Proof.
-rewrite -[x]reprK -[y]reprK eq_sym piE [lt_alg _ _]piE; apply/le_algcrealP/orP.
- move=> /le_creal_neqVlt [/eq_algcrealP/eqquotP/eqP-> //|lt_xy]; first by left.
- by right; apply/lt_algcrealP.
-by move=> [/eqP/eqquotP/eq_algcrealP-> //| /lt_algcrealP /lt_crealW].
-Qed.
-
-Definition AlgNumFieldMixin := RealLtMixin add_alg_gt0 mul_alg_gt0
- gt0_alg_nlt0 sub_alg_gt0 lt0_alg_total norm_algN ge0_norm_alg le_alg_def.
-Canonical alg_numDomainType := NumDomainType alg AlgNumFieldMixin.
-Canonical alg_numFieldType := [numFieldType of alg].
-Canonical alg_of_numDomainType := [numDomainType of {alg F}].
-Canonical alg_of_numFieldType := [numFieldType of {alg F}].
-
-Definition AlgRealFieldMixin := RealLeAxiom alg.
-Canonical alg_realDomainType := RealDomainType alg AlgRealFieldMixin.
-Canonical alg_realFieldType := [realFieldType of alg].
-Canonical alg_of_realDomainType := [realDomainType of {alg F}].
-Canonical alg_of_realFieldType := [realFieldType of {alg F}].
-
-Lemma lt_pi x y : \pi_{alg F} x < \pi y = lt_algcreal x y.
-Proof. by rewrite [_ < _]lt_alg_pi. Qed.
-
-Lemma le_pi x y : \pi_{alg F} x <= \pi y = le_algcreal x y.
-Proof. by rewrite [_ <= _]le_alg_pi. Qed.
-
-Lemma norm_pi (x : algcreal) : `|\pi_{alg F} x| = \pi (norm_algcreal x).
-Proof. by rewrite [`|_|]piE. Qed.
-
-Lemma lt_algP (x y : algcreal) : reflect (x < y)%CR (\pi_{alg F} x < \pi y).
-Proof. by rewrite lt_pi; apply: lt_algcrealP. Qed.
-Arguments lt_algP [x y].
-
-Lemma le_algP (x y : algcreal) : reflect (x <= y)%CR (\pi_{alg F} x <= \pi y).
-Proof. by rewrite le_pi; apply: le_algcrealP. Qed.
-Arguments le_algP [x y].
-Prenex Implicits lt_algP le_algP.
-
-Lemma ler_to_alg : {mono to_alg : x y / x <= y}.
-Proof.
-apply: homo_mono=> x y lt_xy; rewrite !piE -(rwP lt_algP).
-by apply/lt_creal_cst; rewrite lt_xy.
-Qed.
-
-Lemma ltr_to_alg : {mono to_alg : x y / x < y}.
-Proof. by apply: lerW_mono; apply: ler_to_alg. Qed.
-
-Lemma normr_to_alg : { morph to_alg : x / `|x| }.
-Proof.
-move=> x /=; have [] := ger0P; have [] := ger0P x%:RA;
- rewrite ?rmorph0 ?rmorphN ?oppr0 //=.
- by rewrite ltr_to_alg lerNgt => ->.
-by rewrite ler_to_alg ltrNge => ->.
-Qed.
-
-Lemma inf_alg_proof x : {d | 0 < d & 0 < x -> (d%:RA < x)}.
-Proof.
-have [|] := lerP; first by exists 1.
-elim/quotW: x=> x; rewrite zeroE=> /lt_algP /= x_gt0.
-exists (diff x_gt0 / 2%:R); first by rewrite pmulr_rgt0 ?gtr0E ?diff_gt0.
-rewrite piE -(rwP lt_algP) /= => _; pose_big_enough i.
- apply: (@lt_crealP _ (diff x_gt0 / 2%:R) i i) => //.
- by rewrite pmulr_rgt0 ?gtr0E ?diff_gt0.
- by rewrite -[_ + _](splitf 2) diff0P.
-by close.
-Qed.
-
-Definition inf_alg (x : {alg F}) : F :=
- let: exist2 d _ _ := inf_alg_proof x in d.
-
-Lemma inf_alg_gt0 x : 0 < inf_alg x.
-Proof. by rewrite /inf_alg; case: inf_alg_proof. Qed.
-
-Lemma inf_lt_alg x : 0 < x -> (inf_alg x)%:RA < x.
-Proof. by rewrite /inf_alg=> x_gt0; case: inf_alg_proof=> d _ /(_ x_gt0). Qed.
-
-Lemma approx_proof x e : {y | 0 < e -> `|x - y%:RA| < e}.
-Proof.
-elim/quotW:x => x; pose_big_enough i.
- exists (x i)=> e_gt0; rewrite (ltr_trans _ (inf_lt_alg _)) //.
- rewrite !piE sub_pi norm_pi -(rwP lt_algP) /= norm_algcrealE /=.
- pose_big_enough j.
- apply: (@lt_crealP _ (inf_alg e / 2%:R) j j) => //.
- by rewrite pmulr_rgt0 ?gtr0E ?inf_alg_gt0.
- rewrite /= {2}[inf_alg e](splitf 2) /= ler_add2r.
- by rewrite ltrW // cauchymodP ?pmulr_rgt0 ?gtr0E ?inf_alg_gt0.
- by close.
-by close.
-Qed.
-
-Definition approx := locked
- (fun (x : alg) (e : alg) => projT1 (approx_proof x e) : F).
-
-Lemma approxP (x e e': alg) : 0 < e -> e <= e' -> `|x - (approx x e)%:RA| < e'.
-Proof.
-by unlock approx; case: approx_proof=> /= y hy /hy /ltr_le_trans hy' /hy'.
-Qed.
-
-Lemma alg_archi : Num.archimedean_axiom alg_of_numDomainType.
-Proof.
-move=> x; move: {x}`|x| (normr_ge0 x) => x x_ge0.
-pose a := approx x 1%:RA; exists (Num.bound (a + 1)).
-have := @archi_boundP _ (a + 1); rewrite -ltr_to_alg rmorph_nat.
-have := @approxP x _ _ ltr01 (lerr _); rewrite ltr_distl -/a => /andP [_ hxa].
-rewrite -ler_to_alg rmorphD /= (ler_trans _ (ltrW hxa)) //.
-by move=> /(_ isT) /(ltr_trans _)->.
-Qed.
-
-Canonical alg_archiFieldType := ArchiFieldType alg alg_archi.
-Canonical alg_of_archiFieldType := [archiFieldType of {alg F}].
-
-(**************************************************************************)
-(* At this stage, algebraics form an archimedian field. We now build the *)
-(* material to prove the intermediate value theorem. We first prove a *)
-(* "weak version", which expresses that the extension {alg F} indeed *)
-(* contains solutions of the intermediate value probelem in F *)
-(**************************************************************************)
-
-Notation "'Y" := 'X%:P.
-
-Lemma weak_ivt (p : {poly F}) (a b : F) : a <= b -> p.[a] <= 0 <= p.[b] ->
- { x : alg | a%:RA <= x <= b%:RA & root (p ^ to_alg) x }.
-Proof.
-move=> le_ab; have [-> _|p_neq0] := eqVneq p 0.
- by exists a%:RA; rewrite ?lerr ?ler_to_alg // rmorph0 root0.
-move=> /andP[pa_le0 pb_ge0]; apply/sig2W.
-have hpab: p.[a] * p.[b] <= 0 by rewrite mulr_le0_ge0.
-move=> {pa_le0 pb_ge0}; wlog monic_p : p hpab p_neq0 / p \is monic.
- set q := (lead_coef p) ^-1 *: p => /(_ q).
- rewrite !hornerZ mulrCA !mulrA -mulrA mulr_ge0_le0 //; last first.
- by rewrite (@exprn_even_ge0 _ 2).
- have mq: q \is monic by rewrite monicE lead_coefZ mulVf ?lead_coef_eq0.
- rewrite monic_neq0 ?mq=> // [] [] // x hx hqx; exists x=> //.
- move: hqx; rewrite /q -mul_polyC rmorphM /= rootM map_polyC rootC.
- by rewrite fmorph_eq0 invr_eq0 lead_coef_eq0 (negPf p_neq0).
-pose c := (a + b) / 2%:R; pose r := (b - a) / 2%:R.
-have r_ge0 : 0 <= r by rewrite mulr_ge0 ?ger0E // subr_ge0.
-have hab: ((c - r = a)%R * (c + r = b)%R)%type.
- rewrite -mulrDl -mulrBl opprD addrA addrK opprK.
- rewrite addrAC addrA [a + _ + _]addrAC subrr add0r.
- by rewrite !mulrDl -![_ + _](splitf 2).
-have hp: p.[c - r] * p.[c + r] <= 0 by rewrite !hab.
-pose x := AlgDom monic_p r_ge0 hp; exists (\pi_alg (to_algcreal x)).
- rewrite !piE; apply/andP; rewrite -!(rwP le_algP) /=.
- split;
- by do [ unlock to_algcreal=> /=; apply: (@le_crealP _ 0%N)=> /= j _;
- have := @to_algcreal_ofP p c r 0%N j r_ge0 isT;
- rewrite ler_distl /= expr0 divr1 !hab=> /andP []].
-apply/rootP; rewrite horner_pi zeroE -equiv_alg horner_algcrealE /=.
-by rewrite -(@to_algcrealP x); unlock to_algcreal.
-Qed.
-
-(* any sequence of algebraic can be expressed as a sequence of
-polynomials in a unique algebraic *)
-Lemma pet_alg_proof (s : seq alg) :
- { ap : {alg F} * seq {poly F} |
- [forall i : 'I_(size s), (ap.2`_i ^ to_alg).[ap.1] == s`_i]
- & size ap.2 = size s }.
-Proof.
-apply: sig2_eqW; elim: s; first by exists (0,[::])=> //; apply/forallP=> [] [].
-move=> x s [[a sp] /forallP /= hs hsize].
-have:= char0_PET _ (root_annul_alg a) _ (root_annul_alg x).
-rewrite !annul_alg_neq0 => /(_ isT isT (char_num _)) /= [n [[p hp] [q hq]]].
-exists (x *+ n - a, q :: [seq r \Po p | r <- sp]); last first.
- by rewrite /= size_map hsize.
-apply/forallP=> /=; rewrite -add1n=> i; apply/eqP.
-have [k->|l->] := splitP i; first by rewrite !ord1.
-rewrite add1n /= (nth_map 0) ?hsize // map_comp_poly /=.
-by rewrite horner_comp hp; apply/eqP.
-Qed.
-
-(****************************************************************************)
-(* Given a sequence s of algebraics (seq {alg F}) *)
-(* pet_alg == primitive algebraic *)
-(* pet_alg_poly == sequence of polynomials such that when instanciated in *)
-(* pet_alg gives back the sequence s (cf. pet_algK) *)
-(* *)
-(* Given a polynomial p on algebraic {poly {alg F}} *)
-(* pet_ground == bivariate polynomial such that when the inner *)
-(* variable ('Y) is instanciated in pet_alg gives back *)
-(* the polynomial p. *)
-(****************************************************************************)
-
-Definition pet_alg s : {alg F} :=
- let: exist2 (a, _) _ _ := pet_alg_proof s in a.
-Definition pet_alg_poly s : seq {poly F}:=
- let: exist2 (_, sp) _ _ := pet_alg_proof s in sp.
-
-Lemma size_pet_alg_poly s : size (pet_alg_poly s) = size s.
-Proof. by unlock pet_alg_poly; case: pet_alg_proof. Qed.
-
-Lemma pet_algK s i :
- ((pet_alg_poly s)`_i ^ to_alg).[pet_alg s] = s`_i.
-Proof.
-rewrite /pet_alg /pet_alg_poly; case: pet_alg_proof.
-move=> [a sp] /= /forallP hs hsize; have [lt_is|le_si] := ltnP i (size s).
- by rewrite -[i]/(val (Ordinal lt_is)); apply/eqP; apply: hs.
-by rewrite !nth_default ?hsize // rmorph0 horner0.
-Qed.
-
-Definition poly_ground := locked (fun (p : {poly {alg F}}) =>
- swapXY (Poly (pet_alg_poly p)) : {poly {poly F}}).
-
-Lemma sizeY_poly_ground p : sizeY (poly_ground p) = size p.
-Proof.
-unlock poly_ground; rewrite sizeYE swapXYK; have [->|p_neq0] := eqVneq p 0.
- apply/eqP; rewrite size_poly0 eqn_leq leq0n (leq_trans (size_Poly _)) //.
- by rewrite size_pet_alg_poly size_poly0.
-rewrite (@PolyK _ 0) -?nth_last ?size_pet_alg_poly //.
-have /eqP := (pet_algK p (size p).-1); apply: contraL=> /eqP->.
-by rewrite rmorph0 horner0 -lead_coefE eq_sym lead_coef_eq0.
-Qed.
-
-Lemma poly_ground_eq0 p : (poly_ground p == 0) = (p == 0).
-Proof. by rewrite -sizeY_eq0 sizeY_poly_ground size_poly_eq0. Qed.
-
-Lemma poly_ground0 : poly_ground 0 = 0.
-Proof. by apply/eqP; rewrite poly_ground_eq0. Qed.
-
-Lemma poly_groundK p :
- ((poly_ground p) ^ (map_poly to_alg)).[(pet_alg p)%:P] = p.
-Proof.
-have [->|p_neq0] := eqVneq p 0; first by rewrite poly_ground0 rmorph0 horner0.
-unlock poly_ground; rewrite horner_polyC /eval /= swapXY_map swapXYK.
-apply/polyP=> i /=; rewrite coef_map_id0 ?horner0 // coef_map /=.
-by rewrite coef_Poly pet_algK.
-Qed.
-
-Lemma annul_from_alg_proof (p : {poly alg}) (q : {poly F}) :
- p != 0 -> q != 0 -> root (q ^ to_alg) (pet_alg p)
- -> {r | resultant (poly_ground p) (r ^ polyC) != 0
- & (r != 0) && (root (r ^ to_alg) (pet_alg p))}.
-Proof.
-move=> p_neq0; elim: (size q) {-2}q (leqnn (size q))=> {q} [|n ihn] q.
- by rewrite size_poly_leq0=> ->.
-move=> size_q q_neq0 hq; apply/sig2_eqW.
-have [|apq_neq0] :=
- eqVneq (resultant (poly_ground p) (q ^ polyC)) 0; last first.
- by exists q=> //; rewrite q_neq0.
-move/eqP; rewrite resultant_eq0 ltn_neqAle eq_sym -coprimep_def.
-move=> /andP[] /(Bezout_coprimepPn _ _) [].
-+ by rewrite poly_ground_eq0.
-+ by rewrite map_polyC_eq0.
-move=> [u v] /and3P [] /andP [u_neq0 ltn_uq] v_neq0 ltn_vp hpq.
-rewrite ?size_map_polyC in ltn_uq ltn_vp.
-rewrite ?size_poly_gt0 in u_neq0 v_neq0.
-pose a := pet_alg p.
-have := erefl (size ((u * poly_ground p) ^ (map_poly to_alg)).[a%:P]).
-rewrite {2}hpq !{1}rmorphM /= !{1}hornerM poly_groundK -map_poly_comp /=.
-have /eq_map_poly-> : (map_poly to_alg) \o polyC =1 polyC \o to_alg.
- by move=> r /=; rewrite map_polyC.
-rewrite map_poly_comp horner_map (rootP hq) mulr0 size_poly0.
-move/eqP; rewrite size_poly_eq0 mulf_eq0 (negPf p_neq0) orbF.
-pose u' : {poly F} := lead_coef (swapXY u).
-have [/rootP u'a_eq0|u'a_neq0] := eqVneq (u' ^ to_alg).[a] 0; last first.
- rewrite horner_polyC -lead_coef_eq0 lead_coef_map_eq /=;
- by do ?rewrite swapXY_map /= lead_coef_map_eq /=
- ?map_poly_eq0 ?lead_coef_eq0 ?swapXY_eq0 ?(negPf u'a_neq0).
-have u'_neq0 : u' != 0 by rewrite lead_coef_eq0 swapXY_eq0.
-have size_u' : (size u' < size q)%N.
- by rewrite /u' (leq_ltn_trans (max_size_lead_coefXY _)) // sizeYE swapXYK.
-move: u'a_eq0=> /ihn [] //; first by rewrite -ltnS (leq_trans size_u').
-by move=> r; exists r.
-Qed.
-
-Definition annul_pet_alg (p : {poly {alg F}}) : {poly F} :=
- if (p != 0) =P true is ReflectT p_neq0 then
- let: exist2 r _ _ :=
- annul_from_alg_proof p_neq0 (annul_alg_neq0 _) (root_annul_alg _) in r
- else 0.
-
-Lemma root_annul_pet_alg p : root (annul_pet_alg p ^ to_alg) (pet_alg p).
-Proof.
-rewrite /annul_pet_alg; case: eqP=> /=; last by rewrite ?rmorph0 ?root0.
-by move=> p_neq0; case: annul_from_alg_proof=> ? ? /andP[].
-Qed.
-
-Definition annul_from_alg p :=
- if (size (poly_ground p) == 1)%N then lead_coef (poly_ground p)
- else resultant (poly_ground p) (annul_pet_alg p ^ polyC).
-
-Lemma annul_from_alg_neq0 p : p != 0 -> annul_from_alg p != 0.
-Proof.
-move=> p_neq0; rewrite /annul_from_alg.
-case: ifP; first by rewrite lead_coef_eq0 poly_ground_eq0.
-rewrite /annul_pet_alg; case: eqP p_neq0=> //= p_neq0 _.
-by case: annul_from_alg_proof.
-Qed.
-
-Lemma annul_pet_alg_neq0 p : p != 0 -> annul_pet_alg p != 0.
-Proof.
-rewrite /annul_pet_alg; case: eqP=> /=; last by rewrite ?rmorph0 ?root0.
-by move=> p_neq0; case: annul_from_alg_proof=> ? ? /andP[].
-Qed.
-
-End RealAlg.
-
-Notation to_alg F := (@to_alg_def _ (Phant F)).
-Notation "x %:RA" := (to_alg _ x)
- (at level 2, left associativity, format "x %:RA").
-
-Lemma upper_nthrootVP (F : archiFieldType) (x : F) (i : nat) :
- 0 < x -> (Num.bound (x ^-1) <= i)%N -> 2%:R ^- i < x.
-Proof.
-move=> x_gt0 hx; rewrite -ltf_pinv -?topredE //= ?gtr0E //.
-by rewrite invrK upper_nthrootP.
-Qed.
-
-Notation "{ 'alg' F }" := (alg_of (Phant F)).
-
-Section AlgAlg.
-
-Variable F : archiFieldType.
-
-Local Open Scope ring_scope.
-
-Local Notation "p ^ f" := (map_poly f p) : ring_scope.
-Local Notation "'Y" := 'X%:P.
-Local Notation m0 := (fun _ => 0%N).
-
-Definition approx2 (x : {alg {alg F}}) i :=
- approx (approx x (2%:R ^- i)) (2%:R ^- i).
-
-Lemma asympt_approx2 x : { asympt e : i / `|(approx2 x i)%:RA%:RA - x| < e }.
-Proof.
-exists_big_modulus m {alg {alg F}}.
- move=> e i e_gt0 hi; rewrite distrC /approx2.
- rewrite (@split_dist_add _ (approx x (2%:R ^- i))%:RA) //.
- rewrite approxP ?gtr0E // ltrW //.
- by rewrite upper_nthrootVP ?divrn_gt0 ?ltr_to_alg.
- rewrite (ltr_trans _ (inf_lt_alg _)) ?divrn_gt0 //.
- rewrite -rmorphB -normr_to_alg ltr_to_alg approxP ?gtr0E // ltrW //.
- by rewrite upper_nthrootVP ?divrn_gt0 ?inf_alg_gt0 ?ltr_to_alg.
-by close.
-Qed.
-
-Lemma from_alg_crealP (x : {alg {alg F}}) : creal_axiom (approx2 x).
-Proof.
-exists_big_modulus m F.
- move=> e i j e_gt0 hi hj; rewrite -2!ltr_to_alg !normr_to_alg !rmorphB /=.
- rewrite (@split_dist_add _ x) // ?[`|_ - _%:RA|]distrC;
- by rewrite (@asympt1modP _ _ (asympt_approx2 x)) ?divrn_gt0 ?ltr_to_alg.
-by close.
-Qed.
-
-Definition from_alg_creal := locked (fun x => CReal (from_alg_crealP x)).
-
-Lemma to_alg_crealP (x : creal F) : creal_axiom (fun i => to_alg F (x i)).
-Proof.
-exists_big_modulus m (alg F).
- move=> e i j e_gt0 hi hj.
- rewrite -rmorphB -normr_to_alg (ltr_trans _ (inf_lt_alg _)) //.
- by rewrite ltr_to_alg cauchymodP ?inf_alg_gt0.
-by close.
-Qed.
-Definition to_alg_creal x := CReal (to_alg_crealP x).
-
-Lemma horner_to_alg_creal p x :
- ((p ^ to_alg F).[to_alg_creal x] == to_alg_creal p.[x])%CR.
-Proof.
-by apply: eq_crealP; exists m0=> * /=; rewrite horner_map subrr normr0.
-Qed.
-
-Lemma neq_to_alg_creal x y :
- (to_alg_creal x != to_alg_creal y)%CR <-> (x != y)%CR.
-Proof.
-split=> neq_xy.
- pose_big_enough i.
- apply: (@neq_crealP _ (inf_alg (lbound neq_xy)) i i) => //.
- by rewrite inf_alg_gt0.
- rewrite -ler_to_alg normr_to_alg rmorphB /= ltrW //.
- by rewrite (ltr_le_trans (inf_lt_alg _)) ?lbound_gt0 ?lboundP.
- by close.
-pose_big_enough i.
- apply: (@neq_crealP _ (lbound neq_xy)%:RA i i) => //.
- by rewrite ltr_to_alg lbound_gt0.
- by rewrite -rmorphB -normr_to_alg ler_to_alg lboundP.
-by close.
-Qed.
-
-Lemma eq_to_alg_creal x y :
- (to_alg_creal x == to_alg_creal y)%CR -> (x == y)%CR.
-Proof. by move=> hxy /neq_to_alg_creal. Qed.
-
-Lemma to_alg_creal0 : (to_alg_creal 0 == 0)%CR.
-Proof. by apply: eq_crealP; exists m0=> * /=; rewrite subrr normr0. Qed.
-
-Import Setoid.
-
-Add Morphism to_alg_creal
- with signature (@eq_creal _) ==> (@eq_creal _) as to_alg_creal_morph.
-Proof. by move=> x y hxy /neq_to_alg_creal. Qed.
-Global Existing Instance to_alg_creal_morph_Proper.
-
-Lemma to_alg_creal_repr (x : {alg F}) : (to_alg_creal (repr x) == x%:CR)%CR.
-Proof.
-apply: eq_crealP; exists_big_modulus m {alg F}.
- move=> e i e_gt0 hi /=; rewrite (ler_lt_trans _ (inf_lt_alg _)) //.
- rewrite -{2}[x]reprK !piE sub_pi norm_pi.
- rewrite -(rwP (le_algP _ _)) norm_algcrealE /=; pose_big_enough j.
- apply: (@le_crealP _ j)=> k hk /=.
- by rewrite ltrW // cauchymodP ?inf_alg_gt0.
- by close.
-by close.
-Qed.
-
-Local Open Scope quotient_scope.
-
-Lemma cst_pi (x : algcreal F) : ((\pi_{alg F} x)%:CR == to_alg_creal x)%CR.
-Proof.
-apply: eq_crealP; exists_big_modulus m {alg F}.
- move=> e i e_gt0 hi /=; rewrite (ltr_trans _ (inf_lt_alg _)) //.
- rewrite !piE sub_pi norm_pi /= -(rwP (lt_algP _ _)) norm_algcrealE /=.
- pose_big_enough j.
- apply: (@lt_crealP _ (inf_alg e / 2%:R) j j) => //.
- by rewrite ?divrn_gt0 ?inf_alg_gt0.
- rewrite /= {2}[inf_alg _](splitf 2) ler_add2r ltrW // distrC.
- by rewrite cauchymodP ?divrn_gt0 ?inf_alg_gt0.
- by close.
-by close.
-Qed.
-
-End AlgAlg.
-
-Section AlgAlgAlg.
-
-Variable F : archiFieldType.
-
-Local Open Scope ring_scope.
-
-Local Notation "p ^ f" := (map_poly f p) : ring_scope.
-Local Notation "'Y" := 'X%:P.
-
-Lemma from_alg_crealK (x : {alg {alg F}}) :
- (to_alg_creal (to_alg_creal (from_alg_creal x)) == x%:CR)%CR.
-Proof.
-apply: eq_crealP; exists_big_modulus m {alg {alg F}}.
- move=> e i e_gt0 hi; unlock from_alg_creal=> /=.
- by rewrite (@asympt1modP _ _ (asympt_approx2 x)).
-by close.
-Qed.
-
-Lemma root_annul_from_alg_creal (x : {alg {alg F}}) :
- ((annul_from_alg (annul_alg x)).[from_alg_creal x] == 0)%CR.
-Proof.
-do 2!apply: eq_to_alg_creal.
-rewrite -!horner_to_alg_creal from_alg_crealK !to_alg_creal0.
-rewrite horner_creal_cst; apply/eq_creal_cst; rewrite -rootE.
-rewrite /annul_from_alg; have [/size_poly1P [c c_neq0 hc]|sp_neq1] := boolP (_ == _).
- set p := _ ^ _; suff ->: p = (annul_alg x) ^ to_alg _ by apply: root_annul_alg.
- congr (_ ^ _); rewrite -{2}[annul_alg x]poly_groundK /=.
- by rewrite !hc lead_coefC map_polyC /= hornerC.
-have [||[u v] /= [hu hv] hpq] := @resultant_in_ideal _
- (poly_ground (annul_alg x)) (annul_pet_alg (annul_alg x) ^ polyC).
-+ rewrite ltn_neqAle eq_sym sp_neq1 //= lt0n size_poly_eq0.
- by rewrite poly_ground_eq0 annul_alg_neq0.
-+ rewrite size_map_polyC -(size_map_poly [rmorphism of to_alg _]) /=.
- rewrite (root_size_gt1 _ (root_annul_pet_alg _)) //.
- by rewrite map_poly_eq0 annul_pet_alg_neq0 ?annul_alg_neq0.
-move: hpq=> /(f_equal (map_poly (map_poly (to_alg _)))).
-rewrite map_polyC /= => /(f_equal (eval (pet_alg (annul_alg x))%:P)).
-rewrite {1}/eval hornerC !rmorphD !{1}rmorphM /= /eval /= => ->.
-rewrite -map_poly_comp /=.
-have /eq_map_poly->: (map_poly (@to_alg F)) \o polyC =1 polyC \o (@to_alg F).
- by move=> r /=; rewrite map_polyC.
-rewrite map_poly_comp horner_map /= (rootP (root_annul_pet_alg _)) mulr0 addr0.
-by rewrite rmorphM /= rootM orbC poly_groundK root_annul_alg.
-Qed.
-
-Lemma annul_alg_from_alg_creal_neq0 (x : {alg {alg F}}) :
- annul_from_alg (annul_alg x) != 0.
-Proof. by rewrite annul_from_alg_neq0 ?annul_alg_neq0. Qed.
-
-Definition from_alg_algcreal x :=
- AlgCRealOf (@annul_alg_from_alg_creal_neq0 x) (@root_annul_from_alg_creal x).
-
-Definition from_alg : {alg {alg F}} -> {alg F} :=
- locked (\pi%qT \o from_alg_algcreal).
-
-Lemma from_algK : cancel from_alg (to_alg _).
-Proof.
-move=> x; unlock from_alg; rewrite -{2}[x]reprK piE -equiv_alg /= cst_pi.
-by apply: eq_to_alg_creal; rewrite from_alg_crealK to_alg_creal_repr.
-Qed.
-
-Lemma ivt (p : {poly (alg F)}) (a b : alg F) : a <= b ->
- p.[a] <= 0 <= p.[b] -> exists2 x : alg F, a <= x <= b & root p x.
-Proof.
-move=> le_ab hp; have [x /andP [hax hxb]] := @weak_ivt _ _ _ _ le_ab hp.
-rewrite -[x]from_algK fmorph_root=> rpx; exists (from_alg x)=> //.
-by rewrite -ler_to_alg from_algK hax -ler_to_alg from_algK.
-Qed.
-
-Canonical alg_rcfType := RcfType (alg F) ivt.
-Canonical alg_of_rcfType := [rcfType of {alg F}].
-
-End AlgAlgAlg.
-End RealAlg.
-
-Notation "{ 'realclosure' F }" := (RealAlg.alg_of (Phant F)).
-
-Notation annul_realalg := RealAlg.annul_alg.
-Notation realalg_of F := (@RealAlg.to_alg_def _ (Phant F)).
-Notation "x %:RA" := (realalg_of x)
- (at level 2, left associativity, format "x %:RA").
-
-Canonical RealAlg.alg_eqType.
-Canonical RealAlg.alg_choiceType.
-Canonical RealAlg.alg_zmodType.
-Canonical RealAlg.alg_Ring.
-Canonical RealAlg.alg_comRing.
-Canonical RealAlg.alg_unitRing.
-Canonical RealAlg.alg_comUnitRing.
-Canonical RealAlg.alg_iDomain.
-Canonical RealAlg.alg_fieldType.
-Canonical RealAlg.alg_numDomainType.
-Canonical RealAlg.alg_numFieldType.
-Canonical RealAlg.alg_realDomainType.
-Canonical RealAlg.alg_realFieldType.
-Canonical RealAlg.alg_archiFieldType.
-Canonical RealAlg.alg_rcfType.
-
-Canonical RealAlg.alg_of_eqType.
-Canonical RealAlg.alg_of_choiceType.
-Canonical RealAlg.alg_of_zmodType.
-Canonical RealAlg.alg_of_Ring.
-Canonical RealAlg.alg_of_comRing.
-Canonical RealAlg.alg_of_unitRing.
-Canonical RealAlg.alg_of_comUnitRing.
-Canonical RealAlg.alg_of_iDomain.
-Canonical RealAlg.alg_of_fieldType.
-Canonical RealAlg.alg_of_numDomainType.
-Canonical RealAlg.alg_of_numFieldType.
-Canonical RealAlg.alg_of_realDomainType.
-Canonical RealAlg.alg_of_realFieldType.
-Canonical RealAlg.alg_of_archiFieldType.
-Canonical RealAlg.alg_of_rcfType.
-
-Canonical RealAlg.to_alg_is_rmorphism.
-Canonical RealAlg.to_alg_is_additive.
-
-Section RealClosureTheory.
-
-Variable F : archiFieldType.
-Notation R := {realclosure F}.
-
-Local Notation "p ^ f" := (map_poly f p) : ring_scope.
-
-Lemma root_annul_realalg (x : R) : root ((annul_realalg x) ^ realalg_of _) x.
-Proof. exact: RealAlg.root_annul_alg. Qed.
-Hint Resolve root_annul_realalg.
-
-Lemma monic_annul_realalg (x : R) : annul_realalg x \is monic.
-Proof. exact: RealAlg.monic_annul_alg. Qed.
-Hint Resolve monic_annul_realalg.
-
-Lemma annul_realalg_neq0 (x : R) : annul_realalg x != 0%R.
-Proof. exact: RealAlg.annul_alg_neq0. Qed.
-Hint Resolve annul_realalg_neq0.
-
-Lemma realalg_algebraic : integralRange (realalg_of F).
-Proof. by move=> x; exists (annul_realalg x). Qed.
-
-End RealClosureTheory.
-
-Definition realalg := {realclosure rat}.
-Canonical realalg_eqType := [eqType of realalg].
-Canonical realalg_choiceType := [choiceType of realalg].
-Canonical realalg_zmodType := [zmodType of realalg].
-Canonical realalg_ringType := [ringType of realalg].
-Canonical realalg_comRingType := [comRingType of realalg].
-Canonical realalg_unitRingType := [unitRingType of realalg].
-Canonical realalg_comUnitRingType := [comUnitRingType of realalg].
-Canonical realalg_idomainType := [idomainType of realalg].
-Canonical realalg_fieldTypeType := [fieldType of realalg].
-Canonical realalg_numDomainType := [numDomainType of realalg].
-Canonical realalg_numFieldType := [numFieldType of realalg].
-Canonical realalg_realDomainType := [realDomainType of realalg].
-Canonical realalg_realFieldType := [realFieldType of realalg].
-Canonical realalg_archiFieldType := [archiFieldType of realalg].
-Canonical realalg_rcfType := [rcfType of realalg].
-
-Module RatRealAlg.
-Canonical RealAlg.algdom_choiceType.
-Definition realalgdom_CountMixin :=
- PcanCountMixin (@RealAlg.encode_algdomK [archiFieldType of rat]).
-Canonical realalgdom_countType :=
- CountType (RealAlg.algdom [archiFieldType of rat]) realalgdom_CountMixin.
-Definition realalg_countType := [countType of realalg].
-End RatRealAlg.
-
-Canonical RatRealAlg.realalg_countType.
-
-(* From mathcomp
-Require Import countalg. *)
-(* Canonical realalg_countZmodType := [countZmodType of realalg]. *)
-(* Canonical realalg_countRingType := [countRingType of realalg]. *)
-(* Canonical realalg_countComRingType := [countComRingType of realalg]. *)
-(* Canonical realalg_countUnitRingType := [countUnitRingType of realalg]. *)
-(* Canonical realalg_countComUnitRingType := [countComUnitRingType of realalg]. *)
-(* Canonical realalg_countIdomainType := [countIdomainType of realalg]. *)
-(* Canonical realalg_countFieldTypeType := [countFieldType of realalg]. *)