///|
pub struct Equation {
coefficients : Symbols
payload : Symbols
}
///|
pub fn Equation::new(
coefficients : Symbols,
payload : Symbols,
) -> Equation raise CodeError {
if coefficients.length() < 1 || coefficients.length() > 64 {
raise Limit("equation coefficient count must be 1..64")
}
if payload.length() < 1 || payload.length() > 4096 {
raise Limit("equation payload width must be 1..4096")
}
{ coefficients, payload, }
}
///|
pub fn Equation::coefficients(self : Equation) -> Symbols {
self.coefficients
}
///|
pub fn Equation::payload(self : Equation) -> Symbols {
self.payload
}
///|
pub enum Admission {
Innovative(Int32, Int32)
Dependent
}
///|
pub struct Basis {
columns : Int32
width : Int32
rows : Array[Equation?]
mut rank_value : Int32
}
///|
pub fn Basis::new(columns : Int32, width : Int32) -> Basis raise CodeError {
if columns < 1 || columns > 64 {
raise Limit("basis columns must be 1..64")
}
if width < 1 || width > 4096 {
raise Limit("basis payload width must be 1..4096")
}
{ columns, width, rows: Array::make(columns, None), rank_value: 0, }
}
///|
pub fn Basis::rank(self : Basis) -> Int32 {
self.rank_value
}
///|
pub fn Basis::deficit(self : Basis) -> Int32 {
self.columns - self.rank_value
}
///|
pub fn Basis::pivots(self : Basis) -> Array[Int32] {
let out : Array[Int32] = []
for i in 0.. Array[Equation] {
let out : Array[Equation] = []
for row in self.rows {
if row is Some(equation) {
out.push(equation)
}
}
out
}
///|
// Compute everything privately, then publish the new RREF state atomically.
// A dependent nonzero residual is a contradiction, never an innovation.
pub fn Basis::admit(
self : Basis,
equation : Equation,
) -> Admission raise CodeError {
if equation.coefficients.length() != self.columns ||
equation.payload.length() != self.width {
raise Shape("equation does not match basis dimensions")
}
let coefficients = equation.coefficients.to_array()
let payload = equation.payload.to_array()
for i in 0.. Array[Symbols] raise CodeError {
if self.deficit() != 0 {
raise Incomplete(self.deficit())
}
let out : Array[Symbols] = []
for row in self.rows {
match row {
Some(equation) => out.push(equation.payload)
None => raise Incomplete(self.deficit())
}
}
out
}
///|
// Rows containing just one coefficient already determine a source symbol.
pub fn Basis::known(self : Basis) -> Array[(Int32, Symbols)] {
let out : Array[(Int32, Symbols)] = []
for i in 0..