(* $Id: FTA.v,v 1.15 2000/11/10 11:27:32 freek Exp $ *)

Require Export CPoly_Rev.
Require Export FTAreg.

(* Tex_Prose
\section{Fundamental Theorem of Algebra}
*)

Section FTA_reg'.

(* Begin_Tex_Verb *)
Variable f : (cpoly_cring CC).
Variable n : nat.
Hypothesis f_degree : (Degree (S n) f).

Lemma fta_reg' :
  (EX f1 | (Degree (1) f1) /\ (EX f2 | (Degree n f2) /\ (f [=] f1[*]f2))).
(* End_Tex_Verb *)
Elim (fta_reg f (S n)). Intro c. Intros.
Cut (Degree (1) _X_[-](_C_ c)). Intro.
Exists _X_[-](_C_ c). Split. Auto.
Elim (poly_linear_factor ??? H).
Intro f2. Intros.
Exists f2. Split.
Apply Degree_mult_imp with _X_[-](_C_ c) (1). Auto.
Apply Degree_wd with f; Auto. Auto.
Apply Degree_minus_lft with (0). Apply Degree_le_c_. Apply Degree_x_. Auto.
Auto with arith.
Auto.
Qed.

End FTA_reg'.


Section FTA_1.

(* Begin_Tex_Verb *)
Variable f : (cpoly_cring CC).
Variable n : nat.
Hypothesis f_degree : (Degree_le (S n) f).
Variable c : CC.
Hypothesis f_c : f!c [#] Zero.
(* End_Tex_Verb *)

Lemma fta_1a : (Degree_le (S n) (Shift c f)).
Apply poly_shift_degree_le.
Auto.
Qed.

Local g := (Rev (S n) (Shift c f)).

Lemma fta_1b : (Degree (S n) g).
Unfold g.
Apply poly_rev_degree.
Step_ap_lft f!(Zero[+]c).
Step_ap_lft f!c.
Qed.

(* Begin_Tex_Verb *)
Lemma fta_1 :
  (EX f1 | (Degree_le (1) f1) /\ (EX f2 | (Degree_le n f2) /\
    (f [=] f1[*]f2))).
(* End_Tex_Verb *)
Elim (fta_reg' g n fta_1b). Intro g1. Intros.
Elim H. Clear H. Intros.
Elim H0. Clear H0. Intro g2. Intros.
Elim H0. Clear H0. Intros.
Cut (Degree_le (1) g1). Intro.
Cut (Degree_le n g2). Intro.
Exists (Shift [--]c (Rev (1) g1)).
Split.
Apply poly_shift_degree_le.
Apply poly_rev_degree_le.
Exists (Shift [--]c (Rev n g2)).
Split.
Apply poly_shift_degree_le.
Apply poly_rev_degree_le.
Cut (Degree_le (plus (1) n) g1[*]g2). Intro.
Cut (Degree_le (plus (1) n) g). Intro.
Cut (Degree_le (plus (1) n) (Shift c f)). Intro.
Step (Shift [--]c (Shift c f)).
Step (Shift [--]c (Rev (plus (1) n) (Rev (S n) (Shift c f)))).
Step (Shift [--]c (Rev (plus (1) n) g)).
Step (Shift [--]c (Rev (plus (1) n) g1[*]g2)).
Step_final (Shift [--]c (Rev (1) g1)[*](Rev n g2)).
Exact fta_1a.
Apply Degree_le_wd with g1[*]g2; Algebra.
Apply Degree_le_mult; Auto.
Apply Degree_imp_Degree_le; Auto.
Apply Degree_imp_Degree_le; Auto.
Qed.

(* Begin_Tex_Verb *)
Lemma fta_1' :
  (EX a | (EX b | (EX g | (Degree_le n g) /\
    (f [=] ((_C_ a)[*]_X_[+](_C_ b))[*]g)))).
(* End_Tex_Verb *)
Elim fta_1. Intro f1. Intros.
Elim H. Clear H. Intros.
Elim H0. Clear H0. Intro f2. Intros.
Elim H0. Clear H0. Intros.
Elim (Degree_le_1_imp ? f1); Auto. Intro a. Intros. Exists a.
Elim H2. Clear H2. Intro b. Intros. Exists b.
Exists f2. Split. Auto.
Step_final f1[*]f2.
Qed.

End FTA_1.


Section Fund_Thm_Alg.

(* Begin_Tex_Verb *)
Lemma fta' :
  (n:nat)(f:(cpoly_cring CC))
    (Degree_le n f) -> (nonConst ? f) -> (EX z | f!z [=] Zero).
(* End_Tex_Verb *)
Intro n. Induction n.
Unfold nonConst. Unfold degree_le. Intros.
Elim H0. Clear H0. Intro n. Intros. Elim H0. Clear H0. Intros.
Elim (eq_imp_not_ap ??? (H ? H0) H1).
Unfold nonConst. Intros.
Elim H0. Clear H0. Intro m'. Intros. Elim H0. Clear H0. Intros.
Elim (poly_apzero_CC f). Intro c. Intros.
Elim (fta_1' f n H c H2). Intro a. Intros.
Elim H3. Clear H3. Intro b. Intros.
Elim H3. Clear H3. Intro g. Intros. Elim H3. Clear H3. Intros.
Elim (O_or_S m'); Intros.
Elim y. Clear y. Intro m. Intros. Rewrite <- y in H0. Rewrite <- y in H1.
Cut (a[*](Nth_coeff m g) [#] Zero) \/ (b[*](Nth_coeff (S m) g) [#] Zero).
Intro.
Elim H5; Clear H5; Intros.
Cut a [#] Zero. Intro.
Exists [--]b[/]a[//]H6.
Step (((_C_ a)[*]_X_[+](_C_ b))[*]g)!([--]b[/]a[//]H6).
Step (((_C_ a)[*]_X_[+](_C_ b))!([--]b[/]a[//]H6))[*](g!([--]b[/]a[//]H6)).
Step (((_C_ a)[*]_X_)!([--]b[/]a[//]H6)[+]((_C_ b)!([--]b[/]a[//]H6)))[*]
  (g!([--]b[/]a[//]H6)).
Step (((_C_ a)!([--]b[/]a[//]H6)[*](_X_!([--]b[/]a[//]H6)))[+]b)[*]
  (g!([--]b[/]a[//]H6)).
Step (a[*]([--]b[/]a[//]H6)[+]b)[*](g!([--]b[/]a[//]H6)).
Rational.
Apply cring_mult_ap_zero with (Nth_coeff m g). Auto.
Elim (Hrecn g); Auto. Intro z. Intros. Exists z.
Step (((_C_ a)[*]_X_[+](_C_ b))[*]g)!z.
Step (((_C_ a)[*]_X_[+](_C_ b))!z)[*](g!z).
Step_final (((_C_ a)[*]_X_[+](_C_ b))!z)[*]Zero.
Unfold nonConst. Exists (S m). Split. Auto.
Apply cring_mult_ap_zero_op with b. Auto.
Apply cg_add_ap_zero.
Step_ap_lft (Nth_coeff (S m) ((_C_ a)[*]_X_[+](_C_ b))[*]g).
Step_ap_lft (Nth_coeff (S m) f).
Rewrite <- y in H0. Elim (lt_n_n (0) H0).
Apply Nth_coeff_ap_zero_imp with m'. Auto.
Qed.

(* Begin_Tex_Verb *)
Lemma fta : (f:(cpoly_cring CC))(nonConst ? f) -> (EX z | f!z [=] Zero).
(* End_Tex_Verb *)
Intros.
Elim (poly_ex_degree ? f). Intro n. Intros.
Apply fta' with n; Auto.
Qed.

End Fund_Thm_Alg.


