Executable rational linear solving with module-valued right-hand sides #
Gaussian elimination and back-substitution for A x = b, where A has rational
entries and b and x take values in any ℚ-module M with decidable equality.
Declaration checking needs this generality: the coefficients (exponents of base
units) are rational, but the right-hand sides are logarithms of declared
factors. DeclSolver.solve takes M to be LogFactor, whose equality is
decided in exact rational arithmetic; DeclSolver.factorCoefficients and
DeclarationComplete.checkSpan take M = ℚ.
Pivot selection is a finite search for a nonzero rational coefficient. A row
whose coefficients are all zero after reduction is a rigid residual: the
system has no solution if its right-hand side is nonzero, and that is the only
equality test performed in M. Variables never chosen as pivots are set to
0. No basis choice, real equality test, or noncomputable data occurs.
The entry point is solve. solve_sound shows that every returned assignment
satisfies the system, and solve_isSome_iff that solve succeeds exactly
when a solution exists in M. solve_map and solvable_map_iff transfer
solvability along an injective ℚ-linear map; DeclSolver.solve_isSome_iff
uses them with LogFactor.interpret to pass from exact logarithms to real
valuations.
The first nonzero coefficient, or no pivot for a zero row.
Equations
- r.pivot = List.find? (fun (j : Fin n) => decide (r.coeff j ≠ 0)) (List.finRange n)
Instances For
Row subtraction eliminates a chosen pivot coefficient.
Equations
Instances For
Solve one pivot variable with the remaining coordinates held fixed.
Equations
Instances For
Reduce all remaining rows against one pivot.
Equations
- LambdaS.RationalSolver.reduceRows rows p j = List.map (fun (r : LambdaS.RationalSolver.Row n M) => r.reduce p j) rows
Instances For
Gaussian elimination with executable pivot search and back-substitution.
Each call consumes the head row. A row with a pivot eliminates that variable
from the remaining rows, and back-substitution solves for it after the
recursive call. A row with no pivot is dropped when its right-hand side is 0
and makes the result none otherwise. Variables never chosen as pivots are
set to 0.
Equations
Instances For
Every assignment the executable solver returns satisfies the system.
Solve A x = b, where coefficients are rational and values lie in M.
Equations
Instances For
Success decides solvability over the supplied decidable ℚ-module.
Apply a linear map to the right-hand side, leaving coefficients untouched.
Instances For
Executable solving commutes with an injective linear change of value carrier. Injectivity ensures the same rigid-residual zero tests in both.
The matrix solver commutes with an injective linear embedding.
Solvability reflects along an injective linear embedding, even if equality in the larger carrier is not executable. Classical equality is used only in this proof, never in the solver that computes over the smaller carrier.
Failure decides absence of any solution, rather than an algorithmic inability to select pivots.
Executable boundary checks. Soundness and completeness above are kernel proofs; these guards also exercise the actual finite-search implementation.