open import Algebra.DecidableField
module SystemEquations.Data {c ℓ₁ ℓ₂} (dField : DecidableField c ℓ₁ ℓ₂) where
open import Level
open import Function
open import Data.Empty
open import Data.Bool
open import Data.Unit.Polymorphic
open import Data.Nat hiding (_⊔_)
open import Data.Maybe as Maybe
open import Data.Product
open import Data.Vec
open import Data.Vec.Functional using (fromVec; toVec)
open import Vec.Base
open import Algebra.MatrixData.Base
open DecidableField dField renaming (Carrier to F)
open import SystemEquations.Definitions dField as SE using ()
open import SystemEquations.UniqueSolution dField
private variable
m n : ℕ
infix 6 _+span_
record Affine (p : ℕ) : Set c where
constructor vAff
field
coeff : Vec F p
constant : F
VecAffine : (nVars freeVars : ℕ) → Set c
VecAffine nVars freeVars = Vec (Affine freeVars) nVars
unfoldConstants : VecAffine n m → Vec F n
unfoldConstants [] = []
unfoldConstants (vAff coeff constant ∷ xs) = constant ∷ unfoldConstants xs
unfoldVecs : VecAffine n m → Matrix F n m
unfoldVecs [] = []
unfoldVecs (vAff coeff constant ∷ xs) = coeff ∷ unfoldVecs xs
record AffineTranspose (nVars freeVars : ℕ) : Set c where
constructor _+span_
field
constants : Vec F nVars
coeffs : Matrix F freeVars nVars
open AffineTranspose
vAff→vAffT : VecAffine n m → AffineTranspose n m
vAff→vAffT xs = unfoldConstants xs +span transpose (unfoldVecs xs)
record SystemEquations (rows cols : ℕ) : Set c where
constructor system
field
A : Matrix F rows cols
b : Vec F rows
data Solution (n : ℕ) : Set (c ⊔ ℓ₁) where
sol : ∀ p (affine : VecAffine n p) → Solution n
noSol : Solution n
HasSolution? : Solution n → Bool
HasSolution? (sol _ _) = true
HasSolution? noSol = false
HasNoSolution? : Solution n → Bool
HasNoSolution? = not ∘ HasSolution?
HasNoSolution : Solution n → Set
HasNoSolution = T ∘ HasNoSolution?
HasUniqueSolution? : Solution n → Bool
HasUniqueSolution? (sol ℕ.zero affine) = true
HasUniqueSolution? (sol (ℕ.suc p) affine) = false
HasUniqueSolution? noSol = false
HasUniqueSolution : Solution n → Set
HasUniqueSolution = T ∘ HasUniqueSolution?
solve : SystemEquations n m → Solution m
solve se = help solF
where
open SystemEquations se
seF = SE.system (matrixData→Fun A) (fromVec b)
module SeF = SE.SystemEquations seF
solF = solveUniqueSystemEquations seF
help : SeF.Solution → Solution _
help (SE.SystemEquations.sol p affine x) = sol p $ tabulate $ help2 ∘ affine
where
help2 : _ → _
help2 (SE.vAff coeff constant) = vAff (toVec coeff) constant
help (SE.SystemEquations.noSol _) = noSol
sizeSolutionT : Solution n → Set _
sizeSolutionT (sol _ _) = ℕ
sizeSolutionT noSol = ⊤
sizeSolution : (solution : Solution n) → sizeSolutionT solution
sizeSolution (sol p _) = p
sizeSolution noSol = _
solMComplexT : Solution m → Set _
solMComplexT {m} (sol p affine) = Matrix F p m
solMComplexT noSol = ⊤
solMComplex : (solution : Solution n) → solMComplexT solution
solMComplex (sol p affine) = coeffs $ vAff→vAffT affine
solMComplex noSol = _
solveComplex0 : (A : Matrix F n m) → solMComplexT $ solve $ system A $ repeat 0#
solveComplex0 A = solMComplex $ solve $ system A $ repeat 0#
solAllT : Solution m → Set c
solAllT {m} (sol ℕ.zero affine) = Vec F m
solAllT {m} (sol p@(ℕ.suc _) affine) = AffineTranspose m p
solAllT noSol = ⊤
solAll : (solt : Solution m) → solAllT solt
solAll (sol ℕ.zero affine) = unfoldConstants affine
solAll (sol (ℕ.suc p) affine) = vAff→vAffT affine
solAll noSol = _
solveAll : (A : Matrix F n m) (b : Vec F n) → solAllT $ solve $ system A b
solveAll A b = solAll $ solve $ system A b