Symbolic mathematics
Symbolic mathematics
Grid symbolic mathematics is part of the ordinary reactive language. It is not
a quoted expression language, a string evaluator, or a second compiler. Declare
unknowns with contextual symbol statements, then compose them with ordinary
Grid operators, references, literals, and admitted mathematical functions.
symbol x
input A1 = 2
polynomial = x^2 + 2*x + 1
reactive = A1*x^2 + 1x is an immutable symbolic_variable. Its identity includes the authority of
the module that declared it; importing or aliasing it does not rename it. A1
is still an ordinary reactive input. Editing A1 rebuilds reactive and its
dependants, while unrelated symbolic values retain their identities.
The compiler evaluates a purely ordinary subtree before lifting its result. In
(A1 + B1) * x, A1 + B1 is one ordinary coefficient with both dependency
edges; it does not turn either cell into an unknown. Values that cannot cross
the exact symbolic boundary—strings, blanks, booleans, errors, units, lossy
coercions, volatile results, and effectful results—fail closed.
Transformations return records
Constructors return symbolic values directly. Transformations return an atomic record so status, conditions, work, completeness, and certificate cannot be silently separated from the answer.
canonical_result = SYMBOLIC.CANONICALIZE(polynomial)
canonical = canonical_result.expression
expanded_result = SYMBOLIC.EXPAND(polynomial)
collected_result = SYMBOLIC.COLLECT(polynomial, x)
factored_result = SYMBOLIC.FACTOR(polynomial)
derivative_result = SYMBOLIC.D(polynomial, x)An expression-operation result contains:
| Field | Meaning |
|---|---|
status |
:complete, :conditional, :not_applicable, :limit, or :invalid |
expression |
The completed symbolic expression, or BLANK when no answer was certified |
conditions |
Normalized unresolved propositions required by the result |
changed |
Whether the returned expression differs structurally from the input |
complete |
Whether the named operation completed its declared algorithm |
work |
Deterministic bounded kernel and certificate-adapter work charged by the operation |
certificate |
A certificate-bound Tree derivation handle that is replayable with the exact operation input |
The public record and its bounded WHY projection can verify that the handle
binds the visible output, conditions, operation/version, input fingerprint,
and stated work coordinate. They deliberately do not retain the operation
input, so that inspection-only check is not itself a replay or an independent
proof of the adapter-work amount. Authoritative validation supplies the exact
input, recomputes its portable bytes and every adapter charge, and reconstructs
the handle byte for byte. For SOLVE, it also validates the result and all
branch certificates as one cumulative batch.
Operators may enable that validation at the publication boundary; in that verification mode, every completed expression, decision, and solution reruns its closed native operation before publication. The mode is off by default because it deliberately performs a second kernel run. It is not a fallback, a second evaluator, or part of ordinary symbolic execution.
:complete means the named deterministic algorithm completed. It does not
claim that SIMPLIFY found a globally smallest expression. A limit or
unsupported domain never publishes a plausible uncertified partial answer.
The initial exact transformation family is:
| Function | Contract |
|---|---|
SYMBOLIC.CANONICALIZE(f) |
Deterministic structural canonical form |
SYMBOLIC.SIMPLIFY(f, assumptions?) |
Assumption-aware deterministic simplification |
SYMBOLIC.EXPAND(f) |
Exact polynomial expansion |
SYMBOLIC.COLLECT(f, x) |
Exact coefficient collection by variable |
SYMBOLIC.FACTOR(f) |
Complete admitted univariate factorization over the rationals |
SYMBOLIC.CANCEL(f, assumptions?) |
Rational-factor cancellation with nonzero obligations |
SYMBOLIC.TOGETHER(f, assumptions?) |
Exact common-denominator combination |
SYMBOLIC.APART(f, x, assumptions?) |
Exact univariate partial fractions |
SYMBOLIC.D(f, x, assumptions?) |
Symbolic differentiation with branch conditions |
Existing unqualified EXPAND, SOLVE, DERIVATIVE, and numeric root
functions retain their existing array, matrix, and numeric meanings.
Substitution, evaluation, and approximation
A substitution is a typed immutable binding. Its selector is a
symbolic_variable value, never identifier text.
at_three = SYMBOLIC.SUBSTITUTION(x, 3)
value_result = SYMBOLIC.EVALUATE(polynomial, at_three)
value = value_result.expression # 16SYMBOLIC.EVALUATE(f, binding, assumptions?) substitutes, performs exact
ground arithmetic, and then consumes the optional assumptions while
simplifying the result and discharging supported conditions. The assumptions
are semantic input to the operation and its certificate; they are not merely
validated metadata. Evaluation does not imply an approximate conversion. Use
SYMBOLIC.APPROXIMATE explicitly for a ground expression:
third = SYMBOLIC.RATIONAL(1, 3)
approx_result = SYMBOLIC.APPROXIMATE(third, 128, :nearest_even)
approx = approx_result.expressionThe precision is in bits. Supported rounding symbols are :nearest_even,
:toward_negative, :toward_positive, :toward_zero, and
:away_from_zero. The result retains its effective precision, rounding policy,
representative value, and outward exact enclosure. Effective precision is the
requested precision capped by the authority of any approximate source—for
example, a machine-real input cannot acquire more than its 53 source bits merely
by requesting a larger result. Approximate values remain explicitly approximate
and cannot satisfy an exact proof obligation.
Assumptions and decisions
Assumptions are immutable, fingerprinted four-state evidence values. They are local inputs to an operation; they do not mutate the expression or global model truth.
positive_real = SYMBOLIC.ASSUMPTIONS(
SYMBOLIC.DOMAIN(x, :real),
x > 0
)
cancelled_result = SYMBOLIC.CANCEL(x / x, positive_real)
decision_result = SYMBOLIC.DECIDE(x > 0, positive_real)Evidence states are :neither, :supported, :refuted, and :both.
Contradictory evidence remains :both; it is never coerced to true. Domain
evidence follows the mathematical refinement lattice: integer implies real,
and real implies complex, subject to the same four-state rules.
The four states are the same canonical evidence type used by Grid Predicate.
Here, predicate_proposition means the operation-local symbolic relation/domain
adapter accepted by SYMBOLIC.ASSUMPTIONS; it is not a publication into the
global Predicate program. Constructing an assumption therefore does not add a
model fact or run Predicate inference. The adapter retains local
provenance-shaped records and ordinary Grid dependency edges for the symbolic
operation that consumes it.
Without supported nonzero evidence, cancelling x/x returns an explicit
condition. With supported and unrefuted x > 0, the condition is discharged.
Branch-sensitive identities for radicals, logarithms, and noninteger powers
retain their real/complex and sign obligations instead of assuming generic
values or principal branches.
SYMBOLIC.SAME(left, right) is only structural Tree identity. Build a
symbolic relation with ordinary comparison syntax and use SYMBOLIC.DECIDE
when asking for mathematical truth. A symbolic expression or relation cannot
be used as an IF, AND, OR, or NOT condition.
Ordinary function calls use one closed, default-deny Tree policy shared by
the compiler and resident evaluator. Explicit Tree consumers and reviewed
value carriers may receive a mathematical Tree in payload positions; every
other position rejects it with GRID_SYMBOLIC_CALL_TYPE, and every implicit
Boolean position rejects it with GRID_SYMBOLIC_TRUTHINESS. The runtime check
also covers a Tree that materializes from a callable union or is nested inside
an array or native collection, before a fast path or function bridge can
coerce or ignore it. Models with no symbolic authority do not run this scan.
Exact solving
SYMBOLIC.SOLVE solves an exact univariate polynomial relation in the selected
domain:
roots = SYMBOLIC.SOLVE(polynomial == 0, x, :complex)
constrained = SYMBOLIC.SOLVE(polynomial == 0, x, :complex, positive_real)The domain argument is optional. An assumptions value may occupy the third
argument when no domain is written, or the fourth argument after an explicit
domain. Assumptions are consumed by the solve: a certified exact branch is
removed only when its binding is refuted without simultaneous support.
:both, unknown, and non-scalar algebraic candidates are retained rather than
guessed away.
The result contains status, canonical branches, domain, complete,
work, and a result-level certificate. Every branch contains typed
bindings, conditions, an exact multiplicity, and its own certificate.
Rational roots are returned directly; other algebraic roots use canonical
root_of values with certified real intervals or complex rectangles.
:none is used only with a complete no-solution certificate in the named
domain. :unknown and :limit are distinct and never presented as no
solution. Over the complex domain, branch multiplicities account for the full
polynomial degree within the admitted limits.
One resident Tree value
Symbolic expressions and relations refine Grid's portable syntax_tree value
under the shipped math.expression authority. The internal prefix grammar is
only a validation and hydration contract; it is not author syntax.
Consequently the same resident value works with TREE.RENDER, structural Tree
inspection, GRAPH, history, and WHY. Display text is bounded and is never
used to reconstruct or compare a symbolic value. Persistence hydrates the Tree
and derivation identities directly. A canary or restart audit re-evaluates the
resident operation with input-bearing replay; the inspection-only projection
does not validate the operation's input or charged work.
Limits and refusal
Symbolic construction and algorithms enforce bounded term size, depth,
coefficient bits, polynomial degree, precision, encoded bytes, assumptions,
branches, and deterministic work. A breached bound returns an explicit
:limit result or a GRID_SYMBOLIC_* diagnostic without partially publishing
an answer.
See the complete function signatures in the function catalog and the diagnostics in Errors and diagnostics. Worked recipes live in the cookbook.