A widened codomain is written out, so Stringize round-trips it (#1048) - #1098
Merged
Conversation
`Domain.Any` had no spelling. The second argument of `domain(...)` had to be one of the five special sets and none of them means "no restriction", so a node widened to `Any` from a narrower default printed as though it had not been: `abs(x)` widened to `Any` printed `abs(x)` and read back as `Real`. #746's lie-free channel asks that what the library prints reads back as what it printed. `Any` is not a set literal. There is still no node for "no restriction" -- `SpecialSet.Create(Domain.Any)` throws for it, deliberately -- so this is read in the second argument of `domain(...)` and nowhere else. That commits to a spelling without deciding whether there is a universal *set*, which is #996 and stays open. **Read rather than lexed, and the first attempt is why.** Writing `'Any'` as a literal in the parser rule makes ANTLR mint a global lexer token, so the name became reserved everywhere and `Any + 1` stopped parsing. Reading it in the action reserves nothing, and `AVariableNamedAnyIsStillAVariable` keeps that from coming back. `PrintsItsCodomain` no longer excludes `Any`, and its remark -- which explained that the grammar could not write it -- now records what changed instead. `Latexize` renders the subscript as `\mathrm{Any}`, since there is no set to render. The grammar was regenerated with the procedure in the codebase skill, and the unmodified grammar was regenerated first to confirm the toolchain produces a byte-identical tree. Only `AngouriMathParser.cs` changed, not the lexer or the token files -- which is the mechanical confirmation that nothing was reserved. `WideningToAnyIsTheOneThingThePrintedFormStillCannotSay` pinned the limitation and failed the moment it stopped being true, which is what that test was for. It is now a theory over three shapes asserting the round-trip.
Rafael-SOWNet
force-pushed
the
fix/any-codomain-is-writable-1048
branch
from
August 27, 2026 23:30
b839392 to
67181b2
Compare
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 case 1 of #1048.
Domain.Anyhad no spelling — the second argument ofdomain(...)had to be one of the fivespecial sets, and none means "no restriction". So a node widened to
Anyfrom a narrowerdefault printed as though it had not been:
MathS.Abs("x").WithCodomain(Any).Stringize()abs(x)domain(abs(x), Any)Real— the widening was lostAnyMathS.Abs("x").WithCodomain(Integer).Stringize()domain(abs(x), ZZ)"Any + 1"Anyis a variable#746's lie-free channel asks that what the library prints reads back as what it printed.
Anyis not a set literal, and that is the pointThere is still no node for "no restriction" —
SpecialSet.Create(Domain.Any)throws for it,deliberately. So
Anyis read in the second argument ofdomain(...)and nowhere else.That commits to a spelling without deciding whether there is a universal set. The issue offers
domain(x, Any)and aUU-style token as both plausible; the second is entangled with #996,which is open, so this takes the one that does not prejudge it.
Read rather than lexed — and the first attempt is why
Writing
'Any'as a literal in the parser rule makes ANTLR mint a global lexer token, so thename became reserved everywhere and
Any + 1stopped parsing. Reading it in the action reservesnothing, and
AVariableNamedAnyIsStillAVariablekeeps that from coming back.Mechanical confirmation: only
AngouriMathParser.cschanged — not the lexer or the tokenfiles.
The grammar regeneration
Followed the procedure in the codebase skill, including regenerating the unmodified grammar
first and confirming
git diffwas empty, so a toolchain difference could not be mistaken for achange of mine.
The test that was designed to fail
WideningToAnyIsTheOneThingThePrintedFormStillCannotSaypinned the limitation, and #1048 saysthose pins exist so the gap "cannot rot silently". It failed the moment this started working,
which is exactly its job. It is now a theory over three shapes asserting the round-trip.
Case 2 of the issue — no input yields a rational literal whose codomain is
Complex— isuntouched. It is a sentinel sharing a representation with a real value, and the issue says nothing
is currently lost by it.
Full suite: 8767 passed, 0 failed.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Bjumi5K7fg8yx6UK1mZTQd