Repository navigation
Add ResidueClass(k, n), an element of ℤ/nℤ, and list ℤ/nℤ through it - #411
enumeratio wants to merge 1 commit into
Conversation
… equality, exact bigint arithmetic with inverses only for units, integer coercion, \overline{k}_{n} LaTeX; list and decide membership of QuotientRing(Integers, n) through it, with element type value; add tests. Fix cortex-js#399
|
Thanks, this is very close to what we had in mind. Because the remaining fixes are in core arithmetic (canonical folds, simplify, the .N() path), we'll take it from here and land it with those fixes, with you as co-author. Two decisions changed: arithmetic on classes of two different moduli stays unevaluated (so x + y − y = x always holds), and an integer is not an element of ℤ/nℤ (Element(7, ℤ/5ℤ) is False, consistent with Intersection and Union). We'll close this PR when the commit lands. |
|
Landed in a5e3170, with you as co-author. Thanks! Changes from the PR: classes of two moduli stay unevaluated; an integer is not an element of ℤ/nℤ; no number rule (canonical folds, simplify, Expand, Factor, the arithmetic methods) applies to an expression that holds a class; Solve, D and Integrate stay unevaluated for one. |
Fix #399
The built-in head you invited on #407, as
ResidueClass(k, n).Modstays the remainder.setResidueClassesis not here: the classes are a built-in value, so there is no host hook.kis reduced into0…n−1:ResidueClass(7, 5)isResidueClass(2, 5),ResidueClass(-1, 7)isResidueClass(6, 7).nmust be an integer literal ≥ 1 (n = 1is the zero ring, one class). A rationalkwith a unit denominator reads asu·v⁻¹(ResidueClass(1/3, 7)isResidueClass(5, 7)). A symbolic or non-positiven, a non-integern, or a symbolic or floatkstays inert, asQuotientRingdoes.kandnarebigint, so a modulus past 2^53 is exact.ResidueClass(7, 5) == ResidueClass(2, 5)isTrue, and two classes of one modulus with different residues areFalse. Classes of different moduli, or a class and an integer, are not compared (no answer). Classes are not ordered:Lessand the others stay unevaluated.+,−,×, negation and integer powers are classes, underevaluate(),.N()(a class is exact, so.N()leaves it) andsimplify():ResidueClass(5, 7) + ResidueClass(4, 7)isResidueClass(2, 7). The inverse, a division and a negative power needgcd(k, n) = 1:1/ResidueClass(3, 7)isResidueClass(5, 7), while1/ResidueClass(2, 4)andResidueClass(2, 4)^-1stay unevaluated.ResidueClass(5, 7) + 3isResidueClass(1, 7). Classes of two moduli meet in ℤ/gcd(m, n), the largest ring both reduce onto, soResidueClass(2, 4) + ResidueClass(1, 6)isResidueClass(1, 2). We took this over leaving mixed moduli unevaluated because it is the usual coercion; if you would rather it not answer, it is one line (liftinresidue-class.ts).value, and so does a sum, product, quotient or power with a class operand. The element type ofQuotientRing(Integers, n)isvalue(it wasunknown), and staysunknownfor another base.QuotientRing(Integers, n)is enumerable: it listsResidueClass(0, n)…ResidueClass(n−1, n)lazily (a modulus of 10^9 is counted without building anything), soListFrom,Union,SetMinus, … walk it.Element(ResidueClass(7, 5), ℤ/5ℤ)isTrue, and a class of another modulus isFalse.Element(7, ℤ/5ℤ)is still not decided, as onmain: 7 is a representative, not a class. Count and finiteness are unchanged.\overline{k}_{n}isResidueClass(k, n)whenkandnare integer literals andn ≥ 1; it serializes back the same way. Before, it parsed toSubscript(Conjugate(k), n). A bare\overline{7},\overline{z}_1,\overline{7}_{n},\overline{-3}_{5}and repeating decimals (0.\overline{3}) are unchanged.Epsil spells it
residueClass(k, n). The compiled lane has no lowering for a class, so it falls back (checked); nothing guesses.Tests: a new
item-399-residue-class.test.ts. TheQuotientRingtests that pinned "classes are not listed" andset<unknown>now pin the new behavior, andfinite-non-enumerable-collections.test.tskeeps its coverage onLinspace(a, 1, 3), the one remaining finite collection without computable elements (two held-setCountcases only ℤ/5ℤ reached are dropped). Your CHANGELOG entries forQuotientRingand for non-computable collections are edited so they no longer say the classes aren't listed.A bare integer still isn't a class, so
Element(7, ℤ/5ℤ)stays undecided as on main, andIntersection({1}, ℤ/5ℤ)is empty.