1.2.4
1.2.4
Features
Minor release that widens solving for y past the "one occurrence of y"
frontier of 1.2.3, and gives obs-integral the quotient rule it was missing.
The new solver paths are general rewrites over the AST — clear the denominators,
collect the linear coefficient, square away the radicals — not per-equation
cases. Every transformation that is not an equivalence now states its condition
or is rejected: a solved form still never claims a point the curve doesn't have.
And the conditions that survive are now solved as a system instead of listed,
so a domain reads x ≥ \sqrt3 rather than as two raw inequalities. The full test
suite (334 tests), the zoom suite (12) and the graduated battery (220 generated
towers) pass.
-
yno longer has to occur once — it has to be grouped. The structural
inverter peels the outermost layer and recurses into the child holdingy,
which never neededyto be unique: the whole layer is inverted at once, so it
is enough that a single child contains it. When the tower gets stuck —y
split across both branches of an operator — what has been peeled so far is an
equivalent, simpler equation, and it is re-solved from scratch:
\ln\frac{y-1}{y+2}=x → y=\frac{2e^x+1}{1-e^x},
e^{\frac{y-1}{y+2}}=x → y=\frac{2\ln x+1}{1-\ln x},
\ln(y^2+y)=x → y=\frac{-1±\sqrt{4e^x+1}}{2}. -
yin a denominator is cleared and the equation re-solved. No additive
strategy could reach aysitting in a factor of exponent −1 unless the
numerator was free ofy. Multiplying through by the denominators — the first
step of any textbook solution — leaves a polynomial equation the existing
machinery finishes:\frac{y-1}{y+2}=x → y=\frac{2x+1}{-x+1}. -
Equations affine in
ywhose coefficient needs expanding. A sum of terms
each carrying a barey(y\ln x+y=3) already worked; what fell through was
yinside a group that has to be distributed first, when the coefficient is
not polynomial — the linear strategy reads the coefficient off the structure
of the term, soyhas to be a bare factor, and the quadratic path needs
rationalizeto expand, which only works on polynomials. Since an affine
function is fixed by two values,AandBare now recovered by
substituting two values ofy— substitution works with any coefficient, no
expansion needed — and the affinity itself is what gets checked numerically:
y-(y+2)e^x-1=0 → y=\frac{2e^x+1}{1-e^x}(this is the shape the cleared
Möbius above lands on, and it is what makes that case finish). -
Scattered square roots are rationalized by successive squaring, carrying the
domain condition of every step. One isolated root was already invertible, but
two roots — or a root plusyoutside it — leaveyungrouped and no layer
peelable. Isolating one root and squaring, repeated, produces a polynomial the
solver finishes. Squaring is not an equivalence (A=B ⟺ A²=B²and
B≥0), so each step records its guard and all of them travel to the result as
domain conditions, written inxby substituting back what the later steps
determined:\sqrt{y+1}+\sqrt{y-2}=x → y=\frac{x^4+2x^2+9}{4x^2}with
x ≥ \sqrt3(the two raw guards, resolved into one by the condition
simplifier below). Verified point by point: the solved form draws nothing for
x<\sqrt3and has no gap above it. -
Domain conditions are now solved as a system, not listed one by one. Each
restricted-range layer and each squaring step contributes its own guard, and
the panel used to print all of them — correct but unreadable, because they are
inequalities over the samexand nobody was looking at the system as a whole.
A new module resolves each condition by its sign table (the zeros of
numerator and denominator split the line into constant-sign runs) and
intersects the results, which is where redundant conditions vanish on their
own, adjacent runs merge, and contradictions surface as an empty intersection.
So\frac{x^2+3}{2x}≥0,\ \frac{x^2-3}{2x}≥0is displayed as what it says:
x ≥ \sqrt3. Critical points are computed symbolically precisely because
they are what gets displayed — the root ofx^2-3has to read\sqrt3, not
1.7320508— so-x^2+2 ≥ 0becomes-\sqrt2 ≤ x ≤ \sqrt2andx-27 ≥ 0
becomesx ≥ 27. Its declared reach is closed-form roots: degree 1, degree 2
by the general formula (with the square factor pulled out of the radical,
\sqrt{12}=2\sqrt3), and higher degrees only where integer roots deflate them.
Anything else — a guard with\tan x,|x|,\sqrt x, or a solution set made
of disjoint pieces — leaves the conditions displayed exactly as before: the
module's failure mode is "I don't simplify", never "I simplify wrongly". It is
presentation only; the engine keeps evaluating the original guards, so what is
drawn does not change. -
Contradictory guards are detected across the whole system. Each guard can
be satisfiable on its own while the system is not, and the per-guard check
could not see that. An empty intersection now means there is no real curve and
the equation is left in its reduced form instead of carrying a formula that
never applies. -
obs-integral: the logarithmic derivative
∫\frac{c·q'}{q}=c\ln|q|. A
quotient withxin both numerator and denominator always returned "no
antiderivative". The ratiop/q'is measured by finite differences rather than
by symbolic differentiation, so it does not depend on mathjs being able to
differentiate\cscor\abs. This covers∫\frac{2x}{x^2+1},
∫\frac{3x^2+2}{x^3+2x-5},∫\cot,∫\frac{f'}{f}in general. -
obs-integral: trigonometric canonicalisation as a retry. Expressions
written "by identity" reduce to something the structural rules recognise once
\csc/\sec/\cot/\tanare rewritten in\sin/\cosand the double angle is
opened:∫\frac{1}{\csc 2x-\cot 2x}collapses to∫\cot x = \ln|\sin x|. The
original form is always integrated first, so∫\sin 2xstill gives
-\frac{\cos 2x}{2}and not the expanded version. Also adds the missing
\cot,\secand\csctable entries (with linear substitution:
∫\cot 3x = \frac{\ln|\sin 3x|}{3}).
Bug fixes
-
Clearing a denominator no longer invents branches. Multiplying by
qonly
preserves the curve whereq≠0, and the cleared equation is defined there —
so it can carry solutions that do not exist.\frac{y^2-1}{y-1}=xclears to
y^2-1=x(y-1), whose roots arey=x-1andy=1, and the second is not
curve at all (the original is0/0aty=1). Since a≠condition cannot be
written with the existing≥0domain sentinel, the candidate is instead
validated branch by branch against the equation before multiplying — the only
one that knows about its own holes — and the whole solution is dropped if any
branch contradicts it. -
Removable holes are no longer silently filled.
\frac{y^2-4}{y+2}=xis
affine inythroughout its domain and solves toy=x+2, but the curve does
not containy=-2, i.e. the solved form is missing its hole atx=-4and is
laxer than the curve. Same validation, same outcome: the equation is left in
its reduced form rather than stated more loosely than it is true. -
A singular sampling point no longer leaks into the formula. Recovering the
affine coefficients by substitutingy=0,1hits0/0on an equation like
\frac{y^2-1}{y-1}, and the resultingInfinitytravelled all the way into
the displayed solution (y = ∞x + ∞). Several sampling pairs are tried until
one is clean, and a non-finite coefficient rejects the pair. -
Both branches of a
±are now validated, not just the principal one. The
numeric check evaluated the±sentinel at its principal value, so the second
branch entered the result unchecked. Validation now runs over the expanded
branches — exactly what the engine will draw. A branch that its own domain
guard empties is not a failure (that is precisely the fate of the extraneous
branch introduced by squaring); a branch that contradicts the equation is.