# PolymathPlus NLE Specification ## What This Program Type Solves NLE is the PolymathPlus nonlinear algebraic program family. It covers expression evaluation and nonlinear root solving. This specification covers: - `NLE0`: explicit-equation and expression-evaluation mode, with no root-solving. - `NLE1`: one nonlinear root equation. - `NLES`: two or more simultaneous nonlinear root equations. Common rules that always apply: - `#` starts a comment. Comments are ignored by validation. - Blank lines are allowed and ignored. - Variable names must start with a letter and then use only letters, digits, or underscore. - Do not use built-in function names or conditional keywords as variable names. Examples to avoid include `sin`, `sqrt`, `log`, `if`, `then`, and `else`. - Also avoid variable names that begin with `and` or `or`, because those prefixes are tokenized as logical operators by the validator. - Keep one consistent program style. Do not mix NLE with DEQ, LEQ, NLP, regression, or table-based program formats. ## User Rules For Writing A Valid NLE Program ### 1. Choose the correct NLE subtype Use `NLE0` when the program only evaluates explicit equations and optional anonymous expressions: ```polymathplus a = 1 b = 4 x = a + b^2 x + 2 ``` Use `NLE1` when solving one nonlinear root equation: ```polymathplus f(x) = x^2 - 4 x(min) = 0 x(max) = 3 ``` Use `NLES` when solving two or more nonlinear root equations: ```polymathplus f(x) = x + y - 1 f(y) = x - y x(0) = 0.5 y(0) = 0.5 ``` ### 2. Root-line rules Root lines use this format: ```polymathplus f(variable) = expression ``` Rules: - The variable inside `f(...)` is the nonlinear variable to solve for. - Write the right-hand side as a residual expression that should become zero. - Do not add a second `= 0` at the end of the root line. - Do not define the same nonlinear variable more than once. - Root expressions must be valid math expressions. - Multiplication may be explicit or implicit, for example `2*x^2` or `2x^2`. Example conversion: If the mathematical equation is: ```polymathplus 2x^2 - sin(1/x) = 0.5 ``` write it as: ```polymathplus f(x) = 2*x^2 - sin(1/x) - 0.5 ``` Invalid: ```polymathplus f(x) = x^2 - 4 = 0 x(min) = 0 x(max) = 3 ``` Repair: ```polymathplus f(x) = x^2 - 4 x(min) = 0 x(max) = 3 ``` ### 3. Explicit-equation rules Explicit equations use this format: ```polymathplus variable = expression ``` Rules: - Explicit equations are allowed in all NLE subtypes. - Use explicit equations to simplify long formulas or reuse repeated sub-expressions. - Explicit variable names must be unique. - Explicit variables must not be circular or self-referencing. - An explicit variable cannot use the same name as a nonlinear root variable. Valid: ```polymathplus f(x) = g - 0.5 g = sin(x) + x^2 x(min) = 0 x(max) = 1 ``` Invalid direct self-reference: ```polymathplus f(x) = a - 2 a = a + 1 x(min) = 0 x(max) = 3 ``` Invalid circular reference: ```polymathplus f(x) = a - 2 a = b + 1 b = a + 1 x(min) = 0 x(max) = 3 ``` Invalid overlap between explicit and nonlinear variable: ```polymathplus f(x) = g x = 2 g = x + 1 x(min) = 0 x(max) = 3 ``` Repair by renaming or removing the overlapping explicit variable: ```polymathplus f(x) = g g = x + 1 x(min) = 0 x(max) = 3 ``` ### 4. Anonymous-expression rules Anonymous expressions are expressions without a left-hand variable assignment. Rules: - `NLE0` allows anonymous expressions when they are syntactically valid and use variables defined by explicit assignments in the same program. For validation, the explicit assignment may appear before or after the anonymous expression; for readability, define variables before using them. - `NLE1` and `NLES` do not allow anonymous expressions. Valid `NLE0`: ```polymathplus a = 1 b = 4 x = a + b^2 x + 2 ``` Invalid `NLE1`: ```polymathplus f(x) = x^2 - 4 x(min) = 0 x(max) = 3 x + 2 ``` Repair: ```polymathplus f(x) = x^2 - 4 x(min) = 0 x(max) = 3 ``` ### 5. Initial-guess and boundary rules For `NLE0`: - Do not use `x(0)=...`, `x(min)=...`, `x(max)=...`, or `x(f)=...` lines. For `NLE1`: - Provide exactly one minimum boundary: `x(min)=number`. - Provide exactly one maximum boundary: `x(max)=number`. - Do not use `x(0)=...` initial-guess lines. - Recommended: use the same variable name as the root line, for example `x(min)` and `x(max)` for `f(x)`. - Current precheck behavior: it requires exactly one numeric `min` boundary and one numeric `max` boundary, and checks that `min < max`; it does not currently enforce that the boundary variable name matches the root variable name. - Minimum must be strictly less than maximum. - Boundary values must be numeric literals, not expressions. Invalid `NLE1` using an initial guess: ```polymathplus f(x) = x^2 - 4 x(0) = 1 ``` Repair: ```polymathplus f(x) = x^2 - 4 x(min) = 0 x(max) = 3 ``` Invalid `NLE1` boundary expression: ```polymathplus f(x) = x^2 - 4 x(min) = 0 x(max) = 2 + 1 ``` Repair: ```polymathplus f(x) = x^2 - 4 x(min) = 0 x(max) = 3 ``` Current precheck accepts this, but it is not recommended because the boundary variable names do not match the root variable: ```polymathplus f(x) = x^2 - 4 y(min) = 0 y(max) = 3 ``` Recommended form: ```polymathplus f(x) = x^2 - 4 x(min) = 0 x(max) = 3 ``` For `NLES`: - Do not use `x(min)=...` or `x(max)=...` lines. - Provide one initial guess per nonlinear variable: `x(0)=number`. - Each initial-guess variable must match a variable defined in a root line. - Do not provide guesses for variables that do not have a matching root line. - Initial-guess values must be numeric literals unless constrained mode is enabled. Invalid `NLES` with a missing initial guess: ```polymathplus f(x) = x + y - 1 f(y) = x - y x(0) = 0.5 ``` Repair: ```polymathplus f(x) = x + y - 1 f(y) = x - y x(0) = 0.5 y(0) = 0.5 ``` ### 6. Constrained initial guesses Constrained initial guesses are allowed only for `NLES` when the constrained method directive is present: ```polymathplus #@ NLE_SOLUTION_METHOD_INDEX = 3 ``` For precheck, this directive must be on its own comment line. Do not add trailing text after `3` on the same line. Allowed constrained guess forms: ```polymathplus x(0) = 0.5 >0 y(0) = 0.35 >=0 ``` Invalid without constrained mode: ```polymathplus f(x) = x + y - 1 f(y) = x - y x(0) = 0.5 >0 y(0) = 0.5 ``` Repair: ```polymathplus #@ NLE_SOLUTION_METHOD_INDEX = 3 f(x) = x + y - 1 f(y) = x - y x(0) = 0.5 >0 y(0) = 0.5 ``` Invalid because the constrained directive has trailing text on the same line: ```polymathplus #@ NLE_SOLUTION_METHOD_INDEX = 3 # constrained method f(x) = x + y - 1 f(y) = x - y x(0) = 0.5 >0 y(0) = 0.5 ``` Repair by keeping the directive line exact and moving comments to another line: ```polymathplus # constrained method #@ NLE_SOLUTION_METHOD_INDEX = 3 f(x) = x + y - 1 f(y) = x - y x(0) = 0.5 >0 y(0) = 0.5 ``` Optional solver method hint: ```polymathplus #@ NLE_SOLUTION_METHOD_INDEX = 1 ``` Known method index values used by PolymathPlus: - `0`: Fast-Newton - `1`: Safe-Newton - `2`: Safe-Broydn - `3`: Constrained Default when omitted: `1` (`Safe-Newton`). Precheck note: - The precheck specifically uses the `3` directive to allow constrained initial-guess syntax such as `>0` and `>=0`. - Other method values are treated as comment metadata by precheck and are not validated as supported or unsupported values. ### 7. Unknown-variable rules Every variable used inside root expressions and explicit expressions must be defined as one of: - a nonlinear variable from a root line - an explicit variable from an assignment line For `NLE0`, anonymous expressions may use only variables defined by explicit assignments in the same program. Validation is order-independent, but defining variables before anonymous expressions is clearer for users and LLMs. Invalid: ```polymathplus f(x) = x + y - 1 x(min) = 0 x(max) = 2 ``` Repair: ```polymathplus f(x) = x + y - 1 y = 0.5 x(min) = 0 x(max) = 2 ``` ## Practical Checklist Before Solve - Choose exactly one NLE style: `NLE0`, `NLE1`, or `NLES`. - Use `f(variable)=expression` only for root equations. - Write root equations as residuals; do not end with a second `=0`. - Keep root variables unique. - Keep explicit variables unique and non-circular. - Do not reuse a root variable name as an explicit variable name. - Use anonymous expressions only in `NLE0`. - For `NLE1`, provide exactly one matching `min` and `max` boundary. - For `NLES`, provide exactly one matching initial guess per root variable. - Use constrained initial guesses only with `#@ NLE_SOLUTION_METHOD_INDEX = 3`. - Make sure every referenced variable is defined. ## Examples Of Valid NLE Programs ### Example A: `NLE0` explicit equations and anonymous expression ```polymathplus a = 1 b = 4 x = a + b^2 x + 2 ``` ### Example B: `NLE1` one root equation with helper expression ```polymathplus f(x) = t + 4*x^2 - 1620 t = x*log(x/2) x(min) = 0.1 x(max) = 100 ``` ### Example C: `NLES` nonlinear system ```polymathplus f(c) = 3.8907 - ln(6*c) - a f(a) = a + b - c b = 5*a - 3 c(0) = 2 a(0) = 2 ``` ### Example D: `NLES` with constrained initial guesses ```polymathplus #@ NLE_SOLUTION_METHOD_INDEX = 3 f(x1) = x1 + x2 - 1 f(x2) = x1^2 + x2 - 0.75 x1(0) = 0.35 >=0 x2(0) = 0.5 >0 ``` ## Verification Notes This hardened repo-local copy was checked against NLE behavior in: ```txt C:\dev\js\solver_precheck\solver_precheck.js C:\dev\js\solver_precheck\solver_precheckTests.js ``` The examples were selected or adapted from the test corpus and validator behavior. Test-only comments were removed, and example variable names/comments were adjusted for documentation use.