Symbolica 3.0 documentation inventory

Audited 2026-09-18, after website commit 824c48c.

Sources: the adjacent Symbolica checkout at 1f38ba9e (Release Symbolica 3.0), its current source/stubs and migration tests, the website’s draft 3.0 migration guide and release post, and the bundled WASM runtime (symbolica-1f38ba9). The Symbolica checkout has local modifications, including root documentation and implementation changes; check those against the intended published build before regenerating reference docs. The system Python installation reports symbolica-77c1374 and lacks the new extension keywords, so it is not a suitable 3.0 validation target.

This is an inventory, not an implementation of the remaining documentation updates. Existing edits to API pages, installation, licensing, navigation, and the release/migration drafts were left intact.

Priority 1: incorrect behavior or broken examples

Page / location Required update Evidence / status
docs/pattern_matching.qmd:133, :634 Rewrite both antisymmetry explanations. Wildcard-containing calls retain argument order; matching is positional. Replace the permutation and helper-sign examples and their expected outputs. The current text says antisymmetric matching has symmetric permutation freedom. In the bundled 3.0 runtime, (fa(1,2)*f(2)).replace(fa(x_,y_)*f(x_), f(x_,y_)) stays f(2)*fa(1,2), rather than the displayed f(2,1).
docs/pattern_matching.qmd:331, docs/transformers.qmd:58 Explain Boolean ==/!= versus deferred .eq()/.ne(); restrict the existing comparison-operator claims to ordered comparisons. Use None, not Inconclusive, for an unknown Python condition, and explain explicit .eval() handling. Confirmed in ../symbolica/tests/python/test_comparison_contract.py. The callback and matching-level sections have already been updated and need no wholesale rewrite.
docs/polynomials.qmd:193, :240 Replace/recheck the Rust algebraic-field examples. Construct AlgebraicExtension from a polynomial, use the current field-composition API or the new context conversion, and fix et p. Regenerate the shared expected outputs. AlgebraicExtension::new takes a MultivariatePolynomial, not the Atom currently supplied. The old g.extend(&g2) recipe should be replaced with a verified 3.0 example. The Python example now uses explicit radicals while the displayed composite-field output still uses the old formal generator.
docs/numerical_integration.qmd:309, :392 Update Rust grid constructors to handle Result, use the compatible RNG re-export, and supply both learning rates to DiscreteGrid.update. Compile the full examples. Current Numerica constructors return Result; discrete update takes two rates. These blocks also have older defects: undefined sample, iterations, imaginary_part, and imag_eval, and one-dimensional grids used as two-dimensional ones. The runnable Python examples have already been corrected.
docs/python_api/ Regenerate the Python reference from the intended 3.0 stubs, then review changed examples and anchors. Update the generator’s index groups and the manual sidebar. Concrete stale entries include Expression.solve_linear_system, Expression.__eq__ -> Condition, property checks returning only bool, Decimal-based evaluation/root results, Evaluator.get_instructions() returning a tuple, and old root-isolation signatures. See the API checklist below.

Priority 2: missing 3.0 tutorial coverage

