oscar-system / Oscar.jl

A comprehensive open source computer algebra system for computations in algebra, geometry, and number theory.
https://www.oscar-system.org
Other
344 stars 126 forks source link

`gens` should work for all rings, including univariate ones #912

Closed fingolfin closed 1 month ago

fingolfin commented 2 years ago

I am seeing this:

julia> Kx, x = QQ["x"]
(Univariate Polynomial Ring in x over Rational Field, x)

julia> gens(Kx)
1-element Vector{fmpq_poly}:
 x

That's good! But it fails for many other rings. E.g.:

julia> Kt, t = RationalFunctionField(QQ,"t")
(Rational function field over Rational Field, t)

julia> gen(Kt)
t

julia> gens(Kt)
ERROR: MethodError: no method matching gens(::AbstractAlgebra.Generic.RationalFunctionField{fmpq})
...

Or:

julia> F = FiniteField(2, 1)[1]
Finite field of degree 1 over F_2

julia> gen(F)
1

julia> gens(F)
ERROR: MethodError: no method matching gens(::FqNmodFiniteField)
fingolfin commented 2 years ago

Actually, there are even rings where not even gen works:

julia> F = FiniteField(2)
Galois field with characteristic 2

julia> gen(F)
ERROR: MethodError: no method matching gen(::Nemo.GaloisField)
...

julia> gens(F)
ERROR: MethodError: no method matching gens(::Nemo.GaloisField)
thofma commented 2 years ago

I agree that the finite fields should be consistent, but why would one expect it to work for every ring? It has very specific meaning in the examples above. Maybe there are rings for which there is no useful concept of "generators".

fingolfin commented 2 years ago

Of course if a ring has no "generators" because it is not finitely generated, or because no generators are known, then it's fine to get an error (although I really think the error then should be specific, e.g. "ERROR: this ring is not finitely generated" or "ERROR: no generators known / can be computed".

But if gen(R) is supported, then IMHO also gens(R) should be supported (and also for that matter, gen(R,1) and ngens(R)).

As to that they have "a very specific meaning in the examples above", that's part of the problem to me, too. It seems difficult to write correct generic code in Oscar right now, because I cannot see a clear pattern; alas, this may be entirely my failure to find and read the correct docs, though -- hints welcome!

Naively, I'd think that e.g. the meaning of "generator(s)" depend on the category in which you are. For rings and modules, I'd expect "generators" to be "generators as S-module for some ring S" which for a finite field could be the prime field or (for a relative extension) the "base field" being extended. In Oscar/AA, we only have base_ring which sometimes fills this role, but in general does not (it is non-mathematical concept, and as far as I can tell purely depends on implementation details, which also seems to make it hard to use correctly in generic code ... Hence the "recent" to also have coefficient_ring. In GAP, there is LeftActingDomain to fill that mathematical niche: it returns precisely the ring S from above which gives meaning to gens.

wdecker commented 2 years ago
julia> Kx, x = QQ["x"]
(Univariate Polynomial Ring in x over Rational Field, x)

julia> gens(Kx)
1-element Vector{fmpq_poly}:
 x

I have no idea what this should mean: x is a generator of Kx? In what sense? It generates the maximal homogeneous ideal of x. The generator of Kx as a ring is one(Kx). So any ring as a generator. What do you menan by "no generators are known"?

thofma commented 2 years ago

What is the LeftActingDomain when the elements are generators in the category of rings?

thofma commented 2 years ago

Also 2x would be a generator as a Q-module in the example of @wdecker, but we promise it to be the x in K[x]. Maybe the argument is that gen is the wrong name for polynomial rings?

fingolfin commented 2 years ago

Indeed the problem may run deeper than I realized... sigh. "The generators" reads fine until one has not implemented the ring in question and really wants to know what it means (and discovers that different rings implemented by different people use different interpretations)...

I don't have a good answer right now. But just as some more background: In GAP, we distinguish between GeneratorsOfAlgebra and GeneratorsOfAlgebraWithOne; then for R = S[x], we have the following generating sets:

wdecker commented 2 years ago

Yes, precisely, the question is generator in what sense! Sorry, Max, I thought you where talking about generors of rings.

fieker commented 2 years ago

On Mon, Dec 20, 2021 at 04:48:12AM -0800, Wolfram Decker wrote:

Yes, precisely, the question is generator in what sense! Sorry, Max, I thought you where talking about generors of rings.

OK, currently, in Oscar - and I think it should stay this way, possibly documented somewhere in capitals:

  • groups: gens gives the generators as groups
  • rings: gens are (natural) algebra generators over the base ring
  • ideals: gens are generators as ideals

Is this mathematically well defined: no Is this different from Gap: yes (it is also slightly different from Magma) Is this perfect: no Are there gaps: yes!

I agree: if gen works, then gens should work as well.

All the current 'gen(s)' are natural wrt. the presentation of the objects. I agree, 2x would also generate Q[x], but why? In the same way, for an ideal I could arbitraryly add generators - or try to restrict to minimal sets. In reality, gens returned what is obviously there, in the canonical context inferred from the type.

Most missing cases are because we (mainly Tommy, Carlo and I) haven't missed them, not due to a decision. Most existing caes are there since Bill (in most places) decided to provide them.

Generically, I agree with Max that some error messages could be more helpful - although writing a function just because we cannot compute s.th. feels weired:

gens(::Ring) = error("no can do")

Do we want/ can do this for all functions where we cannot cover everything? Yes, it would illustrate our deliberate decision, however, it still is weird.

I cannot see really generic code where using gens will be meaningful and helpful across many categories (not in the hom-alg sense). There are too many differences outside gens. I can see that homomorphisms can be defined via gens, however, I cannot see a generic implementation....

But I am happy to collect examples.

-- Reply to this email directly or view it on GitHub: https://github.com/oscar-system/Oscar.jl/issues/912#issuecomment-997894706 You are receiving this because you are subscribed to this thread.

Message ID: @.***>

wdecker commented 2 years ago

Do we want/ can do this for all functions where we cannot cover everything? Yes, it would illustrate our deliberate decision, however, it still is weird.

There all kinds of user unfriendly error messages in all kinds of contexts. May be we should create a todo list somewhere.

julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"]) (Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])

julia> f = x+y^2 x + y^2

julia> exponent_vector(f, 2) 3-element Vector{Int64}: 0 2 0

julia> exponent_vector(f, 3) Flint exception (General error): Index out of range in fmpq_mpoly_get_term_exp_siERROR: Problem in the Flint-Subsystem Stacktrace: [1] error(s::String) @ Base ./error.jl:33 [2] flint_abort() @ Nemo ~/.julia/packages/Nemo/5CDLD/src/Nemo.jl:96 [3] exponent_vector! @ ~/.julia/packages/Nemo/5CDLD/src/flint/fmpq_mpoly.jl:880 [inlined] [4] exponent_vector(#unused#::Type{Int64}, a::fmpq_mpoly, i::Int64) @ Nemo ~/.julia/packages/Nemo/5CDLD/src/flint/mpoly.jl:23 [5] exponent_vector(a::fmpq_mpoly, i::Int64) @ Nemo ~/.julia/packages/Nemo/5CDLD/src/flint/mpoly.jl:37 [6] top-level scope @ REPL[75]:1

Here, we have a problem of TMI: Something like ERROR: Index out of range would be enough.