Type expressions into the Input Problems box — one per line — then click Expand Polynomials.
! to any whole number for its factorial, in any mode — e.g. 3!+2 expands to 8, 5!=x solves to x = 120. A decimal or a bare variable before ! is left untouched.
[[1,2],[3,4]], and are recognized directly — no mode switch needed, in any mode, the same way ! is. See §6.
;:mode to any line to feed its result into another command, e.g. x^2-1;:factor factors the expanded result. Chainable — ;:factor;:expand runs both in turn. See §4.
Every @: mode command in this reference, alphabetically, with a link to where it's documented in full. For syntax that isn't an @: command — the @@: one-line override (§3), ;: answer chaining (§4), matrix bracket notation (§6), or differentiate/integrate without a command (§8.1) — see those sections directly. Use the search bar above for full-text search across the whole page.
@:t works exactly like @:trigonometric, @@:fa expr like @@:factor expr, and mid-chain ;:dc like ;:dcalc — anywhere a command name is typed. A command whose short form would collide with another's (e.g. concavity/conic/continuity all start con) simply has no short form; its full name always still works.
| Command | Short | Does | Section |
|---|---|---|---|
@:acceleration <var> | ac | Differentiate a position function twice | §9.2 |
@:areabetween <var> [a b] | ar | Area between two curves | §8.11 |
@:balance | ba | Balance a chemical equation | §10.1 |
@:bracket2csv | br | Matrix bracket notation → CSV cell | §2.1 |
@:canon | ca | Sort a sum's terms by degree without expanding | §2.1 |
@:clearval | cl | Clear values set by @:setval | §2.1 |
@:compose | com | Function composition | §2.1 |
@:concavity <var> | — | Concave-up/down intervals | §8.4 |
@:conic / @:conics | — | Conic sections | §2.1 |
@:continuity <var> <point> | — | Classify continuous/discontinuous at a point | §8.8 |
@:critpoints <var> | cr | Critical points, classified max/min | §8.4 |
@:csv2bracket | cs | CSV cell → matrix bracket notation | §2.1 |
@:dcalc <var> | dc | Differentiate (sin/cos/tan/exp/ln/log/sqrt too) | §8.2 |
@:defint <var> <lower> <upper> | def | Definite integral (FTC) | §8.6 |
@:degtorad | deg | Degrees → radians (symbolic π) | §2.1 |
@:differentiate [var] | di | Differentiate — polynomials only | §2.1 |
@:domain | do | Domain | §2.1 |
@:eval <var> <value> | ev | Evaluate an expression at a point | §8.7 |
@:expand | — | Expand (the default mode) | §2.1 |
@:exptolog | — | Exponential → log form | §2.1 |
@:factor | fa | Factor | §2.1 |
@:flip | fl | Negate every term on both sides of an equation | §2.1 |
@:icalc <var> | ic | Integrate (sin/cos/tan/sec/csc/cot/exp/sqrt/1/x, trig powers/products, integration by parts including cyclic/3+-factor cases) | §8.6 |
@:implicit <xVar> <yVar> | im | Implicit differentiation, solve for dy/dx | §8.5 |
@:inflection <var> | inf | Inflection points | §8.4 |
@:integrate [var] | int | Integrate — polynomials only | §2.1 |
@:inverse | inv | Inverse functions | §2.1 |
@:limit <var> <point> <direction> | lim | Evaluate a limit | §8.3 |
@:linapprox <var> <center> <target> | lin | Tangent-line approximation | §8.9 |
@:logtoexp | lo | Log → exponential form | §2.1 |
@:monotonic <var> | mo | Increasing/decreasing intervals | §8.4 |
@:mvt <var> <a> <b> | mv | Mean Value Theorem / Rolle's Theorem | §8.10 |
@:oxstate | o | Oxidation states of a formula | §10.2 |
@:physics | p | Give known quantities, solve for the rest | §9.1 |
@:radical | — | Solve a radical equation | §2.1 |
@:radtodeg | — | Radians → degrees (numeric decimal) | §2.1 |
@:range | ran | Range | §2.1 |
@:rational | rat | Solve a rational equation | §2.1 |
@:riemann <f(x)> <a> <b> <n> <side> | — | Riemann sum (left/right/midpoint) | §8.13 |
@:riemannlimit <f(x)> <a> <b> | — | Exact definite integral via the limit definition | §8.14 |
@:rotate | ro | Swap an equation's two sides | §2.1 |
@:sci | — | Scientific notation, and persists across later mode switches until @:scioff | §2.1 |
@:scioff | — | Turn off the persistent scientific-notation formatting @:sci started | §2.1 |
@:scmS <code> / @:scmL <code> | — | Run your own Chez Scheme code | §7 |
@:set | — | Finite set operations | §12 |
@:setval <var>=<val> ... | — | Set variable values for following lines | §2.1 |
@:showwork on/off | sh | Show step-by-step work | §11.1 |
@:sketch <var> | sk | Critical points + monotonicity + inflection + concavity, together | §8.4 |
@:solve [var] | — | Solve algebraic equations (also inequalities, exp/log) | §2.1 |
@:sqrt | sq | Simplify a square root (largest perfect-square factor) | §2.1 |
@:sumcalc | su | Evaluate finite summation (sigma notation) | §8.12 |
@:system | sy | Solve a system of linear equations | §2.1 |
@:trigonometric / @:trig | t | Solve a trigonometric equation | §2.1 |
@:velocity <var> | v | Differentiate a position function once | §9.2 |
Just type the expression. PAE Bird expands and simplifies it.
(x + 1)(x + 2) 2x^2y - 3xy^2 (a - b)^3
@: Mode Switch (affects all following lines)Place a mode switch on its own line. Every line after it uses that mode until you switch again.
| Command | Mode |
|---|---|
@:expand | Expand (default) — also recognizes a bare log(...)/ln(...)/log_N(...) call and expands it via the product/quotient/power rules, e.g. log(x*y) → log(x) + log(y) — see the note below. |
@:factor | Factor |
@:solve [var] | Solve algebraic equations — also recognizes </>/<=/>= directly (a linear inequality, interval notation) instead of requiring an =, and an exponential (2^x=16) or logarithmic (log_3(x)=4) equation shape the same way — see the note below. Give var explicitly to solve a genuinely multivariable equation for it, e.g. ax+b=c solved for x gives x = (c-b) / (a), treating every other variable symbolically. |
@:differentiate [var] | Differentiate — polynomials only (default variable: x) |
@:integrate [var] | Integrate — polynomials only (default variable: x) |
@:sci | Scientific notation — converts a bare number directly under this mode, e.g. 299792458 → 2.99792458 × 10⁸. Also persistent: once on, ANY later command's plain-number result keeps getting reformatted into scientific notation too, even after switching to a different @: mode or chaining with ;: — until @:scioff turns it back off. A result that isn't a bare number (a polynomial, an equation, text with units, etc.) is left alone either way. |
@:scioff | Turns off the persistent formatting @:sci started. Doesn't change whatever @: mode is currently active — only clears the flag. |
@:degtorad | Degrees → radians, symbolic (e.g. 90 → π/2 radians) |
@:radtodeg | Radians → degrees, numeric decimal — not the inverse of @:degtorad's symbolic form (e.g. 1 → 57.29577951 degrees) |
@:logtoexp | Log → exponential form |
@:exptolog | Exponential → log form |
@:trigonometric (alias @:trig) | Solve a trigonometric equation, e.g. sin(x)=1/2 → x = 30° + 360°n, x = 150° + 360°n |
@:conic (alias @:conics) | Conic sections |
@:radical | Solve a radical equation for x, e.g. √(x+1)=3 (or sqrt(x+1)=3) → x = 8. Isolates the radical, squares both sides, solves the resulting polynomial equation, then verifies each rational candidate root against the original equation's own domain (rejecting an extraneous root introduced by squaring). |
@:rational | Solve a rational equation for x, e.g. (x^2-4)/(x-2)=4 → No solution (every candidate was extraneous) (x=2 solves the cross-multiplied polynomial but makes the original denominator zero). Cross-multiplies, solves the resulting polynomial equation, then filters out any candidate root that makes either original denominator zero. |
@:compose | Function composition |
@:inverse | Inverse functions |
@:domain | Domain |
@:range | Range |
@:system | Solve a system of linear equations — one line, equations separated by ;, same number of equations as unknowns, e.g. x+y=5;x-y=1 → x = 3, y = 2 (coefficients can use implicit multiplication, 2x, or explicit 2*x — both work) |
@:sqrt | Simplify a square root by extracting its largest perfect-square factor, e.g. 12 → 2√3 — also accepts an outer coefficient, e.g. 2√12 → 4√3 |
@:rotate | Swap an equation's two sides, e.g. x+2=3y-1 → 3y-1 = x+2 |
@:flip | Negate every term on both sides of an equation, e.g. -2x-3=-7 → +2x+3 = +7 |
@:canon | Sort a sum's top-level terms by degree WITHOUT expanding — reprints each term's own original text unchanged, unlike @:expand which fully multiplies through, e.g. (x+1)(x-2)+3x^2 → 3x²+(x+1)(x-2) |
@:set | Finite set operations (union/intersection/difference/subset/membership) — see §12 |
@:setval <var>=<val> ... | Sets one or more variable values (space-separated var=val pairs, e.g. @:setval x=3 y=1/2) — every following line has those values substituted in before evaluating, until @:clearval. |
@:clearval | Clears every value set by @:setval. |
@:csv2bracket | CSV cell → matrix bracket notation |
@:bracket2csv | Matrix bracket notation → CSV cell |
@:scmS <code> / @:scmL <code> | Run your own Chez Scheme code against each line's data — see §7 |
@:showwork on/off | Shows step-by-step work for whichever mode is already active (differentiate/dcalc/solve/expand) — see §11. |
@:expand, a bare log(...)/ln(...)/log_N(...) call is expanded via the product rule (log(xy) → log(x) + log(y)), quotient rule (log(x/y) → log(x) - log(y)), and power rule (log(x^3) → 3*log(x)), applied per factor so e.g. log(x^2*y^3) → 2*log(x) + 3*log(y) in one pass — no separate mode needed. Only a call spanning the ENTIRE line expands this way; one embedded in a larger expression (e.g. log(x*y)+1) is left unchanged rather than guessed at.
@:solve, typing a comparison instead of an equation — 2x+3>7, 3x<=9 — solves it as a linear inequality and returns interval notation ((2, ∞), (-∞, 3]), no separate mode needed. Only linear (degree ≤ 1) inequalities are supported; dividing by a negative coefficient correctly flips the direction (-2x+3>7 → (-∞, -2)), and strict vs. non-strict comparisons print the matching open/closed bracket.
@:solve x (naming a variable) solves a genuinely multivariable equation for just that one, treating every other variable as a symbolic constant rather than requiring a number — e.g. 3xy+z=w solved for x gives x = (w-z) / (3y). Only linear-in-x equations are supported this way (x itself must appear to exactly the first power everywhere it appears) — a symbolic quadratic formula isn't implemented, so e.g. x^2+y=1 reports a clear error rather than attempting one. An equation with only one variable still gets the full ordinary treatment (quadratic, higher-degree, etc.) even when that variable is named explicitly — the multivariable path only takes over once a second variable is genuinely present.
@:solve also recognizes an exponential or logarithmic equation directly, no mode switch needed: 2^x=16 → x = 4 (a numeric base with the variable in the exponent — an ordinary polynomial power like x^2=16 is left alone, since there the base is the variable, not a number), and log_3(x)=4 → x = 81 (the base right after log_).
| Command | Mode |
|---|---|
| (no command) | Differentiate/integrate directly, in any mode — d/dx(expr), (expr)', ∫expr dx, ∫(0,2)expr dx — see §8.1. |
@:dcalc <var> | Differentiate — adds sin/cos/tan/exp/ln/log/sqrt support; variable required, no default. |
@:limit <var> <point> <direction> | Evaluate a limit. |
@:critpoints <var> | Critical points, classified as local max/min. |
@:monotonic <var> | Increasing/decreasing intervals. |
@:inflection <var> | Inflection points. |
@:concavity <var> | Concave up/down intervals. |
@:sketch <var> | Full curve analysis in one call — critical points, monotonicity, inflection points, and concavity together. |
@:implicit <xVar> <yVar> | Implicit differentiation — solves an equation for dy/dx. |
@:icalc <var> | Integrate — adds sin/cos/tan/sec/csc/cot/exp/sqrt/1/x, linear-argument substitution (e.g. sin(3x)), trig power/product integrals (e.g. sin(x)^3, tan(x)^3*sec(x)^3), and integration by parts for a product of factors — including 3+-factor products (e.g. x^2*sin(x)*cos(x)) and cyclic cases (e.g. exp(x)*sin(x)); variable required, no default. |
@:defint <var> <lower> <upper> | Definite integral (Fundamental Theorem of Calculus). |
@:eval <var> <value> | Evaluate an expression at a point (works for sin/cos/tan/exp/ln/log/sqrt too, unlike @:setval). |
@:continuity <var> <point> | Classify continuous/discontinuous at a point. |
@:linapprox <var> <center> <target> | Tangent-line (linear) approximation. |
@:mvt <var> <a> <b> | Mean Value Theorem (Rolle's Theorem is the f(a)=f(b) special case). Polynomials only. |
@:areabetween <var> [a b] | Area between two curves (given as expr1;expr2 on one line). Polynomials only. |
sum(term,index,lower,upper) / @:sumcalc | Finite summation (sigma notation) — parses anywhere, evaluates only under @:sumcalc; see §8.12. |
@:riemann <f(x)> <a> <b> <n> <side> | Left/right/midpoint Riemann sum approximating a definite integral — self-contained on one line, variable inferred automatically; see §8.13. |
@:riemannlimit <f(x)> <a> <b> | Exact definite integral via the limit-of-Riemann-sums definition (degree ≤3 polynomials only); see §8.14. |
| Command | Mode |
|---|---|
@:physics | Give some known quantities (with units), it detects which relation applies and solves for the rest — covers everything from SUVAT kinematics through gravitation. See §9.1. |
@:velocity <var> | Differentiate a position function once. |
@:acceleration <var> | Differentiate a position function twice. |
| Command | Mode |
|---|---|
@:balance | Balance a chemical equation. |
@:oxstate | Oxidation states of each element in a formula. |
@@: One-Line OverrideApply a mode to just one line without changing the current mode.
| Command | Example |
|---|---|
@@:<mode> <expr> | @@:factor x^2 + 5x + 6 |
@@:setval <var>=<val> ... <expr> | @@:setval x=3 x^2+1 → 10. Applies to this line only — doesn't persist the value the way @:setval does. |
;:command Answer ChainingFeeds the previous solution into a new command — a running "Ans" that persists across lines, not just within one. Suffix any line with ;:<mode> to run that command on the line's own result, or start a line with ;:<mode> on its own to run it on the PREVIOUS line's result instead. Chain further by suffixing another ;:<mode>.
| Command | Example | Result |
|---|---|---|
<expr>;:<mode> | x^2-1;:factor | Expands x^2-1, then factors it: (x-1)(x+1) |
;:<mode> (own line) | x^2-1 then, on the next line, ;:factor | Same result — the second line has no expression of its own, so it factors the first line's answer |
;:mode1;:mode2 | x^2-1;:factor;:expand | Factors, then re-expands: back to x²-1 |
If nothing has been computed yet, the fed-in value defaults to 0. A command that returns multiple values (solve, system, critpoints, monotonic, inflection, concavity, sketch, etc.) can only appear as the LAST step in a chain — using one earlier reports a clear error rather than a confusing one, since there's no single answer to hand to the next step.
;:scmS and ;:scmL (see §7) are a special case: instead of applying a fixed built-in command, they run whichever Scheme program you most recently set with @:scmS <code>/@:scmL <code> — that program stays available for chaining even after switching to a different @: mode in between. ;:dcalc, ;:critpoints, ;:monotonic, ;:inflection, ;:concavity, ;:sketch, and ;:icalc work the same way with their own variable, most recently set by @:dcalc <var> or any of the others — see §8. ;:implicit works the same way too, with its own <xVar> <yVar> pair, most recently set by @:implicit <xVar> <yVar> — but since its input must be an equation (expr=expr), not a plain expression, it can only usefully chain off another equation-shaped result, not off dcalc/expand/etc. ;:defint works the same way with its own <var> <lower> <upper> triple, most recently set by @:defint <var> <lower> <upper>. ;:eval works the same way with its own <var> <value> pair, most recently set by @:eval <var> <value> — note that setting @:eval also switches the ambient mode to eval, so to chain expr;:dcalc;:eval (differentiate, then evaluate the derivative at a point, in one line), set @:eval <var> <value> before switching to @:dcalc <var> — the later @:dcalc directive only replaces the ambient mode, it leaves the already-set eval point alone. A nice trick: expr;:icalc chained off @:dcalc differentiates then re-integrates, useful as a sanity check that both sides agree.
# Polynomial expansion (default — no prefix needed) (x + 1)(x + 2) (a - b)^3 # Logarithm expansion -- recognized directly under @:expand too log(x*y) log(x^3/y) # Switch to factoring for a block @:factor x^2 - 9 x^3 - 8 # One-off factor without switching mode back @:expand (x - 2)(x + 5) @@:factor x^2 + 7x + 12 # Calculus (polynomials only) @:differentiate x x^3 + 2x^2 - 5x + 1 @:integrate x x^4 - 3x^2 # Calculus (sin/cos/tan/exp/ln/log/sqrt, limits, curve analysis) @:dcalc x sin(x^2) @:limit x 0 two-sided sin(x)/x @:sketch x x^3 - 3x # Equations @:solve 3x - 7 = 11 x^2 - 4 = 0 2x+3 > 7 2^x = 16 log_3(x) = 4 # Multivariable -- name the variable to solve for; every other # variable is treated symbolically @:solve x ax + b = c # Chemistry @:balance Fe + O2 -> Fe2O3 # Scientific notation (integers only, under 1 billion) -- persists # across a later mode switch, until @:scioff @:sci 299792458 @:eval x 3 x^2+1 @:scioff x^2+1 # Matrices (recognized directly from bracket notation -- no mode switch needed) det([[1,2],[3,4]]) inverse([[1,2],[3,4]]) [[1,2],[3,4]]+[[5,6],[7,8]] # Factorial (works in any mode, not just expand) @:expand 3! + 2 # Answer chaining -- feed one result into another command x^2-1;:factor ;:expand # Set variable values -- substituted into every following line # until @:clearval @:setval x=3 y=1/2 x^2+y @:clearval # Your own Scheme code @:scmL (reverse data) x+1
Matrices use bracket notation, e.g. [[1,2],[3,4]], and are recognized directly from the input in any mode — no mode switch needed, the same way ! (factorial) already works everywhere.
| Op | Syntax | Example |
|---|---|---|
| Add | matrixA+matrixB | [[1,2],[3,4]]+[[5,6],[7,8]] |
| Subtract | matrixA-matrixB | [[5,6],[7,8]]-[[1,2],[3,4]] |
| Multiply | matrixA*matrixB | [[1,2],[3,4]]*[[5,6],[7,8]] |
| Scalar multiply | k*matrix or matrix*k | 3*[[1,2],[3,4]] |
| Transpose | transpose(matrix) | transpose([[1,2,3],[4,5,6]]) |
| Determinant | det(matrix) | det([[1,2],[3,4]]) |
| Inverse | inverse(matrix) | inverse([[1,2],[3,4]]) |
| Row reduce | rref(matrix) | rref([[1,2,3],[4,5,6]]) |
A bare matrix on its own (just [[1,2],[3,4]], no operator or function) is validated and reformatted. Cell values may be integers, decimals, or fractions (e.g. 3/4), and always print back exactly — never rounded to a decimal. Dimension mismatches and non-square/singular inputs report a clear error rather than crashing.
A matrix result isn't a plain number, so a whole-line matrix expression is returned directly, regardless of whatever @: mode happens to be active — but det(...)'s numeric result composes normally into a larger expression, exactly like !: det([[1,2],[3,4]])+5 expands to 3.
@:csv2bracket / @:bracket2csv convert between bracket notation and a single quoted CSV cell, for pasting a matrix result into a spreadsheet row alongside other data. A dedicated matrix-only CSV or .xlsx file (a real Excel file — cells keep their exact values, e.g. 3/4, rather than a decimal or a misread date) can be imported/exported directly from the command line.
@:scmS / @:scmL — Run Your Own Scheme CodeWrite your own Chez Scheme program and run it against a line's data, converted to a plain symbol list bound to data — the same representation PAE Bird uses internally for a polynomial. PAE Bird's own commands (expand, factor, solve, etc.) are not available inside your program — this runs your code in a plain Scheme sandbox operating on data, not a way to call PAE Bird's own operations by another name.
| Command | Output |
|---|---|
@:scmS <code> | Renders the result back like a normal solution (e.g. 3x^2/5+x) |
@:scmL <code> | Prints the raw Scheme value (e.g. (x + 1 +)) |
@:scmL (reverse data) x+1
Set your program once with @:scmS <code>/@:scmL <code>, then every following line's data runs through it. You can also chain a bare ;:scmS or ;:scmL onto any line (see §4) to run the same program against that line's own result instead of the current line's data.
data mixes numbers and symbols (operators, variables), so a numbers-only helper needs to filter first: @:scmL (define (numbers-only l) (filter number? l)) (numbers-only data)
Two ways to reach the same engine: no-command notation (§8.1) for differentiation/integration directly in the input, or the @: commands below for everything else in this section (limits, curve analysis, implicit differentiation, evaluation) plus @:dcalc/@:icalc themselves. @:dcalc and everything below it in this section run on a newer engine than plain @:differentiate/@:integrate — it understands sin, cos, tan, exp, ln, log, and sqrt as well as polynomials. It's a separate command family rather than a replacement: @:differentiate/@:integrate still work exactly as before, polynomials only. Every command in this section requires its variable explicitly — there's no default the way @:differentiate defaults to x — with one exception, @:sumcalc (§8.12), whose variable (the summation index) lives inside its sum(...) input syntax instead of as a separate command argument.
Three notations, recognized directly in the input — no @: mode switch needed at all, in any active mode, the same way matrix bracket notation and ! factorial already are (§6, §2.1). Built on the same engine as @:dcalc/@:icalc/@:defint above — sin/cos/tan/exp/ln/log/sqrt all work.
| Notation | Meaning | Input | Result |
|---|---|---|---|
d/d<var>(expr) | Differentiate, variable explicit | d/dt(5cos(2t)) | -5*sin(2*t)*2 |
(expr)' | Differentiate, variable inferred | (x^2+3x)' | 2*x+3 |
expr' (chained) | Repeated differentiation | (x^3)'' | 6*x |
∫expr dx | Indefinite integral (no +C, same as @:icalc) | ∫x^2dx | x³/3 |
∫(a,b)expr dx | Definite integral, bounds in parens | ∫(0,2)x^2dx | 8/3 |
∫ₐᵇexpr dx | Definite integral, textbook subscript/superscript bounds | ∫₀²x^2dx | 8/3 |
The prime form (') infers which variable to differentiate with respect to — unambiguous whenever the expression has exactly one; a bare constant (e.g. 5') trivially differentiates to 0. A genuinely multivariable expression (e.g. (x*y)') reports a clear error asking for the explicit d/d<var>(...) form instead of guessing which variable was meant. The integral notation never needs inference at all — the trailing d<var> always supplies it, exactly like ordinary calculus notation on paper. Both bound-syntax forms above mean the same thing; the subscript/superscript form is also what you get back if you paste a previous definite-integral answer in as new input.
@:dcalc <var> — Differentiate| Input | Result |
|---|---|
sin(x^2) | cos(x²)*2*x |
x^2*exp(x) | 2*x*exp(x)+x²*exp(x) |
@:limit <var> <point> <direction> — Evaluate a Limit<point> is a number (2, -1, 1/2) or +infinity/-infinity. <direction> is two-sided, left, or right.
| Command | Input | Result |
|---|---|---|
@:limit x 0 two-sided | sin(x)/x | 1 |
@:limit x 2 two-sided | (x²-4)/(x-2) | 4 |
@:limit x +infinity two-sided | (2x²+3x)/(x²-1) | 2 |
@:limit x 0 right | 1/x | +infinity |
@:limit x 0 left | 1/x | -infinity |
A result of undefined means the two one-sided limits disagree (a genuine vertical asymptote with no single two-sided value) — try left or right instead.
@:critpoints, @:monotonic, @:inflection, @:concavity, @:sketchPolynomials only — these four all solve an equation internally to locate critical/inflection points, and equation-solving in PAE Bird doesn't yet understand sin/cos/exp/ln/etc. A function like x + sin(x) reports a clear error here rather than a wrong answer.
| Command | Returns |
|---|---|
@:critpoints <var> | Each critical point, classified as a local maximum or minimum |
@:monotonic <var> | Increasing/decreasing intervals |
@:inflection <var> | Inflection points (only genuine ones — a flat spot where concavity doesn't actually change, like x⁴ at x=0, isn't included) |
@:concavity <var> | Concave-up/concave-down intervals |
@:sketch <var> | All four of the above together, in one call |
Example — @:sketch x on x^3-3x (one comma-separated line; wrapped here for readability):
x = -1: local maximum, x = 1: local minimum, increasing on (-infinity, -1), decreasing on (-1, 1), increasing on (1, infinity), x = 0: inflection point, concave down on (-infinity, 0), concave up on (0, infinity)
Irrational boundary points print symbolically (e.g. x = √2), the same convention @:solve already uses.
@:implicit <xVar> <yVar> — Implicit DifferentiationInput is a full equation (expr=expr), not a bare expression — e.g. a circle, x^2+y^2=25, doesn't define y as an explicit function of x the way @:dcalc needs, but dy/dx can still be found by differentiating both sides. Works with sin/cos/tan/exp/ln/log/sqrt as well as polynomials, same as @:dcalc.
| Input | Result |
|---|---|
x^2+y^2=25 | -x/y |
xy=1 | -y/x |
sin(y)=x | 1/cos(y) |
The result may involve both x and y — that's normal for implicit differentiation, not a sign something went wrong. An equation where y doesn't actually appear (e.g. x^2=25) reports a clear error rather than a meaningless result.
@:icalc <var> / @:defint <var> <lower> <upper> — Integrate@:icalc covers the basic integral table (the reverse of @:dcalc's derivative table, including sec/csc/cot), sum/difference/constant-multiple rules, one curated substitution case (a linear argument, e.g. sin(3x) or exp(2x+1) or 1/(2x+3)), trig power and product integrals (any nonnegative integer powers of sin/cos, tan/sec, or cot/csc, e.g. sin(x)^3, sec(x)^4, tan(x)^3*sec(x)^3), and integration by parts for a product of var-dependent factors, e.g. x*sin(x), x^2*exp(x), x*ln(x) — including a product of three or more factors (e.g. x^2*sin(x)*cos(x)) and a cyclic case like exp(x)*sin(x), where integration by parts alone would otherwise loop forever — solved algebraically instead. Which factor plays u vs. dv is picked automatically (LIATE: Log, Inverse trig, Algebraic, Trig, Exponential — this engine has no inverse-trig functions, so in practice it's L-A-T-E), and a case needing more than one pass (e.g. x^3*exp(x)) recurses on its own rather than stopping after the first round. A hard 3-second time limit guards against a pathological case (e.g. a very high odd trig power) running away instead of reporting a clean error.
| Input | Result |
|---|---|
x^2 | x³/3 |
sin(x) | -cos(x) |
1/x | ln(abs(x)) |
sin(3x) | -1/3*cos(3*x) |
(2x+1)^5 | 1/2*(2*x+1)⁶/6 |
x*sin(x) | -x*cos(x)+sin(x) |
x*exp(x) | x*exp(x)-exp(x) |
x*ln(x) | ln(x)*1/2*x²-1/4*x² |
x^3*exp(x) | x³*exp(x)-(3*x²*exp(x)-(6*x*exp(x)-exp(x)*6)) |
sin(x)^3 | -cos(x)+cos(x)³/3 |
sec(x)^3 | sec(x)*tan(x)/2+1/2*ln(abs(sec(x)+tan(x))) |
tan(x)^3*sec(x)^3 | sec(x)⁵/5-sec(x)³/3 |
x^2*sin(x)*cos(x) | -x²*cos(x)²/2+x*(1/2*x+1/2*1/2*sin(2*x))-(1/4*x²-1/2*1/2*1/2*cos(2*x)) |
exp(x)*sin(x) | (sin(x)*exp(x)-cos(x)*exp(x))/2 |
1/x integrates to ln(abs(x)), not ln(x) — ln is undefined for a negative number, and the antiderivative needs to stay valid on the whole domain the original expression was, not just where x happens to be positive.
Still out of scope: ln(x) alone (not literally a product — a bare dv=dx factor isn't handled), substitution beyond a linear argument (sin(x^2)), trig substitution (e.g. x=2tanθ — a different technique from trig integrals above despite the similar name), and partial fractions. A genuinely mixed, unsolvable case (e.g. sin(x)*cos(x)*tan(x), mixing trig families with no common reduction) reports a clear error rather than a silently wrong answer or a hang.
@:defint evaluates the same antiderivative at two bounds and subtracts (the Fundamental Theorem of Calculus) — bounds are plain numbers, not +infinity/-infinity (an improper integral isn't supported).
| Command | Input | Result |
|---|---|---|
@:defint x 0 2 | x^2 | 8/3 |
@:defint x 1 2 | 1/x | .693147... |
@:eval <var> <value> — Evaluate at a pointReports the expression's actual value at <var>=<value>. Unlike @:setval (which only understands plain polynomials), @:eval works on any expression this calculus engine understands, including sin/cos/tan/exp/ln/log/sqrt — this is what makes it possible to evaluate a @:dcalc/@:icalc result (which can be transcendental) at a specific point. A value that isn't exactly computable rounds to 6 significant figures, matching @:limit's own convention. A genuine domain violation at that exact point (e.g. dividing by zero) reports undefined — this is deliberately different from @:limit, which can still resolve a value there via indeterminate-form analysis even though the expression itself is undefined at that point.
| Command | Input | Result |
|---|---|---|
@:eval x 3 | x^2+1 | 10 |
@:eval t 2 | 5cos(2t) | -3.26822 |
@:eval x 0 | 1/x | undefined |
A common combination: @:eval t 2 then, on a separate line, @:dcalc t, then 5cos(2t);:eval — differentiates 5cos(2t) under the ambient dcalc mode, then evaluates that derivative at t=2 in the same line (7.56802). See §4's chaining notes for why the @:eval directive has to come first.
@:continuity <var> <point> — ContinuityClassifies the expression's behavior at <var>=<point>: continuous, or one of the three standard discontinuity types. Built entirely on @:limit/@:eval's own machinery (two-sided and one-sided limits, plus the value at the point) — no separate resolution logic of its own.
| Command | Input | Result |
|---|---|---|
@:continuity x 2 | x^2+3x | continuous at x = 2 |
@:continuity x 0 | 1/x | infinite discontinuity at x = 0 (vertical asymptote) |
@:continuity x 2 | (x^2-4)/(x-2) | removable discontinuity at x = 2 (the limit is 4, but x=2 is not in the domain) |
The fourth standard type, a jump discontinuity, needs a genuinely different one-sided limit on each side of the point — the classic textbook examples all involve either a piecewise definition or an absolute value, neither of which this engine's grammar supports at all, so it isn't reachable yet in practice; it falls back to discontinuous at ... (limit does not exist) instead.
@:linapprox <var> <center> <target> — Linear ApproximationEstimates the expression's value at <target> using the tangent line at <var>=<center>: L(x) = f(center) + f'(center)*(x - center). <target> can be a fraction (there's no decimal-literal support anywhere in this engine, matching @:eval/every other numeric input) — e.g. estimate sqrt(4.02) by writing the target as 201/50.
| Command | Input | Result |
|---|---|---|
@:linapprox x 4 201/50 | sqrt(x) | 401/200 |
@:linapprox x 2 21/10 | x^3 | 46/5 |
@:mvt <var> <a> <b> — Mean Value TheoremFinds every c in the open interval (a, b) with f'(c) = (f(b)-f(a))/(b-a) — there can be more than one. Rolle's Theorem isn't a separate command: it's exactly the case where f(a)=f(b), which makes the target slope 0 automatically: the result is labeled (Rolle's Theorem) instead of (the Mean Value Theorem) when that happens, but the underlying computation is identical either way. Polynomials only — same restriction as §8.4's curve analysis, for the same reason (solve() has no concept of a transcendental function).
| Command | Input | Result |
|---|---|---|
@:mvt x 1 3 | x^2 | x = 2 (the Mean Value Theorem) |
@:mvt x 1 3 | x^2-4x+3 | x = 2 (Rolle's Theorem) |
@:areabetween <var> [a b] — Area Between CurvesNeeds two expressions on one line — write them separated by ;, e.g. x;x^2 for the region between y=x and y=x^2 — the only command in this reference with that shape. Give explicit bounds (@:areabetween x 0 1) or leave them off to use the two curves' own intersection points as the region's boundary (@:areabetween x, needs at least two intersections to enclose anything). Either way, the result is sign-aware around any point where the curves cross inside the interval — the naive "just take |one definite integral|" approach silently undercounts whenever which curve is on top flips partway through, since a positive and a negative region can cancel each other out before the absolute value is ever applied. Polynomials only, same reason as @:mvt above (finding where the curves cross reuses solve()).
| Command | Input | Result |
|---|---|---|
@:areabetween x 0 1 | x;x^2 | 1/6 |
@:areabetween x | x;x^2 | 1/6 (same answer — 0 and 1 are exactly where these two curves cross) |
@:areabetween x -1 1 | x;0 | 1 (not 0 — y=x crosses the x-axis at x=0, right in the middle of the given interval) |
sum(term,index,lower,upper) / @:sumcalc — Finite Summation (Sigma Notation)sum(...) is ordinary notation, parseable anywhere an expression is (like any other function call), but it only actually evaluates under @:sumcalc mode — feeding it to @:dcalc/@:icalc/@:limit/@:eval etc. parses fine but reports a clear "not supported" error, since differentiating/integrating/limit-taking through a summation is a different, larger problem this doesn't attempt. Unlike @:dcalc/@:icalc, @:sumcalc takes no variable argument at all — a line is expected to already be a closed, fully numeric expression once every sum(...) in it is evaluated (composition is fine, e.g. 2*sum(n,n,1,5)+3). lower/upper must be literal integers (or a constant expression that reduces to one, like 1+2) — a symbolic bound isn't supported. sigma(...) (word form) and ∑(...) (the U+2211 summation glyph, not the Greek letter Σ) are interchangeable spellings of sum(...) — all three parse to the exact same thing and always render back as sum(...).
| Command | Input | Result |
|---|---|---|
@:sumcalc | sum(n^2,n,1,10) | 385 |
@:sumcalc | 2*sum(n,n,1,5)+3 | 33 |
@:sumcalc | ∑(2^n,n,0,10) | 2047 (geometric series, closed-form) |
@:sumcalc | sigma(sqrt(n),n,1,4) | 6.14626 (no closed form for this shape — direct term-by-term sum) |
@:sumcalc | sum(1/n!,n,0,10) | 9864101/3628800 (≈ 2.71828 — a Taylor-series partial sum for e) |
A curated closed-form table (constant/linear/quadratic/cubic/geometric terms, extended through linearity) is tried first, so a huge range like sum(n,n,1,10000000) resolves instantly; anything else falls back to a direct term-by-term sum. A direct sum that's still running after 10 seconds starts printing progress and accepts sumc (typed on its own, in a live session) to abort — this only does anything in an interactive session, not a batch worksheet run. term can also use factorial (n!, postfix, tighter-binding than ^) — this is what makes a Taylor-series-shaped sum like 1/n! expressible at all; it's only defined for a nonnegative integer, and n!! isn't double-factorial notation here, just a clear parse error. Not supported: a symbolic/variable bound (sum(n,n,1,N)), a term depending on any variable besides its own index (sum(x*n,n,1,5)), and a nested sum as another sum's term (parses and round-trips fine, errors on evaluation) — all report a clear error rather than a wrong answer.
@:riemann <f(x)> <a> <b> <n> <side> — Riemann SumsApproximates ∫[a,b] f(x) dx by n equal-width rectangles, sampled at each subinterval's left endpoint, right endpoint, or midpoint (<side> is the literal word left, right, or midpoint). Self-contained on one line, unlike every other calculus command in this section — there's no separate header line followed by a data line; the function goes directly in the command line itself. The variable is inferred automatically (there's nowhere to name one explicitly in this syntax) — unambiguous whenever f(x) has exactly one. Built entirely on @:sumcalc's own sigma-notation machinery above, not a separate evaluator — it's exactly the sum Δx·Σf(sample), constructed as a real sum(...) expression internally (Δx=(b-a)/n; sample index i ranges 0..n-1 for left, 1..n for right and midpoint; midpoint samples the CENTER of each subinterval, a+(i-½)·Δx, rather than an endpoint). Works with sin/cos/tan/exp/ln/log/sqrt as well as polynomials, same vocabulary as @:dcalc/@:icalc — not restricted to polynomials the way @:mvt/@:areabetween/curve analysis are.
| Input | Result |
|---|---|
@:riemann x^2 0 4 4 left | 14 |
@:riemann x^2 0 4 4 right | 30 (exact integral is 64/3 ≈ 21.3, between the two, as expected) |
@:riemann x^2 0 4 4 midpoint | 21 (closer to the exact 64/3 ≈ 21.3 than either endpoint sum, as is typical) |
@:riemann x^2 0 1 1000 left | 665667/2000000 = .332834 (exact integral 1/3=.333333 — the underestimate has closed most of the gap by n=1000) |
@:riemann sin(x) 0 1 4 left | .352117 (transcendental f works too, not just polynomials) |
As n grows, all three converge to the same exact value @:defint (§8.6) or @:riemannlimit (§8.14) would give directly. For an increasing function, the left sum stays an underestimate and the right sum stays an overestimate (or vice versa for a decreasing one, e.g. -x^2) — a good way to sanity-check a result by eye: running both left and right at the same n should always bracket the true integral, narrowing as n grows. midpoint doesn't bracket this way (it can land on either side of the true value), but typically converges faster than either endpoint sum at the same n.
<n> must be a positive whole number of subintervals — 0 or a fraction is a clear error, not an empty/zero result. f may only depend on one variable (same one-variable convention sum(...)/@:dcalc/@:icalc already have) — a second free variable in f is also a clear error rather than a guess. Not built: trapezoidal rule and Simpson's rule aren't true Riemann sums (no single per-subinterval sample point) and aren't here.
@:riemannlimit <f(x)> <a> <b> — Exact Definite Integral via the Limit DefinitionEvaluates ∫[a,b] f(x) dx exactly, not by approximation — the same limit-of-Riemann-sums definition §8.13's right-endpoint sum is built on, but carried all the way to n→∞ in closed form: binomial-expand f(a+i·Δx), replace each Σiᵏ with its closed-form power-sum formula, then take the limit termwise. Self-contained on one line, same as @:riemann — no <n> or <side> to give, since the underlying definition always uses right endpoints and always takes n→∞. Polynomials of degree ≤3 only — the closed-form power-sum formulas this relies on stop at Σi³, and there's no shortcut past that (squaring Σi² does not give Σi⁴); a degree-4-or-higher f reports a clear error rather than a wrong answer. Always agrees exactly with @:defint (§8.6, the Fundamental-Theorem-of-Calculus method) on anything both can handle — two structurally unrelated methods computing the same quantity.
| Input | Result |
|---|---|
@:riemannlimit x^3-6x 0 3 | -27/4 (-6.75) |
@:riemannlimit x^2 0 4 | 64/3 |
@:riemannlimit x^4 0 1 | clear error — degree 4 is out of scope |
Two modes: quantity-based (@:physics, unit-aware — give some known quantities, it figures out which relation applies and solves for the rest) and function-based (@:velocity/@:acceleration, unitless, just @:dcalc with physics vocabulary).
@:physics — Give some quantities, it detects which relation appliesOne mode covers every quantity-based relation in this reference (kinematics through gravitation, §9.3's table below) — no need to know or type a specific command name for "Newton's second law" vs. "circular motion" vs. "orbital velocity", etc. Switch to it once, then just give role=value+unit pairs, space-separated, same convention every one of these relations has always used:
@:physics u=0m/s a=9.8m/s^2 t=2s f=10N m=2kg
v = 98/5m/s, s = 98/5m a = 5m/s²
The first line's variables (u, a, t) only belong to the SUVAT kinematic equations, so that's what runs; the second line's (f, m) only belong to Newton's second law. Most inputs are this unambiguous — every variable letter means the same physical quantity everywhere in this reference (m is always mass, v is always velocity, etc.), so which relation applies is usually obvious from the letters alone.
Sometimes the SAME given variables are genuinely shared by two different relations — e.g. m and v alone are consistent with both kinetic energy (k=½mv²) and momentum (q=mv). Mark whichever variable you actually want solved for with ? instead of a value to disambiguate:
| Input | Result |
|---|---|
k=? m=2kg v=3m/s | k = 9J (kinetic energy) |
q=? m=2kg v=3m/s | q = 6kg*m/s (momentum) |
? can mark more than one variable at once for a relation that solves for two unknowns from three-plus knowns (e.g. SUVAT, circular motion, power) — it's just a hint about which variable(s) you want, not a hard requirement; the relation still solves for whatever's genuinely missing either way.
If ? is omitted and more than one relation matches, or a target IS named but two relations still tie on it (see orbitalvelocity/escapevelocity below — they use the exact same four variables, so naming v doesn't help), @:physics shows every matching relation's answer rather than silently guessing or erroring — each labeled by name, separated with |:
| Input | Result |
|---|---|
m=2kg v=3m/s | kinetic: k = 9J | momentum: q = 6kg*m/s |
v=? r=2m g_c=3N*m^2/kg^2 n=6kg | orbitalvelocity: v = 3m/s; v = -3m/s | escapevelocity: v = 3√2m/s; v = -3√2m/s |
(The ; inside one relation's own answer above separates that SAME relation's multiple roots — e.g. a ± pair — from each other; | always separates two DIFFERENT relations.) A variable set matching no known relation at all, or an unrecognized variable name, reports a clear error instead of either of the above.
@:velocity <var> / @:acceleration <var> — Function-based kinematicsGive a position function s(t); @:velocity differentiates it once, @:acceleration twice. Deliberately unitless — these are thin wrappers over @:dcalc (§8.2), so they support the same sin/cos/tan/exp/ln/log/sqrt functions dcalc does (useful for an SHM position function like 5cos(2t)). Chain with ;:eval (§8.7) to get a numeric value at a specific time in one line.
| Command | Input | Result |
|---|---|---|
@:velocity t | t^3-2t+5 | 3*t²-2 |
@:acceleration t | t^3-2t+5 | 6*t |
Drag/terminal-velocity problems don't need a dedicated command either: given a candidate velocity function like v(t) = (m·g/b)·(1-exp(-b·t/m)), differentiate it with @:dcalc t to check it against the drag equation by hand, and use @:limit t +infinity two-sided directly on the whole expression for terminal velocity.
Every relation @:physics knows, for reference — give however many variables a row needs (all but the ones you want solved for, or use ? to say so explicitly).
| Relation | Variables | Formula | Notes |
|---|---|---|---|
| SUVAT (constant acceleration) | s displacement, u initial velocity, v final velocity, a acceleration, t time | the 4 standard kinematic equations | Give 3, solves for the other 2 — branches over paired real solutions when a step is quadratic. |
| Newton's second law | f force, m mass, a acceleration | f=ma | |
| Circular motion | a centripetal accel., v speed, r radius, f centripetal force, m mass | a·r=v², f=m·a | Period/frequency and banking-angle scenarios aren't covered. |
| Work | w work, f force, d distance | w=f·d | Force along the direction of motion only (no angled-force cos(θ) case). |
| Kinetic energy | k energy, m mass, v speed | k=½mv² | |
| Gravitational PE (near-surface) | e energy, m mass, g grav. accel., h height | e=mgh | The near-surface approximation — see the general form below for arbitrary distance. |
| Power | p power, w work, t time, f force, v speed | p=w/t, p=f·v | Not every combination of 3 is solvable — p is the only variable shared by both equations, so e.g. {p,f,v} alone (missing w,t) is genuinely underdetermined. |
| Work-energy theorem | w work, m mass, u initial speed, v final speed | w=½mv²-½mu² | |
| Momentum | q momentum, m mass, v velocity | q=mv | |
| Impulse | j impulse, f force, t time | j=ft | Same dimension/unit as momentum. |
| Impulse-momentum theorem | j impulse, m mass, u initial speed, v final speed | j=mv-mu | |
| Two-body collision | m/n masses, u/v object 1's initial/final velocity, x/y object 2's initial/final velocity | mu+nx=mv+ny | Momentum conservation only — deriving both final velocities from scratch for an elastic collision isn't supported. |
| Perfectly inelastic collision | m/n masses, u/x initial velocities, v shared final velocity | mu+nx=(m+n)v | |
| Torque | c torque, f force, r lever-arm length | c=fr | Force perpendicular to the lever arm only. |
| Rotational Newton's second law | c torque, z moment of inertia, b angular accel. | c=zb | |
| Angular momentum | l angular momentum, z moment of inertia, o angular velocity | l=zo | |
| Rotational kinetic energy | k energy, z moment of inertia, o angular velocity | k=½zo² | |
| Period-frequency | t period, f_s frequency | t=1/f_s | T=2π/ω-style formulas aren't supported (no symbolic π). |
| Hooke's law | f spring force, k_s spring constant, d displacement | f=k_s·d | |
| Spring potential energy | e energy, k_s spring constant, d displacement | e=½k_s·d² | |
| Maximum SHM velocity | v max velocity, s amplitude, o angular frequency | v=sω | |
| Maximum SHM acceleration | a max accel., s amplitude, o angular frequency | a=sω² | |
| Newton's law of universal gravitation | f grav. force, g_c constant G, m/n masses, r distance | f=Gmn/r² | |
| Gravitational field/acceleration | g field strength, g_c constant G, n source mass, r distance | g=Gn/r² | |
| Orbital velocity | v speed, r radius, g_c constant G, n mass | v²r=Gn | Identical variable set to escape velocity below — always a tie (§9.1). |
| Escape velocity | v speed, r radius, g_c constant G, n mass | v²r=2Gn | Identical variable set to orbital velocity above — always a tie (§9.1). |
| Gravitational PE (general form) | e energy, g_c constant G, m/n masses, r distance | e=-Gmn/r | Negative by convention (zero at infinite separation) — distinct from the near-surface form above. |
Units: m/km/cm/ft/mi (length), s/min/hr (time), m/s/km/hr/mph/ft/s (velocity), m/s^2/ft/s^2 (acceleration), kg/g (mass), N (force), J (energy/work), W (power), kg*m/s (momentum/impulse), N*m (torque), kg*m^2 (moment of inertia), rad/s/rad/s^2 (angular velocity/acceleration), kg*m^2/s (angular momentum), Hz (frequency), N/m (spring constant), N*m^2/kg^2 (gravitational constant G — also accepts scientific notation, e.g. g_c=6.674e-11N*m^2/kg^2). Results are always shown in SI base units. This completes the Mechanics curriculum (kinematics through gravitation) — a full first-semester, calculus-based physics course.
Two commands, independent of the algebra/calculus/physics engine above — chemical formulas and equations, not polynomial expressions.
@:balance — Balance a chemical equationWrite reactants and products separated by +, with -> between the two sides — standard chemical formula notation (element symbols with a plain-digit count, no spaces needed inside a formula). Returns the same equation with the smallest whole-number coefficients that balance every element, rendered with a real → arrow and each formula's own element counts as real Unicode subscript digits — only the leading stoichiometric coefficient (e.g. the 2 in 2H₂O) stays a plain, non-subscript number, exactly like a textbook prints it. Input accepts either form — a plain digit (H2O) or a real subscript digit (H₂O) — so a previous result can be pasted straight back in as new input.
| Input | Result |
|---|---|
H2 + O2 -> H2O | 2H₂ + O₂ → 2H₂O |
Fe + O2 -> Fe2O3 | 4Fe + 3O₂ → 2Fe₂O₃ |
@:oxstate — Oxidation statesGive a single chemical formula; reports the oxidation state of every element in it. An element appearing with a count is reported grouped under that same count (e.g. H₂, not two separate H entries) — matching the formula's own notation, not a per-atom breakdown. Both the echoed formula and every element's count print as real Unicode subscript digits, same convention as @:balance — including accepting either digit form back as input.
| Input | Result |
|---|---|
H2O | H₂O: H₂: +1, O: -2 |
KMnO4 | KMnO₄: O₄: -2, K: +1, Mn: +7 |
Fe2O3 | Fe₂O₃: O₃: -2, Fe₂: +3 |
@:showwork on/off — Show step-by-step work for the active modeA persistent toggle, same convention as @:setval/@:clearval (§2.1) — set it once, every following line gets steps until you turn it back off. There's no separate command to remember for each operation: @:showwork detects what kind of problem to solve by looking at whichever @: mode is already active — differentiate, dcalc, solve, or expand — and shows that operation's own step-by-step derivation automatically. Any OTHER active mode (factor, the physics/chemistry commands, radical/rational/trig, etc.) has no step-by-step version built, so a line under one of those modes is completely unaffected by @:showwork on — same result as if it were off. Unlike every other command in this reference, a steps result is a single line of JSON — {"result": ..., "steps": [{"rule": ..., "narration": ..., "expr": ...}, ...]} — rather than a rendered expression; typing it into the Solutions box isn't pretty (a friendlier in-app rendering is a planned follow-up, not yet built), but the JSON itself is real and fully wired today. rule is a stable symbol (e.g. power-rule, chain-rule) a future UI/icon choice can key off; narration is a free-text sentence; expr is that step's resulting expression. The LAST step's expr always exactly equals what the plain (non-steps) command would return for the same input. @:showwork is purely additive — turning it on never changes what answer a line produces, only whether the steps behind it are also shown, and it never turns an otherwise-working line into an error (see the fallback examples below).
@:showwork on @:solve x^2-5x+6=0 @:expand (x+1)*(x+2) 3x^2+5x+7 @:dcalc x sin(x^2) @:solve @:showwork off x^2-5x+6=0
Produces exactly (blank lines above are just for readability, not part of the real input; note the mode is switched back to @:solve before the final line -- @:showwork off only toggles the steps flag, it leaves the ambient mode at whatever it was last set to, which would otherwise still be dcalc from the line above):
{"result":"x = 3, x = 2","steps":[{"rule":"quadratic-formula",...},{"rule":"quadratic-formula",...}]}
{"result":"x^2+3x+2","steps":[...4 "foil" steps, then "combine-like-terms"...]}
3x²+5x+7
{"result":"cos(x^2)*2*x","steps":[{"rule":"power-rule",...},{"rule":"chain-rule",...}]}
x = 3, x = 2
The third line (3x^2+5x+7 under @:expand) is the graceful-fallback case: it's already fully expanded, not a product-of-groups or group-raised-to-a-power shape, so there's no FOIL step to show — it just prints the plain answer, not an error.
@:differentiate / @:dcalc)Built on @:dcalc's own AST-based engine (§8.2), so it understands the same sin/cos/tan/exp/ln/log/sqrt vocabulary, chain rule included. Under @:differentiate (polynomial-only), a missing variable is inferred the same way @:differentiate itself already does; under @:dcalc, the variable is required, same as always. Logs one step per product rule, quotient rule, power rule, exponential rule (a^u), or chain-rule/table lookup actually applied along the way. Sum/difference and a constant multiple (e.g. the "3" in 3*x) are deliberately NOT narrated on their own — too trivial to count as a taught "rule", the same way a textbook wouldn't call out "now apply the sum rule" either — so a purely linear input like 3x+5 gets a single fallback step covering the whole thing rather than zero steps. rule is one of power-rule, chain-rule, product-rule, quotient-rule, exponential-rule, or (only when needed) a trailing simplify step.
| Input | Result |
|---|---|
sin(x^2) | {"result":"cos(x^2)*2*x","steps":[{"rule":"power-rule","narration":"Differentiate x^2 using the power rule: d/dx[u^n] = n*u^(n-1)*u', with n = 2","expr":"2*x"},{"rule":"chain-rule","narration":"Differentiate sin(x^2) using the derivative of sin and the chain rule (u = x^2)","expr":"cos(x^2)*2*x"}]} |
@:solve)For a quadratic, logs the discriminant, which branch it falls into (rational/irrational/complex), and the radical simplification (simplify-radical) when the discriminant isn't a perfect square. For degree 3 and up, logs each rational-root-theorem division as its own rational-root-divide step until the remaining factor is degree <= 2, then hands off to the quadratic/linear steps above — since only ONE root gets peeled per step logged there (degree drops by exactly 1 each time, not straight to the final answer), a higher-degree equation's own last logged step only covers its own final branch's roots, so one tidy-up step restating the FULL solution set is appended automatically to preserve the "last step matches the real answer" guarantee.
| Input | Result |
|---|---|
x^2-5x+6=0 | {"result":"x = 3, x = 2","steps":[{"rule":"quadratic-formula","narration":"Apply the quadratic formula to x^2-5x+6 = 0 (a=1, b=-5, c=6): the discriminant is b^2-4ac = 1","expr":"1"},{"rule":"quadratic-formula","narration":"The discriminant 1 is a perfect square (√1 = 1), so the roots are rational","expr":"x = 3, x = 2"}]} |
@:expand) — FOILOnly shows steps for a plain product of parenthesized groups — (x+1)*(x+2), the implicit-multiplication (x+1)(x+2), or three-or-more distinct factors like (x+1)*(x+2)*(x+3) — or a single group raised to an integer power from 2 to 10, e.g. (x+1)^3, which rewrites to repeated multiplication first (logged as its own rewrite-power step) since (A)^n literally means A*A*...*A (n times). Anything outside that scope — a multi-term sum, a negated product, division, a bare (non-parenthesized) factor like the x in x*(x+1), or a power above 10 — just falls back to the ordinary plain @:expand answer (see §11.1's fallback note), not an error. Logs one foil step per pairwise product, then one combine-like-terms step; three or more factors fold left, so e.g. a cube runs TWO full FOIL+combine rounds — the second round multiplies the FIRST round's already-combined (3-term) result by the third factor, so it logs more FOIL pairs than the first round did (6, not 4). The power cap exists because a step-by-step trace has no realistic classroom use past ^10, and each additional factor at least doubles the FOIL step count of the round before it — (x+1)^11 still expands correctly, it just quietly skips the steps.
| Input | Result |
|---|---|
(x+1)*(x+2) | {"result":"x^2+3x+2","steps":[{"rule":"foil","narration":"Multiply x by x","expr":"x^2"},{"rule":"foil","narration":"Multiply x by 2","expr":"2x"},{"rule":"foil","narration":"Multiply 1 by x","expr":"x"},{"rule":"foil","narration":"Multiply 1 by 2","expr":"2"},{"rule":"combine-like-terms","narration":"Combine like terms","expr":"x^2+3x+2"}]} |
(x+1)^2 | {"result":"x^2+2x+1","steps":[{"rule":"rewrite-power","narration":"Rewrite (x+1)^2 as repeated multiplication: (x+1)*(x+1)","expr":"(x+1)*(x+1)"}, …same 4 foil steps as above, then combine-like-terms → "x^2+2x+1"…]} |
(x+1)^11 | x¹¹+11x¹⁰+55x⁹+165x⁸+330x⁷+462x⁶+462x⁵+330x⁴+165x³+55x²+11x+1 (plain answer, no steps — past the ^10 cap) |
Finite sets of atomic elements — a plain number or a bare word, not a nested set or an algebraic expression. A set literal is {e1,e2,...}, or {}/∅ for the empty set; results print with numbers sorted ascending before symbols sorted alphabetically, regardless of input order, and with duplicates always collapsed. Under @:set, every following line is a single self-contained set expression — <left> <op> <right> — with no separate variable or parameter the way @:dcalc/@:limit need one.
Each operator accepts either its glyph or one of these ASCII spellings (no space required around either form):
| Operator | Meaning | Both sides |
|---|---|---|
∪ / union | Union | set literals |
∩ / intersect / intersection | Intersection | set literals |
\ / difference / diff / minus | Difference (left minus right) | set literals |
⊆ / subset | Is left a subset of right? (true/false) | set literals |
∈ / member / element | Is left an element of right? (true/false) | left is a bare element, right is a set literal |
| Input | Result |
|---|---|
{1,2,3}∪{2,3,4} | {1,2,3,4} |
{1,2,3}∩{2,3,4} | {2,3} |
{1,2,3}\{2,3,4} | {1} |
{1,2}⊆{1,2,3} | true |
2∈{1,2,3} | true |
{a,b} union {b,c} | {a,b,c} |
{1,2,3}∩{4,5} | ∅ |
çPrefix or suffix a mode-switch command with ç (c-cedilla, U+00E7) to place every following line's computed answer on the next line/cell instead of alongside the problem — e.g. in a spreadsheet, the formula's own cell shows the problem text and the result spills into the cell below. The marker lives on the command, not the expression — so it applies to every line under that mode switch, not just one, and never has to be stripped back out of an expression before it's parsed. The @@: one-line override (§3) also supports it: @@:<mode>ç <expr> triggers for just that single line.
@:solveç x + 5 = 12 # this cell shows "x + 5 = 12", "x = 7" appears one row below x - 3 = 9 # still triggered, same mode @:solve # drop the ç to go back to normal (in-place) mode
A lowercase letter followed by _ and a digit, single letter, or parenthesized expression is a genuinely distinct indexed variable — x_1 and x_2 are different symbols, not just different-looking text, and combine/expand correctly like any other variable. Parenthesized subscripts are normalized, so x_(1+x) and x_(x+1) refer to the same variable.
x_1 + x_2 + x_1 # -> 2x_1 + x_2 (x_1)^2 * x_1 # -> x_1³
Results are displayed with real Unicode superscript/subscript characters — ^exponent and _subscript notation in output is rendered as e.g. x², x_1 → x₁ — no special input needed, this happens automatically to every result. These characters are also accepted as input — copy a previous answer like x²+1 straight back into a new line (or type ²/₁ directly) and it parses exactly like x^2+1.
Excel Custom Functions have two hard platform constraints the Mac app, Google Sheets, and LibreOffice don't: a function can never write to any cell besides its own, and a function's name can't change per call. Two things in this reference work differently in Excel as a result.
| Feature | Everywhere else | Excel |
|---|---|---|
| Next-line trigger | ç on a mode switch (§13): @:factorç | A separate function name per scalar op: PAE.FACTOR_N(...) instead of PAE.FACTOR(...) — one _N variant exists for every scalar function. Matrix functions (PAE.MATRIXADD and friends) don't have _N variants — they take cell ranges, not typed expressions, so ç has no meaning there. |
| Where the answer lands | The next line/cell, as a plain value immediately | PAE.FACTOR_N(...) spills the answer into the cell below via Excel's own dynamic-array mechanism. While the PAE Bird task pane is open, that spilled cell is automatically converted to a plain, independently-editable value shortly after — matching Copy → Paste Special → Values — since Excel otherwise always shows a spilled cell's formula grayed out and non-editable. The formula cell itself keeps its live formula either way. If the task pane is closed, the spilled cell just stays as a live spill result until it's reopened. |
=PAE.FACTOR_N("x^2-9") # formula cell keeps this exact formula
# cell below shows: (x-3)(x+3)