Page / location Add or revise
docs/polynomials.qmd:11, :176, :344 Make this the primary guide to coefficient-domain selection. Cover the construction routes below, selected algebraic roots, factorization, and conversion back to expressions. Add the Rust rational-polynomial context path without implying an equivalent Python keyword exists.
docs/expressions.qmd:212, :256 Introduce Float and ComplexFloat, explicit precision and conversions, and exact Expression.root(index, variable=...) values. Explain structural equality versus deferred conditions and the unknown result of mathematical property checks, or link to the matching/symbols explanations. Decimal inputs still work; do not describe them as removed.
docs/symbols.qmd:112, :220, :652 Add is_flat=True / Flat, lookup with Expression.get() / Symbol::get(), and examples of True / False / None property results. Explain that decimal and decimal_complex callbacks now receive Float and ComplexFloat. Demonstrate a precision-aware Float constant; the existing Decimal constant callback remains valid. Mention the wildcard exception to antisymmetric normalization.
docs/numerical_evaluation.qmd:103, :157, :326 Add concrete arbitrary-precision examples and result types, Float/ComplexFloat callback examples, and the inlining="auto"/"always"/"never" choice on FunctionDefinition. Document EvaluatorInstructions, dimensions, constants, and nested function bodies. Replace the stale reference to a Python functions dictionary key with the current FunctionDefinition/tag API. The compiled-library loading example is already updated.
docs/quick_start.qmd:262, :307, :408 Keep this short: link to algebraic-domain construction, mention multivariate/automatic apart, and broaden the solving introduction beyond linear systems. Explain or link to solution conditions/coverage before readers copy [0] as a general solve recipe. Link to series coefficient semantics. The current basic examples already run on the bundled 3.0 runtime.
New focused solving/series coverage, or expanded existing tutorials Give SolutionSet/Solution a durable tutorial: nonlinear equations, parameters, free variables, domain selection, complete versus generic coverage, exceptional cases, and algebraic roots. Explain known-zero versus unknown series coefficients (IndexError outside the computed order), fractional/negative powers and the exclusive absolute-order boundary. These are currently covered principally by the migration draft, not a normal concept page.
docs/get_started.qmd:31, :78, :286 Link the 3.0 migration guide; document independent integer/float backend features and WASM/native-code-generation choices where relevant to source builds. Replace UUID-shaped license examples with an explicitly illustrative current-format placeholder and explain renewal of old offline keys. The Rust prelude import already remains valid.
docs/upgrade/migration_to_3_0.qmd, posts/symbolica_3_0_release/index.qmd Add Python algebraic-domain construction and a link to the rewritten polynomial guide. The migration draft currently only mentions the Rust algebraic module move. Add root-isolation API migration (IsolatedRoot and the real-interval helper), and validate root-index examples against the intended release build. Resolve the migration draft’s “When 3.0 is available” wording when publishing. Both files are existing untracked drafts.
docs/matrices.qmd:12, :119 Add concise notes on constructor shape validation and singular inverses if those behaviors are demonstrated. Any future sparse-matrix coverage must explain validated CSR construction. Also fix the existing Rust diagonal-matrix example to use Matrix::eye, not the size-based Matrix::identity.

Polynomial / algebraic-domain teaching sequence

These routes should be presented together so users can choose deliberately:

  1. Default conversion: E('x+sqrt(2)').to_polynomial() keeps sqrt(2) as an independent polynomial variable. Preserve this behavior in the construction explanation; automatic algebraic coefficients are opt-in.
  2. Discover algebraic coefficients: E('x+sqrt(2)').to_polynomial(extensions=[]) constructs a common number field and leaves only x as a polynomial variable.
  3. Adjoin additional generators: E('x^2-2').to_polynomial(extensions=[E('sqrt(2)')]) factors over a field containing a generator absent from the input. Show a multiple-generator example, and a selected root(...) generator as well as radicals.
  4. Choose a formal field by its minimal polynomial: E('x^2-2').to_polynomial(minimal_poly=P('t^2-2')). Explain the formal generator t versus the selected embedding represented by a radical/root. A defining polynomial alone does not select a particular real/complex root.
  5. Convert an existing polynomial: P('x^2-2').to_number_field(P('t^2-2')).
  6. Explicitly compose minimal polynomials: P('a^2-2').adjoin(P('b^2-3')) returns the new minimal polynomial plus representations of both generators. Explain substituting those representations before converting to the combined field. This is a useful advanced route already documented in the API, but absent from the tutorial; do not label every existing route as newly introduced in 3.0.
  7. Factor an expression directly: E('x^2-2').factor(extension=[E('sqrt(2)')]). Point out the singular extension here versus plural extensions in to_polynomial.

Document vars ordering and that extensions cannot be combined with modulus, power, or minimal_poly. Keep finite/Galois-field construction separate (modulus, power); those are not algebraic number fields over Q.

For Rust, show to_polynomial_in_algebraic_extension::<u16>(variables, generators) returning (context, polynomial), discovery with an empty generator slice, and to_expression_with_context(&context) to recover the embedded expressions. Explain AlgebraicContext construction/adjoining for advanced workflows, and the distinction between a formal quotient and a selected algebraic embedding. Add to_rational_polynomial_in_algebraic_extension to the rational-polynomial section. Python to_rational_polynomial currently has no extensions option.

