Refuse eleven function names the library does not have (#733) - #750
Merged
Conversation
A name the grammar does not know, followed by a bracket, is the implicit
multiplication that lets `a(b + c)` mean `a * (b + c)`. For a one-argument call
that never fails, so every CAS spelling AngouriMath lacks came back as the
product of an undeclared variable with its argument, and nothing said so:
"floor(x)" -> floor * x
"floor(x) - 3 = 0".Solve("x") -> { 3 / floor }, a root of nothing
`floor`, `ceil`, `ceiling`, `round`, `trunc`, `min`, `max`, `gcd`, `lcm`, `erf`
and `conjugate` are refused by name now, as `arcsinh` already is, with a message
saying what happened and why. None of them is being removed: none was there.
The absence was already reported for two arguments and only reported *badly* --
`min(x, y)` raised `no viable alternative at input '*('` from the parser
generator, so whether a missing function was invisible or merely cryptic
depended on how many arguments the caller happened to pass. Now it is the same
error either way, and it names the function.
Refusing every unknown name is not an option, since that rule is what `a(b + c)`
is, so these are refused one at a time and nothing else moves: each name on its
own is still a variable (`min + 1`, `floor + floor`), and a longer name
beginning the same way is still a product (`minimum(x)`, `rounded(x)`,
`maxx(y)`).
`re` and `im` are deliberately left. They are the sympy spellings for the real
and imaginary parts and misparse identically, but two letters is short enough
that a caller may reasonably have a variable of that name, and refusing would
break their expression to fix nobody's. Pinned by a test so the choice is
visible rather than an oversight.
Grammar regenerated with `Sources/Utils/antlr_rerun.bat`. Recorded in
`BREAKING-CHANGES.md` -- it is a loud break, and the file's own rule is that a
call which used to succeed and now does not gets an entry -- and in
`Docs/Usage/Syntax.md`, which is a reading of the grammar.
Suite 4979 -> 5004 passed / 0 failed, F# 130/130, corpus 112/117 with 0 wrong
and every verdict and answer byte-identical.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the remaining defect half of #733. The feature half — actually having these functions — is not this.
What was wrong
A name the grammar does not know, followed by a bracket, is the implicit multiplication that lets
a(b + c)meana * (b + c). For a one-argument call that never fails, so every CAS spelling AngouriMath lacks came back as the product of an undeclared variable with its argument, silently:The same absence was already reported for two arguments, and only reported badly:
So whether a missing function was invisible or merely cryptic depended on how many arguments the caller happened to pass, and neither told them the function does not exist.
What the fix does
Eleven names —
floor,ceil,ceiling,round,trunc,min,max,gcd,lcm,erf,conjugate— are refused by name, exactly asarcsinhalready is, with a message that says what happened:Nothing is being removed — none of these was ever there. This turns a silent wrong answer into a parse error, which is the whole of it.
Refusing every unknown name is not an option, since that rule is what
a(b + c)is. So these are refused one at a time and nothing else moves:min + 1,max * 2,floor + floorminimum(x),rounded(x),maxx(y)a(b + c)a * (b + c)sgn,sign,signum,abs,gamma,factorial,exp,log10,log2,arsinh,phireandimare deliberately not refused. They are the sympy spellings for the real and imaginary parts and misparse identically, but two letters is short enough that a caller may reasonably have a variable of that name, and refusing would break their expression to fix nobody's. Pinned by a test so the choice is visible rather than an oversight.Measured
work/rootcheck595/596; its one incomplete case is A power of a polynomial is solved by inverting into itself, so the roots come back containing x #744, fixed in Only invert an equation whose variable occurs once (#744) #745, not here.Grammar regenerated with
Sources/Utils/antlr_rerun.bat, so the generated files underCore/Antlrare part of the diff.Recorded in
BREAKING-CHANGES.md— it is a loud break and that file's rule is that a call which used to succeed and now does not gets an entry — and inDocs/Usage/Syntax.md, which is a reading of the grammar.🤖 Generated with Claude Code