Pending breakages: changes agreed or arguable that cannot ship before a major version
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 25/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Da chiarire
- Stato di attività
- Attiva
- Stack tecnologico
- csharp
- Ambito
- backend-api-design, compilers, release
Direzione di ricerca
Inizia da AGENTS.md e dalle issue collegate per capire quali decisioni sulla major version siano ancora aperte. Poi esamina ToString.Discrete.Classes.cs, Syntax.md e Sources/AngouriMath/Convenience/Experimental/ insieme ai test di round-trip indicati. Il lavoro è completato quando ogni breaking change proposta ha una decisione registrata, un ambito e un piano di validazione prima di dare un nome alla prossima major version.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
"Maybe an issue on pending breakages would be appropriate. Remember to note to yourself to follow through on the next major version. Also, maybe noting down to promote experimentals and removing obsoletions would be appropriate."
— @Happypig375, #1009
This is that issue: the list of changes that are agreed or arguable but cannot ship in a minor, so that 3.0 has a docket rather than a memory. Nothing here is scheduled and nothing here is a defect report.
A change belongs on this list when it moves the value of existing user input, or removes a published member. A changed answer has gone in a minor here before, on the stated principle that correctness outranks compatibility — but every one of those was a wrong answer becoming right. Everything below is a deliberate convention change, which is a different thing and should not borrow that licence.
1. implies becomes right-associative
Raised on #1009. The grammar folds implies to the left; mathematics, Lean, Coq, Agda, Haskell and CSharpMath.Evaluation all read → to the right. Ours is the outlier, and CSharpMath reading it differently from us is a live inconsistency across a boundary we do not control.
It cannot go in a minor because it re-values existing text:
"false implies true implies false" today False after True
Nothing fails to compile; answers move silently. #1009 makes the printer state the grouping the grammar actually has, so the change is a one-line flip in ToString.Discrete.Classes.cs (from <=-on-the-right to <=-on-the-left) plus the grammar, and the round-trip tests written there keep it honest.
Also decide provided at the same time. It folds right today, which #1009 documents and tests. If implies moves to the right, the two agree and Syntax.md's rule becomes "^, implies and provided group to the right"; that is worth settling in one go rather than twice.
2. FreeVariables, VarsAndConsts, and a property that does not exist
Raised on #989.
"VarAndConsts is what it says: free variables and constants (pi and e). "Used variables" looks like another property." — @Happypig375
Measured on master at 6b93b401, against that definition. The documented example is Lambda(x, x * 2 + sin(y * pi)):
| today | by the definition above | |
|---|---|---|
Vars |
x, y |
— |
VarsAndConsts |
x, y, pi |
y, pi — x is bound |
FreeVariables |
y |
y |
So VarsAndConsts returns bound names, and its XML example pins that. It is wrong for lambda, which is the one binder the library already honours elsewhere — and wrong for the other five (sum, product, integral, limit, derivative, set-builder) in the same way:
sum(k, k, 1, 3) Vars = k VarsAndConsts = k FreeVariables = k
sum(k, k, 1, 3) is 6. Nothing about that value depends on k, and all three properties say it does.
The shape of the fix, which is three published properties moving at once:
FreeVariables— extend "bound" from lambda to every binder. Its own doc comment currently defines bound as "a parameter of some outer lambda", which was accurate when written and is not now thatCalculusOperatorandConditionalSetboth declare aVar(#986).VarsAndConsts— free variables and constants, per the definition above.- A new property for "used variables" — every name that occurs, bound ones included. That is what
Vars/VarsAndConstsdo today, so the behaviour is not lost, it is renamed to something that describes it.
Part 1 of #989 — the %1 placeholder escaping — was a defect on any definition and is already fixed (#1000). This is part 2, which was always a design call.
3. Promote or retire the experimental features
MathS.ExperimentalFeatures (Sources/AngouriMath/Convenience/Experimental/) is 11 public members, documented as "features that might become stable in the future, but are not guaranteed to do anything useful or correctly at the current moment":
SolveDiophantineEquation · DecomposeRational ×2 · GetSineOfHalvedAngle · GetCosineOfHalvedAngle · ExpandSineArgumentMultiplied · ExpandCosineArgumentMultiplied · ExpandSineOfSum · ExpandCosineOfSum · SymbolicFormOfSine · SymbolicFormOfCosine
Each wants one of three verdicts, and the third is why this is on a breakage list:
- promote — move to the stable surface under its proper name, and commit to the answer;
- keep — it is still not guaranteed, and say what would settle it;
- remove — it has not earned a place, and deleting a published member is a major-version act.
Worth doing as one pass rather than one member at a time, because "experimental" is a promise about the whole namespace and it decays if it is never spent.
Note also that Experimental is a folder inside the kernel package, not a separate package as #746 describes it — see #1008.
4. Removing obsoletions — a standing practice, not a backlog
There are currently zero [Obsolete] members in the tree: 2.0.0 removed the lot. So there is nothing to schedule, and the note to keep is the rule:
Anything marked [Obsolete] during 2.x is removed at 3.0. An obsoletion that survives a major stops meaning anything, and 1.x accumulated a set precisely by never spending them.
5. Already-known decisions that belong on the same docket
AGENTS.md names three under "Decisions only a major version may take", all still open:
- #204 — roots versus fractional powers.
SimplificationContract.mdcalls it "open and deliberately a major-version question". - #326 — the syntax for
piecewise. #327's simplification half shipped; the syntax was never touched and no design is recorded. - #721 — unify
Codomainwith aprovided … in RRcondition. Named on #746 as a consumer of the retired expression-metadata item, and still open.
And one more that is breaking by construction:
- #217 — complex infinity. It changes
1/0fromNaN, and every consumer branching onNaNis blast radius.
6. | stops meaning or
Raised on #1212, where the invitation was explicit:
"You may change the meaning of
|on the next major version if that's more mathematically appropriate. Consider this for all the other parsed inputs as well." — @Happypig375
| is an alias for or today. It is the only spelling in the grammar that already means something else in mathematics — divides (a | b), "such that" ({x | P(x)}), "given" (P(A | B)), and the delimiter in |x| — so input written by a mathematician is read as a disjunction and answered as one. Measured on 281e0d0c:
| written | reads today as |
|---|---|
2 | 6 |
2 or 6 — a disjunction of two numbers |
{ x | x > 0 } |
{ x or x > 0 } — a FiniteSet of one element, that element a disjunction |
The second is what decided it: {x | x > 0} is ordinary set-builder notation, and we read it as a one-element set. Well-formed, silent, and nothing like what was written.
Nothing is lost by retiring the alias, since or is the primary spelling and is what everything prints as. & is deliberately not on this list: it is equally a programming convention, but no mathematical meaning competes for it, and the test applied throughout was "does this symbol already mean something else to a mathematician", not "would a mathematician have chosen it".
It cannot go in a minor because it re-values existing text, and the proposal is that it should not go in one major either:
"x > 0 | x < -1" today a disjunction after a divisibility statement
Nothing fails to compile; the answer moves silently. So two steps rather than one:
- First major:
|becomes a parse error, with a message namingor. Loud rather than silent, and it costs a release of waiting to remove the entire class of quietly-wrong results. - The major after:
|means divides, and "given" inside an expectation or probability — the scoping @Happypig375 proposed on #1212, whereE/Pintroduce the meaning and their closing bracket ends it.divides(#1220) then becomes the alias and|the canonical spelling.
If one step is preferred, the refusal step is the half I would keep regardless of how long it lasts.
7. Not-equal is a relation of its own, and != spells it
Raised on #1212's survey, filed as #1225; the node proposed there by @Happypig375, and the syntax below approved on #1225 (2026-10-02).
Measured on 94ba5ff6:
| written | parses as | prints | Solve("x") |
|---|---|---|---|
x <> 3 |
not (x = 3) |
not x = 3 |
{ x : not x = 3 } |
a != b |
a! = b, an Equalsf |
a! = b |
|
a ≠ b |
a parse error at ≠ |
The relation exists only as a negated equality, which the solver does not read, and != is silently a factorial equation.
What moves:
- A node,
NotEqualsf(a, b). It prints as one relation, is solved (x ≠ 3isCC \ { 3 }, orRR \ { 3 }over the reals), and is matched by rules as a relation of its own.not (a = b)simplifies to it, so there is one canonical form. - Input
≠,<>and!=, with!=one token, as Mathematica reads it beside the same postfix!:a != banda!=bare the relation, and the factorial equation is writtena! = b, with the space. - Printed
<>in ASCII,≠in Unicode output,\neqin LaTeX.
Why a minor cannot carry it: a!=b and a != b change meaning, and not (a = b) prints and simplifies differently.
8. PeterO's types leave the public API
Raised on #1338, queued for v3 by @Happypig375 there (2026-09-16).
The library's numbers are PeterO's EInteger, ERational and EDecimal, and 48 published members expose them — Integer.EInteger, Rational.ERational, Real.EDecimal, Real.Create(EDecimal), Rational.Create(ERational), Complex.Create(EDecimal, EDecimal), the Deconstructs, the implicit conversions on Entity, Number, Real, Rational, Integer and Complex, MathS.Numbers.Create(...), ToNumber(...), DecimalConst.pi/e, Settings.DecimalPrecisionContext : Setting<EContext>, MaxAbsNumeratorOrDenominatorValue : Setting<EInteger>, PrecisionErrorCommon/PrecisionErrorZeroRange : Setting<EDecimal>, NewtonSetting.From/To, MathS.Utils.TryGetPolynomial(..., Dictionary<EInteger, Entity>), Number.GetAllRoots(Complex, EInteger), GetAllRootsOf1(EInteger), Number.IsZero(EDecimal), Entity.DefiniteIntegral(Variable, EDecimal, EDecimal, int), Rational.FindRational(EDecimal, int).
What moves and why a minor cannot carry it: measured on #1338, one multiply of two hundred-digit integers is 1,271 ns in EInteger and 109 ns in System.Numerics.BigInteger, and an EDecimal multiply or divide is 8–11× a decimal on a BigInteger mantissa; the fixed-point series already run on BigInteger (#1364, #1366) with the conversion at the boundary, and the remaining factor of two to mpmath is that boundary and the decimal layer above it. The plan posted there is in three steps, and only the last is breaking:
- done — the series on
BigIntegerbehind an unchangedEDecimalsurface; - an internal
AngouriMath.Numericstower —BigInteger, a(BigInteger, BigInteger)rational and a(BigInteger mantissa, int exponent)decimal with a precision context — used byNumberbehind the current properties, which become conversions; measurable on the whole gate before any signature changes; - v3: the 48 members above take and return the new types,
PeterO.Numbersleaves the package's dependencies, andBREAKING-CHANGES.mdcarries the migration: everyEDecimala caller passes today becomes a decimal of ours (a parse fromEDecimal.ToString()is lossless), everyEIntegeraBigInteger(EInteger.ToBytes/new BigInteger(bytes)both ways), andSetting<EContext>becomes a setting of a precision-and-rounding record of ours.
No answer moves: this changes the types a caller holds, not what any of them is worth.
9. An architectural review, every major version — and for v3, a global restructure
"Remember to do an architectural review every major version." — "refactor the API to reflect the best architecture as needed; major versions are for breaking changes." — and for this one in particular: "for v2->3 we still want to do a global architecture review and restructure pass because v1->2 didn't consider how a Math OS (according to everything in #746) should be structured - it followed mostly v1. Everything across file structure and API structure as well as projects and packages need to be restructured according to that vision. And because this is a global architecture pass, ensure that it's Claude Fable doing it instead of Opus." — @Happypig375, 1, 2, 3
Two things, then. As a standing rule, every major version gets an architectural review: the API read against what was added since the last one, and the parts that now share a better abstraction with the new work refactored to it there, since the major is where the breakage is allowed. For v3 specifically, a global pass: 2.0 followed 1.x's structure and never asked how a Math OS in #746's sense should be laid out, so the file structure, the API structure, the projects and the packages are to be restructured against that vision, not only patched where an abstraction has drifted — item 8's tower and the 48 members it retires are one piece of it, #746's package boundaries (its item 78) another. It is to be done by Claude Fable rather than Opus, per the maintainer, being a global pass; what it decides lands here or in the release, and it runs before v3 is named, not after.
The review also looks for duplicates and synthesises them — "whether hidden in implementation or types representing similar concepts" (4). Two kinds: the same computation written twice in different places (a rule and a solver each doing their own long division, a check re-implemented beside the helper that already answers it), and two types standing for one concept (a Setting<EContext> beside the precision the numeric tower will carry; an ERational beside a Rational; the several spellings of "a polynomial over x" that TryGetPolynomial, MultivariatePolynomial and the Hermite ansatz each keep). Each pair either becomes one thing or gets a written reason for being two, and a major is where the surviving one may take the other's name.
And every release, major or not, updates the website (AngouriMathSite): its What's new and its quickstart name the version they were last brought to, and as of 2026-09-16 that is 2.1.0 against a library at 2.5.0. It is a line on the release checklist in AGENTS.md from here on, not a thing to remember.
10. Numbers, evaluation and comparison: exact where exact, to a requested accuracy where not
Raised on #1376 and queued for v3 by @Happypig375 there (2026-09-16): "It just doesn't look right to have a logical boolean change its value just because we ask it at a different precision. An approximate comparison should be written properly as a chained inequality instead." — "we might want to separate the idea of a complex number that consists of two EDecimals and a real number that consists of an EDecimal from the node hierarchy as well. Any approximate operations with a floating point number would instead be interval arithmetic (or statistical distribution arithmetic if modelled that way)."
What is wrong today: 2 + 2^(-100) = 2 is True, because Equalsf subtracts the sides, evaluates, and asks Number.IsZero, which is |d| < PrecisionErrorZeroRange = 1e-16; Real == Real uses a third constant, PrecisionErrorCommon = 1e-6; and Evaled runs everything to DecimalPrecisionContext's hundred digits whether the question needs one or none. A boolean's value depends on the precision, and an exact rational is thrown away on the way to it.
What moves (the decisions are the review's, item 9):
- Exact stays exact. Every parsable construction is exact — integers, rationals, radicals,
pi,e. A comparison of exact quantities is decided exactly, symbolically where the numbers are algebraic, and enumerates no digits:1 < 1 + 1^(-1000) < 2is settled by arithmetic on rationals. - Evaluation to a requested accuracy, not to a global context:
3 < sqrt(2) + sqrt(3) < 4needs one digit after the point and0 < sqrt(2) + sqrt(3) - pi < 1needs more, and each asks for what it needs ("Evaled as necessary"). The settingDecimalPrecisionContext : Setting<EContext>(item 8's PeterO type) becomes a request carried by the call, in significant digits or digits after the point, with a repeating expansion for a rational. Speed and memory of getting the correct digits with minimal computation is its own area, and worth it. - Approximate values are approximate on their face. A number that arrived as a
double, or through an explicitRealconstructor, is not exact, and arithmetic on it is interval arithmetic (or a distribution, if modelled so) rather than a decimal that pretends to a hundred digits. An approximate comparison is a chained inequality with the accuracy in it, never an equality with a hidden tolerance. - The numeric representation leaves the node hierarchy: a real as one
EDecimaland a complex as two are representation, and the tower of item 8 is where that lives, with the nodes holding numbers rather than being them.
Why a minor cannot carry it: Equalsf, Number.IsZero, Real ==, the three PrecisionError* settings and Evaled itself all change what they answer, and every True that came from a tolerance may become False — recorded in BREAKING-CHANGES.md per input as the review finds them.
11. Newton's method is an entry point of its own
Raised on #1573 and queued for v3 by @Happypig375 there (2026-09-29): "Newton's solver is to be a separate entry point compared to the analytical solver since the guarantees of the answers are too different - Newton's solver guarantees "some" solutions on "more" equations while the analytical solver guarantees "all" solutions on "less" equations. Moreover, numerical approximation is to be their own types separate from the normal exact node hierarchy."
What is wrong today: where every analytical route declines, Solve falls back to Newton's method (MathS.Settings.AllowNewton, on by default) and answers the points it finds as a FiniteSet, which reads exactly like a complete, exact solution set. abs(x - 2) = abs(x - 3) was three points of the line Re x = 5/2. #1578 keeps the fallback away from equations real for every complex x, which is a guard and not the separation.
What moves: Solve answers what the analytical solvers establish, all the solutions or the equation left unsolved, and Newton's method becomes its own entry point, returning approximations typed as approximations (item 10) with no claim to be all of them.
Why a minor cannot carry it: every equation Solve answers today only through the fallback becomes unsolved there, a changed answer for each, and the types the new entry point returns are item 10's.
12. "Simplified" is a stated property, not a rating
Raised on #1409 by @Happypig375 (2026-09-29): "We also need a better definition of "simplified" for v3 (#1019). Counting the arbitrarily defined simplified rate isn't how mathematicians do it..."
What is wrong today: Simplify returns whichever candidate it generated has the lowest SimplifiedRate, a weighted count of nodes, and a tie goes to whichever was generated first. CanonicalForm.md §1 makes that the definition: "simplest is the best-rated member of an equivalence class under a cost metric." So an answer is simplified only relative to a number nobody states, and moving a weight moves answers nobody asked about.
What moves: simplified becomes a list of properties a result has, written per node class beside the canonical form, the way a textbook defines simplest radical form:
- like terms combined;
- a quotient in lowest terms, with no fraction nested in it;
- no radical in a denominator, and no perfect power under a radical;
- no negative exponents;
- a function of an exact number evaluated where the value is exact.
Each is checkable on the answer, so Simplify is tested against the list the way canoncheck tests canonical form. A rate at most breaks ties among forms that already satisfy it. A shape that a question wants for its own purpose (factored, expanded, in partial fractions, over a common denominator) is asked for by name, as Factorize and Expand already are.
Why a minor cannot carry it: most answers Simplify gives today would be re-derived against the list, and every one that changes is a changed answer.
13. Exceptions are for unrecoverable errors; the lack of a value is null
Raised on this issue by @Happypig375 (2026-09-30): "Design principle for v3: exceptions are for unrecoverable errors; the lack of value is null."
What is wrong today: several public methods throw when they have no value to give, and a caller finds out only by catching.
EvalNumericalandEvalBooleanthrowCannotEvalExceptionwhere an expression has no value (#1570).- An operation the library does not support throws
NotSufficientlySupportedException, from 12 sites (#1569). CompileandSolveNtthrowUncompilableNodeExceptionwhere the compiler has no form for a node, from 17 sites. #1603 keepsSolvefrom reaching it; #1605 leavesSolveNt's exception in place for 2.x, because it is a public contract.- A limit toward a complex infinity throws
LimitOperationNotSupportedException.
#1540 took exceptions out of the library's own control flow for 2.6.0. These are what remain, and all of them are on the public surface.
What moves: each of these returns null, typed as nullable, so that the compiler holds every caller to the check. Every other exception type is to be reviewed the same way, and presumably replaced (@Happypig375 on #1569, 2026-09-30: "all exception types require a review to see if null-returns or returning a union type (think how you'd do it in functional languages like F#) is cleaner for the API shape instead. Presumably all exceptions are to be replaced with proper return types."). Where there is more than one reason for the lack of a value, the reason is itself the return value, as a union. The candidates for staying an exception, which the review decides:
- misuse, such as
SolveRequiresStatementExceptionandWrongNumberOfArgumentsException; - the library contradicting itself:
AngouriBugException, 57 sites; - input that is not an expression at all: the parse exceptions. A
TryParse-style entry that returns null, or a union with the parse error, can sit besideParse.
One is kept already (@Happypig375 on #1569): the implicit conversion from a string, which declares an entity in one line and has no return value to put a failure in. No other case for throwing is known.
Two decisions went with it, and @Happypig375 settled both (2026-09-30): "treat Undefined and Indeterminate as proper values on their own like Mathematica does (We won't have NaN in v3 because it's inherently a value defined by an approximate floating point type)."
- An operation on matrices of shapes it isn't defined for is Undefined, a value: neither misuse nor null (
InvalidMatrixOperationExceptionandInvalidNumberException, 24 sites between them). - There is no
NaNin v3.0/0is Indeterminate, as one of the indeterminate forms, and1/0is complex infinity (#217). Null still says only that no value was produced.
Why a minor cannot carry it: every method named above changes its return type or its contract, and a caller that catches today either stops compiling or stops being reached.
14. Definedness comes from the arithmetic, and from a rule's stated condition
Raised on #1648 by @Happypig375 (2026-10-01): "Note the correct design for v3 (#1019) if you identify one".
What is wrong today: rewrites such as a / (b / c) → a * c / b give a value where the expression has none. 1/(1/x) simplifies to x, which is 0 at x = 0, where 1/(1/x) is NaN. O4 of SimplificationContract.md forbids that, and of the three 2.x fixes measured on #1648, none is clean.
What moves:
-
On v3's arithmetic, most of these rewrites are identities. There
1/0is complex infinity (#217) and0/0is Indeterminate (item 13), so1/(1/0)is1/∞ = 0, the same asx. Measured with sympy'szooandnan, letting each hole take 0, ∞, Indeterminate and five finite values. Holes need the infinite values because a hole matches a subexpression, and a subexpression can be infinite where the variables are not:rewrite assignments that agree a/(b/c) → a*c/b512 of 512 (a/b)/(c/d) → (a*d)/(b*c)4096 of 4096 (a/b)/c → a/(b*c)512 of 512 (a^n)^m → a^(n*m),mwhole200 of 200 a/csc(b) → a*sin(b), and likewisesec/cosandcot/tan88 of 88 each All eight examples of #1648 agree at their singular points. These rules carry no condition in v3, and any condition 2.x attaches to them in the meantime comes off.
-
The rest state their condition in the rule, as data. Some rewrites change definedness even on the sphere, and the same measurement finds them:
a/a → 1at 0, ∞ and Indeterminate;0·a → 0anda − a → 0at ∞ and Indeterminate;(a·b)/(a·c) → b/c, which is what pairwise grouping does when it cancels;e^ln(a) → aat 0 and ∞. Whether this one belongs here depends on whether #217's infinity is directed: in Mathematica,Log[0]is-Infinityande^-∞is 0.
Each such rule declares its condition beside its pattern, where
when:sits today, andsoundcheckchecks each declaration at the points where the two sides differ. -
The engine carries conditions beside the candidate, not inside it. It collects what the applied rules declare and drops whatever the input's own domain (
DomainConditionIn) or the preamble already implies. What remains is stated once, on the answer. The alternative was measured on #1648: aprovidedinside the search hid the rewrite's shape from the rules that continue from it, and gave 34 failures, about 20 of them lost capability.
Why a minor cannot carry it: the arithmetic is #217's, and every answer that gains or loses a condition is a changed answer.
15. The number system says which infinities it has
Raised on #1648 by @Happypig375 (2026-10-02). over RR and over CC don't include infinities, and today's default includes them in a way that is neither the extended reals nor the Riemann sphere.
What is true today, measured on master bc6c190c:
ooand-ooare reals. Each part of a complex number can be infinite on its own, as inoo + ior-oo i. There is no complex infinity:1/0isNaN(#217). So the default is the complex plane with an infinity in each axis direction.RRtreats the two infinities differently:-oo in RRsimplifies toTrue, whileoo in RRis left undecided.oo - ooand0 * oosimplify to0. These are item 14'sa − a → 0and0·a → 0at ∞.
What moves:
- Five sets, each with a name, agreed on #1648:
RRandCCwithout infinities; the extended reals,RRbar, which areRRwith-∞and+∞; and the two projective lines,RRhatandCChat, which areRRandCCeach with one unsigned∞— the projectively extended reals and the Riemann sphere. The bar is a line with two ends, the hat two lines meeting at one point. Each algebra with an unambiguous notation has a short name, and its full name is a synonym (@Happypig375, 2026-10-02):Reals,Complexes,ExtendedReals,ProjectiveRealsandProjectiveComplexes. The default has no notation, so it has only its full name. - One projective infinity, printed
∞̃and\tilde{\infty}in LaTeX as Mathematica (ComplexInfinity) and Calcium (UnsignedInfinity) print it, with SymPy'szooproposed for its ASCII spelling: the point at infinity ofRRhatis the same point asCChat's, sinceP¹(R) ⊂ P¹(C), and it is the default's undirected infinity, #217's1/0. - The default is the complex singularity closure, Calcium's term (Johansson, arXiv 2011.01728, after Mathematica):
CC, the directed infinities,∞̃, and item 13's two exceptional values, Undefined and Indeterminate, where Calcium has one. Calcium's sets match these:ExtendedRealNumbersisRRbar,ProjectiveRealNumbersandProjectiveComplexNumbersareRRhatandCChat. Writtenover ComplexSingularityClosurewhere it has to be named. ooby algebra:+∞in the default and inRRbar; underRRhatorCChat,ooand-ooboth name the one point at infinity; underRRorCC, neither is a member.- Undefined and Indeterminate propagate in every algebra (@Happypig375 on #1648): an operation on either gives it, over
RRas over the default. What an algebra decides is membership —Undefined in RRis false,Undefined in ComplexSingularityClosuretrue — and the value at its own special points:1/0is Undefined overRR, outside it, so division is partial there; and∞̃over the projective lines and the default, inside them, so division is total there. - Mixing
overs: every named set sits inside the default, so nodes under differentovers combine in the default and the result is the default's:(oo over RRbar) + (oo over RRhat)is+∞ + ∞̃, Indeterminate. Noovermeans the default, and a prelude can set another for every node. - The projective lines share one arithmetic:
x/0 = ∞forx ≠ 0,x ± ∞ = ∞andx/∞ = 0for finitex,x·∞ = ∞forx ≠ 0;∞ + ∞,∞ - ∞,0·∞,∞/∞and0/0are Indeterminate; and there is no order, so∞ > 0has no value. Where they differ fromRRbaris limits:1/xat0tends to∞on the projective line and has no limit over the extended reals. - The default is stated. One model already has the default's shape, and it is Mathematica's: directed infinities
∞·e^(iθ), with+∞and-∞as the real directions, plus one undirected complex infinity, which is #217's1/0. Together with Indeterminate (item 13), that set is closed under the arithmetic. Over the extended reals only the two real directions remain, and over the sphere every infinity is the one∞. Its name is Calcium's, the complex singularity closure (below). It is documented as what evaluation works in, andovertakes the named sets only. over RRandover CCexclude every infinity. A limit of+∞has no value overRR, andx in RRis false at±∞.oo - ooand0·ooare Indeterminate.- Rules ask for properties, not for algebras (@Happypig375 on #1648, 2026-10-02). Every algebra declares: division by every nonzero element (a field); no zero divisors; commutative multiplication; an order compatible with the arithmetic; its characteristic. A rule names what it needs --
a/a = 1division,a^2 = 0 ⇒ a = 0no zero divisors,a b = b acommutativity -- and applies only where the algebra has it. These are the assumptions #1252 says the 177SoundUnderAssumptionsrules declare and do not name. ZZ/nZZ, the integers modulo the idealnZZ,na number or a symbol: a field for a primen, with zero divisors otherwise (2 * 3 = 0inZZ/6ZZ). Today'sa = b (mod n)is membership in one class of it.ZZ_3is not used, being the 3-adic integers to many readers.- No further algebras in the default: hyperreals, infinitesimals, quaternions. @Happypig375 on #1648: the simplification rules would be damaged the further the default goes beyond the complex numbers with infinities, because more functions become multi-valued under inversion and more identities stop holding. Orders of vanishing and asymptotics, what infinitesimals would be used for here, limits and series already answer. Dual numbers (
ε^2 = 0, for automatic differentiation) would be a separate algebra, outside the default.
Why a minor cannot carry it: oo - oo, 0·oo and the membership of every infinity change their answers, and #217 changes 1/0.
16. amcli's commands say what they do
Raised on #1654 by @Happypig375 (2026-10-02): "remember to revise the command names for clarity and correctness for v3".
#1654 kept the standalone CLI's names so that its scripts would keep working. A proposal:
| today | v3 | why |
|---|---|---|
eval |
evaluate |
the library's verb. It evaluates what it can, so amcli eval "x + 1" prints x + 1, and the usage line's "evaluates to a number" claims too much |
simp |
simplify |
the library's verb |
fsimp |
normalize |
it is the normalisation without the search, InnerSimplified, and fsimp names neither |
diff |
differentiate |
diff reads as a difference |
sub |
substitute |
sub reads as subtract |
info |
describe |
the code already calls it describe, and the name says what it prints |
solve, latex |
unchanged |
Why a minor cannot carry it: removing a name breaks the scripts that call it. A minor can add the new names beside the old ones first, and v3 then removes the abbreviations.
17. Solve takes several unknowns, and EquationSystem goes
Raised on #1673 by @Happypig375 (2026-10-02): "this method is to be removed for v3 - let solve return for multiple variables."
A system is a conjunction, and Solve already reads and for one unknown. MathS.Equations(...).Solve(x, y) is a second entry point that takes each equation in = 0 form and returns a matrix of solution rows. Proposed:
"x + y = 3 and x - y = 1".Solve("x", "y")solves for both unknowns and returns the solutions jointly,{ (2, 1) }, which wants a tuple that is not a vector.MathS.EquationsandEquationSystemare removed.
Before it, #1680 has to hold: a conjunction with a parameter keeps its second equation where its members leave it undecided, rather than dropping it.
Why a minor cannot carry it: removing MathS.Equations breaks every caller, and a minor can only add Solve(x, y) beside it.
What this issue is for
To be read before the next major version is named, in the same way #746 is read before any version is named. It is not a plan and it does not commit anyone.
Anything added here should say what moves, what the old and new values are, and why a minor cannot carry it.
- Lingua principale
- C#
- Stelle
- 831
- Fork
- 79
- Merge medio
- 2h 22m
- PR unite (30g)
- 507
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di ASC-Community/AngouriMath
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 30/100
ASC-Community/AngouriMath#1807 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
ASC-Community/AngouriMath#1692 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 30/100
ASC-Community/AngouriMath#1690 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
ASC-Community/AngouriMath#1689 · 5 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
ASC-Community/AngouriMath#1684 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di ASC-Community/AngouriMath
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 80/100
I maintainer di solito rispondono entro 1 giorno
-
:watch: Not Triaged aspnet-core/svc fundamentals/subsvc Source - Docs.ms
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
dotnet/AspNetCore.Docs#37785 ·
I maintainer di solito rispondono entro 1 giorno
-
needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 1 giorno
-
needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
Azure/azure-sdk-tools#17204 ·
I maintainer di solito rispondono entro 1 giorno
-
Проблема с Dotnet RUApertaarea-tutorials needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
dotnet/website-feedback#1779 ·