Evidence: ../symbolica/src/api/python/expression.rs (factor, to_polynomial), ../symbolica/src/api/python/polynomial.rs, ../symbolica/src/atom/core.rs, ../symbolica/src/domains/algebraic.rs, and ../symbolica/examples/algebraic_factor_expression.rs. Routes 1–7 above were exercised successfully in the bundled WASM runtime.

Python API regeneration checklist

  • Refresh Expression, Transformer, HeldExpression, Condition, PatternRestriction, and Replacement for comparison/condition and callback contracts; refresh S, N, E, and SymbolAttribute as applicable.
  • Refresh Polynomial, NumberFieldPolynomial, RationalPolynomial, and related domain classes. In particular, Polynomial.isolate_roots now returns complex isolated-root objects and multiplicities; real isolation and rational intervals have explicit helpers. Refresh algebraic conversion overloads and factorization keywords on Expression.
  • Refresh Series, Evaluator, compiled evaluator classes, and numeric input unions throughout. Existing local compiled-loader corrections must be preserved by updating their source documentation where necessary.
  • Add/index the 15 classes present in the checked-out stub but missing as website pages: Float, ComplexFloat, SolveDomain, SolveError, UnsupportedProblem, IncompleteCoverage, SolutionCondition, Solution, SolutionSet, RootLocation, Symbol, IsolatedRoot, FunctionDefinition, EvaluatorInstructions, and EvaluatorFunction.
  • Include the Integers, Rationals, Reals, and Complexes exported domain values. The generator collects classes and functions; adding classes alone does not document these module-level values.
  • Update scripts/generate_python_api_docs.py (SECTION_SPECS and type-link handling), docs/python_api/index.qmd, and the manual API list in _quarto.yml. Merely rerunning the generator writes pages for new classes but does not put them into the hard-coded overview/sidebar.
  • Correct the upstream NumberFieldPolynomial summary, which still says “rational coefficients”, so regeneration retains the fix.
  • Keep API pages static: this inventory does not propose making their signature blocks or isolated reference fragments runnable.

Existing cleanup found alongside the 3.0 work

  • docs/coefficients.qmd:64 and :86 still use removed .transform() / .execute() patterns in the static continuation examples. Convert to the current callable-transformer / held-expression API. This is not established as a new 3.0 break; the first runnable example was already corrected.
  • docs/logging.qmd:19 calls use_custom_logging(); the exported function is use_custom_logger().
  • The integration and matrix defects noted above include older copy/paste errors, not just 3.0 changes.
  • scripts/check_code_snippets.py does not recognize {.python .live-python} fences. Update its extractor before treating its output as a complete audit.
  • The live runtime tests check that examples execute and produce output; they do not compare every tutorial’s static expected result. Add targeted semantic assertions for changed behavior such as antisymmetric matching and algebraic coefficient discovery. Successful execution did not catch the antisymmetric example’s wrong displayed result.

No specific 3.0 rewrite was identified for the current graph, streaming, or automatic-differentiation tutorials in this source review. The memory page is still a placeholder. Preserve old release posts and 2.0/2.2 migration examples as historical material, with links to the 3.0 guide where useful. Licensing text already has local edits; review it with the 3.0 release rather than overwriting it as part of the runnable-example work.

Suggested implementation order and verification

  1. Correct antisymmetric matching and the comparison explanations.
  2. Rewrite the algebraic-domain section with Python/Rust examples, then link it from First steps, expressions, and the migration/release pages.
  3. Regenerate and index the Python API against the intended 3.0 build.
  4. Add numeric scalar/callback, solving, and series tutorial coverage.
  5. Fix/compile Rust examples, then update installation and release navigation.

Validate new runnable snippets in the bundled 3.0 WASM runtime, native/JIT examples against a matching native 3.0 build, and Rust examples against the local 3.0 crate. Check expected mathematical results, render the affected pages, and check reference links after regeneration. This audit did not compile every Rust example or execute every static documentation fragment.