Grace/Cumulus/Algebra/Polynomial/HornerRoots.g17
Open in Workbench Download source
Imports
Horner
Declarations
Source
1234567module Grace.Cumulus.Algebra.Polynomial.HornerRoots8import Horner910def hornerRoots {A : Set} (add z mul leading : Set) (cs : List(A)) : Set :=11 {x ∈ A | hornerAt{A}(add, mul, leading, x, cs) = z}1213theorem hornerRoots.nil (A add z mul leading : Set)14 requires nonzero : leading ≠ z15 shows hornerRoots{A}(add, z, mul, leading, []) = ∅16proof17 ext x18 have value := hornerAt.nil at A, add, mul, leading, x19 constructor20 . intro member21 have data := hornerRoots.membership.forward with member22 have equal := data.right23 rw value at equal24 exfalso25 exact nonzero with equal26 . intro impossible27 exfalso28 simp2930section Fields31variable (A add z neg mul one leading : Set)32notation ring R := (A, add, z, neg, mul, one)33hypothesis field : IsField(R)34hypothesis initial : leading ∈ R3536theorem hornerRoots.divide (a c : Set) (cs : List(A))37 requires center : a ∈ R38 requires coefficient : c ∈ R39 requires root : hornerAt{A}(add, mul, leading, a, c :: cs) = R[0]40 shows hornerRoots{A}(add, z, mul, leading, c :: cs) ⊆ insert(a, hornerRoots{A}(add, z, mul, leading, hornerQuotient{A}(add, mul, leading, a, cs)))41proof42 have ring := IsField.comm_ring with field43 have ordinary := IsCommRing.ring with ring44 have quotient := hornerQuotient.closed at A, add, z, neg, mul, one, leading, a, cs with *45 have noZero := IsField.no_zero_divisors with field46 intros x hx47 obtain ⟨element, vanishes⟩ := hornerRoots.membership.forward at48 A, add, z, mul, leading, c :: cs, x with *49 have division := hornerAt.synthetic_division at A, add, z, neg, mul, one, leading, a, x, c, cs with *50 have value := hornerAt.closed at A, add, z, neg, mul, one, leading, x, hornerQuotient{A}(add, mul, leading, a, cs) with *51 have negative := IsRing.neg_closed with ordinary, center52 have difference := IsRing.add_closed with ordinary, element, negative53 rw [root, vanishes] at division54 have productZero : R[(x - a) * hornerAt{A}(add, mul, leading, x, hornerQuotient{A}(add, mul, leading, a, cs))] = R[0]55 linear_combination -division56 have alternatives := noZero with R[x - a], difference, hornerAt{A}(add, mul, leading, x, hornerQuotient{A}(add, mul, leading, a, cs)), productZero57 cases alternatives with same | remaining58 . have equal : x = a59 linear_combination same60 rw equal61 exact insert.self62 . have member : x ∈ hornerRoots{A}(add, z, mul, leading, hornerQuotient{A}(add, mul, leading, a, cs))63 apply hornerRoots.membership.backward64 refine ⟨element, remaining⟩65 exact insert.contains with member6667hypothesis nonzero : leading ≠ R[0]6869theorem hornerRoots.finite_of_length (n : Nat) (cs : List(A))70 requires size : length{A}(cs) = n71 shows Finite(hornerRoots{A}(add, z, mul, leading, cs))72proof73 induction n generalizing cs74 | zero =>75 intros cs list size76 have cases := List.cases with list77 cases cases with empty | cons78 . rw [empty, hornerRoots.nil]79 exact Finite.empty80 . obtain ⟨c, coefficient, tail, tailList, shape⟩ := cons81 rw [shape, length.cons] at size82 have impossible := Naturals.disjoint.zero.succ at length{A}(tail)83 exfalso84 apply impossible85 symm86 exact size87 | succ(k) using ih =>88 intros cs list size89 have cases := List.cases with list90 cases cases with empty | cons91 . rw [empty, hornerRoots.nil]92 exact Finite.empty93 . obtain ⟨c, coefficient, tail, tailList, shape⟩ := cons94 have tailSize : length{A}(tail) = k95 rw [shape, length.cons] at size96 exact Naturals.injective.succ with size97 have alternatives : (∃ a, a ∈ hornerRoots{A}(add, z, mul, leading, cs)) ∨ ¬(∃ a, a ∈ hornerRoots{A}(add, z, mul, leading, cs))98 tauto99 cases alternatives with inhabited | emptyRoots100 . obtain ⟨a, ha⟩ := inhabited101 rw shape at ha102 obtain ⟨center, root⟩ := hornerRoots.membership.forward at103 A, add, z, mul, leading, c :: tail, a with *104 have ring := IsField.comm_ring with field105 have quotient := hornerQuotient.closed at A, add, z, neg, mul, one, leading, a, tail with *106 have quotientLength := hornerQuotient.length at A, add, z, neg, mul, one, leading, a, tail with *107 have quotientSize : length{A}(hornerQuotient{A}(add, mul, leading, a, tail)) = k by cc108 have finite := ih with hornerQuotient{A}(add, mul, leading, a, tail), quotientSize109 have inserted := Finite.insert at hornerRoots{A}(add, z, mul, leading, hornerQuotient{A}(add, mul, leading, a, tail)), a with finite110 have subset := hornerRoots.divide at A, add, z, neg, mul, one, leading, a, c, tail with *111 rw shape112 exact Finite.subset with inserted, subset113 . have empty : hornerRoots{A}(add, z, mul, leading, cs) = ∅114 ext x115 constructor116 . intro member117 exfalso118 apply emptyRoots119 refine ⟨x, member⟩120 . intro impossible121 exfalso122 exact set.empty with impossible123 rw empty124 exact Finite.empty125126theorem hornerRoots.finite (cs : List(A))127 shows Finite(hornerRoots{A}(add, z, mul, leading, cs))128proof129 have size : length{A}(cs) = length{A}(cs) by rfl130 exact hornerRoots.finite_of_length with *131132theorem hornerAt.exists_nonzero (cs : List(A))133 requires infinite : ¬Finite(R)134 shows ∃ x ∈ R, hornerAt{A}(add, mul, leading, x, cs) ≠ R[0]135proof136 have finite := hornerRoots.finite with *137 by_contra absent138 have equal : hornerRoots{A}(add, z, mul, leading, cs) = R139 ext x140 constructor141 . intro member142 have data := hornerRoots.membership.forward with member143 exact data.left144 . intro member145 apply hornerRoots.membership.backward146 refine ⟨member, ?_⟩147 by_contra value148 apply absent149 refine ⟨x, member, value⟩150 rw equal at finite151 exact infinite with finite152153theorem hornerAt.exists_nonzero_avoiding (F : Set) (cs : List(A))154 requires infinite : ¬Finite(R)155 requires excluded : Finite(F)156 shows ∃ x ∈ R, ¬(x ∈ F) ∧ hornerAt{A}(add, mul, leading, x, cs) ≠ R[0]157proof158 have roots := hornerRoots.finite with *159 have finite := Finite.union with excluded, roots160 by_contra absent161 have included : R ⊆ F ∪ hornerRoots{A}(add, z, mul, leading, cs)162 intros x hx163 have alternatives : x ∈ F ∨ ¬(x ∈ F) by tauto164 cases alternatives with forbidden | fresh165 . settle with union2.membership166 . have vanishes : hornerAt{A}(add, mul, leading, x, cs) = R[0]167 by_contra value168 apply absent169 refine ⟨x, hx, fresh, value⟩170 have root : x ∈ hornerRoots{A}(add, z, mul, leading, cs)171 apply hornerRoots.membership.backward172 refine ⟨hx, vanishes⟩173 simp174 have impossible := Finite.subset with finite, included175 exact infinite with impossible176177end Fields178