nx_solve_steps_lib.nx
buildroot/runtime/nx_solve_steps_lib.nx
about
nx_solve_steps_lib.nx -- A SOLVE, WORKED STEP BY STEP, EACH STEP NAMING THE RULE IT APPLIED.
WHY THIS EXISTS (measured 2026-09-03). nx_capsearch over 7,305 sources with corpus_complete=1 shows the
estate ALREADY HAS a solver: nx_calc_solve ships nx_calc_solve_linear and nx_calc_solve_quadratic and
returns roots. What it does not produce is the WORKING. The rival the operator named states its own
product as "get step-by-step algebra answers instantly", so the gap against it was never the arithmetic
-- it was the explanation. This organ is that join, and it is deliberately a SEPARATE lib rather than a
change to the solver, because "what is the answer" and "how would a person get there" are two questions
and one organ should do one thing.
EVERY STEP CARRIES ITS RULE. A worked solution that shows lines without naming the operation is a
magic trick; a learner cannot tell a legal move from a wrong one. So each row is RULE then LaTeX, and
the LaTeX goes through nx_mathml at render time, so the page shows real typeset mathematics with no
third-party typesetter anywhere in the path.
★EXACT WHERE EXACT IS POSSIBLE, AND HONEST WHERE IT IS NOT. Rational answers are reduced by gcd and
printed as fractions, never as truncated decimals. When a quadratic root is irrational this says so and
prints the EXACT radical form rather than a rounded decimal pretending to be the answer. A solver that
silently rounds is teaching that mathematics is approximately true.
license_tier: ORIGINAL
dependencies 2 imports · 2 importers
imports: syscalls.nxnx_isqrt.nx
imported by: nx_math_page.nxnx_solve_steps_gate.nx
structs
| none |
consts
| 25 | const SS_OK: i64 = 0 |
| 26 | const SS_ERR_SHORT: i64 = 0 - 1 |
| 27 | const SS_ERR_NOT_LINEAR: i64 = 0 - 2 // a == 0 in a*x + b = c is not an equation in x |
| 28 | const SS_ERR_NOT_QUAD: i64 = 0 - 3 // a == 0 in a*x^2 + bx + c is the linear case, refuse by name |
| 29 | const SS_MAXSTEPS: i64 = 16 |
functions
| 31 | func ss_slen(s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { i = i + 1 } return i } called by 1: ss_put |
| 33 | func ss_put(b: *u8, off: i64, cap: i64, s: *u8) -> i64 |
| 42 | func ss_num(b: *u8, off: i64, cap: i64, v: i64) -> i64 |
| 61 | func ss_gcd(a: i64, b: i64) -> i64 called by 1: ss_rational |
| 73 | func ss_rational(b: *u8, off: i64, cap: i64, num: i64, den: i64) -> i64 |
| 90 | func ss_row(b: *u8, off: i64, cap: i64, rule: *u8) -> i64 |
| 95 | func ss_end(b: *u8, off: i64, cap: i64) -> i64 { return ss_put(b, off, cap, "\n" as *u8) } |
| 98 | func ss_linear_lhs(b: *u8, off: i64, cap: i64, a: i64, bb: i64) -> i64 |
| 108 | func ss_steps_linear(a: i64, b0: i64, c: i64, out: *u8, cap: i64) -> i64 |
| 143 | func ss_steps_quadratic(a: i64, b: i64, c: i64, out: *u8, cap: i64) -> i64 |
| 212 | func ss_err_name(e: i64) -> *u8 called by 1: mp_render |