The symbolic calculus layer provides a small expression-tree system for CNRS-oriented workflows. It supports symbolic differentiation, conservative rule-based symbolic integration, evaluation through CnrsComplex, and cross-checking through the CnrsDual autodiff layer.
from cnrs.symbolic import Var, exp, sin, diff
s = Var("s")
L = Var("L")
expr = sin(exp(s / L))
deriv = diff(expr, s).simplify()
print(deriv)value = expr.eval({"s": 1.2, "L": 5.0}, L=20)
deriv_value = deriv.eval({"s": 1.2, "L": 5.0}, L=20)from cnrs.symbolic import integrate
A = Var("A")
k = Var("k")
scale_law = A * exp(k * s)
antideriv = integrate(scale_law, s).simplify()
print(antideriv)Unsupported integrals remain explicit:
integrate(exp(s * s), s)returns an unevaluated Integral object rather than inventing a closed form.
from cnrs.autodiff import CnrsDual
dual_result = expr.eval({"s": CnrsDual.variable(1.2, L=20), "L": 5.0}, L=20)
print(dual_result.value)
print(dual_result.deriv)This provides a useful regression check: evaluating diff(expr, s) numerically should agree with evaluating expr on a dual variable and reading the derivative component.
v0.5.1 adds explicit local branch choices for logarithms, square roots, and branch-aware powers.
from cnrs.symbolic import BranchState, Var, log, sqrt, pow_branch, diff
z = Var("z")
state = BranchState(log_branch=2, sqrt_branch=1, pow_branch=1)
expr = log(z, branch=2, branch_state=state)
root = sqrt(z, branch=1, branch_state=state)
power = pow_branch(z, 0.5, branch=1, branch_state=state)
print(expr.eval({"z": -1}, L=20))
print(root.eval({"z": -1}, L=20))
print(diff(expr, z))The derivative of log_k(z) is still locally 1/z away from singularities and branch cuts; the branch affects the value and is retained as expression metadata. The simplifier is conservative and does not globally rewrite log(exp(z)) or sqrt(z*z).
This is a minimal symbolic layer. It is not a full computer algebra system or a global analytic-continuation engine. The current goal is to support transparent CNRS chain-rule, differentiation, integration, explicit local branch choices, and scale-law workflows without unsafe simplification or overclaiming.
The v0.5.1 release adds cnrs.cnrs_h_bridge, a conservative bridge from supported symbolic expressions to finite CNRS-H EGF coefficient representations. It supports constants, polynomials, simple scale laws such as A*exp(k*s), and exp/sin/cos of affine arguments. Unsupported expressions raise UnsupportedBridgeExpression.
The v0.5.1 release adds cnrs.cnrs_h_chain, which implements finite-order EGF-series composition and verifies the chain-rule identity directly in CNRS-H coefficient space:
D(f ∘ g) = (Df ∘ g) * Dg
This layer is distinct from CnrsDual autodiff. It uses CNRS-H digit-shift differentiation plus finite EGF composition. It is intentionally truncated to a requested order and should be read as a computational coefficient-calculus implementation, not a full global analytic-continuation engine.
cnrs.cnrs_h_jet adds explicit expansion-point support for finite local CNRS-H coefficient calculus:
from cnrs.symbolic import Var, exp
from cnrs.cnrs_h_jet import jet_from_symbolic
s = Var("s")
jet = jet_from_symbolic(exp(0.08*s), s, center=-12, order=8)
djet = jet.diff(order=8)A jet represents f(s) ~= sum d_n (s-s0)^n/n!. This is useful for local scale analysis around nonzero scale addresses. It is a finite local representation, not a global analytic-continuation engine.