1-- Odd powers preserve enough unit directions to separate nonzero vectors.2-- Part of Cumulus, the Grace17 mathematics library.3-- Copyright (c) 2026 Grant Passmore.4-- Released under the Apache License 2.0. See LICENSE in the repository root.5-- Authors: Grant Passmore67module Grace.Cumulus.Complex.OddDirections8import PowerArithmetic910section Complexes11notationring ℂ := (complexCarrier, complexAdd, complexZero, complexNeg, complexMul, complexOne)12notationring R := (ℝ, realAdd, realZero, realNeg, realMul, realOne)1314theorem complexDot.neg_right (z w : Set)15requires first : z ∈ ℂ16requires second : w ∈ ℂ17shows Euclidean.dot(z, ℂ[-w]) = R[-Euclidean.dot(z, w)]18proof19obtain⟨a, aReal, b, bReal, zs⟩:= complexCarrier.cases at z with*20obtain⟨c, cReal, d, dReal, ws⟩:= complexCarrier.cases at w with*21rw [zs, ws]22simp [complexNeg.pair, Euclidean.dot, Euclidean.x.pair, Euclidean.y.pair]23ring2425theorem complexDot.imaginary_pair (a b c d : Real)26shows Euclidean.dot((a, b), ℂ[complexImaginaryUnit * (c, d)]) = R[b * c - a * d]27proof28unfold complexImaginaryUnit29simp [complexMul.pair, Euclidean.dot, Euclidean.x.pair, Euclidean.y.pair]30ring3132theorem complexDot.square_zero (z w u : Set)33requires first : z ∈ ℂ34requires second : w ∈ ℂ35requires direction : u ∈ ℂ36requires realPart : Euclidean.dot(z, w) = realZero37requires imaginaryPart : Euclidean.dot(z, ℂ[complexImaginaryUnit * w]) = realZero38shows Euclidean.dot(z, ℂ[(u * u) * w]) = realZero39proof40obtain⟨a, aReal, b, bReal, zs⟩:= complexCarrier.cases at z with*41obtain⟨c, cReal, d, dReal, ws⟩:= complexCarrier.cases at w with*42obtain⟨x, xReal, y, yReal, us⟩:= complexCarrier.cases at u with*43rw [zs, ws] at realPart44simp [Euclidean.dot, Euclidean.x.pair, Euclidean.y.pair] at realPart45rw [zs, ws, complexDot.imaginary_pair] at imaginaryPart46rw [zs, ws, us, complexDot.square_pair, realPart, imaginaryPart]47ring4849theorem complexDot.odd_power_direction (z w : Set) (n : Nat)50requires first : z ∈ ℂ51requires second : w ∈ ℂ52requires nonzeroZ : z ≠ ℂ[0]53requires nonzeroW : w ≠ ℂ[0]54shows∃ u ∈ ℂ, Euclidean.dot(z, ℂ[u ^ (succ(Grace.Core.Nat.Rec.add(n, n))) * w]) < realZero55proof56by_contra noDirection57havering:= complexes.comm_ring58have ordinary := IsCommRing.ring withring59have monoid := IsRing.multiplicative with ordinary60have pointZ := complex.point at z with*61have all : ∀ u ∈ ℂ, realZero ≤ Euclidean.dot(z, ℂ[u ^ (succ(Grace.Core.Nat.Rec.add(n, n))) * w])62intros u uIn63have power := monoidPow.closed at ℂ, complexMul, complexOne, u, succ(Grace.Core.Nat.Rec.add(n, n)) with*64have product := IsRing.mul_closed with ordinary, power, second65have point := complex.point with product66by_contra notNonnegative67have negative := realLess.of_not_le with*68apply noDirection69refine⟨u, uIn, negative⟩70have oneIn := complexOne.member71have negOne := IsRing.neg_closed with ordinary, oneIn72have iIn := complexImaginaryUnit.member73have niIn := IsRing.neg_closed with ordinary, iIn74have iw := IsRing.mul_closed with ordinary, iIn, second75have oneBound := all with ℂ[1], oneIn76have negBound := all with ℂ[-1], negOne77rw complexPower.one at oneBound78rw complexPower.negative_one_odd at negBound79have unit : ℂ[1* w] = w byring80have negativeUnit : ℂ[(-1) * w] = ℂ[-w] byring81rw unit at oneBound82rw [negativeUnit, complexDot.neg_right] at negBound83have pointW := complex.point at w with*84have realPart := realLe.zero_of_opposite_bounds with*85have iBound := all with complexImaginaryUnit, iIn86have niBound := all with ℂ[-complexImaginaryUnit], niIn87have negativeProduct : ℂ[(-complexImaginaryUnit) * w] = ℂ[-(complexImaginaryUnit * w)] byring88have iwPoint := complex.point with iw89have imaginaryPart : Euclidean.dot(z, ℂ[complexImaginaryUnit * w]) = realZero90have alternatives := complexPower.imaginary_odd with*91cases alternatives with direct | reversed92 . rw direct.left at iBound93rw [direct.right, negativeProduct, complexDot.neg_right] at niBound94exact realLe.zero_of_opposite_bounds with*95 . rw reversed.left at iBound96rw reversed.right at niBound97rw [negativeProduct, complexDot.neg_right] at iBound98exact realLe.zero_of_opposite_bounds with*99obtain⟨u, uIn, negative⟩:= complexDot.square_direction at z, w with*100have zero := complexDot.square_zero at z, w, u with*101rw zero at negative102have irrefl := realLess.irreflexive_on103exact irrefl with realZero, negative104105end Complexes106