open import Algebra.DecidableField
module SystemEquations.VecPiv {c ℓ₁ ℓ₂} (dField : DecidableField c ℓ₁ ℓ₂) where
open import Level using (Level; _⊔_)
open import Algebra
open import Algebra.Apartness
open import Algebra.Module
open import Function
open import Data.Bool using (Bool; true; false; if_then_else_)
open import Data.Unit
open import Data.Product
open import Data.Irrelevant
open import Data.Maybe using (Is-just; Maybe; just; nothing)
open import Data.Maybe.Relation.Unary.All
open import Data.Sum renaming ([_,_] to [_∙_])
open import Data.Sum.Properties
open import Data.Empty
open import Data.Nat as ℕ using (ℕ; _∸_; 2+; z≤n; s≤s)
open import Data.Nat.Properties as ℕ using (module ≤-Reasoning)
open import Data.Fin as F using (Fin; suc; splitAt; fromℕ; fromℕ<; toℕ; inject₁)
open import Data.Fin.Properties as F
open import Data.Fin.Patterns
open import Data.Vec.Functional
open import Relation.Nullary
open import Fin.Base
open import Fin.Properties
open import Vector.Structures
open import Vector.Properties
open import Algebra.Matrix.Structures
open import SystemEquations.Definitions dField
open import MatrixFuncNormalization.Definitions dField
import Algebra.Module.Definition as MDefinition
import Algebra.Module.Props as MProps′
open import Algebra.BigOps
open DecidableField dField renaming (Carrier to F)
open import Algebra.Properties.Ring ring
open VRing rawRing
open import Algebra.Module.Instances.AllVecLeftModule ring using (leftModule)
open MRing rawRing using (Matrix)
open import Algebra.Module.Instances.CommutativeRing commutativeRing
open import Data.Vec.Functional.Relation.Binary.Equality.Setoid setoid
open import Relation.Binary.PropositionalEquality as ≡ using (_≡_; _≢_; subst; subst₂; cong; module ≡-Reasoning)
open import Relation.Binary.Reasoning.Setoid setoid
open import Algebra.Solver.CommutativeMonoid +-commutativeMonoid hiding (id)
open import Algebra.Module.PropsVec commutativeRing hiding (module MProps)
open import lbry
private
open module MProps {n} = MProps′ (*ⱽ-commutativeRing n) (leftModule n)
open SumRing ring using (∑Ext; ∑0r; δ; ∑Mul1r; ∑Split)
open MDef′
private variable
m n : ℕ
allRowsNormed[] : ∀ n → AllRowsNormalized≁0 {n} []
allRowsNormed[] n {()}
vecIn→vecBool : Vector (Fin n) m → Vector Bool n
vecIn→vecBool {m = ℕ.zero} xs i = false
vecIn→vecBool {m = ℕ.suc m} xs 0F with xs 0F
... | 0F = true
... | suc c = false
vecIn→vecBool {m = ℕ.suc m} xs (suc {ℕ.suc n} i) with xs 0F
... | 0F = vecIn→vecBool (λ j → predFin (xs (suc j))) i
... | suc c = vecIn→vecBool (λ j → predFin (xs j)) i
private
testV : Vector (Fin 5) 2
testV 0F = 1F
testV 1F = 3F
vResult = vecIn→vecBool testV
+-right : ∀ m p → m ℕ.+ ℕ.suc p ≡ ℕ.suc (m ℕ.+ p)
+-right ℕ.zero p = ≡.refl
+-right (ℕ.suc m) p rewrite +-right m p = ≡.refl
qtTrue : Vector Bool n → ℕ
qtTrue {ℕ.zero} xs = ℕ.zero
qtTrue {ℕ.suc n} xs = let v = (qtTrue (tail xs)) in if xs 0F then ℕ.suc v else v
VTail : (m n : ℕ) → Set
VTail m n = Vector (Fin $ 2+ n) $ ℕ.suc m
V2+ : (m n : ℕ) → Set
V2+ m n = Vector (Fin $ 2+ n) m
pred-tail : Vector (Fin $ 2+ n) $ ℕ.suc m → Vector (Fin $ ℕ.suc n) m
pred-tail xs = predFin ∘ tail xs
pred-vec : Vector (Fin $ 2+ n) m → Vector (Fin $ ℕ.suc n) m
pred-vec = predFin ∘_
pred-tail-normed : {xs : Vector (Fin $ 2+ n) $ ℕ.suc m} (normed : AllRowsNormalized≁0 xs)
→ AllRowsNormalized≁0 (pred-tail xs)
pred-tail-normed {xs = xs} normed {i} {j} i<j with xs (suc i) | xs (suc j) | normed {y = suc i} (s≤s z≤n) | normed (s≤s i<j)
... | 0F | 0F | _ | ()
... | 0F | suc k | () | s≤s q
... | suc _ | 0F | _ | ()
... | suc _ | suc _ | _ | s≤s isNormed = isNormed
pred-normed : ∀ {xs : Vector (Fin $ 2+ n) $ ℕ.suc m} (normed : AllRowsNormalized≁0 xs) {c}
→ xs 0F ≡ suc c → AllRowsNormalized≁0 (pred-vec xs)
pred-normed {xs = xs} normed eq0 {0F} {suc j} i<j with xs 0F | xs (suc j) | normed i<j
... | suc _ | suc _ | s≤s isNormed = isNormed
pred-normed {xs = xs} normed eq0 {suc i} {suc j} i<j with xs 0F | xs (suc i) | xs (suc j)
| normed {y = suc i} (s≤s z≤n) | normed {y = suc j} (s≤s z≤n) | normed i<j
... | suc _ | suc _ | suc _ | _ | _ | s≤s isNormed = isNormed
suc-pred-tail : ∀ {xs : VTail m n} (normed : AllRowsNormalized≁0 xs) i → suc (pred-tail xs i) ≡ tail xs i
suc-pred-tail {xs = xs} normed i with xs (suc i) | normed {x = 0F} {y = suc i} (s≤s z≤n)
... | suc _ | _ = ≡.refl
suc-pred-vec : ∀ {xs : VTail m n} (normed : AllRowsNormalized≁0 xs) i → suc ((tail $ pred-vec xs) i) ≡ tail xs i
suc-pred-vec {xs = xs} normed i with xs (suc i) | normed {x = 0F} {y = suc i} (s≤s z≤n)
... | suc _ | _ = ≡.refl
vecIn→vecBool-qtTrue : (xs : Vector (Fin n) m) (normed : AllRowsNormalized≁0 xs) → qtTrue (vecIn→vecBool xs) ≡ m
vecIn→vecBool-qtTrue {ℕ.zero} {ℕ.zero} _ _ = ≡.refl
vecIn→vecBool-qtTrue {ℕ.suc n} {ℕ.zero} _ _ = vecIn→vecBool-qtTrue {n} [] (allRowsNormed[] n)
vecIn→vecBool-qtTrue {ℕ.zero} {ℕ.suc m} xs _ with () ← xs 0F
vecIn→vecBool-qtTrue {ℕ.suc ℕ.zero} {ℕ.suc ℕ.zero} xs _ with xs 0F
... | 0F = ≡.refl
vecIn→vecBool-qtTrue {ℕ.suc ℕ.zero} {ℕ.suc (ℕ.suc m)} xs normed with xs 0F | xs 1F | normed {y = 1F} (s≤s z≤n)
... | 0F | 0F | ()
vecIn→vecBool-qtTrue {ℕ.suc (ℕ.suc n)} {ℕ.suc m} xs normed with vecIn→vecBool-qtTrue (pred-vec xs) | xs 0F in eqx
... | _ | 0F rewrite vecIn→vecBool-qtTrue (pred-tail xs) (pred-tail-normed normed) = ≡.refl
... | vBefore | suc c rewrite vBefore (pred-normed normed eqx) = ≡.refl
module _ {xs : Vector (Fin $ ℕ.suc n) $ ℕ.suc m} where
module EqXs (eqXs : xs 0F ≡ 0F) where
tailXs>0 : ∀ (normed : AllRowsNormalized≁0 xs) i → toℕ (tail xs i) ℕ.> 0
tailXs>0 normed i = <.begin-strict
0 <.≡˘⟨ cong toℕ eqXs ⟩
toℕ (xs 0F) <.<⟨ normed (s≤s z≤n) ⟩
toℕ (xs (F.suc i)) <.∎
where module < = ≤-Reasoning
ysPiv : .(normed : AllRowsNormalized≁0 xs) → Vector (Fin n) m
ysPiv normed i = F.reduce≥ (tail xs i) (tailXs>0 normed i)
allRowsNormed : (normed : AllRowsNormalized≁0 xs) → AllRowsNormalized≁0 (ysPiv normed)
allRowsNormed normed {x} {y} x<y
rewrite toℕ-reduce≥ _ (tailXs>0 normed x) | toℕ-reduce≥ _ (tailXs>0 normed y) = <.begin
ℕ.suc (ℕ.pred (toℕ (tail xs x))) <.≡⟨ suc-pred (tailXs>0 normed _) ⟩
toℕ (xs (suc x)) <.≤⟨ ℕ.∸-monoˡ-≤ 1 (normed (s≤s x<y)) ⟩
toℕ (xs (suc y)) ∸ 1 <.∎
where module < = ≤-Reasoning
module NEqXs (xs0F≢0F : xs 0F ≢ 0F) where
tailXs>0 : ∀ (normed : AllRowsNormalized≁0 xs) i → toℕ (tail xs i) ℕ.> 0
tailXs>0 normed i = <.begin-strict
0 <.<⟨ ≤∧≢⇒< z≤n (xs0F≢0F ∘ ≡.sym) ⟩
toℕ (xs 0F) <.<⟨ normed (s≤s z≤n) ⟩
toℕ (xs (F.suc i)) <.∎
where module < = ≤-Reasoning
ysPiv : .(normed : AllRowsNormalized≁0 xs) → Vector (Fin n) m
ysPiv normed i = F.reduce≥ (tail xs i) (tailXs>0 normed i)
allRowsNormed : (normed : AllRowsNormalized≁0 xs) → AllRowsNormalized≁0 (ysPiv normed)
allRowsNormed normed {x} {y} x<y
rewrite toℕ-reduce≥ _ (tailXs>0 normed x) | toℕ-reduce≥ _ (tailXs>0 normed y) = <.begin
ℕ.suc (ℕ.pred (toℕ (tail xs x))) <.≡⟨ suc-pred (tailXs>0 normed _) ⟩
toℕ (xs (suc x)) <.≤⟨ ℕ.∸-monoˡ-≤ 1 (normed (s≤s x<y)) ⟩
toℕ (xs (suc y)) ∸ 1 <.∎
where module < = ≤-Reasoning
normed≥ : {xs : Vector (Fin n) m} (normed : AllRowsNormalized≁0 xs) → n ℕ.≥ m
normed≥ {ℕ.zero} {ℕ.zero} {xs} normed = z≤n
normed≥ {ℕ.zero} {ℕ.suc m} {xs} normed with () ← xs 0F
normed≥ {ℕ.suc n} {ℕ.zero} {xs} normed = z≤n
normed≥ {ℕ.suc n} {ℕ.suc m} {xs} normed with xs 0F F.≟ 0F
... | yes xs0≡0 = s≤s (normed≥ {xs = ysPiv xs0≡0 normed} (allRowsNormed xs0≡0 normed))
where open EqXs
... | no xs0≢0 = s≤s (normed≥ {xs = ysPiv xs0≢0 normed} (allRowsNormed xs0≢0 normed))
where open NEqXs
normed< : ∀ {xs : Vector (Fin $ ℕ.suc n) (ℕ.suc m)} (normed : AllRowsNormalized≁0 xs) {c}
(xs0≡s : xs 0F ≡ suc c) → n ℕ.> m
normed< {ℕ.suc n} {ℕ.zero} {xs} normed xs0≡s = s≤s z≤n
normed< {ℕ.suc n} {ℕ.suc m} {xs} normed xs0≡s with xs 0F | xs 1F in eq1 | normed {0F} {1F} (s≤s z≤n) | normed< {n} {m}
... | suc _ | suc (suc _) | s≤s _ | f = s≤s $ f (pred-tail-normed normed) (cong predFin eq1)
normed> : {xs : Vector (Fin $ ℕ.suc n) (ℕ.suc m)} (normed : AllRowsNormalized≁0 xs)
(xs≢0F : xs 0F ≢ 0F) → n ℕ.> m
normed> {ℕ.zero} {xs = xs} normed xs≢0F with xs 0F in eqn
... | 0F with () ← xs≢0F ≡.refl
normed> {ℕ.suc n} {ℕ.zero} normed xs≢0F = s≤s z≤n
normed> {ℕ.suc n} {ℕ.suc m} {xs} normed xs≢0F with xs 1F in eq1F | normed {0F} {1F} (s≤s z≤n)
... | 0F | ()
... | 1F | s≤s m≤n = contradiction (toℕ-injective (ℕ.≤-antisym m≤n z≤n)) xs≢0F
... | suc (suc c) | _ = s≤s norm
where
open NEqXs
tNormed = tailXs>0 {xs = xs} xs≢0F normed 0F
ysPiv≢0 : F.reduce≥ {m = 1} (xs 1F) tNormed ≢ 0F
ysPiv≢0 ysPiv≡0 = ℕ.0≢1+n $ N.begin-equality
0 N.≡˘⟨ cong toℕ ysPiv≡0 ⟩
toℕ (F.reduce≥ (xs 1F) tNormed) N.≡⟨ toℕ-reduce≥ (xs 1F) tNormed ⟩
toℕ (xs 1F) ∸ 1 N.≡⟨ cong (λ x → toℕ x ∸ 1) eq1F ⟩
ℕ.suc (toℕ c) N.∎
where module N = ≤-Reasoning
norm = normed> {xs = ysPiv xs≢0F normed} (allRowsNormed xs≢0F normed) ysPiv≢0
private
n∸m-suc : n ℕ.≥ m → ℕ.suc n ∸ m ≡ ℕ.suc (n ∸ m)
n∸m-suc z≤n = ≡.refl
n∸m-suc (s≤s n≥m) = n∸m-suc n≥m
rPivs : (xs : Vector (Fin n) m) → ∃ (Vector (Fin n))
rPivs {ℕ.zero} {ℕ.zero} xs = ℕ.zero , []
rPivs {ℕ.zero} {ℕ.suc m} xs with () ← xs 0F
proj₁ (rPivs {ℕ.suc n} {ℕ.zero} xs) = _
proj₂ (rPivs {ℕ.suc n} {ℕ.zero} xs) i = i
rPivs {ℕ.suc ℕ.zero} {ℕ.suc m} xs = ℕ.zero , const 0F
rPivs {ℕ.suc (ℕ.suc n)} {ℕ.suc m} xs with xs 0F | rPivs (pred-vec xs)
... | 0F | _ = _ , suc ∘ (proj₂ (rPivs $ pred-vec (tail xs)))
... | suc _ | _ , ys = _ , 0F ∷ suc ∘ ys
rPivs-n∸m : (xs : Vector (Fin n) m) (normed : AllRowsNormalized≁0 xs) → rPivs xs .proj₁ ≡ n ∸ m
rPivs-n∸m {ℕ.zero} {ℕ.zero} xs _ = ≡.refl
rPivs-n∸m {ℕ.zero} {ℕ.suc m} xs normed with () ← xs 0F
rPivs-n∸m {ℕ.suc n} {ℕ.zero} xs normed = ≡.refl
rPivs-n∸m {ℕ.suc ℕ.zero} {ℕ.suc m} xs normed = ≡.sym (ℕ.m≤n⇒m∸n≡0 {n = m} z≤n)
rPivs-n∸m {ℕ.suc (ℕ.suc n)} {ℕ.suc m} xs normed with xs 0F in eqXs0 | rPivs-n∸m (pred-vec xs)
... | 0F | _ rewrite rPivs-n∸m (pred-tail xs) (pred-tail-normed normed) = ≡.refl
... | suc c | f-normed rewrite f-normed (pred-normed normed eqXs0) = ≡.sym (n∸m-suc {n = n} {m = m}
(ℕ.≤-pred (normed> {xs = xs} normed λ eqXs → contradiction (≡.trans (≡.sym eqXs) eqXs0) 0≢1+n)))
∑-pivs-same : (xs : Vector (Fin n) m) (g : Vector F n) (normed : AllRowsNormalized≁0 xs)
→ ∑ (g ∘ xs) + ∑ (g ∘ rPivs xs .proj₂) ≈ ∑ g
∑-pivs-same {ℕ.zero} {ℕ.zero} xs g normed = +-identityˡ _
∑-pivs-same {ℕ.zero} {ℕ.suc m} xs g normed with () ← xs 0F
∑-pivs-same {ℕ.suc n} {ℕ.zero} xs g normed = +-identityˡ _
∑-pivs-same {ℕ.suc ℕ.zero} {ℕ.suc ℕ.zero} xs g normed with xs 0F
... | 0F = trans (+-assoc _ _ _) (+-congˡ (+-identityˡ _))
∑-pivs-same {ℕ.suc ℕ.zero} {2+ m} xs g normed with xs 0F | xs 1F | normed {x = 0F} {y = 1F} (s≤s z≤n)
... | 0F | 0F | ()
... | 0F | suc () | _
∑-pivs-same {ℕ.suc n@(ℕ.suc n′)} {ℕ.suc m} xs g normed with ∑-pivs-same {n} {ℕ.suc m} (pred-vec xs) (tail g)
| xs 0F in eqXs
... | _ | 0F = begin
_ + _ + _ ≈⟨ +-assoc _ _ _ ⟩
g 0F + (∑ (g ∘ tail xs) + _) ≈˘⟨ +-congˡ (+-congʳ (∑Ext (λ i → reflexive (cong g (suc-pred-tail normed i))))) ⟩
g 0F + (∑ (g ∘ suc ∘ pred-tail xs) + ∑ (g ∘ suc ∘ rPivs (pred-tail xs) .proj₂))
≈⟨ +-congˡ (∑-pivs-same {n} {m} (pred-vec xs ∘ suc) (g ∘ suc) (pred-tail-normed normed) ) ⟩
g 0F + ∑ (tail g) ∎
... | peq | suc c = begin
_ + (g 0F + _) ≈⟨ solve 3 (λ a b c → a ⊕ b ⊕ c , b ⊕ a ⊕ c) refl _ (g 0F) _ ⟩
g 0F + (g (suc c) + ∑ (g ∘ xs ∘ suc) + ∑ (g ∘ suc ∘ rPivs (pred-vec xs) .proj₂) ) ≈⟨ +-congˡ (+-congʳ
(+-cong (reflexive (cong g sc≡xs0)) (sym (∑Ext (λ i → reflexive (cong g (suc-pred-vec normed i))))))) ⟩
g 0F + (g (suc (predFin (xs 0F))) + ∑ (g ∘ suc ∘ pred-vec xs ∘ suc) + ∑ (g ∘ suc ∘ rPivs (pred-vec xs) .proj₂))
≈⟨ +-congˡ (peq (pred-normed normed eqXs)) ⟩
g 0F + ∑ (tail g) ∎
where
sc≡xs0 : suc c ≡ suc (predFin (xs 0F))
sc≡xs0 rewrite eqXs = ≡.refl
vSplit : (xs : Vector (Fin n) m) → Vector (ℕ ⊎ Fin m) n
vSplit {ℕ.suc n} {ℕ.zero} xs i = inj₁ $ toℕ i
vSplit {ℕ.suc n} {ℕ.suc m} xs 0F with xs 0F
... | 0F = inj₂ 0F
... | suc c = inj₁ ℕ.zero
vSplit {ℕ.suc (ℕ.suc n)} {ℕ.suc m} xs (suc i) with xs 0F
... | 0F = [ inj₁ ∙ inj₂ ∘ suc ] (vSplit (pred-tail xs) i)
... | suc c = [ inj₁ ∘ ℕ.suc ∙ inj₂ ] (vSplit (pred-vec xs) i)
private
vSplitTest = vSplit testV
vSplitTest2 = vSplit {n = 5} []
vSplitTest3 = vSplit {1} {1} λ x → 0F
vSplitFirst<n∸m : ∀ (xs : Vector (Fin n) m) i (normed : AllRowsNormalized≁0 xs)
→ All (ℕ._< n ∸ m) (isInj₁ (vSplit xs i))
vSplitFirst<n∸m {ℕ.suc n} {ℕ.zero} xs i normed = just (toℕ<n i)
vSplitFirst<n∸m {ℕ.suc ℕ.zero} {ℕ.suc ℕ.zero} xs 0F normed with 0F ← xs 0F = nothing
vSplitFirst<n∸m {ℕ.suc ℕ.zero} {2+ m} xs 0F normed with 0F ← xs 0F = nothing
vSplitFirst<n∸m {2+ n} {ℕ.suc m} xs 0F normed with xs 0F in eq0
... | 0F = nothing
... | suc _ rewrite n∸m-suc $ ℕ.≤-pred $ normed< normed eq0 = just (s≤s z≤n)
vSplitFirst<n∸m {2+ n} {ℕ.suc m} xs (suc i) normed with xs 0F in eqXs
| vSplit (pred-vec xs) i in eqPred
| vSplit (pred-tail xs) i in eqTail
| vSplitFirst<n∸m (pred-vec xs) i
| vSplitFirst<n∸m (pred-tail xs) i
... | 0F | _ | inj₁ a | f | g rewrite eqTail = just $ drop-just $ g $ pred-tail-normed normed
... | 0F | _ | inj₂ a | f | g rewrite eqTail = nothing
... | suc a | inj₁ p | _ | f | _ rewrite eqPred = just $ ℕ.≤-trans
(s≤s (drop-just $ f (pred-normed normed eqXs)))
(ℕ.≤-reflexive (≡.sym (n∸m-suc {n} {m}
(ℕ.≤-pred $ normed> normed λ xs0≡0 → 0≢1+n (≡.trans (≡.sym xs0≡0) eqXs)))))
... | suc a | inj₂ p | _ | f | _ rewrite eqPred = nothing
vSplit-same : ∀ (xs : Vector (Fin n) m) i (normed : AllRowsNormalized≁0 xs) →
vSplit xs (xs i) ≡ inj₂ i
vSplit-same {ℕ.zero} {ℕ.suc m} xs i normed with () ← xs 0F
vSplit-same {ℕ.suc ℕ.zero} {ℕ.suc m} xs 0F normed with xs 0F in eq0
... | 0F rewrite eq0 = ≡.refl
vSplit-same {ℕ.suc ℕ.zero} {2+ m} xs (suc i) normed with xs 0F | xs 1F | normed {x = 0F} {y = 1F} (s≤s z≤n)
... | 0F | 0F | ()
... | 0F | suc () | _
vSplit-same {ℕ.suc (ℕ.suc n)} {ℕ.suc m} xs 0F normed with xs 0F in eq0 | vSplit-same (pred-vec xs) 0F
... | 0F | b rewrite eq0 = ≡.refl
... | suc c | f rewrite eq0 | f (pred-normed normed eq0) = ≡.refl
vSplit-same {ℕ.suc (ℕ.suc n)} {ℕ.suc m} xs (suc i) normed with
xs 0F in eq0 |
vSplit-same (pred-vec xs) |
vSplit-same (pred-tail xs) i (pred-tail-normed normed) |
xs (suc i) in eqS |
normed {x = 0F} {y = suc i} (s≤s z≤n)
... | 0F | f | g | 0F | ()
... | 0F | f | g | suc p | _ rewrite eq0 = help2
where
help : vSplit (λ x → predFin (xs (suc x))) (predFin (xs (suc i))) ≡ inj₂ i
→ vSplit (pred-tail xs) p ≡ inj₂ i
help rewrite eqS = id
help2 : [ inj₁ ∙ inj₂ ∘ suc ] (vSplit (pred-tail xs) p) ≡ inj₂ (suc i)
help2 = cong [ inj₁ ∙ inj₂ ∘ suc ] (help g)
... | suc c | f | g | 0F | ()
... | suc c | f | g | suc p | _ rewrite eq0 = help2
where
help : vSplit (pred-vec xs) (predFin (xs (suc i))) ≡ inj₂ (suc i)
→ vSplit (pred-vec xs) p ≡ inj₂ (suc i)
help rewrite eqS = id
help2 : [ inj₁ ∘ ℕ.suc ∙ inj₂ ] (vSplit (pred-vec xs) p) ≡ inj₂ (suc i)
help2 = cong [ inj₁ ∘ ℕ.suc ∙ inj₂ ] (help (f (suc i) (pred-normed normed eq0)))
vSplit-rPivs : ∀ (xs : Vector (Fin n) m) i (normed : AllRowsNormalized≁0 xs)
→ vSplit xs (rPivs xs .proj₂ i) ≡ inj₁ (toℕ i)
vSplit-rPivs {ℕ.zero} {ℕ.suc m} xs i normed with () ← xs 0F
vSplit-rPivs {ℕ.suc n} {ℕ.zero} xs i normed = ≡.refl
vSplit-rPivs {2+ n} {ℕ.suc m} xs i normed with xs 0F in eq0
vSplit-rPivs {2+ n} {ℕ.suc m} xs i normed | 0F
rewrite eq0 | vSplit-rPivs (pred-tail xs) i (pred-tail-normed normed) = ≡.refl
vSplit-rPivs {2+ n} {ℕ.suc m} xs 0F normed | suc c rewrite eq0 = ≡.refl
vSplit-rPivs {2+ n} {ℕ.suc m} xs (suc i) normed | suc c
rewrite eq0 | vSplit-rPivs (pred-vec xs) i (pred-normed normed eq0) = ≡.refl
split⊎ : (union : ℕ ⊎ Fin m) .(norm : All (ℕ._< n ∸ m) (isInj₁ union))
→ Fin (n ∸ m) ⊎ Fin m
split⊎ (inj₁ x) norm = inj₁ $ fromℕ< (drop-just norm)
split⊎ (inj₂ y) norm = inj₂ y
vSplit′ : (xs : Vector (Fin n) m) .(normed : AllRowsNormalized≁0 xs) → Vector (Fin (n ∸ m) ⊎ Fin m) n
vSplit′ xs normed i = split⊎ (vSplit xs i) (vSplitFirst<n∸m xs i normed)
vSplit′-same : ∀ (xs : Vector (Fin n) m) i (normed : AllRowsNormalized≁0 xs) →
vSplit′ xs normed (xs i) ≡ inj₂ i
vSplit′-same xs i normed with vSplit xs (xs i)
| vSplitFirst<n∸m xs (xs i) normed
| vSplit-same xs i normed
... | inj₂ _ | _ | eq rewrite inj₂-injective eq = ≡.refl
rPivs′ : (xs : Vector (Fin n) m) .(normed : AllRowsNormalized≁0 xs) → Vector (Fin n) (n ∸ m)
rPivs′ xs normed i = rPivs xs .proj₂ (F.cast (≡.sym $ rPivs-n∸m xs normed) i)
vSplit′-rPivs : ∀ (xs : Vector (Fin n) m) i (normed : AllRowsNormalized≁0 xs)
→ vSplit′ xs normed (rPivs′ xs normed i) ≡ inj₁ i
vSplit′-rPivs xs i normed with vSplit xs (rPivs′ xs normed i)
| vSplitFirst<n∸m xs (rPivs′ xs normed i) normed
| vSplit-rPivs xs (F.cast (≡.sym $ rPivs-n∸m xs normed) i) normed
... | inj₁ x | just b | f rewrite inj₁-injective f = cong inj₁ $
toℕ-injective $ ≡.trans (toℕ-fromℕ< b) $ toℕ-cast (≡.sym $ rPivs-n∸m xs normed) i
≋-cast : m ≡ n → Vector F m → Vector F n → Set _
≋-cast m≡n xs ys = ∀ i → xs i ≈ ys (F.cast m≡n i)
∑Ext′ : {U : Vector F m} {V : Vector F n} → (m≡n : m ≡ n) → ≋-cast m≡n U V → ∑ U ≈ ∑ V
∑Ext′ {m} {V = V} ≡.refl eq = trans (∑Ext eq) (∑Ext {m} (λ i → reflexive (cong V (cast-is-id ≡.refl _))))
∑-pivs′-same : (xs : Vector (Fin n) m) (g : Vector F n) (normed : AllRowsNormalized≁0 xs)
→ ∑ (g ∘ xs) + ∑ (g ∘ rPivs′ xs normed) ≈ ∑ g
∑-pivs′-same xs g normed = begin
∑ (g ∘ xs) + ∑ (g ∘ rPivs′ xs normed) ≈⟨ +-congˡ (∑Ext′ (≡.sym $ rPivs-n∸m xs normed) λ _ → refl) ⟩
∑ (g ∘ xs) + ∑ (g ∘ rPivs xs .proj₂) ≈⟨ ∑-pivs-same xs g normed ⟩
∑ g ∎
∃-piv⊎pivRes : ∀ (xs : Vector (Fin n) m) (normed : AllRowsNormalized≁0 xs) i
→ ∃ (λ j → xs j ≡ i) ⊎ ∃ (λ j → rPivs xs .proj₂ j ≡ i)
∃-piv⊎pivRes {ℕ.suc n} {ℕ.zero} xs normed i = inj₂ (i , ≡.refl)
∃-piv⊎pivRes {ℕ.suc ℕ.zero} {ℕ.suc ℕ.zero} xs normed 0F with xs 0F in eq0
... | 0F = inj₁ (0F , eq0)
∃-piv⊎pivRes {ℕ.suc ℕ.zero} {2+ m} xs normed 0F with xs 0F | xs 1F | normed {x = 0F} {1F} (s≤s z≤n)
... | 0F | 0F | ()
∃-piv⊎pivRes {2+ n} {ℕ.suc m} xs normed 0F with xs 0F in eq0
... | 0F = inj₁ (0F , eq0)
... | suc a = inj₂ (0F , ≡.refl)
∃-piv⊎pivRes {2+ n} {ℕ.suc m} xs normed (suc i) with xs 0F in eq0
| rPivs (pred-vec xs)
| ∃-piv⊎pivRes (pred-vec xs)
| ∃-piv⊎pivRes (pred-tail xs)
| normed {x = 0F}
... | 0F | b | c | d | _ = help $ d (pred-tail-normed normed) i
where
help : _ → _
help (inj₁ (x , y)) with xs (suc x) in eqs | normed {x = 0F} {suc x} (s≤s z≤n)
... | suc f | _ = inj₁ ((suc x) , (≡.trans eqs (cong suc y)))
help (inj₂ (x , y)) = inj₂ (x , cong suc y)
... | suc a | f , g | c | d | nn = help (c (pred-normed normed eq0) i)
where
help : _ → _
help (inj₁ (x , y)) with xs x in eqx
help (inj₁ (0F , ≡.refl)) | 0F = ⊥-elim (0≢1+n (≡.trans (≡.sym eqx) eq0))
help (inj₁ (suc x , ≡.refl)) | 0F = ⊥-elim $ help2 $ subst (λ w → 2+ (toℕ a) ℕ.≤ toℕ w) eqx
$ nn {y = suc x} (s≤s z≤n)
where
help2 : _ → ⊥
help2 ()
... | suc a rewrite y = inj₁ (x , eqx)
help (inj₂ (x , y)) = inj₂ (suc x , cong suc y)
∃-piv⊎pivRes′ : ∀ (xs : Vector (Fin n) m) (normed : AllRowsNormalized≁0 xs) i
→ ∃ (λ j → xs j ≡ i) ⊎ ∃ (λ j → rPivs′ xs normed j ≡ i)
∃-piv⊎pivRes′ xs normed i with ∃-piv⊎pivRes xs normed i | rPivs-n∸m xs normed
... | inj₁ x | _ = inj₁ x
... | inj₂ (a , ≡.refl) | eq = inj₂ (F.cast eq a , cong (rPivs xs .proj₂)
(≡.trans (cast-trans eq (≡.sym eq) a) $ cast-is-id ≡.refl a))