open import Algebra open import Algebra.Apartness open import Algebra.Module open import Function open import Algebra.DecidableField module Algebra.Module.PropsField {c ℓ₁ ℓ₂ mr ℓm} (dField : DecidableField c ℓ₁ ℓ₂) (leftModule : LeftModule (CommutativeRing.ring $ HeytingCommutativeRing.commutativeRing $ HeytingField.heytingCommutativeRing $ DecidableField.heytingField dField) mr ℓm) where open import Data.Bool hiding (_≟_) open import Data.Nat using (ℕ; zero; suc) open import Data.Fin using (Fin; _≟_) open import Data.Product open import Data.Vec.Functional open import Data.Vec.Functional.Properties open import Relation.Unary.Properties open import Algebra.BigOps open import Vector.Base open import Vector.Properties open import Vector.Structures open DecidableField dField renaming (heytingField to hField; _≟_ to _#?_) using () open HeytingField hField renaming (Carrier to A) hiding (sym) open HeytingCommutativeRing heytingCommutativeRing using (commutativeRing) open CommutativeRing commutativeRing using (rawRing; *-commutativeMonoid; ring; sym) open import Algebra.Module.DefsField hField leftModule open LeftModule leftModule renaming (Carrierᴹ to M) open SumCommMonoid +ᴹ-commutativeMonoid open VRing rawRing using (_*ⱽ_) import Algebra.Solver.CommutativeMonoid *-commutativeMonoid as *-Solver hiding (_≟_) import Algebra.Solver.CommutativeMonoid +ᴹ-commutativeMonoid as +-Solver hiding (_≟_) open import Algebra.HeytingCommutativeRing.Properties heytingCommutativeRing open import Algebra.Module.Base ring open import Algebra.Module.Props commutativeRing leftModule public open import Algebra.Module.VecSpace leftModule public open import Relation.Binary.PropositionalEquality as ≡ using (_≡_; _≢_) open import Relation.Binary.Definitions using (Decidable) open import Relation.Nullary open import Relation.Nullary.Decidable import Relation.Binary.Reasoning.Setoid as RSetoid module ≈-Reasoning = RSetoid setoid private variable n : ℕ xs ys : Vector M n *#0⊆ⱽ : ∀ (xs : Vector M n) {ys : Vector A n} (ys#0 : ∀ i → ys i # 0#) → xs ⊆ⱽ ys *ᵣ xs *#0⊆ⱽ {n} xs {ys} ys#0 {x} (zs by xs*zs≈x) = as by ∑as*zs≈x where ass : _ → _ ass i = #0⇒invertible (ys#0 i) .proj₁ as = ass *ⱽ zs module _ (i : Fin n) where open *-Solver x⁻¹ = #0⇒invertible (ys#0 i) .proj₁ x⁻¹≈ys = #0⇒invertible (ys#0 i) .proj₂ .proj₁ as*ys≈zs : as i * ys i ≈ zs i as*ys≈zs = begin ass i * zs i * ys i ≈⟨ solve 3 (λ a b c → (a ⊕ b) ⊕ c ⊜ (a ⊕ c) ⊕ b) refl (ass i) (zs i) (ys i) ⟩ x⁻¹ * ys i * zs i ≈⟨ *-congʳ x⁻¹≈ys ⟩ 1# * zs i ≈⟨ *-identityˡ _ ⟩ zs i ∎ where open ≈-Reasoning as≈xs : as i *ₗ (ys i *ₗ xs i) ≈ᴹ zs i *ₗ xs i as≈xs = begin as i *ₗ ys i *ₗ xs i ≈˘⟨ *ₗ-assoc _ _ _ ⟩ (as i * ys i) *ₗ xs i ≈⟨ *ₗ-congʳ as*ys≈zs ⟩ zs i *ₗ xs i ∎ where open ≈ᴹ-Reasoning ∑as*zs≈x = begin ∑ (as *ᵣ (ys *ᵣ xs)) ≈⟨ ∑Ext {n} as≈xs ⟩ ∑ (zs *ᵣ xs) ≈⟨ xs*zs≈x ⟩ x ∎ where open ≈ᴹ-Reasoning *ₗ#0⊆ⱽ : (xs : Vector M n) (ys : Vector A n) → ys *ᵣ xs ⊆ⱽ xs *ₗ#0⊆ⱽ {n} xs ys {x} (ws by xs*ws≈x) = as by as*xs≈x where open ≈ᴹ-Reasoning as = ws *ⱽ ys as*xs≈x = begin ∑ ((ws *ⱽ ys) *ᵣ xs) ≈⟨ ∑Ext {n} (λ _ → *ₗ-assoc _ _ _) ⟩ ∑ (ws *ᵣ (ys *ᵣ xs)) ≈⟨ xs*ws≈x ⟩ x ∎ *#0≈ⱽ : ∀ (xs : Vector M n) {ys : Vector A n} (ys#0 : ∀ i → ys i # 0#) → xs ≋ⱽ (ys *ᵣ xs) *#0≈ⱽ xs ys#0 = record { fwd = *#0⊆ⱽ xs ys#0 ; bwd = *ₗ#0⊆ⱽ xs _ } linInd→¬linDep : IsLinearIndependent xs → ¬ IsLinearDependent xs linInd→¬linDep linIndep (_ by xs*ys≈x , i , ysI#0) = tight _ _ .proj₂ (linIndep xs*ys≈x i) ysI#0 private _[_]←₂_*[_] : Vector A n → Fin n → A → Fin n → Vector A n (M [ q ]←₂ r *[ p ]) i with does (q ≟ i) ... | true = M i + r * M p ... | false = M i private swapV-assoc : ∀ wws (zs : Vector M n) {p q} (p≢q : p ≢ q) i → (swapV wws p q *ᵣ swapV zs p q) i ≈ᴹ swapV (wws *ᵣ zs) p q i swapV-assoc wws zs {p} {q} p≢q i = help where open ≈ᴹ-Reasoning help : _ help with i ≟ p | i ≟ q ... | no i≢p | no i≢q = begin _ ≈⟨ *ₗ-cong (reflexive (swap-diff wws i i≢p i≢q)) $ ≈ᴹ-reflexive $ swap-diff _ i i≢p i≢q ⟩ _ ≡˘⟨ swap-diff (wws *ᵣ zs) _ i≢p i≢q ⟩ swapV (wws *ᵣ zs) p q i ∎ ... | no i≢p | yes ≡.refl = begin _ ≈⟨ *ₗ-cong (reflexive $ updateAt-updates i _) (≈ᴹ-reflexive $ updateAt-updates q _) ⟩ wws p *ₗ zs p ≡˘⟨ updateAt-updates q _ ⟩ swapV (wws *ᵣ zs) p q q ∎ ... | yes ≡.refl | no i≢q = begin _ *ₗ _ ≈⟨ *ₗ-cong (reflexive (≡.trans (updateAt-minimal _ _ _ i≢q) (updateAt-updates p _))) (≈ᴹ-reflexive (≡.trans (updateAt-minimal _ _ _ i≢q) (updateAt-updates p _))) ⟩ wws q *ₗ zs q ≡˘⟨ updateAt-updates p _ ⟩ _ ≡˘⟨ updateAt-minimal p q _ p≢q ⟩ swapV (wws *ᵣ zs) p q p ∎ ... | yes ≡.refl | yes ≡.refl = begin _ ≈⟨ *ₗ-cong (reflexive (updateAt-updates p _)) (≈ᴹ-reflexive (updateAt-updates p _)) ⟩ wws p *ₗ zs p ≡˘⟨ updateAt-updates p _ ⟩ swapV (wws *ᵣ zs) p p p ∎ sameLinDep : (xs ys : Vector M n) → xs ≈ⱽ ys → IsLinearDependent xs → IsLinearDependent ys sameLinDep {n} xs ys (idR xs≋ys) (ws by xs*ws≈x , i , ws#0) = ws by ≈ᴹ-trans (∑Ext (*ₗ-congˡ ∘ ≈ᴹ-sym ∘ xs≋ys)) xs*ws≈x , i , ws#0 sameLinDep {n} xs ys (rec {ys = zs} (swapOp p q p≢q) xs≈ⱽzs same) dep@(ws by xs*ws≈x , i , ws#0) with wws by xs*wws≈x , j , wws#0 ← sameLinDep _ _ xs≈ⱽzs dep = swapV wws p q by ≈ᴹ-trans ∑Same xs*wws≈x , ∃#0 where open ≈ᴹ-Reasoning sameness : ∀ i → swapV wws p q i *ₗ ys i ≈ᴹ swapV (wws *ᵣ zs) p q i sameness i = begin swapV wws p q i *ₗ ys i ≈˘⟨ *ₗ-congˡ (same i) ⟩ swapV wws p q i *ₗ swapV zs p q i ≈⟨ swapV-assoc wws _ p≢q _ ⟩ swapV (wws *ᵣ zs) p q i ∎ ∃#0 : _ ∃#0 with j ≟ p | j ≟ q ... | yes ≡.refl | yes ≡.refl = p , #-congʳ (reflexive (≡.sym (updateAt-updates j _))) wws#0 ... | yes ≡.refl | no j≢q = q , #-congʳ (reflexive (≡.sym (updateAt-updates q _))) wws#0 ... | no j≢p | yes ≡.refl = p , #-congʳ (reflexive (≡.sym (≡.trans (updateAt-minimal _ _ _ (j≢p ∘ ≡.sym)) (updateAt-updates p _)))) wws#0 ... | no j≢p | no j≢q = _ , #-congʳ (reflexive (≡.sym (swap-diff _ _ j≢p j≢q))) wws#0 ∑Same : ∑ (swapV wws p q *ᵣ ys) ≈ᴹ ∑ (wws *ᵣ zs) ∑Same = begin ∑ (swapV wws p q *ᵣ ys) ≈⟨ ∑Ext sameness ⟩ ∑ (swapV (wws *ᵣ zs) p q) ≈⟨ ∑Swap _ p q ⟩ ∑ (wws *ᵣ zs) ∎ sameLinDep xs ys (rec {ys = zs} (addCons p q p≢q r) xs≈ⱽzs same) dep@(ws by xs*ws≈x , i , ws#0) with wws by xs*wws≈x , j , wws#0 ← sameLinDep _ _ xs≈ⱽzs dep = ks by ≈ᴹ-trans ∑Same xs*wws≈x , ∃#0 where open ≈ᴹ-Reasoning q≢p = p≢q ∘ ≡.sym v0 = - r ks = wws [ q ]←₂ 0# *[ p ] [ p ]←₂ v0 *[ q ] zsk = zs [ q ]← r *[ p ] ksZs = ks *ᵣ zsk wsZs = wws *ᵣ zs genSum : (xs : Vector M _) → xs p +ᴹ xs q +ᴹ ∑ (xs [ p ]≔ 0ᴹ [ q ]≔ 0ᴹ) ≈ᴹ ∑ xs genSum xs = ∑Two xs _ _ p≢q sameInd : ∀ i → (ksZs [ p ]≔ 0ᴹ [ q ]≔ 0ᴹ) i ≈ᴹ (wsZs [ p ]≔ 0ᴹ [ q ]≔ 0ᴹ) i sameInd i with i ≟ q | i ≟ p ... | yes ≡.refl | _ = begin _ ≡⟨ updateAt-updates q _ ⟩ _ ≡˘⟨ updateAt-updates q _ ⟩ _ ∎ ... | no i≢q | yes ≡.refl = begin _ ≡⟨ updateAt-minimal _ _ _ i≢q ⟩ _ ≡⟨ updateAt-updates p _ ⟩ _ ≡˘⟨ updateAt-updates p _ ⟩ _ ≡˘⟨ updateAt-minimal _ _ _ i≢q ⟩ _ ∎ ... | no i≢q | no i≢p = begin _ ≡⟨ updateAt-minimal _ _ _ i≢q ⟩ _ ≡⟨ updateAt-minimal _ _ _ i≢p ⟩ _ ≡⟨ help ⟩ _ ≡˘⟨ updateAt-minimal _ _ _ i≢p ⟩ _ ≡˘⟨ updateAt-minimal _ _ _ i≢q ⟩ _ ∎ where help : ksZs i ≡ wsZs i help rewrite dec-no (p ≟ i) (i≢p ∘ ≡.sym) | dec-no (q ≟ i) (i≢q ∘ ≡.sym) = ≡.refl sameTwo : ksZs p +ᴹ ksZs q ≈ᴹ wsZs p +ᴹ wsZs q sameTwo rewrite dec-yes (p ≟ p) ≡.refl .proj₂ | dec-yes (q ≟ q) ≡.refl .proj₂ | dec-no (q ≟ p) (p≢q ∘ ≡.sym) | dec-no (p ≟ q) p≢q | dec-yes (q ≟ q) ≡.refl .proj₂ = begin (wws p + v0 * (wws q + 0# * wws p)) *ₗ zs p +ᴹ (wws q + 0# * wws p) *ₗ (zs q +ᴹ r *ₗ zs p) ≈⟨ +ᴹ-cong (*ₗ-congʳ (+-congˡ (*-congˡ (trans (+-congˡ (zeroˡ _)) (+-identityʳ _))))) (*ₗ-congʳ (trans (+-congˡ (zeroˡ _)) (+-identityʳ _))) ⟩ (wws p + v0 * wws q) *ₗ zs p +ᴹ wws q *ₗ (zs q +ᴹ r *ₗ zs p) ≈⟨ +ᴹ-cong (*ₗ-distribʳ _ _ _) (*ₗ-distribˡ _ _ _) ⟩ wws p *ₗ zs p +ᴹ (v0 * wws q) *ₗ zs p +ᴹ (wws q *ₗ zs q +ᴹ wws q *ₗ r *ₗ zs p) ≈⟨ +ᴹ-assoc _ _ _ ⟩ wws p *ₗ zs p +ᴹ ((v0 * wws q) *ₗ zs p +ᴹ (wws q *ₗ zs q +ᴹ wws q *ₗ r *ₗ zs p)) ≈⟨ +ᴹ-congˡ help ⟩ wws p *ₗ zs p +ᴹ wws q *ₗ zs q ∎ where open +-Solver help2 = begin (v0 * wws q) *ₗ zs p +ᴹ wws q *ₗ r *ₗ zs p ≈˘⟨ +ᴹ-congˡ (*ₗ-assoc _ _ _) ⟩ (v0 * wws q) *ₗ zs p +ᴹ (wws q * r) *ₗ zs p ≈˘⟨ *ₗ-distribʳ _ _ _ ⟩ (v0 * wws q + wws q * r) *ₗ zs p ≈⟨ *ₗ-congʳ (trans (+-congˡ (*-comm _ _)) (trans (trans (sym (distribʳ _ _ _)) (*-congʳ (-‿inverseˡ _))) (zeroˡ (wws q)))) ⟩ 0# *ₗ zs p ≈⟨ *ₗ-zeroˡ _ ⟩ 0ᴹ ∎ help = begin (v0 * wws q) *ₗ zs p +ᴹ (wws q *ₗ zs q +ᴹ wws q *ₗ r *ₗ zs p) ≈⟨ solve 3 (λ a b c → (a ⊕ (b ⊕ c)) , ((a ⊕ c) ⊕ b)) ≈ᴹ-refl _ _ _ ⟩ ((v0 * wws q) *ₗ zs p +ᴹ wws q *ₗ r *ₗ zs p) +ᴹ wws q *ₗ zs q ≈⟨ +ᴹ-congʳ help2 ⟩ 0ᴹ +ᴹ wws q *ₗ zs q ≈⟨ +ᴹ-identityˡ _ ⟩ wws q *ₗ zs q ∎ ∑Same = begin ∑ (ks *ᵣ ys) ≈˘⟨ ∑Ext (*ₗ-congˡ ∘ same) ⟩ ∑ ksZs ≈˘⟨ genSum ksZs ⟩ ksZs p +ᴹ ksZs q +ᴹ ∑ (ksZs [ p ]≔ 0ᴹ [ q ]≔ 0ᴹ) ≈⟨ +ᴹ-cong sameTwo (∑Ext sameInd) ⟩ wsZs p +ᴹ wsZs q +ᴹ ∑ (wsZs [ p ]≔ 0ᴹ [ q ]≔ 0ᴹ) ≈⟨ genSum wsZs ⟩ ∑ wsZs ∎ ∃#0 : _ ∃#0 with j ≟ p | j ≟ q | wws q #? 0# ... | yes ≡.refl | _ | yes wwsQ#0 = q , #-congʳ help wwsQ#0 where help : wws q ≈ ks q help rewrite dec-no (p ≟ q) p≢q | dec-yes (q ≟ q) ≡.refl .proj₂ = sym (trans (+-congˡ (zeroˡ _)) (+-identityʳ _)) ... | yes ≡.refl | _ | no wwsQ≈0 = p , #-congʳ (sym ksJ≈wwsP) wws#0 where ksJ≈ : ks j ≈ wws p - r * wws q ksJ≈ rewrite dec-yes (j ≟ j) ≡.refl .proj₂ | dec-yes (q ≟ q) ≡.refl .proj₂ | dec-no (q ≟ j) q≢p = +-congˡ (trans (distribˡ _ _ _) (trans (+-congˡ (trans (*-congˡ (zeroˡ _)) (zeroʳ _))) (trans (+-identityʳ _) (sym (-‿distribˡ-* _ _))))) ksJ≈wwsP : ks j ≈ wws p ksJ≈wwsP = trans ksJ≈ (trans (+-congˡ (trans (-‿cong (trans (*-congˡ (tight _ _ .proj₁ wwsQ≈0 )) (zeroʳ _))) -0#≈0#)) (+-identityʳ _)) ... | no j≢p | yes ≡.refl | _ = j , #-congʳ help wws#0 where help : wws j ≈ ks j help rewrite dec-no (p ≟ j) (j≢p ∘ ≡.sym) | dec-yes (j ≟ j) ≡.refl .proj₂ = sym (trans (+-congˡ (zeroˡ _)) (+-identityʳ _)) ... | no j≢p | no j≢q | _ = j , #-congʳ help wws#0 where help : wws j ≈ ks j help rewrite dec-no (p ≟ j) (j≢p ∘ ≡.sym) | dec-no (q ≟ j) (j≢q ∘ ≡.sym) = refl sameLinInd : (xs ys : Vector M n) → xs ≈ⱽ ys → IsLinearIndependent xs → IsLinearIndependent ys sameLinInd xs ys (idR xs≈ys) lxs xs*zs≈x = lxs (≈ᴹ-trans (∑Ext $ *ₗ-congˡ ∘ xs≈ys) xs*zs≈x) sameLinInd {n} xs ys (rec {ys = ws} (addCons p q p≢q r) xs≈ⱽys same) lxs {zs} xs*zs≈x i = help i (ks≈0 i) where open ≈ᴹ-Reasoning q≢p = p≢q ∘ ≡.sym v0 = r wss = ws [ q ]← r *[ p ] ks = _ [ p ]←₂ v0 *[ q ] zsChange : ∀ j → j ≢ p → j ≢ q → wss j ≈ᴹ ys j → (ks *ᵣ ws) j ≈ᴹ (zs *ᵣ ys) j zsChange j j≢p j≢q rewrite dec-no (p ≟ j) (j≢p ∘ ≡.sym) | dec-no (q ≟ j) (j≢q ∘ ≡.sym) = *ₗ-congˡ ksQ≈zs : ks q ≈ zs q ksQ≈zs rewrite dec-no (p ≟ q) p≢q = refl ksP≈zsV : ks p ≈ zs p + v0 * zs q ksP≈zsV rewrite dec-yes (p ≟ p) ≡.refl .proj₂ = refl wsP≈wss : ws p ≈ᴹ wss p wsP≈wss rewrite dec-no (q ≟ p) q≢p = ≈ᴹ-refl wsQ≈wss : ws q +ᴹ r *ₗ ws p ≈ᴹ wss q wsQ≈wss rewrite dec-yes (q ≟ q) ≡.refl .proj₂ = ≈ᴹ-refl sameR2 = begin (v0 * zs q) *ₗ ws p ≈⟨ *ₗ-congʳ (*-comm _ _) ⟩ (zs q * r) *ₗ ws p ≈⟨ *ₗ-assoc _ _ _ ⟩ zs q *ₗ r *ₗ ws p ∎ sameRight = begin (v0 * zs q) *ₗ ws p +ᴹ zs q *ₗ ws q ≈⟨ +ᴹ-comm _ _ ⟩ zs q *ₗ ws q +ᴹ (v0 * zs q) *ₗ ws p ≈⟨ +ᴹ-congˡ sameR2 ⟩ zs q *ₗ ws q +ᴹ zs q *ₗ r *ₗ ws p ∎ samePq = begin (ks *ᵣ ws) p +ᴹ (ks *ᵣ ws) q ≈⟨ +ᴹ-cong (*ₗ-congʳ ksP≈zsV) (*ₗ-congʳ ksQ≈zs) ⟩ (zs p + v0 * zs q) *ₗ ws p +ᴹ zs q *ₗ ws q ≈⟨ +ᴹ-congʳ (*ₗ-distribʳ _ _ _) ⟩ zs p *ₗ ws p +ᴹ (v0 * zs q) *ₗ ws p +ᴹ zs q *ₗ ws q ≈⟨ +ᴹ-assoc _ _ _ ⟩ zs p *ₗ ws p +ᴹ ((v0 * zs q) *ₗ ws p +ᴹ zs q *ₗ ws q) ≈⟨ +ᴹ-congˡ sameRight ⟩ zs p *ₗ ws p +ᴹ (zs q *ₗ ws q +ᴹ zs q *ₗ r *ₗ ws p) ≈˘⟨ +ᴹ-congˡ (*ₗ-distribˡ _ _ _) ⟩ zs p *ₗ ws p +ᴹ zs q *ₗ (ws q +ᴹ r *ₗ ws p) ≈⟨ +ᴹ-cong (*ₗ-congˡ (≈ᴹ-trans wsP≈wss (same p))) (*ₗ-congˡ (≈ᴹ-trans wsQ≈wss (same q))) ⟩ (zs *ᵣ ys) p +ᴹ (zs *ᵣ ys) q ∎ ∑Same = ∑TwoExt _ _ _ _ p≢q samePq λ j j≢p j≢q → zsChange j j≢p j≢q (same j) ks≈0 : ∀ j → ks j ≈ 0# ks≈0 = sameLinInd _ _ xs≈ⱽys lxs (≈ᴹ-trans ∑Same xs*zs≈x) zsQ≈0 : ks q ≈ 0# → zs q ≈ 0# zsQ≈0 rewrite dec-no (p ≟ q) p≢q = id help : ∀ i → ks i ≈ 0# → zs i ≈ 0# help i with p ≟ i ... | no p≢i = id ... | yes ≡.refl = help2 where help2 : _ → _ help2 zsP = trans (trans (sym (+-identityʳ _)) (+-congˡ (sym (trans (*-congˡ (zsQ≈0 (ks≈0 q))) (zeroʳ _))))) zsP sameLinInd {n} xs ys (rec {ys = ws} (swapOp p q p≢q) xs≈ⱽys same) lxs {zs} xs*zs≈x i = help i where open ≈ᴹ-Reasoning ks = swapV zs p q swapYs≈ : ∀ k → swapV ys p q k ≈ᴹ ws k swapYs≈ k with k ≟ p | k ≟ q ... | yes ≡.refl | yes ≡.refl = begin _ ≡⟨ updateAt-updates p _ ⟩ _ ≈˘⟨ same _ ⟩ _ ≡⟨ updateAt-updates k _ ⟩ _ ∎ ... | yes ≡.refl | no k≢q = begin _ ≡⟨ updateAt-minimal _ _ _ k≢q ⟩ _ ≡⟨ updateAt-updates k _ ⟩ _ ≈˘⟨ same q ⟩ _ ≡⟨ updateAt-updates q _ ⟩ _ ∎ ... | no k≢p | yes ≡.refl = begin _ ≡⟨ updateAt-updates k _ ⟩ _ ≈˘⟨ same _ ⟩ _ ≡⟨ updateAt-minimal _ _ _ (k≢p ∘ ≡.sym) ⟩ _ ≡⟨ updateAt-updates p _ ⟩ _ ∎ ... | no k≢p | no k≢q = begin _ ≡⟨ updateAt-minimal _ _ _ k≢q ⟩ _ ≡⟨ updateAt-minimal _ _ _ k≢p ⟩ _ ≈˘⟨ same _ ⟩ _ ≡⟨ updateAt-minimal _ _ _ k≢q ⟩ _ ≡⟨ updateAt-minimal _ _ _ k≢p ⟩ _ ∎ ∑Same : ∑ (ks *ᵣ ws) ≈ᴹ ∑ (zs *ᵣ ys) ∑Same = begin ∑ (ks *ᵣ ws) ≈˘⟨ ∑Ext (*ₗ-congˡ ∘ swapYs≈) ⟩ ∑ (ks *ᵣ swapV ys p q) ≈⟨ ∑Ext (swapV-assoc _ _ p≢q) ⟩ ∑ (swapV (zs *ᵣ ys) p q) ≈⟨ ∑Swap _ p q ⟩ ∑ (zs *ᵣ ys) ∎ ks≈0 : ∀ j → ks j ≈ 0# ks≈0 = sameLinInd _ _ xs≈ⱽys lxs (≈ᴹ-trans ∑Same xs*zs≈x) help : ∀ i → zs i ≈ 0# help i with i ≟ p | i ≟ q ... | yes ≡.refl | _ = trans (sym (reflexive (updateAt-updates q _))) (ks≈0 q) ... | no i≢p | yes ≡.refl = trans (sym (reflexive (≡.trans (updateAt-minimal _ _ _ p≢q) (updateAt-updates p _)))) (ks≈0 p) ... | no i≢p | no i≢q = trans (sym (reflexive (≡.trans (updateAt-minimal _ _ _ i≢q) (updateAt-minimal _ _ _ i≢p)))) (ks≈0 i) sameLin : (xs ys : Vector M n) → xs ≈ⱽ ys → ∀ b → LinearIndependent? xs b → LinearIndependent? ys b sameLin xs ys xs≈ⱽys false (linDep ld) = linDep $ sameLinDep xs ys xs≈ⱽys ld sameLin xs ys xs≈ⱽys true (linInd li) = linInd $ sameLinInd xs ys xs≈ⱽys li