Skip to content

Read exp(x) as a power of e rather than as a product (#730) - #731

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
feat/exp-function
Aug 5, 2026
Merged

Rafael-SOWNet merged 1 commit into
masterfrom
feat/exp-function

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Closes #730.

exp is the ordinary name for the exponential function everywhere else — sympy, Mathematica, MATLAB, numpy — and the grammar did not have it.

What was wrong

It did not fail. It fell through to implicit multiplication, the rule that lets a(b + c) mean a * (b + c), and came out as the product of an undeclared variable named exp with the argument:

"exp(x)".ToEntity()          =>  exp * x
"exp(1)".ToEntity().Evaled   =>  exp

Nothing was said about it, so the misreading propagated into an answer that looked like one:

"exp(x) - 3 * x".ToEntity().SolveEquation("x")   =>  { 0 }

0 is a root of exp * x - 3x and of nothing else. The equation has two real roots, near 0.6190612867 and 1.5121345517. A wrong answer to a misread question, rather than a refusal to answer an unsupported one.

This is the same shape as the arcsinh case fixed earlier. The difference is that arcsinh is a misnomer and was right to refuse, whereas exp names something the library already has.

The fix

One grammar rule, mapping to MathS.Pow(MathS.e, arg) rather than to a new node. A distinct Expf would have to be taught differentiation, integration and simplification over again; a power of e already has all of it — which is why exp(x) * exp(y) comes out e ^ (x + y) with nothing further added.

Only the exact name followed by a bracket is the function, as for every other function in the grammar: expr(x), expo(x), aexp(x) and a bare exp are the products they were, and a test pins that.

Measured

before after
exp(x) exp * x e ^ x
exp(1) evaluated exp 2.71828…
exp(x) - 3x = 0 { 0 } both real roots
d/dx exp(2x) 2 * exp 2 * e ^ (2 * x)

Parser regenerated with the committed antlr-4.13.1-complete.jar and the AntlrPostProcessorReplacePublicWithInternal step. Regenerating the unmodified grammar first produced an empty diff, so the toolchain here reproduces the committed files and the only change is the new rule.

Full suite 4866 passed / 0 failed, F# 130/130, 117-problem corpus 112/117 with 0 wrong, 0 error, 0 timeout.

🤖 Generated with Claude Code

`exp` is the ordinary name for the exponential function everywhere else
-- sympy, Mathematica, MATLAB, numpy -- and the grammar did not have it.

It did not fail. It fell through to implicit multiplication, the rule
that lets `a(b + c)` mean `a * (b + c)`, and came out as the product of
an undeclared variable named `exp` with the argument. Nothing was said
about it, so the misreading propagated into an answer that looked like
one: `exp(x) - 3x = 0` answered `{ 0 }`, which is a root of `exp * x -
3x` and of nothing else. The equation has two real roots, near 0.6191
and 1.5121.

That is the same shape as the arcsinh case -- a name that looks like a
function, is not one, and is quietly absorbed by implicit
multiplication. The difference is that arcsinh is a misnomer and was
right to refuse, whereas exp names something the library already has.

So it maps to `MathS.Pow(MathS.e, arg)` rather than to a new node. A
distinct Expf would have to be taught differentiation, integration and
simplification over again; a power of e already has all of it, which is
why `exp(x) * exp(y)` comes out `e^(x + y)` with nothing further added.

Only the exact name followed by a bracket is taken as the function, as
for every other function in the grammar: `expr(x)`, `expo(x)` and a bare
`exp` are the products they were.

Measured: `exp(x) - 3x = 0` from `{ 0 }` to both real roots. Parser
regenerated with antlr-4.13.1 and the post-processor; regenerating the
unmodified grammar first gave an empty diff, so the only change is the
rule. Full suite 4866 passed / 0 failed, F# 130/130, corpus 112/117 with
0 wrong, 0 error, 0 timeout.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Rafael-SOWNet
Rafael-SOWNet merged commit 7f83a82 into master Aug 5, 2026
24 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the feat/exp-function branch August 5, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

exp(x) is silently read as a product, so exp equations get wrong answers

1 participant