gcd refuses over a toField extension while working over the GF spelling of the same field, and the documentation states no restriction
- Dominant language
- Macaulay2
- Stars
- 435
- Forks
- 297
- Avg merge
- 4d 20h
- Merged PRs (30d)
- 11
Description
This issue was triaged from [`bugs/mike/0-gcd-doc.m2`](https://github.com/Macaulay2/M2/blob/388c1ff0ce30d83751dea7bc7eac77fdc1305dd7/bugs/mike/0-gcd-doc.m2), one of the 857 files removed from the pre-GitHub `bugs/` tree by [`d2c8d27826`](https://github.com/Macaulay2/M2/commit/d2c8d27826) and catalogued in [#36](https://github.com/Macaulay2/M2/issues/36). **The commentary below was written by Claude (Claude Opus 5, via Claude Code)**, not by @d-torrance, whose account posted it -- please weigh it accordingly.
The original file, verbatim (121 lines)
```m2
-- gcd problems:
-- doc is lacking
-- rawGCDRingElement is not being called from the front end.
-- and in fact seems to be problematic...
-- GF code
-- works if the ring is declared via GF
-- but we can't seem to use rawGCDRingElement to get the minpoly in?
--
--
R = ZZ[x,y,z]
F = (3*x^3-y*x+17*y^4)^3 * (x+y+1)^4
G = (3*x^3-y*x+17*y^4)^2 * (x-y+1)^4
gcd(F,G) == (3*x^3-y*x+17*y^4)^2
R = QQ[x,y,z]
F = (3*x^3-y*x+17*y^4)^3 * (x+y+1)^4
G = (3*x^3-y*x+17*y^4)^2 * (x-y+1)^4
gcd(F,G) == (3*x^3-y*x+17*y^4)^2
gcd(1/2*F,1/3*G) == (3*x^3-y*x+17*y^4)^2
K = QQ[a]/(a^6-a^3-1)
toField K
R = K[t]
F = t^6-t^3-1
G = (t-a)*(t+a)
gcd(F,G) -- via syzygies.
F//(t-a)
gcd(F//(t-a), t-a-1)
debug Core
rawGCD(raw(F//(t-a)), raw(t-a-1), raw (ideal K)_0)
K = QQ[a,b]/(a^6-a^3-1,b^2-a)
toField K
R = K[t]
F = t^6-t^3-1
G = (t-a)*(t+a)
gcd(F,G) -- works, uses syzygies
F//(t-a)
gcd(F//(t-a), t-a-1)
gcd((t-a)^3*(t-b), (t-a)*(t-b)^3) == (t-a)*(t-b)
-- Example: computing gcd's over Galois fields given via toField
--
loadPackage "ConwayPolynomials"
A = GF(9, Variable=>a)
R = A[x]
F = (a*x^3-2*a*x^2-x-1)*(x-a)
G = (a*x^3-2*a*x^2-x-1)*(x-a^2)
assert(gcd(F,G) == a^-1 * (a*x^3-2*a*x^2-x-1))
-- this one is not implemented yet: factor F
-- Now a bivariate example
R = A[x,y]
F = (a*x^3-2*a*x^2*y-x-1)^4*(x-a*y-a^2)^2
G = (a*x^3-2*a*x^2*y-x-1)*(x-a^2-y^3)^8
assert(gcd(F,G) == a^-1 * (a*x^3-2*a*x^2*y-x-1))
-- factor F -- not implemented yet
-- What about one that we construct ourselves?
A = GF(3,4, Variable=>a)
R = A[x]
F = (a*x^3-2*a*x^2-x-1)*(x-a)
G = (a*x^3-2*a*x^2-x-1)*(x-a^2)
assert(gcd(F,G) == a^-1 * (a*x^3-2*a*x^2-x-1)) -- this calls the gcd via syzygies routine
factor F -- this one is not implemented yet
value oo == F
A = toField(ZZ/3[a]/(a^4-a^3-1))
R = A[x]
F = (a*x^3-2*a*x^2-x-1)*(x-a)
G = (a*x^3-2*a*x^2-x-1)*(x-a^2)
assert(gcd(F,G) == a^-1 * (a*x^3-2*a*x^2-x-1)) -- this calls the gcd via syzygies routine
factor F -- this one works!
value oo == F
-- Now let's use this to factor a polynomial over GF(9)
A = toField(ZZ/3[a]/(a^4+a+2))
R = A[x,y]
F = (a*x^3-2*a*x^2*y-x-1)^4*(x-a*y-a^2)^2
G = (a*x^3-2*a*x^2*y-x-1)*(x-a^2-y^3)^8
assert(gcd(F,G) == a^-1 * (a*x^3-2*a*x^2*y-x-1)) -- not implemented yet
factor F -- NOT CORRECT!!
A = GF(3,20, Variable => a)
R = A[x]
F = (a*x^3-2*a*x^2-x-1)*(x-a)
G = (a*x^3-2*a*x^2-x-1)*(x-a^2)
gcd(F,G) -- gives ERROR
factor F -- gives ERROR
-- let's try to use UPolynomials to get this to work.
loadPackage "ConwayPolynomials"
path = prepend("~/src/M2/Macaulay2/packages/development/", path)
loadPackage "UPolynomials"
A = GF(3,20, Variable => a)
A1 = ambient A; toField A1; setUFD A1;
R = A1[x]; setUFD R
F = (a*x^3-2*a*x^2-x-1)*(x-a)
G = (a*x^3-2*a*x^2-x-1)*(x-a^2)
gcd(F,G) -- uses syzygies
time myGCD(F,G) -- this works
assert(myGCD(F,G) == a^-1 * (a*x^3-2*a*x^2-x-1)) -- this calls the gcd via syzygies routine
-- now let's factor a polynomial over A
factor F -- this works for some reason!
value oo == F
gcd(F,G) == myGCD(F,G) -- this works
-- let's try factoring F using the resultants, computing gcds over ZZ/3:
F
C1 = ZZ/3[x]; setUFD C1;
R1 = C1[a]; setUFD R1
F1 = sub(F,R1)
G1 = sub((ideal A1)_0, R1)
F1 = sub(F1, x => x-a-a^3-a^5-a^9) % G1
use C1; use R1
time myResultant(F1,G1)
factor oo
time apply(oo//toList/toList/first, H -> if first degree H > 0 then myGCD(sub(sub(H, x=>x+a+a^3+a^5+a^9),ring F), F) else null)
Fa = product select(oo, f -> f =!= null)
use coefficientRing ring F
F == a * Fa -- true. This is currently a very slow way to factor here!!
-- since myGCD works, we can use Cantor-Zassenhaus to factor polynomials over A in one variable.
```
### Where it stands today
`gcd` refuses to work over a field extension built with `toField`, while working over the `GF`
spelling of the same field. Both rings below are fields of order 81:
```m2
i1 : A = GF(3,4, Variable => a);
i2 : R = A[x];
i3 : F = (a*x^3-2*a*x^2-x-1)*(x-a);
i4 : G = (a*x^3-2*a*x^2-x-1)*(x-a^2);
i5 : gcd(F,G)
3 2 3 2 3 2
o5 = x + x + (- a + a )x - a + a
o5 : R
i6 : B = toField(ZZ/3[b]/(b^4-b^3-1));
i7 : S = B[y];
i8 : FF = (b*y^3-2*b*y^2-y-1)*(y-b);
i9 : GG = (b*y^3-2*b*y^2-y-1)*(y-b^2);
i10 : gcd(FF,GG)
stdio:10:3:(3):[1]: error: expected coefficient ring of the form ZZ/n, ZZ, QQ, or GF
```
`b^4-b^3-1` is irreducible over `ZZ/3` — `factor` returns it whole — so `toField` was told the truth
and `B` is a field. The same refusal occurs with a characteristic-zero base, e.g.
`toField(QQ[a]/(a^6-a^3-1))`.
### The documentation promises otherwise
The `gcd` node takes `ZZ`, `QQ` or any `RingElement`, and says nothing about the coefficient ring:
https://github.com/Macaulay2/M2/blob/development/M2/Macaulay2/packages/Macaulay2Doc/operators.m2#L208-L236
Its examples are over `ZZ` and `QQ[x,y,z]`. There is no `Caveat`, so a reader has no way to learn that
the coefficient ring must be one of `ZZ/n`, `ZZ`, `QQ` or `GF` — which is the file's own complaint,
*"doc is lacking"*, still true after fifteen years.
### Three spellings, three behaviours
Worth seeing together, because the middle row is a separate open issue and the difference between the
rows is the point:
| ring | `gcd` |
| --- | --- |
| `GF(3,4)[x]` | correct |
| `(QQ[a]/(a^6-a^3-1))[t]`, no `toField` | returns `1` — a common divisor that is not greatest ([#4583](https://github.com/Macaulay2/M2/issues/4583)) |
| `toField(...)[x]`, any base | errors as above |
So the undeclared quotient answers wrongly and the declared field refuses; only `GF` works. A fix for
[#4583](https://github.com/Macaulay2/M2/issues/4583) would not necessarily address this one, since
that issue is about `gcd` proceeding when it should not.
### It may be a lost capability rather than a missing one
The bug file asserts these cases *succeed*, twice annotating them *"this calls the gcd via syzygies
routine"*:
```m2
A = toField(ZZ/3[a]/(a^4-a^3-1))
R = A[x]
F = (a*x^3-2*a*x^2-x-1)*(x-a)
G = (a*x^3-2*a*x^2-x-1)*(x-a^2)
assert(gcd(F,G) == a^-1 * (a*x^3-2*a*x^2-x-1)) -- this calls the gcd via syzygies routine
```
If a syzygy fallback once handled this, restoring it may be cheaper than extending the dispatch.
### Where this came from
Cataloguing the `bugs/` directory removed in d2c8d27826 (#36). `bugs/mike/0-gcd-doc.m2` is a 120-line
file whose header lists three complaints — *"doc is lacking"*, *"rawGCDRingElement is not being called
from the front end"*, and that the GF code *"works if the ring is declared via GF"*. The second is
[#4583](https://github.com/Macaulay2/M2/issues/4583); the first and third are this issue. One of its
other claims has since been fixed: over `GF(3,20)` it records both `gcd` and `factor` as *"gives
ERROR"*, and both work now.
`open` · disposition `issue` · source of truth: [`bug-triage/catalog.tsv`](https://github.com/d-torrance/M2/blob/bug-triage/bug-triage/catalog.tsv)
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reproducing the toField and GF examples in the issue, then read the gcd documentation in Macaulay2/packages/Macaulay2Doc/operators.m2 and the original bugs/mike/0-gcd-doc.m2 report. Trace the gcd entry point to determine why the toField case is rejected and whether the syzygy path applies. Done means gcd works for the demonstrated field extensions and the documentation states any remaining restrictions.
Written by the indexing model from the issue text.
Assessment
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100