open import Algebra.DecidableField
module SystemEquations.Solving {c ℓ₁ ℓ₂} (dField : DecidableField c ℓ₁ ℓ₂) where
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.Product
open import Data.Maybe using (Is-just; Maybe; just; nothing)
open import Data.Sum renaming ([_,_] to [_∙_])
open import Data.Empty
open import Data.Nat as ℕ using (ℕ; _∸_)
open import Data.Nat.Properties as ℕ using (module ≤-Reasoning)
open import Data.Fin as F using (Fin; suc; splitAt; 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; _++v_)
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)
open import Relation.Binary.Reasoning.Setoid setoid
open import Algebra.Solver.CommutativeMonoid +-commutativeMonoid hiding (id)
open import Algebra.Module.PropsVec commutativeRing
open import SystemEquations.VecPiv dField
open import MatrixFuncNormalization.MainTheo dField
open import lbry
open SumRing ring using (∑Ext; ∑0r; δ; ∑Mul1r; ∑Split)
open MDef′
open MProps
private variable
m n p q : ℕ
lastFin : (n : ℕ) → Fin (ℕ.suc n)
lastFin ℕ.zero = 0F
lastFin (ℕ.suc n) = suc (lastFin n)
injF : Fin n → Fin (n ℕ.+ 1)
injF 0F = 0F
injF (suc i) = suc (injF i)
add-1 : Vector F n → Vector F (ℕ.suc n)
add-1 xs = appendLast xs (- 1#)
same-take : ∀ (xs : Matrix F n (ℕ.suc m)) i j
→ ((λ i j → xs i (inject₁ j)) ++v λ w → xs w (lastFin _)) i j ≡ xs i j
same-take {n} {ℕ.zero} xs i 0F = ≡.refl
same-take {n} {ℕ.suc m} xs i 0F = ≡.refl
same-take {n} {ℕ.suc m} xs i (suc j) rewrite same-take (λ i j → xs i (suc j)) i j = ≡.refl
A++b⇒systemEquations : Matrix F n (ℕ.suc m) → SystemEquations n m
A++b⇒systemEquations xs = record { A = λ i j → xs i (inject₁ j) ; b = λ i → xs i (lastFin _) }
module _ where
open SystemEquations
sameSolutionsSE : {sx : SystemEquations n m} {sy : SystemEquations p m} → A++b sy ⊆ⱽ A++b sx
→ ∀ v → IsSolutionA++b sx v → IsSolutionA++b sy v
sameSolutionsSE sy⊆ⱽsx i = sameSolutions {α = i} sy⊆ⱽsx
tail-lemma : ∀ (u : Vector F (ℕ.suc n)) b k → tail (appendLast u b) k ≈ (appendLast (tail u) b) k
tail-lemma u b k = refl
add-1∑ : ∀ (v : Vector F n) b (u : Vector F n) → (add-1 v ∙ⱽ appendLast u b) ≈ u ∙ⱽ v - b
add-1∑ {ℕ.zero} v b u = begin
- 1# * b + 0# ≈⟨ +-identityʳ _ ⟩
- 1# * b ≈⟨ -1*x≈-x _ ⟩
- b ≈˘⟨ +-identityˡ (- b) ⟩
0# + - b ∎
add-1∑ {ℕ.suc n} v b u = begin
v 0F * u 0F + add-1 (tail v) ∙ⱽ tail (appendLast u b) ≈⟨ +-congʳ (*-comm _ _)⟩
u 0F * v 0F + add-1 (tail v) ∙ⱽ appendLast (tail u) b ≈⟨ +-congˡ (add-1∑ _ b (tail u)) ⟩
u 0F * v 0F + (tail u ∙ⱽ tail v - b) ≈˘⟨ +-assoc _ _ (- b) ⟩
u 0F * v 0F + tail u ∙ⱽ tail v - b ∎
sameSolutionsA++b : ∀ {sx : SystemEquations n m} {v} (open SystemEquations sx)
→ IsSolutionA++b $ add-1 v → IsSolution v
sameSolutionsA++b {n = n} {m = m} {sx = system A b} {v} sv i = begin
A i ∙ⱽ v ≈⟨ +-inverseˡ-unique (A i ∙ⱽ v) (- b i) sv-lemma ⟩
- - b i ≈⟨ -‿involutive _ ⟩
b i ∎
where
sv-lemma = begin
A i ∙ⱽ v - b i ≈˘⟨ add-1∑ v (b i) (A i) ⟩
add-1 v ∙ⱽ appendLast (A i) (b i) ≈⟨ sv i ⟩
0# ∎
sameSolutionsA++b-inv : ∀ {sx : SystemEquations n m} {v} (open SystemEquations sx)
→ IsSolution v → IsSolutionA++b $ add-1 v
sameSolutionsA++b-inv {m = m} {system A b} {v} sv i = begin
add-1 v ∙ⱽ appendLast (A i) (b i) ≈⟨ add-1∑ v _ _ ⟩
A i ∙ⱽ v - b i ≈⟨ +-congʳ (sv i) ⟩
b i - b i ≈⟨ -‿inverseʳ (b i) ⟩
0# ∎
module _ where
open SystemEquations
sameSolutionsS : {sx : SystemEquations n m} {sy : SystemEquations p m} → A++b sy ⊆ⱽ A++b sx
→ ∀ v → IsSolution sx v → IsSolution sy v
sameSolutionsS {sx = sx} {sy} sy⊆ⱽsx v isSol = sameSolutionsA++b {sx = sy}
(sameSolutionsSE {sx = sx} {sy = sy} sy⊆ⱽsx (add-1 v) (sameSolutionsA++b-inv {sx = sx} isSol))
open _≋ⱽ_
systemUnsolvable : ∀ {sx : SystemEquations n m} (open SystemEquations sx) → A≈0∧b#0 → ∀ {v} → IsSolution v → ⊥
systemUnsolvable {n = n} {m} {system A b} (i , A0 , b#0) {v} sv = tight _ _ .proj₂
(begin
b i ≈˘⟨ sv i ⟩
A i ∙ⱽ v ≈⟨ ∑Ext (λ j → trans (*-congʳ (A0 j)) (zeroˡ _)) ⟩
∑ {m} 0ⱽ ≈⟨ ∑0r m ⟩
0# ∎) b#0
module _ where
open MatrixIsNormed≁0≈1
open MatrixIsNormed≁0
emptyNormed : (A : Matrix F 0 n) → MatrixIsNormed≁0≈1 A
pivs (isNormed (emptyNormed A)) ()
mPivots (isNormed (emptyNormed A)) ()
pivsCrescent (isNormed (emptyNormed A)) {y = ()} x
columnsZero (isNormed (emptyNormed A)) () j x
pivsOne (emptyNormed A) ()
systemNormedSplit : ∀ (sx : SystemEquations n m) (open SystemEquations sx) → MatrixIsNormed≁0≈1 A++b
→ A≈0∧b#0 ⊎ MatrixIsNormed≁0≈1 A
systemNormedSplit {ℕ.zero} sx normed = inj₂ (emptyNormed _)
systemNormedSplit {ℕ.suc n} {m} sx (cIsNorm≁0≈1 (cIsNorm≁0 pivs mPivots pivsCrescent columnsZero) pivsOne)
with pivs (fromℕ n) F.≟ fromℕ m
... | yes p = inj₁ (fromℕ _ , (λ i → A≈0 (mPivots (fromℕ n) .proj₂ (inject₁ i) (inj₁< i))) , (b#0 $ mPivots (fromℕ _) .proj₁))
where
open SystemEquations sx
b#0 : appendLast (A $ fromℕ n) (b $ fromℕ n) (pivs $ fromℕ n) # 0# → b (fromℕ n) # 0#
b#0 rewrite p | appendLastFromℕ (A $ fromℕ n) (b $ fromℕ n) = id
A≈0 : {i : Fin _} → appendLast (A (fromℕ n)) (b (fromℕ n)) (inject₁ i) ≈ 0# → A (fromℕ n) i ≈ 0#
A≈0 {i} rewrite appendLastInj (A (fromℕ n)) (b (fromℕ n)) i = id
inj₁< : ∀ i → inject₁ i F.< pivs (fromℕ n)
inj₁< i = ≡.subst (inject₁ i F.<_) (≡.sym p) (≤∧≢⇒< (≤fromℕ _) (fromℕ≢inject₁ ∘ ≡.sym))
... | no pn≢fromℕ = inj₂ (cIsNorm≁0≈1 (cIsNorm≁0 pivsR mPivotsR allRowsR cols0R) pivs≁0)
where
open SystemEquations sx
pn<n : pivs (fromℕ n) F.< fromℕ _
pn<n = ≤∧≢⇒< (≤fromℕ _) pn≢fromℕ
pi≢n : ∀ i → pivs i ≢ fromℕ _
pi≢n i peq with i F.≟ fromℕ _
... | yes ≡.refl = pn≢fromℕ peq
... | no i≢fn = <⇒≢ (<-trans (pivsCrescent (≤∧≢⇒< (≤fromℕ _) i≢fn)) pn<n) peq
toℕ-pi≢n : ∀ i → m ≢ F.toℕ (pivs i)
toℕ-pi≢n i peq = pi≢n i (toℕ-injective (≡.sym (≡.trans (toℕ-fromℕ _) peq)))
pivsR : Vector (Fin m) (ℕ.suc n)
pivsR i = F.lower₁ (pivs i) (toℕ-pi≢n i)
toℕ-pivR-≡ : ∀ i → toℕ (pivsR i) ≡ toℕ (pivs i)
toℕ-pivR-≡ i = toℕ-lower₁ _ (toℕ-pi≢n _)
A++b≡piv : ∀ i → A++b i (pivs i) ≡ A i (pivsR i)
A++b≡piv i = appendLastLower (A i) (b i) (pivs i) (toℕ-pi≢n i)
mPivotsR : MatrixPivots≁0 A pivsR
proj₁ (mPivotsR i) = help $ mPivots i .proj₁
where
help : A++b i (pivs i) # 0# → _
help rewrite A++b≡piv i = id
proj₂ (mPivotsR i) j j<pI = help $ mPivots i .proj₂ (inject₁ j) (subst₂ ℕ._<_ (≡.sym (toℕ-inject₁ _)) (toℕ-pivR-≡ _) j<pI)
where
help : appendLast (A i) (b i) (inject₁ j) ≈ 0# → _
help rewrite appendLastInj (A i) (b i) j = id
allRowsR : AllRowsNormalized≁0 pivsR
allRowsR = subst₂ ℕ._<_ (≡.sym $ toℕ-lower₁ _ $ toℕ-pi≢n _) (≡.sym $ toℕ-lower₁ _ $ toℕ-pi≢n _) ∘ pivsCrescent
cols0R : ColumnsZero≁0 A pivsR
cols0R i j i≢j = trans (sym (reflexive (appendLastLower (A _) (b _) _ (toℕ-pi≢n _)))) (columnsZero i j i≢j)
pivs≁0 : PivsOne≁0 A pivsR
pivs≁0 i = trans (sym (reflexive (A++b≡piv _))) (pivsOne i)
module SolvingNormedEquation (sx : SystemEquations n m)
(ANormed : MatrixIsNormed≁0≈1 (SystemEquations.A sx)) where
open SystemEquations sx public
open MatrixIsNormed≁0≈1 ANormed public
vBool : Vector Bool m
vBool = vecIn→vecBool pivs
pivRes : Vector (Fin m) (m ∸ n)
pivRes = rPivs′ _ pivsCrescent
vSplit' : Vector (Fin (m ∸ n) ⊎ Fin n) m
vSplit' = vSplit′ _ pivsCrescent
vAffRPiv : Vector (Affine $ m ∸ n) $ m ∸ n
vAffRPiv j = vAff (δ j) 0#
vAffPiv : Vector (Affine $ m ∸ n) n
vAffPiv j = vAff (λ k → - A j (pivRes k)) (b j)
vAffine : VecAffine m (m ∸ n)
vAffine = [ vAffRPiv ∙ vAffPiv ] ∘ vSplit'
open Affine
AiPj≈δij : (i j : Fin n) → A i (pivs j) ≈ δ i j
AiPj≈δij i j with i F.≟ j
... | yes ≡.refl = pivsOne _
... | no i≢j = columnsZero _ _ (i≢j ∘ ≡.sym)
vAffFamily : IsFamilySolution vAffine
vAffFamily vecs i = begin
∑ (λ j → A i j * (∑ (λ k → vecs k * coeff (vAffine j) k) + constant (vAffine j))) ≈˘⟨ ∑-pivs′-same _
(λ j → A i j * (∑ (λ k → vecs k * coeff (vAffine j) k) + constant (vAffine j))) pivsCrescent ⟩
∑ (λ j → A i (pivs j) * (∑ (λ k → vecs k * coeff (vAffine $ pivs j) k) + constant (vAffine $ pivs j))) +
∑ (λ j → A i (pivRes j) * (∑ (λ k → vecs k * coeff (vAffine $ pivRes j) k) + constant (vAffine $ pivRes j)))
≈⟨ +-cong ∑Piv ∑NPiv ⟩
b i + ∑ (λ k → - (A i (pivRes k) * vecs k)) + ∑ (λ k → A i (pivRes k) * vecs k) ≈⟨ +-assoc (b i) _ _ ⟩
b i + (∑ {m ∸ n} (λ k → - (A i (pivRes k) * vecs k)) + ∑ λ k → A i (pivRes k) * vecs k) ≈⟨ +-congˡ
(begin
_ ≈˘⟨ ∑Split _ (λ k → A i (pivRes k) * vecs k) ⟩
_ ≈⟨ ∑Ext (λ k → -‿inverseˡ (A i (pivRes k) * vecs k)) ⟩
∑ {m ∸ n} (const 0#) ≈⟨ ∑0r (m ∸ n) ⟩
_ ∎) ⟩
b i + 0# ≈⟨ +-identityʳ _ ⟩
b i ∎
where
coeffVAffine≈ : ∀ k → coeff (vAffine (pivs i)) k ≈ - A i (pivRes k)
coeffVAffine≈ k rewrite vSplit′-same pivs i pivsCrescent = refl
constVAffine≈ : constant (vAffine (pivs i)) ≈ b i
constVAffine≈ rewrite vSplit′-same pivs i pivsCrescent = refl
sameInSum : ∀ k → vecs k * coeff (vAffine (pivs i)) k ≈ - (A i (pivRes k) * vecs k)
sameInSum k = begin
vecs k * coeff (vAffine (pivs i)) k ≈⟨ *-comm _ _ ⟩
coeff (vAffine (pivs i)) k * vecs k ≈⟨ *-congʳ (coeffVAffine≈ k) ⟩
- A i (pivRes k) * vecs k ≈˘⟨ -‿distribˡ-* _ _ ⟩
- (A i (pivRes k) * vecs k) ∎
∑Piv = begin
∑ {n} (λ j → A i (pivs j) * (∑ (λ k → vecs k * coeff (vAffine (pivs j)) k) + constant (vAffine (pivs j))))
≈⟨ ∑Ext {n} (λ j → *-congʳ (AiPj≈δij i j)) ⟩
∑ (λ j → δ i j * (λ p → ∑ (λ k → vecs k * coeff (vAffine (pivs p)) k) + constant (vAffine (pivs p))) j )
≈⟨ ∑Mul1r {n} _ i ⟩
∑ (λ k → vecs k * coeff (vAffine (pivs i)) k) + constant (vAffine (pivs i))
≈⟨ +-cong (∑Ext sameInSum) constVAffine≈ ⟩
∑ (λ k → - (A i (pivRes k) * vecs k)) + b i ≈⟨ +-comm _ _ ⟩
b i + ∑ (λ k → - (A i (pivRes k) * vecs k)) ∎
∑CoeffConst₁ : ∀ j k → coeff (vAffine (pivRes j)) k ≈ δ j k
∑CoeffConst₁ j k rewrite vSplit′-rPivs _ j pivsCrescent = refl
∑CoeffConst₂ : ∀ j → constant (vAffine (pivRes j)) ≈ 0#
∑CoeffConst₂ j rewrite vSplit′-rPivs _ j pivsCrescent = refl
∑Eq = λ j → begin
_ ≈⟨ +-identityʳ _ ⟩
∑ (λ k → vecs k * δ j k) ≈⟨ ∑Ext (λ k → *-comm (vecs k) _) ⟩
∑ (λ k → δ j k * vecs k) ≈⟨ ∑Mul1r _ j ⟩
vecs j ∎
∑NPiv = begin
∑ (λ j → A i (pivRes j) * (∑ (λ k → vecs k * coeff (vAffine (pivRes j)) k) + constant (vAffine (pivRes j))))
≈⟨ ∑Ext (λ j → *-congˡ (+-cong (∑Ext (λ k → *-congˡ (∑CoeffConst₁ j k))) (∑CoeffConst₂ j))) ⟩
∑ (λ j → A i (pivRes j) * (∑ (λ k → vecs k * δ j k) + 0#)) ≈⟨ ∑Ext (λ j → *-congˡ (∑Eq j)) ⟩
∑ (λ j → A i (pivRes j) * vecs j) ∎