Cancel¶
Status: Stable
documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
Description¶
Cancel[expr] cancels out common factors in the numerator and denominator of expr.
Option Extension -> alpha cancels factors over Q(alpha) (e.g. simplifies
(x^2 - 2)/(x - Sqrt[2]) to x + Sqrt[2] when Extension -> Sqrt[2]).
Default Extension -> None treats algebraic numbers as opaque.
Examples¶
All examples below are verified against the current Mathilda build.
In[1]:= Cancel[(x^2 - 1) / (x - 1)]
Out[1]= 1 + x
In[2]:= Cancel[(x - y)/(x^2 - y^2) + (x^3 - 27)/(x^2 - 9)]
Out[2]= (9 + 3 x + x^2)/(3 + x) + 1/(x + y)
In[3]:= Cancel[(y - 1)/(Sqrt[y] - 1)]
Out[3]= 1 + Sqrt[y]
In[4]:= Cancel[(y - 1)/(y^(1/3) - 1)]
Out[4]= 1 + y^(1/3) + y^(2/3)
In[5]:= Cancel[1/(y^(2/3) - 1/y^(1/3))]
Out[5]= y^(1/3)/(-1 + y)
In[6]:= Cancel[(x^2 - 2)/(x - Sqrt[2]), Extension -> Sqrt[2]]
Out[6]= Sqrt[2] + x
In[7]:= Cancel[(x^3 - 2)/(x - 2^(1/3)), Extension -> 2^(1/3)]
Out[7]= 2^(2/3) + 2^(1/3) x + x^2
In[8]:= Cancel[Sqrt[2]/(Sqrt[2] + Sqrt[2] x^4)]
Out[8]= 1/(1 + x^4)
Implementation notes¶
Algorithm. Cancel reduces a rational expression to lowest terms by cancelling the polynomial GCD of numerator and denominator. builtin_cancel_compute strips an optional Extension -> α (with Automatic via extension_autodetect, routing single-generator and tower cases through the Q(α) paths cancel_with_extension / qa_cancel_with_tower) and otherwise calls cancel_recursive. That routine recurses through List/Plus/relational/logical heads, then for a leaf fraction: splits the expression into num/den with extract_num_den (which understands Rational, Complex, Power/Exp with negative or split exponents, and Times), strips common symbolic atoms (rat_strip_symbolic_common), computes g = PolynomialGCD[num, den], and divides both sides by g using fraction-free exact polynomial division (exact_poly_div over the collected variable set). A soundness gate (has_embedded_rational_subterm) leaves the input untouched when a Power[Plus/Times, negative] is present, since the multivariate Euclidean GCD could blow up; the denominator's leading sign is normalised to positive.
Data structures. Expr trees throughout; the cancellation calls into the polynomial subsystem via the PolynomialGCD builtin (dispatching to qaupoly_gcd for extensions) and exact_poly_div, with variable sets collected by collect_variables and sorted by compare_expr_ptrs. Numerator/Denominator (same file) expose extract_num_den directly.
Complexity / limits. Dominated by the multivariate polynomial GCD; the embedded-rational gate and leaf-count fallbacks exist to avoid pathological Euclidean-blowup hangs, so some algebraically-cancellable inputs are returned uncancelled (left for later Simplify passes).
Protected,Listable.- Threads over equations, inequalities, logic functions, and sums dynamically.
- Evaluates greatest common divisors via polynomial GCD derivations avoiding extraneous expansions.
- Handles a single symbolic base appearing with rational fractional exponents (e.g.
Sqrt[y],y^(1/3)) by treating it as an algebraic generator: substitutesy -> g^mwheremis the LCM of denominators, runs the polynomial cancellation ing, then substitutes back. - The algebraic-generator pass runs
Togetheron the substituted form (not just GCD-cancellation), so inputs whoseg-substituted denominator is a Plus of terms with differentg-denominators (e.g.1/(g^2 - 1/g)from1/(y^(2/3) - 1/y^(1/3))) are handled correctly. - Extracts algebraic-constant atoms (
Sqrt[2],Sqrt[3],CubeRoot[5],2^(2/3), ...) that appear in every summand of both numerator and denominator and divides them out before the polynomial GCD step. Closes a long-standing gap wherePolynomialGCD[Sqrt[2], Sqrt[2] + Sqrt[2] x^4]returns 1 (the integer-content recursion treatsSqrt[2]as having content 1), so cancellations whose only shared factor was an algebraic constant survived as-is. The pass is intentionally narrow — onlyPower[integer, rational/non-integer]factors are eligible — to avoid disturbing the rational-function intermediates that the integration dispatcher pattern-matches against. - Option
Extension -> alpha(Phase 0 of the Integrate plan) cancels common factors overQ(alpha)instead ofQ. Implementation: lifts numerator and denominator intoQ(alpha)[x]via the QAUPoly machinery, runsqaupoly_gcd, divides both sides byg, and re-renders. Works for single-fraction inputs;Plusinputs (sums of fractions) currently fall back to the no-extension path becausePolynomialQuotientdoes not yet acceptExtension(Phase 0.5 follow-up).
Attributes: Listable, Protected.
Implementation status¶
Stable — documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
References¶
- von zur Gathen & Gerhard, "Modern Computer Algebra", on polynomial GCD computation.
- Geddes, Czapor & Labahn, "Algorithms for Computer Algebra" (1992), on rational function simplification.
- Source:
src/rat.c - Specification:
docs/spec/builtins/algebra.md
Notes & additional examples¶
Worked examples¶
Notes¶
Cancel removes the common polynomial factors between numerator and denominator by
dividing out their GCD, without performing a partial-fraction split. It reduces
(x^2-1)/(x-1) to 1 + x and recognises perfect-square numerators such as
(x^2+2x+1)/(x+1). When a common factor remains after cancellation, the result
stays a reduced quotient: (x^2-1)/(x^2-2x+1) becomes (1+x)/(-1+x) because both
share the factor (x-1) but the leftover (x+1)/(x-1) is already in lowest
terms. Cancel does not expand the surviving factors back out.
With the Extension -> alpha option, cancellation is performed over the
algebraic field Q(alpha): (x^2 - 2)/(x - Sqrt[2]) factors as
(x - Sqrt[2])(x + Sqrt[2]) over Q(Sqrt[2]), so the denominator divides out
and the quotient collapses to Sqrt[2] + x. The default Extension -> None
treats algebraic numbers as opaque and would leave that quotient intact.