/** * Layer 1 rational-function symbolic integration — Task 1: parse a * single-variable rational-function expression into exact integer * numerator/denominator polynomials, split off the polynomial part via * exact-ℚ long division, and integrate a polynomial termwise (power rule). * * Reuses the univariate expression parser (`polyFromExpression`, from the * Gröbner-basis module) for parsing and the bigint dense-polynomial * convention (`IntPoly`, index = degree) from the #7 factorization engine * for the integer representation. * * See docs/superpowers/plans/2026-07-20-risch-layer1-rational-integration.md * (Task 1). Later tasks build denominator factorization, exact-ℚ partial * fractions, and per-factor closed-form integration on top of this module. */ import { type IntPoly } from '../typed/factorization/integer-poly.js'; import { ratAdd, ratSub, ratMul, ratDiv, ratFromBigint, type Rat } from './rat.js'; export type { Rat }; export { ratAdd, ratSub, ratMul, ratDiv, ratFromBigint }; /** A rational function `numer(x)/denom(x)` with integer dense (`IntPoly`) coefficients. */ export interface RatFunc { numer: IntPoly; denom: IntPoly; } /** * A quadratic surd `a + b·√Δ` for a fixed positive non-square radicand `Δ` * (Δ > 0, non-square — a perfect-square Δ never occurs here since it would * already have split into rational linear factors). `Δ` is NOT stored on the * `Surd` itself: surds produced within one computation share a single `Δ`, * and every op that needs it (`surdMul`, `surdDiv`, `surdRender`) takes it as * an explicit parameter. `surdAdd`/`surdSub`/`surdNeg`/`surdFromRat` are * Δ-independent (componentwise on `a`/`b`), so they don't take it. * * See docs/superpowers/specs/2026-07-21-risch-layer2-quadratic-surd-design.md * (Architecture §1). */ export interface Surd { a: Rat; b: Rat; } /** Lifts a rational number to a surd with zero `√Δ` component. */ export declare function surdFromRat(r: Rat): Surd; /** Negates a surd componentwise. */ export declare function surdNeg(s: Surd): Surd; /** Componentwise surd addition (Δ-independent). */ export declare function surdAdd(x: Surd, y: Surd): Surd; /** Componentwise surd subtraction (Δ-independent). */ export declare function surdSub(x: Surd, y: Surd): Surd; /** * Surd multiplication: `(a+b√Δ)(c+d√Δ) = (ac+bdΔ) + (ad+bc)√Δ`, using exact * `Rat` arithmetic throughout (`Δ` lifted to a `Rat` via `ratFromBigint`). */ export declare function surdMul(x: Surd, y: Surd, delta: bigint): Surd; /** * Surd division, rationalized by the conjugate: `(a+b√Δ)/(c+d√Δ) = * (a+b√Δ)(c−d√Δ) / (c²−d²Δ)`, where `c²−d²Δ` is a plain rational scalar. * Throws when `y` is zero (both components zero). */ export declare function surdDiv(x: Surd, y: Surd, delta: bigint): Surd; /** * Renders a surd as a readable, evaluable string `a + b*sqrt(Δ)`: a zero `a` * or zero `b` component is omitted, `b = 1`/`b = -1` render as bare * `sqrt(Δ)`/`- sqrt(Δ)`, and integer `Rat`s print without a `/1`. Exact * format is non-contractual (correctness is verified by differentiation * elsewhere); this only needs to stay evaluable and readable. */ export declare function surdRender(s: Surd, delta: bigint): string; /** * Parses a single-variable expression `numerExpr/denomExpr` (or a bare * polynomial, denominator `[1n]`) into integer numerator/denominator dense * polynomials. Rational coefficients are cleared by the LCM of their * denominators (numerator and denominator are each cleared independently, * then cross-scaled by the other's factor so the represented ratio * `numer(x)/denom(x)` is unchanged). * * Returns `null` when `expr` is not a rational function of `v`: it contains * a transcendental call (`sin`/`exp`/... — any identifier other than `v`), * more than one variable, a zero denominator, or coefficients that cannot be * cleared to integers. */ export declare function parseRationalFunction(expr: string, v: string): RatFunc | null; /** * Exact-ℚ polynomial long division of `rf.numer` by `rf.denom`: * `numer = quotient·denom + remainder`, `deg(remainder) < deg(denom)`. * Division is performed over ℚ (so a non-monic denominator is handled * correctly); the result is converted back to `bigint` coefficients, which * requires every intermediate `Rat` to reduce to an integer denominator — * true whenever the division is itself exact-integer, as it is for a * genuine rational-function reduction. Throws if it is not (a caller that * expects a non-integer quotient/remainder is out of this module's scope). */ export declare function polynomialPart(rf: RatFunc): { quotient: IntPoly; remainder: IntPoly; }; /** * Termwise power rule: the coefficient `c` at degree `n` in `p` integrates * to `c/(n+1) · v^(n+1)`. Renders a readable (not contractual beyond * containing the expected power) string, e.g. `x^2/2`, `2*x`. */ export declare function integratePolynomial(p: IntPoly, v: string): string; /** * An irreducible factor of a rational function's denominator, classified for * closed-form integration: * - `'linear'` (degree 1) → a `log`; * - `'quadratic-neg'` (degree 2, discriminant `b²−4ac < 0`, complex roots) → * a `log` + `atan` pair (Layer 1); * - `'quadratic-pos'` (degree 2, discriminant `> 0`, real irrational roots, * multiplicity 1) → a pair of real `log`s with quadratic-surd coefficients * (Layer 2, see the quadratic-surd design doc). * Degree-≥3 irreducible factors, and repeated positive-discriminant quadratics, * are out of scope (see `factorDenominator`, which returns `null` for them). */ export interface DenFactor { poly: IntPoly; mult: number; kind: 'linear' | 'quadratic-neg' | 'quadratic-pos'; } /** * Factors `denom` completely over ℤ/ℚ via the #7 factorization engine * (`factorUnivariateZ`) and classifies each irreducible factor by degree. * * A degree-1 factor is `'linear'`. A degree-2 factor, having survived complete * factorization over ℚ, is irreducible over ℚ — but that does NOT fix its * discriminant sign: `disc = b²−4ac < 0` (complex roots, e.g. x²+1) is * `'quadratic-neg'` (Layer 1 arctan path); `disc > 0` (real irrational roots, * a non-square disc, e.g. x²−2) with **multiplicity 1** is `'quadratic-pos'` * (Layer 2 quadratic-surd path). * * Returns `null` when a factor is out of scope: any irreducible factor of * degree ≥ 3, or a **repeated** positive-discriminant quadratic (`disc > 0`, * `mult > 1`) — the reduction formula for repeated real-root quadratics is * Layer 3. The caller then falls back to the `integral(...)` marker. */ export declare function factorDenominator(denom: IntPoly): DenFactor[] | null; /** * A single partial-fraction term `numer(x) / factor(x)^power`. `numer` is a * `Rat[]` of fixed length `deg(factor)` (index = degree, ascending — the same * convention as `IntPoly`): length 1 (a constant) over a linear factor, * length 2 (`[E, D]` meaning `D*x + E`) over a quadratic factor. */ export interface PFTerm { factor: IntPoly; power: number; numer: Rat[]; } /** * Exact-ℚ partial-fraction decomposition of `remainder(x) / ∏ factorᵢ(x)^multᵢ` * (`deg(remainder) < deg(∏ factorᵢ^multᵢ)`, as produced by `polynomialPart`) * into the standard form: for each irreducible factor `qᵢ` with multiplicity * `mᵢ`, terms `A_{i,k}(x) / qᵢ(x)^k` for `k = 1..mᵢ`, `deg A_{i,k} < deg qᵢ`. * * Solved by clearing denominators: multiplying the ansatz by the full * denominator `D = ∏ factorⱼ^multⱼ` turns each unknown numerator coefficient * into a linear unknown whose column is the polynomial * `x^j · qᵢ(x)^{mᵢ−k} · ∏_{j≠i} factorⱼ(x)^multⱼ` (a plain integer polynomial * product — no division is ever needed, since `mᵢ−k ≥ 0`). Equating * coefficients of `remainder(x)` on both sides gives a square (`deg D` × * `deg D`) rational linear system, solved exactly via `solveLinearSystemRat`. */ export declare function partialFractions(remainder: IntPoly, factors: DenFactor[]): PFTerm[]; /** * Integrates a single partial-fraction term in closed form. Dispatches on the * degree of `term.factor` and, for a quadratic, on its discriminant sign: * - degree 1 → `log` (+ rational part for a repeated factor); * - degree 2, `disc < 0` (complex roots) → `log`/rational part + `atan`; * - degree 2, `disc > 0` (real irrational roots, power 1) → a pair of real * `log`s with quadratic-surd coefficients (Layer 2). * The produced string is evaluable by the expression engine (`log`, `atan`, * `sqrt`, `abs`, `^`, `*`); its exact form is not contractual — correctness is * verified by differentiation. Throws on any other factor degree, or on a * positive-discriminant quadratic with power > 1 (both unreachable for a * `factorDenominator`-classified factor). */ export declare function integratePFTerm(term: PFTerm, v: string): string; /** * Full Layer-1 rational-function integration pipeline. Parses `expr` into an * exact integer rational function, splits off and integrates the polynomial * part, factors the denominator into linear + irreducible-quadratic factors, * decomposes into exact-ℚ partial fractions, and integrates each term in * closed form (rational part + `log` + `atan`). * * Returns `null` when `expr` is not a rational function of `v` * (`parseRationalFunction` declines), when the denominator has a degree-≥3 * irreducible factor (`factorDenominator` declines — Layer 2 territory), or * when any internal step throws (e.g. a non-integer polynomial-part division), * so callers get a clean decline rather than an exception. */ export declare function integrateRationalFunction(expr: string, v: string): string | null; //# sourceMappingURL=rational-integrate.d.ts.map