diff --git a/Project.toml b/Project.toml index 9d8f52a32d6a..95415d537948 100644 --- a/Project.toml +++ b/Project.toml @@ -31,7 +31,7 @@ AlgebraicSolving = "0.3.6" Distributed = "1.6" DocStringExtensions = "0.8, 0.9" GAP = "0.10.0" -Hecke = "0.22.5" +Hecke = "0.22.6" JSON = "^0.20, ^0.21" LazyArtifacts = "1.6" Nemo = "0.37.1" diff --git a/docs/src/Groups/basics.md b/docs/src/Groups/basics.md index 373495328eaf..d604a60e8b52 100644 --- a/docs/src/Groups/basics.md +++ b/docs/src/Groups/basics.md @@ -89,10 +89,13 @@ is_finitelygenerated ```@docs order(::Type{T}, x::Union{GAPGroupElem, GAPGroup}) where T <: IntegerUnion +abelian_invariants(G::GAPGroup) +abelian_invariants_schur_multiplier(G::GAPGroup) cyclic_generator(G::GAPGroup) exponent(G::GAPGroup) describe(G::GAPGroup) nilpotency_class(G::GAPGroup) prime_of_pgroup derived_length +schur_multiplier(G::Union{GAPGroup, GrpAbFinGen}) ``` diff --git a/docs/src/NumberTheory/galois.md b/docs/src/NumberTheory/galois.md index 51ff8798960b..eb0cb91b6a91 100644 --- a/docs/src/NumberTheory/galois.md +++ b/docs/src/NumberTheory/galois.md @@ -145,8 +145,8 @@ julia> r = roots(C, 5) 4-element Vector{qadic}: 5*11^0 + 2*11^1 + 6*11^2 + 8*11^3 + 11^4 + O(11^5) 6*11^0 + 8*11^1 + 4*11^2 + 2*11^3 + 9*11^4 + O(11^5) - (11^0 + 6*11^1 + 6*11^2 + 2*11^4 + O(11^5))*a + 9*11^0 + 4*11^1 + 6*11^2 + 7*11^3 + 11^4 + O(11^5) (10*11^0 + 4*11^1 + 4*11^2 + 10*11^3 + 8*11^4 + O(11^5))*a + 2*11^0 + 6*11^1 + 4*11^2 + 3*11^3 + 9*11^4 + O(11^5) + (11^0 + 6*11^1 + 6*11^2 + 2*11^4 + O(11^5))*a + 9*11^0 + 4*11^1 + 6*11^2 + 7*11^3 + 11^4 + O(11^5) julia> r[1]^2 3*11^0 + O(11^5) diff --git a/experimental/GModule/GaloisCohomology.jl b/experimental/GModule/GaloisCohomology.jl index 015b07ad15e1..564e675ba751 100644 --- a/experimental/GModule/GaloisCohomology.jl +++ b/experimental/GModule/GaloisCohomology.jl @@ -426,7 +426,7 @@ function Oscar.gmodule(K::Hecke.LocalField, k::Union{Hecke.LocalField, FlintPadi mQ = mQ*inv(mS) if Sylow > 0 - @assert isprime(Sylow) + @assert is_prime(Sylow) G, mS = sylow_subgroup(G, Sylow) mG = mS*mG end diff --git a/experimental/GaloisGrp/test/runtests.jl b/experimental/GaloisGrp/test/runtests.jl index cbefdf6c4c76..98f336539171 100644 --- a/experimental/GaloisGrp/test/runtests.jl +++ b/experimental/GaloisGrp/test/runtests.jl @@ -3,5 +3,12 @@ K, r = solve(x^3+3*x+5) @test absolute_degree(K) == 12 @test length(r) == 3 + + Qt, t = rational_function_field(QQ, "t") + Qtx, x = Qt["x"] + F, a = function_field(x^6 + 108*t^2 + 108*t + 27) + subfields(F) + G, = galois_group(F) + @test is_isomorphic(G, symmetric_group(3)) end diff --git a/experimental/OrthogonalDiscriminants/test/data.jl b/experimental/OrthogonalDiscriminants/test/data.jl index 069190f827de..7dfcee38df50 100644 --- a/experimental/OrthogonalDiscriminants/test/data.jl +++ b/experimental/OrthogonalDiscriminants/test/data.jl @@ -26,7 +26,7 @@ @test length(all_od_infos(orthogonal_discriminant => "O+")) + length(all_od_infos(orthogonal_discriminant => "O-")) == length(Oplusminus) - @test length(Oplusminus) <= length(all_od_infos(characteristic => ispositive)) + @test length(Oplusminus) <= length(all_od_infos(characteristic => is_positive)) deg_1 = all_od_infos(degree => 1); deg_other = all_od_infos(degree => (x -> x > 1)); @test length(all_entries) == length(deg_1) + length(deg_other) diff --git a/experimental/QuadFormAndIsom/src/embeddings.jl b/experimental/QuadFormAndIsom/src/embeddings.jl index 048b3f141caa..50fc9ed62d60 100644 --- a/experimental/QuadFormAndIsom/src/embeddings.jl +++ b/experimental/QuadFormAndIsom/src/embeddings.jl @@ -1487,7 +1487,7 @@ function _find_admissible_gluing(SAinqA::TorQuadModuleMor, phiHA, _ = sub(SB, elem_type(SB)[phi(SA(lift(a))) for a in gens(HA)]) OSB = orthogonal_group(SB) G = GSetByElements(OSB, _on_subgroups, TorQuadModule[HB]) - ok, g = representative_action(G, phiHA, HB) + ok, g = is_conjugate_with_data(G, phiHA, HB) @hassert :ZZLatWithIsom 1 ok phi_1 = compose(phi, hom(g)) @hassert :ZZLatWithIsom 1 sub(SB, elem_type(SB)[phi_1(SA(lift(a))) for a in gens(HA)])[1] == HB diff --git a/experimental/Schemes/AlgebraicCycles.jl b/experimental/Schemes/AlgebraicCycles.jl index 46fb6273d7a0..2cceeb50f4c1 100644 --- a/experimental/Schemes/AlgebraicCycles.jl +++ b/experimental/Schemes/AlgebraicCycles.jl @@ -491,8 +491,8 @@ function ==(D::AbsAlgebraicCycle, E::AbsAlgebraicCycle) end else # Make sure all generators are actually prime so that they can be compared. - all(I->isprime(I), keys(coefficient_dict(D))) || return irreducible_decomposition(D) == E - all(I->isprime(I), keys(coefficient_dict(E))) || return D == irreducible_decomposition(E) + all(is_prime, keys(coefficient_dict(D))) || return irreducible_decomposition(D) == E + all(is_prime, keys(coefficient_dict(E))) || return D == irreducible_decomposition(E) keys_D = collect(keys(coefficient_dict(D))) keys_E = collect(keys(coefficient_dict(E))) diff --git a/experimental/Schemes/BlowupMorphism.jl b/experimental/Schemes/BlowupMorphism.jl index 0be7f68a5fb9..fabe7620f2d7 100644 --- a/experimental/Schemes/BlowupMorphism.jl +++ b/experimental/Schemes/BlowupMorphism.jl @@ -543,7 +543,7 @@ function strict_transform(p::AbsSimpleBlowdownMorphism, C::EffectiveCartierDivis # sanity check -- we are on a trivializing covering after all! h_orig = C(V)[1] h_total = pullback(pr_refined[U]).(h_orig) - if isunit(h_total) + if is_unit(h_total) ID[U] = one(OO(U)) continue end @@ -552,7 +552,7 @@ function strict_transform(p::AbsSimpleBlowdownMorphism, C::EffectiveCartierDivis length(E(U)) == 1 || error("exceptional divisor is not principal") # sanity check -- default covering of Y is already trivializing for E! e = E(U)[1] - if isunit(e) + if is_unit(e) ID[U] = h_total continue end diff --git a/experimental/Schemes/CartierDivisor.jl b/experimental/Schemes/CartierDivisor.jl index 5875a73879c9..ffdb9d81dc77 100644 --- a/experimental/Schemes/CartierDivisor.jl +++ b/experimental/Schemes/CartierDivisor.jl @@ -331,7 +331,7 @@ function intersect(W::WeilDivisor, C::EffectiveCartierDivisor; check::Bool=true) X = scheme(W) result = zero(W) for I in components(W) - @check isprime(I) "all components of the first argument must be sheaves of prime ideals" + @check is_prime(I) "all components of the first argument must be sheaves of prime ideals" inc_Y = CoveredClosedEmbedding(X, I, check=false) #inc_Y = CoveredClosedEmbedding(X, I, covering=trivializing_covering(C), check=false) Y = domain(inc_Y) diff --git a/experimental/Schemes/CoveredProjectiveSchemes.jl b/experimental/Schemes/CoveredProjectiveSchemes.jl index 4f147e974d17..9d04dfec74d7 100644 --- a/experimental/Schemes/CoveredProjectiveSchemes.jl +++ b/experimental/Schemes/CoveredProjectiveSchemes.jl @@ -519,7 +519,7 @@ function is_regular_sequence(g::Vector{T}) where {T<:RingElem} length(g) == 0 && return true R = parent(g[1]) all(x->parent(x)===R, g) || error("elements do not belong to the correct ring") - isunit(g[1]) && return false # See Bruns-Herzog: Cohen-Macaulay rings, section 1.1. + is_unit(g[1]) && return false # See Bruns-Herzog: Cohen-Macaulay rings, section 1.1. is_zero_divisor(g[1]) && return false A, p = quo(R, ideal(R, g)) return is_regular_sequence(p.(g[2:end])) @@ -1469,7 +1469,7 @@ end # X = hypersurface_complement(subscheme(C, div_list[i]), prod(loc_list[i])) # D = A[row_list[i], column_list[i]] # g = det(D) -# isunit(OO(X)(g)) || error("selected minor is not a unit") +# is_unit(OO(X)(g)) || error("selected minor is not a unit") # end # end # else @@ -1678,7 +1678,7 @@ end # A = Df[rl[i], cl[i]] # g = det(A) # U = hypersurface_complement(subscheme(C, ql[i]), h) -# @show isunit(OO(U)(g)) +# @show is_unit(OO(U)(g)) # end # # diff --git a/experimental/Schemes/FunctionFields.jl b/experimental/Schemes/FunctionFields.jl index 6d27737f0cff..77978c8966a3 100644 --- a/experimental/Schemes/FunctionFields.jl +++ b/experimental/Schemes/FunctionFields.jl @@ -167,7 +167,7 @@ end # try to avoid a groebner basis computation iszero(a::VarietyFunctionFieldElem) = iszero(representative(a)) || iszero(OO(representative_patch(parent(a)))(numerator(a))) isone(a::VarietyFunctionFieldElem) = isone(representative(a)) || iszero(OO(representative_patch(parent(a)))(numerator(a) - denominator(a))) -isunit(a::VarietyFunctionFieldElem) = !iszero(representative(a)) +is_unit(a::VarietyFunctionFieldElem) = !iszero(representative(a)) ######################################################################## # Conversion of rational functions on arbitrary patches # diff --git a/experimental/Schemes/MorphismFromRationalFunctions.jl b/experimental/Schemes/MorphismFromRationalFunctions.jl index 3423f3584aa2..cc228861d6b3 100644 --- a/experimental/Schemes/MorphismFromRationalFunctions.jl +++ b/experimental/Schemes/MorphismFromRationalFunctions.jl @@ -601,7 +601,7 @@ end function pushforward(Phi::MorphismFromRationalFunctions, D::AbsAlgebraicCycle) is_isomorphism(Phi) || error("method not implemented unless for the case of an isomorphism") #is_proper(Phi) || error("morphism must be proper") - all(x->isprime(x), components(D)) || error("divisor must be given in terms of irreducible components") + all(is_prime, components(D)) || error("divisor must be given in terms of irreducible components") X = domain(Phi) Y = codomain(Phi) pushed_comps = IdDict{IdealSheaf, elem_type(coefficient_ring(D))}() diff --git a/experimental/Schemes/ToricIdealSheaves/constructors.jl b/experimental/Schemes/ToricIdealSheaves/constructors.jl index 78d8d2302640..b27ab6166bef 100644 --- a/experimental/Schemes/ToricIdealSheaves/constructors.jl +++ b/experimental/Schemes/ToricIdealSheaves/constructors.jl @@ -44,7 +44,7 @@ function IdealSheaf(X::NormalToricVariety, I::MPolyIdeal) # 1. All maximal cones are smooth, i.e. the fan is smooth/X is smooth. # 2. The dimension of all maximal cones matches the dimension of the fan. @req is_smooth(X) "Currently, ideal sheaves are only supported for smooth toric varieties" - @req ispure(X) "Currently, ideal sheaves require that all maximal cones have the dimension of the variety" + @req is_pure(X) "Currently, ideal sheaves require that all maximal cones have the dimension of the variety" ideal_dict = IdDict{AbsSpec, Ideal}() diff --git a/experimental/Schemes/WeilDivisor.jl b/experimental/Schemes/WeilDivisor.jl index c46062d18519..5d10dd3b6525 100644 --- a/experimental/Schemes/WeilDivisor.jl +++ b/experimental/Schemes/WeilDivisor.jl @@ -429,7 +429,7 @@ function in_linear_system(f::VarietyFunctionFieldElem, D::WeilDivisor; regular_o X === variety(parent(f)) || error("schemes not compatible") C = simplified_covering(X) for I in components(D) - @check isprime(I) "components of the divisor must be prime" + @check is_prime(I) "components of the divisor must be prime" order_on_divisor(f, I, check=false) >= -D[I] || return false end regular_on_complement && return true @@ -461,7 +461,7 @@ generated by rational functions ``f₁,…,fᵣ ∈ K(X)``. X === variety(KK) || error("input not compatible") @check begin - all(I->isprime(I), components(D)) || error("components of the divisor must be prime") + all(is_prime, components(D)) || error("components of the divisor must be prime") all(g->in_linear_system(g, D), f) || error("element not in linear system") end f = Vector{VarietyFunctionFieldElem}(f) diff --git a/experimental/StandardFiniteFields/src/StandardFiniteFields.jl b/experimental/StandardFiniteFields/src/StandardFiniteFields.jl index b37ff137df63..481b2c405c2d 100644 --- a/experimental/StandardFiniteFields/src/StandardFiniteFields.jl +++ b/experimental/StandardFiniteFields/src/StandardFiniteFields.jl @@ -460,7 +460,7 @@ Finite field of degree 24 over GF(3) ``` """ function standard_finite_field(p::IntegerUnion, n::IntegerUnion) - @req isprime(p) "first argument must be a prime" + @req is_prime(p) "first argument must be a prime" F = GF(p) set_standard_prime_field!(F) diff --git a/experimental/SymmetricIntersections/src/representations.jl b/experimental/SymmetricIntersections/src/representations.jl index 7e586aa7d8ba..c53f2b291bda 100644 --- a/experimental/SymmetricIntersections/src/representations.jl +++ b/experimental/SymmetricIntersections/src/representations.jl @@ -1060,7 +1060,7 @@ function _has_pfr(G::Oscar.GAPGroup, dim::Int) f_gap = GG.EpimorphismSchurCover(G_gap) H_gap = GG.Source(f_gap) n, p = ispower(GG.Size(H_gap)) - if isprime(p) + if is_prime(p) fff_gap = GG.EpimorphismPGroup(H_gap, p) E_gap = fff_gap(H_gap) else diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Properties.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Properties.jl index ffc8f6200d10..eb467bb9cc8a 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Properties.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Properties.jl @@ -153,7 +153,7 @@ function issubset( ) where {BRT} R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false - all(x->isunit(OO(X)(x)), denominators(inverted_set(OO(Y)))) || return false + all(x->is_unit(OO(X)(x)), denominators(inverted_set(OO(Y)))) || return false return iszero(localized_ring(OO(Y))(modulus(OO(X)))) end @@ -164,7 +164,7 @@ function issubset( ) where {BRT} R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false - all(x->isunit(OO(X)(x)), denominators(inverted_set(OO(Y)))) || return false + all(x->is_unit(OO(X)(x)), denominators(inverted_set(OO(Y)))) || return false return issubset(modulus(OO(Y)), localized_ring(OO(Y))(modulus(OO(X)))) end @@ -464,7 +464,7 @@ function is_closed_embedding( R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false for f in inverted_set(OO(X)) - isunit(OO(Y)(f)) || return false + is_unit(OO(Y)(f)) || return false end return true end @@ -479,7 +479,7 @@ function is_closed_embedding( R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false for x in inverted_set(OO(X)) - isunit(OO(Y)(x)) || return false + is_unit(OO(Y)(x)) || return false end for g in gens(modulus(OO(Y))) iszero(OO(X)(g)) || return false @@ -517,7 +517,7 @@ function is_closed_embedding( <:MPolyPowersOfElement}} R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false - all(x->(isunit(OO(X)(x))), denominators(inverted_set(OO(Y)))) || return false + all(x->(is_unit(OO(X)(x))), denominators(inverted_set(OO(Y)))) || return false return issubset(modulus(OO(Y)), localized_ring(OO(Y))(modulus(OO(X)))) end diff --git a/src/AlgebraicGeometry/Schemes/CoveredSchemes/Morphisms/Attributes.jl b/src/AlgebraicGeometry/Schemes/CoveredSchemes/Morphisms/Attributes.jl index 214d641c2350..c3709b9f6d0c 100644 --- a/src/AlgebraicGeometry/Schemes/CoveredSchemes/Morphisms/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/CoveredSchemes/Morphisms/Attributes.jl @@ -56,8 +56,8 @@ given by the pullback function (y//z) -> 0 ``` """ -function covering_morphism(f::AbsCoveredSchemeMorphism)::CoveringMorphism - return covering_morphism(underlying_morphism(f)) +function covering_morphism(f::AbsCoveredSchemeMorphism) + return covering_morphism(underlying_morphism(f))::CoveringMorphism end ### generically derived getters diff --git a/src/AlgebraicGeometry/Surfaces/K3Auto.jl b/src/AlgebraicGeometry/Surfaces/K3Auto.jl index c1a00dde74fa..068b8d26b1cf 100644 --- a/src/AlgebraicGeometry/Surfaces/K3Auto.jl +++ b/src/AlgebraicGeometry/Surfaces/K3Auto.jl @@ -1201,7 +1201,7 @@ function is_S_nondegenerate(L::ZZLat, S::ZZLat, w::QQMatrix) D = reduce(vcat, prSDelta_w, init=i) P = positive_hull(D) # the dual cone of C # If P has a linear subspace, then its dual C is not of full dimension. - return ispointed(P) + return is_pointed(P) end function inner_point(L::ZZLat, S::ZZLat, w::QQMatrix) diff --git a/src/AlgebraicGeometry/ToricVarieties/CohomologyClasses/methods.jl b/src/AlgebraicGeometry/ToricVarieties/CohomologyClasses/methods.jl index 040d5de8753b..9157ac8310d9 100644 --- a/src/AlgebraicGeometry/ToricVarieties/CohomologyClasses/methods.jl +++ b/src/AlgebraicGeometry/ToricVarieties/CohomologyClasses/methods.jl @@ -88,7 +88,7 @@ julia> integrate(cohomology_class(anticanonical_divisor_class(X))^3) 62 ``` """ -function integrate(c::CohomologyClass)::QQFieldElem +function integrate(c::CohomologyClass) # can only integrate if the variety is simplicial, complete @req is_simplicial(toric_variety(c)) && is_complete(toric_variety(c)) "Integration only supported over complete and simplicial toric varieties" @@ -97,30 +97,30 @@ function integrate(c::CohomologyClass)::QQFieldElem intersection_dict = _intersection_form_via_exponents(toric_variety(c)) coeffs = coefficients(c) expos = exponents(c) - integral = 0 + integral = zero(QQ) for i in 1:nrows(expos) if expos[i, :] in keys(intersection_dict) integral += coeffs[i] * intersection_dict[expos[i, :]] end end - return integral + return integral::QQFieldElem end # otherwise, proceed "by hand" if is_trivial(c) - return 0 + return zero(QQ) end poly = polynomial(c) dict = homogeneous_components(poly) elem = base_ring(parent(poly)).D([dim(toric_variety(c))]) if !(elem in keys(dict)) - return 0 + return zero(QQ) end top_form = dict[elem] if iszero(top_form) - return 0 + return zero(QQ) end n = AbstractAlgebra.leading_coefficient(top_form.f) m = AbstractAlgebra.leading_coefficient(polynomial(volume_form(toric_variety(c))).f) - return QQFieldElem(n//m) + return n//m end diff --git a/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/attributes.jl b/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/attributes.jl index 133280f7c8a8..b21a6e40c32e 100644 --- a/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/attributes.jl +++ b/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/attributes.jl @@ -1091,7 +1091,7 @@ julia> hilbert_basis(antv) """ @attr ZZMatrix function hilbert_basis(v::AffineNormalToricVariety) @req is_pointed(weight_cone(v)) "Weight cone is not pointed" - @req isfulldimensional(weight_cone(v)) "Weight cone is not full dimensional" + @req is_fulldimensional(weight_cone(v)) "Weight cone is not full dimensional" return matrix(ZZ, hilbert_basis(weight_cone(v))) end diff --git a/src/Groups/GrpAb.jl b/src/Groups/GrpAb.jl index 3f6e29b85f8d..c5533ec60753 100644 --- a/src/Groups/GrpAb.jl +++ b/src/Groups/GrpAb.jl @@ -372,6 +372,94 @@ end is_pgroup_with_prime(G::GrpAbFinGen) = is_pgroup_with_prime(ZZRingElem, G) +# Let `v` be a vector of integers. +# This function returns the unique sorted vector `w` of zeros and prime powers +# such that `v` and `w` describe the same abelian group in the sense that +# the direct product of the groups `ZZ /(v[i]*ZZ)` is isomorphic to +# the direct product of the groups `ZZ /(w[i]*ZZ)`. +function abelian_invariants_of_vector(::Type{T}, v::Vector) where T <: IntegerUnion + invs = T[] + for elm in v + if elm == 0 + push!(invs, 0) + elseif 1 < elm + append!(invs, [x[1]^x[2] for x in factor(elm)]) + elseif elm < -1 + append!(invs, [x[1]^x[2] for x in factor(-elm)]) + end + end + return sort!(invs) +end + +# Let `v` be a vector of integers. +# This function returns the unique vector `w` of nonnegative integers +# such that `w[1] != 1`, `w[i]` divides `w[i+1]` for `1 < i < length(w)-1` +# and such that `v` and `w` describe the same abelian group in the sense that +# the direct product of the groups `ZZ /(v[i]*ZZ)` is isomorphic to +# the direct product of the groups `ZZ /(w[i]*ZZ)`. +function elementary_divisors_of_vector(::Type{T}, v::Vector) where T <: IntegerUnion + invs = T[] + d = Dict{T, Vector{T}}() + for elm in v + if elm == 0 + push!(invs, 0) + else + if elm < -1 + elm = -elm + end + for (p, e) in factor(elm) + if haskey(d, p) + push!(d[p], p^e) + else + d[p] = T[p^e] + end + end + end + end + l = 0 + ps = keys(d) + for p in ps + l = max(l, length(d[p])) + end + o = T(1) + for p in ps + dp = d[p] + for i in 1:(l-length(dp)) + push!(dp, o) + end + sort!(dp) + end + for i in l:-1:1 + e = o + for p in ps + e = e * d[p][i] + end + push!(invs, e) + end + return reverse(invs) +end + +abelian_invariants(::Type{T}, G::GrpAbFinGen) where T <: IntegerUnion = + abelian_invariants_of_vector(T, elementary_divisors(G)) + +abelian_invariants(G::GrpAbFinGen) = abelian_invariants(ZZRingElem, G) + +function abelian_invariants_schur_multiplier(::Type{T}, G::GrpAbFinGen) where T <: IntegerUnion + # By a theorem of I. Schur, + # the multiplier of an abelian group with elementary divisors + # n_1 | n_2 | ... | n_k, with k > 1, + # has the elementary divisors n_i with multiplicity k-i, for 1 <= i < k. + invs = elementary_divisors(G) + res = T[] + k = length(invs) + for i in 1:(k-1) + append!(res, repeat(T[invs[i]], k-i)) + end + return abelian_invariants_of_vector(T, res) +end + +abelian_invariants_schur_multiplier(G::GrpAbFinGen) = abelian_invariants_schur_multiplier(ZZRingElem, G) + nilpotency_class(G::GrpAbFinGen) = (order(G) == 1 ? 0 : 1) # helper for prime_of_pgroup: this helper is efficient thanks to diff --git a/src/Groups/homomorphisms.jl b/src/Groups/homomorphisms.jl index 9b6d64fdbb83..a7b54a46afd0 100644 --- a/src/Groups/homomorphisms.jl +++ b/src/Groups/homomorphisms.jl @@ -420,14 +420,14 @@ function is_isomorphic(G::GAPGroup, H::GAPGroup) return mp !== GAP.Globals.fail end -function isisomorphic(G::GAPGroup, H::GrpGen) +function is_isomorphic(G::GAPGroup, H::GrpGen) P = PermGroup(H) - return isisomorphic(G, P) + return is_isomorphic(G, P) end -function isisomorphic(G::GrpGen, H::GAPGroup) +function is_isomorphic(G::GrpGen, H::GAPGroup) P = PermGroup(G) - return isisomorphic(P, H) + return is_isomorphic(P, H) end """ diff --git a/src/Groups/sub.jl b/src/Groups/sub.jl index ed1f05df922a..aa9a9fd02f56 100644 --- a/src/Groups/sub.jl +++ b/src/Groups/sub.jl @@ -935,6 +935,109 @@ function set_maximal_abelian_quotient(G::T, val::Tuple{GAPGroup, GAPGroupHomomor end +# see `prime_of_pgroup` why we introduce `_abelian_invariants` +@gapattribute _abelian_invariants(G::GAPGroup) = GAP.Globals.AbelianInvariants(G.X) + +""" + abelian_invariants(::Type{T} = ZZRingElem, G::Union{GAPGroup, GrpAbFinGen}) where T <: IntegerUnion + +Return the sorted vector of abelian invariants of the commutator factor group +of `G` (see [`maximal_abelian_quotient`](@ref)). +The entries are prime powers or zeroes and have the type `T`. +They describe the structure of the commutator factor group of `G` +as a direct product of cyclic groups of prime power (or infinite) order. + +# Examples +```jldoctest +julia> abelian_invariants(symmetric_group(4)) +1-element Vector{ZZRingElem}: + 2 + +julia> abelian_invariants(Int, abelian_group([2, 12])) +3-element Vector{Int64}: + 2 + 3 + 4 + +julia> abelian_invariants(alternating_group(5)) +ZZRingElem[] +``` +""" +abelian_invariants(G::GAPGroup) = abelian_invariants(ZZRingElem, G) + +abelian_invariants(::Type{T}, G::GAPGroup) where T <: IntegerUnion = + Vector{T}(_abelian_invariants(G)) + + +# see `prime_of_pgroup` why we introduce `_abelian_invariants_schur_multiplier` +@gapattribute _abelian_invariants_schur_multiplier(G::GAPGroup) = GAP.Globals.AbelianInvariantsMultiplier(G.X) + +""" + abelian_invariants_schur_multiplier(::Type{T} = ZZRingElem, G::Union{GAPGroup, GrpAbFinGen}) where T <: IntegerUnion + +Return the sorted vector of abelian invariants +(see [`abelian_invariants`](@ref)) of the Schur multiplier of `G`. +The entries are prime powers or zeroes and have the type `T`. +They describe the structure of the Schur multiplier of `G` +as a direct product of cyclic groups of prime power (or infinite) order. + +# Examples +```jldoctest +julia> abelian_invariants_schur_multiplier(symmetric_group(4)) +1-element Vector{ZZRingElem}: + 2 + +julia> abelian_invariants_schur_multiplier(Int, alternating_group(6)) +2-element Vector{Int64}: + 2 + 3 + +julia> abelian_invariants_schur_multiplier(abelian_group([2, 12])) +1-element Vector{ZZRingElem}: + 2 + +julia> abelian_invariants_schur_multiplier(cyclic_group(5)) +ZZRingElem[] +``` +""" +abelian_invariants_schur_multiplier(G::GAPGroup) = abelian_invariants_schur_multiplier(ZZRingElem, G) + +abelian_invariants_schur_multiplier(::Type{T}, G::GAPGroup) where T <: IntegerUnion = + Vector{T}(_abelian_invariants_schur_multiplier(G)) + + +""" + schur_multiplier(::Type{T} = GrpAbFinGen, G::Union{GAPGroup, GrpAbFinGen}) where T <: Union{GAPGroup, GrpAbFinGen} + +Return the Schur multiplier of `G`. +This is an abelian group whose abelian invariants can be computed with +[`abelian_invariants_schur_multiplier`](@ref). + +# Examples +```jldoctest +julia> schur_multiplier(symmetric_group(4)) +GrpAb: Z/2 + +julia> schur_multiplier(PcGroup, alternating_group(6)) +Pc group of order 6 + +julia> schur_multiplier(abelian_group([2, 12])) +GrpAb: Z/2 + +julia> schur_multiplier(cyclic_group(5)) +GrpAb: Z/1 +``` +""" +schur_multiplier(G::Union{GAPGroup, GrpAbFinGen}) = schur_multiplier(GrpAbFinGen, G) + +function schur_multiplier(::Type{T}, G::Union{GAPGroup, GrpAbFinGen}) where T <: Union{GAPGroup, GrpAbFinGen} + eldiv = elementary_divisors_of_vector(ZZRingElem, abelian_invariants_schur_multiplier(G)) + M = abelian_group(eldiv) + (M isa T) && return M + return codomain(isomorphism(T, M)) +end + + function __create_fun(mp, codom, ::Type{S}) where S function mp_julia(x::S) el = GAPWrap.Image(mp, x.X) diff --git a/src/Modules/ModulesGraded.jl b/src/Modules/ModulesGraded.jl index 35379d847c0b..acedf679bfe3 100644 --- a/src/Modules/ModulesGraded.jl +++ b/src/Modules/ModulesGraded.jl @@ -1522,7 +1522,7 @@ function Base.show(io::IO, table::sheafCohTable) end @doc raw""" - sheaf_cohomology_bgg(M::ModuleFP{T}, l::Int, h::Int) where {T <: MPolyDecRingElem} + sheaf_cohomology(M::ModuleFP{T}, l::Int, h::Int; algorithm::Symbol = :bgg) where {T <: MPolyDecRingElem} Compute the cohomology of twists of of the coherent sheaf on projective space associated to `M`. The range of twists is between `l` and `h`. @@ -1548,7 +1548,7 @@ S^4 <---- S^6 <---- S^4 <---- S^1 <---- 0 julia> M = cokernel(map(FI, 2)); -julia> tbl = sheaf_cohomology_bgg(M, -6, 2) +julia> tbl = sheaf_cohomology(M, -6, 2) twist: -6 -5 -4 -3 -2 -1 0 1 2 ------------------------------------------ 0: 70 36 15 4 - - - - * @@ -1570,7 +1570,7 @@ julia> R, x = grade(R); julia> F = graded_free_module(R, 1); -julia> sheaf_cohomology_bgg(F, -7, 2) +julia> sheaf_cohomology(F, -7, 2, algorithm = :bgg) twist: -7 -6 -5 -4 -3 -2 -1 0 1 2 ---------------------------------------------- 0: 15 5 1 - - - * * * * @@ -1582,7 +1582,79 @@ twist: -7 -6 -5 -4 -3 -2 -1 0 1 2 chi: * * * * - - * * * * ``` """ -function sheaf_cohomology_bgg(M::ModuleFP{T}, +function sheaf_cohomology(M::ModuleFP{T}, + l::Int, + h::Int; + algorithm::Symbol = :bgg) where {T <: MPolyDecRingElem} + if algorithm == :bgg + return _sheaf_cohomology_bgg(M, l, h) + else + error("Algorithm not supported.") + end +end + +@doc raw""" + _sheaf_cohomology_bgg(M::ModuleFP{T}, l::Int, h::Int) where {T <: MPolyDecRingElem} + +Compute the cohomology of twists of of the coherent sheaf on projective +space associated to `M`. The range of twists is between `l` and `h`. +In the displayed result, '-' refers to a zero enty and '*' refers to a +negative entry (= dimension not yet determined). To determine all values +in the desired range between `l` and `h` use `sheafCoh_BGG_regul(M, l-ngens(base_ring(M)), h+ngens(base_ring(M)))`. +The values of the returned table can be accessed by indexing it +with a cohomological index and a value between `l` and `h` as shown +in the example below. + +```jldoctest +julia> R, x = polynomial_ring(QQ, "x" => 1:4); + +julia> S, _= grade(R); + +julia> I = ideal(S, gens(S)) +ideal(x[1], x[2], x[3], x[4]) + +julia> FI = free_resolution(I) +Free resolution of I +S^4 <---- S^6 <---- S^4 <---- S^1 <---- 0 +0 1 2 3 4 + +julia> M = cokernel(map(FI, 2)); + +julia> tbl = Oscar._sheaf_cohomology_bgg(M, -6, 2) +twist: -6 -5 -4 -3 -2 -1 0 1 2 +------------------------------------------ +0: 70 36 15 4 - - - - * +1: * - - - - - - - - +2: * * - - - - 1 - - +3: * * * - - - - - 6 +------------------------------------------ +chi: * * * 4 - - 1 - * + +julia> tbl[0, -6] +70 + +julia> tbl[2, 0] +1 + +julia> R, x = polynomial_ring(QQ, "x" => 1:5); + +julia> R, x = grade(R); + +julia> F = graded_free_module(R, 1); + +julia> Oscar._sheaf_cohomology_bgg(F, -7, 2) +twist: -7 -6 -5 -4 -3 -2 -1 0 1 2 +---------------------------------------------- +0: 15 5 1 - - - * * * * +1: * - - - - - - * * * +2: * * - - - - - - * * +3: * * * - - - - - - * +4: * * * * - - - 1 5 15 +---------------------------------------------- +chi: * * * * - - * * * * +``` +""" +function _sheaf_cohomology_bgg(M::ModuleFP{T}, l::Int, h::Int) where {T <: MPolyDecRingElem} diff --git a/src/Modules/UngradedModules.jl b/src/Modules/UngradedModules.jl index be33ffba7659..5787d4f22b34 100644 --- a/src/Modules/UngradedModules.jl +++ b/src/Modules/UngradedModules.jl @@ -6852,7 +6852,7 @@ julia> W = [M[1], y*M[2]]; julia> a = hom(M, M, W); -julia> iswelldefined(a) +julia> is_welldefined(a) true julia> matrix(a) diff --git a/src/NumberTheory/GaloisGrp/GaloisGrp.jl b/src/NumberTheory/GaloisGrp/GaloisGrp.jl index fe5d3b269df5..7d89f59e96d9 100644 --- a/src/NumberTheory/GaloisGrp/GaloisGrp.jl +++ b/src/NumberTheory/GaloisGrp/GaloisGrp.jl @@ -477,7 +477,7 @@ mutable struct ComplexRootCtx pr::Int rt::Vector{acb} function ComplexRootCtx(f::ZZPolyRingElem) - @assert ismonic(f) + @assert is_monic(f) rt = roots(AcbField(20), f) return new(f, 20, rt) end @@ -542,12 +542,12 @@ mutable struct SymbolicRootCtx f::ZZPolyRingElem rt::Vector{nf_elem} function SymbolicRootCtx(f::ZZPolyRingElem, ::Nothing) - @assert ismonic(f) + @assert is_monic(f) _, rt = splitting_field(f, do_roots = true) return new(f, rt) end function SymbolicRootCtx(f::ZZPolyRingElem, field::AnticNumberField) - @assert ismonic(f) + @assert is_monic(f) rt = roots(f, field) return new(f, rt) end @@ -1519,7 +1519,7 @@ function starting_group(GC::GaloisCtx, K::T; useSubfields::Bool = true) where T else f, mf = residue_field(parent(r[1])) _F, mF = residue_field(parent(R[1])) - mfF = find_morphism(f, _F) + mfF = Hecke.find_morphism(f, _F) end #we should have # - d == r (in the appropriate setting) @@ -2633,16 +2633,6 @@ function Hecke.absolute_minpoly(a::Oscar.NfNSGenElem{QQFieldElem, QQMPolyRingEle return minpoly(a) end -#TODO copied from MPolyFact in Hecke.... -function find_morphism(k::fqPolyRepField, K::fqPolyRepField) - if degree(k) > 1 - phi = Nemo.find_morphism(k, K) #avoids embed - which stores the info - else - phi = MapFromFunc(k, K, x->K((coeff(x, 0))), y->k((coeff(y, 0)))) - end - return phi -end - function blow_up(G::PermGroup, C::GaloisCtx, lf::Vector, con::PermGroupElem=one(G)) if all(x->x[2] == 1, lf) return G, C @@ -2729,7 +2719,7 @@ function galois_group(f::PolyRingElem{<:FieldElem}; prime=0, pStart::Int = 2*deg r = roots(GC, 5, raw = true) K, mK = residue_field(parent(r[1])) r = map(mK, r) - phi = find_morphism(K, k) + phi = Hecke.find_morphism(K, k) po = vcat(po, [findfirst(x->x == phi(y), rr) for y = r]) end diff --git a/src/NumberTheory/GaloisGrp/RelGalois.jl b/src/NumberTheory/GaloisGrp/RelGalois.jl index 1c6b2b530020..d86e06d8ad1a 100644 --- a/src/NumberTheory/GaloisGrp/RelGalois.jl +++ b/src/NumberTheory/GaloisGrp/RelGalois.jl @@ -216,7 +216,7 @@ function bound_to_precision(C::GaloisCtx{Hecke.vanHoeijCtx}, y::BoundRingElem{ZZ end function galois_group(f::PolyRingElem{nf_elem}, ::QQField) - @assert isirreducible(f) + @assert is_irreducible(f) g = f k = 0 diff --git a/src/Oscar.jl b/src/Oscar.jl index b8ed02708a5a..1f983f0c7c87 100644 --- a/src/Oscar.jl +++ b/src/Oscar.jl @@ -145,12 +145,12 @@ end const PROJECT_TOML = Pkg.TOML.parsefile(joinpath(@__DIR__, "..", "Project.toml")) const VERSION_NUMBER = VersionNumber(PROJECT_TOML["version"]) +const PROJECT_UUID = UUID(PROJECT_TOML["uuid"]) const is_dev = (function() - uuid = PROJECT_TOML["uuid"] deps = Pkg.dependencies() - if Base.haskey(deps, uuid) - if deps[uuid].is_tracking_path + if Base.haskey(deps, PROJECT_UUID) + if deps[PROJECT_UUID].is_tracking_path return true end end diff --git a/src/PolyhedralGeometry/triangulations.jl b/src/PolyhedralGeometry/triangulations.jl index 6651a1e7e4ea..af9267afa463 100644 --- a/src/PolyhedralGeometry/triangulations.jl +++ b/src/PolyhedralGeometry/triangulations.jl @@ -436,7 +436,7 @@ function secondary_polytope(P::Polyhedron{T}) where T<:scalar_types end @doc raw""" - isregular(pts::AbstractCollection[PointVector], cells::Vector{Vector{Vector{Int64}}}) + is_regular(pts::AbstractCollection[PointVector], cells::Vector{Vector{Vector{Int64}}}) Compute whether a triangulation is regular. @@ -452,7 +452,7 @@ julia> is_regular(vertices(c),cells) true ``` """ -function isregular(pts::AbstractCollection[PointVector], cells::Vector{Vector{Int64}}) +function is_regular(pts::AbstractCollection[PointVector], cells::Vector{Vector{Int64}}) as_sop = subdivision_of_points(pts,cells) is_regular(as_sop) end diff --git a/src/Rings/mpoly-affine-algebras.jl b/src/Rings/mpoly-affine-algebras.jl index 0a42d51b0674..106af9041343 100644 --- a/src/Rings/mpoly-affine-algebras.jl +++ b/src/Rings/mpoly-affine-algebras.jl @@ -369,13 +369,13 @@ julia> hilbert_polynomial(A) 3*t + 1 ``` """ -function hilbert_polynomial(A::MPolyQuoRing)::QQPolyRingElem +function hilbert_polynomial(A::MPolyQuoRing) if iszero(A.I) R = base_ring(A.I) @req is_standard_graded(R) "The base ring must be standard ZZ-graded" n = ngens(A) Qt, t = QQ["t"] - b = one(parent(t)) + b = one(Qt) for i in QQ(1):QQ(n-1) b = b * (t+i) end @@ -383,7 +383,7 @@ function hilbert_polynomial(A::MPolyQuoRing)::QQPolyRingElem return b end H = HilbertData(A.I) - return hilbert_polynomial(H) + return hilbert_polynomial(H)::QQPolyRingElem end @doc raw""" diff --git a/src/Rings/mpoly-localizations.jl b/src/Rings/mpoly-localizations.jl index 145de76f4563..375d1a26d61e 100644 --- a/src/Rings/mpoly-localizations.jl +++ b/src/Rings/mpoly-localizations.jl @@ -713,6 +713,7 @@ function issubset(T::AbsMPolyMultSet, U::AbsMPolyMultSet) end function ==(T::AbsMPolyMultSet, U::AbsMPolyMultSet) + T === U && return true return (issubset(T, U) && issubset(U, T)) end @@ -2289,7 +2290,10 @@ function issubset(I::IdealType, J::IdealType) where {IdealType<:MPolyLocalizedId return true end -==(I::IdealType, J::IdealType) where {IdealType<:MPolyLocalizedIdeal} = (issubset(I, J) && issubset(J, I)) +function ==(I::IdealType, J::IdealType) where {IdealType<:MPolyLocalizedIdeal} + I === J && return true + (issubset(I, J) && issubset(J, I)) +end function +(I::IdealType, J::IdealType) where {IdealType<:MPolyLocalizedIdeal} return ideal(base_ring(I), vcat(gens(I), gens(J))) @@ -2911,6 +2915,7 @@ end (f::MPolyLocalizedRingHom)(I::Ideal) = ideal(codomain(f), domain(f).(gens(I))) function ==(f::MPolyLocalizedRingHom, g::MPolyLocalizedRingHom) + f === g && return true domain(f) === domain(g) || return false codomain(f) === codomain(g) || return false for x in gens(base_ring(domain(f))) diff --git a/src/Rings/mpolyquo-localizations.jl b/src/Rings/mpolyquo-localizations.jl index 2bd1fd4bc0b5..6e1d0aec85a6 100644 --- a/src/Rings/mpolyquo-localizations.jl +++ b/src/Rings/mpolyquo-localizations.jl @@ -91,14 +91,14 @@ multiplicative set ``S ⊂ P`` of type `MultSetType`. RingElemType<:MPolyRingElem, MultSetType<:AbsMultSet{RingType, RingElemType} } - base_ring(I) == R || error("Ideal does not belong to the ring") - base_ring(Q) == R || error("The quotient ring does not come from the given ring") + base_ring(I) === R || error("Ideal does not belong to the ring") + base_ring(Q) === R || error("The quotient ring does not come from the given ring") # The following line throws obscure error messages that might yield a bug for MPolyIdeals. # So it's commented out for now. #modulus(Q) == I || error("the modulus of the quotient ring does not coincide with the ideal") - S == inverted_set(W) || error("the multiplicative set does not coincide with the inverted set of the localized ring") - base_ring(W) == R || error("the localization does not come from the given ring") - ambient_ring(S) == R || error("Multiplicative set does not belong to the ring") + S === inverted_set(W) || error("the multiplicative set does not coincide with the inverted set of the localized ring") + base_ring(W) === R || error("the localization does not come from the given ring") + ambient_ring(S) === R || error("Multiplicative set does not belong to the ring") k = coefficient_ring(R) L = new{typeof(k), elem_type(k), typeof(R), RingElemType, MultSetType}(R, I, S, Q, W) return L @@ -324,7 +324,7 @@ function localization( L::MPolyQuoLocRing{BRT, BRET, RT, RET, MST}, S::AbsMPolyMultSet{BRT, BRET, RT, RET} ) where {BRT, BRET, RT, RET, MST} - ambient_ring(S) == base_ring(L) || error("multiplicative set does not belong to the correct ring") + ambient_ring(S) === base_ring(L) || error("multiplicative set does not belong to the correct ring") issubset(S, inverted_set(L)) && return L, MapFromFunc(L, L, x->x) U = inverted_set(L)*S W = MPolyQuoLocRing(base_ring(L), modulus(underlying_quotient(L)), U, underlying_quotient(L), localization(U)[1]) @@ -361,7 +361,7 @@ end function Base.in(f::AbstractAlgebra.Generic.Frac{RET}, L::MPolyQuoLocRing{BRT, BRET, RT, RET, MST}) where {BRT, BRET, RT, RET, MST} R = base_ring(L) - R == parent(numerator(f)) || error("element does not belong to the correct ring") + R === parent(numerator(f)) || error("element does not belong to the correct ring") denominator(f) in inverted_set(L) && return true return numerator(f) in ideal(L, denominator(f)) end @@ -421,7 +421,7 @@ mutable struct MPolyQuoLocRingElem{ S = inverted_set(L) R = base_ring(L) - parent(a) == parent(b) == R || error("elements do not belong to the correct ring") + parent(a) === parent(b) === R || error("elements do not belong to the correct ring") @check b in S || error("denominator is not admissible") return new{BaseRingType, BaseRingElemType, RingType, RingElemType, MultSetType}(L, a, b, is_reduced) end @@ -531,7 +531,7 @@ function (L::MPolyQuoLocRing{BRT, BRET, RT, RET, MST})(f::MPolyLocRingElem{BRT, end function (L::MPolyQuoLocRing{BRT, BRET, RT, RET, MST})(f::MPolyQuoRingElem{RET}; check::Bool=true, is_reduced::Bool=false) where {BRT, BRET, RT, RET, MST} - base_ring(parent(f)) == base_ring(L) || error("the given element does not belong to the correct ring") + base_ring(parent(f)) === base_ring(L) || error("the given element does not belong to the correct ring") if parent(f) !== underlying_quotient(L) @check all(x->(iszero(L(x))), gens(modulus(parent(f)))) "coercion is not well defined" end @@ -589,19 +589,19 @@ function is_unit(f::MPolyQuoLocRingElem) end function is_unit(L::MPolyQuoLocRing, f::MPolyLocRingElem) - parent(f) == localized_ring(L) || error("element does not belong to the correct ring") + parent(f) === localized_ring(L) || error("element does not belong to the correct ring") numerator(f) in inverted_set(L) && return true one(localized_ring(L)) in modulus(L) + ideal(localized_ring(L), f) end function is_unit(L::MPolyQuoLocRing{BRT, BRET, RT, RET, MST}, f::RET) where {BRT, BRET, RT, RET, MST} - parent(f) == base_ring(L) || error("element does not belong to the correct ring") + parent(f) === base_ring(L) || error("element does not belong to the correct ring") f in inverted_set(L) && return true return one(localized_ring(L)) in modulus(L) + ideal(localized_ring(L), localized_ring(L)(f)) end function is_unit(L::MPolyQuoLocRing{BRT, BRET, RT, RET, MST}, f::MPolyQuoRingElem{RET}) where {BRT, BRET, RT, RET, MST} - parent(f) == underlying_quotient(L) || error("element does not belong to the correct ring") + parent(f) === underlying_quotient(L) || error("element does not belong to the correct ring") lift(f) in inverted_set(L) && return true one(localized_ring(L)) in modulus(L) + ideal(localized_ring(L), localized_ring(L)(f)) end @@ -611,7 +611,7 @@ end function inv(L::MPolyQuoLocRing{BRT, BRET, RT, RET, MPolyPowersOfElement{BRT, BRET, RT, RET}}, f::MPolyQuoRingElem{RET}) where {BRT, BRET, RT, RET} Q = underlying_quotient(L) - parent(f) == underlying_quotient(L) || error("element does not belong to the correct ring") + parent(f) === underlying_quotient(L) || error("element does not belong to the correct ring") W = localized_ring(L) R = base_ring(L) I = saturated_ideal(modulus(L)) @@ -663,7 +663,7 @@ function convert( a = numerator(f) b = denominator(f) Q = underlying_quotient(L) - parent(a) == base_ring(L) || error("element does not belong to the correct ring") + parent(a) === base_ring(L) || error("element does not belong to the correct ring") W = localized_ring(L) R = base_ring(L) I = saturated_ideal(modulus(L)) @@ -733,7 +733,7 @@ end ### arithmetic ######################################################### function +(a::T, b::T) where {T<:MPolyQuoLocRingElem} - parent(a) == parent(b) || error("the arguments do not have the same parent ring") + parent(a) === parent(b) || error("the arguments do not have the same parent ring") if lifted_denominator(a) == lifted_denominator(b) return (parent(a))(lifted_numerator(a) + lifted_numerator(b), lifted_denominator(a), check=false) end @@ -755,7 +755,7 @@ function -(a::T, b::T) where {T<:MPolyQuoLocRingElem} end function *(a::T, b::T) where {T<:MPolyQuoLocRingElem} - parent(a) == parent(b) || error("the arguments do not have the same parent ring") + parent(a) === parent(b) || error("the arguments do not have the same parent ring") return (parent(a))(lifted_numerator(a)*lifted_numerator(b), lifted_denominator(a)*lifted_denominator(b), check=false) end @@ -817,7 +817,8 @@ function divexact(a::T, b::T) where {T<:MPolyQuoLocRingElem} end function ==(a::T, b::T) where {T<:MPolyQuoLocRingElem} - parent(a) == parent(b) || error("the arguments do not have the same parent ring") + parent(a) === parent(b) || error("the arguments do not have the same parent ring") + a === b && return true return lifted_numerator(a)*lifted_denominator(b) - lifted_numerator(b)*lifted_denominator(a) in modulus(parent(a)) end @@ -872,7 +873,7 @@ function bring_to_common_denominator(f::Vector{T}) where {T<:MPolyQuoLocRingElem length(f) == 0 && error("need at least one argument to determine the return type") R = base_ring(parent(f[1])) for a in f - R == base_ring(parent(a)) || error("elements do not belong to the same ring") + R === base_ring(parent(a)) || error("elements do not belong to the same ring") end d = one(R) a = Vector{elem_type(R)}() @@ -900,7 +901,7 @@ function write_as_linear_combination( L = parent(f) W = localized_ring(L) for a in g - parent(a) == L || error("elements do not belong to the same ring") + parent(a) === L || error("elements do not belong to the same ring") end return L.(vec(coordinates(lift(f), ideal(L, g)))[1:length(g)]) # temporary hack; to be replaced. end @@ -1097,6 +1098,7 @@ end (f::MPolyQuoLocalizedRingHom)(I::Ideal) = ideal(codomain(f), f.(domain(f).(gens(I)))) function ==(f::MPolyQuoLocalizedRingHom, g::MPolyQuoLocalizedRingHom) + f === g && return true domain(f) === domain(g) || return false codomain(f) === codomain(g) || return false for x in gens(base_ring(domain(f))) @@ -1577,7 +1579,7 @@ Ideals in localizations of affine algebras. ) ) where {LocRingElemType<:MPolyQuoLocRingElem} for f in g - parent(f) == W || error("generator is not an element of the given ring") + parent(f) === W || error("generator is not an element of the given ring") end L = localized_ring(W) @@ -1663,7 +1665,7 @@ julia> (I,J,K) """ function intersect(I::MPolyQuoLocalizedIdeal, J::MPolyQuoLocalizedIdeal) L = base_ring(I) - L == base_ring(J) || error("ideals must be defined in the same ring") + L === base_ring(J) || error("ideals must be defined in the same ring") preI = pre_image_ideal(I) preJ = pre_image_ideal(J) R = base_ring(L) @@ -1675,7 +1677,7 @@ function intersect(I::MPolyQuoLocalizedIdeal, J::MPolyQuoLocalizedIdeal...) L = base_ring(I) erg = pre_image_ideal(I) for K in J - base_ring(K) == L || error("base rings must match") + base_ring(K) === L || error("base rings must match") erg = intersect(erg,pre_image_ideal(K)) end return L(erg) @@ -1684,7 +1686,7 @@ end function intersect(VI::Vector{<:MPolyQuoLocalizedIdeal{T}}) where T @assert length(VI) != 0 L = base_ring(VI[1]) - all(J -> base_ring(J) == L,VI) || error("base rings must match") + all(J -> base_ring(J) === L,VI) || error("base rings must match") VIpre = [pre_image_ideal(J) for J in VI] erg = intersect(VIpre) return L(erg) @@ -1693,13 +1695,13 @@ end ### Basic functionality function ideal_membership(a::RingElem, I::MPolyQuoLocalizedIdeal) L = base_ring(I) - parent(a) == L || return L(a) in I + parent(a) === L || return L(a) in I return lift(a) in pre_image_ideal(I) end function coordinates(a::RingElem, I::MPolyQuoLocalizedIdeal) L = base_ring(I) - parent(a) == L || return coordinates(L(a), I) + parent(a) === L || return coordinates(L(a), I) a in I || error("the given element is not in the ideal") x = coordinates(lift(a), pre_image_ideal(I), check=false) return map_entries(L, x[1, 1:ngens(I)]) @@ -1792,7 +1794,7 @@ function quo( end function quo(A::MPolyQuoRing, I::MPolyQuoIdeal) - base_ring(I) == A || error("ideal does not belong to the correct ring") + base_ring(I) === A || error("ideal does not belong to the correct ring") R = base_ring(A) Q, _ = quo(R, modulus(A) + ideal(R, lift.(gens(I)))) return Q, hom(A, Q, Q.(gens(R)), check=false) @@ -1800,7 +1802,7 @@ end function divides(a::MPolyQuoLocRingElem, b::MPolyQuoLocRingElem) W = parent(a) - W == parent(b) || error("elements do not belong to the same ring") + W === parent(b) || error("elements do not belong to the same ring") F = FreeMod(W, 1) A = matrix(W, 1, 1, [b]) M, _ = sub(F, A) @@ -1833,7 +1835,7 @@ end function jacobi_matrix(g::Vector{<:MPolyQuoLocRingElem}) L = parent(g[1]) n = nvars(base_ring(L)) - @assert all(x->parent(x) == L, g) + @assert all(x->parent(x) === L, g) return matrix(L, n, length(g), [derivative(x, i) for i=1:n for x = g]) end @@ -1935,7 +1937,7 @@ Return ``I:J^{\infty}`` together with the smallest integer ``m`` such that ``I:J """ function saturation_with_index(I::T,J::T) where T <: Union{ MPolyQuoIdeal, MPolyLocalizedIdeal, MPolyQuoLocalizedIdeal} R = base_ring(I) - R == base_ring(J) || error("Ideals do not live in the same ring.") + R === base_ring(J) || error("Ideals do not live in the same ring.") I_sat = saturated_ideal(I) J_sat = saturated_ideal(J) @@ -1955,7 +1957,7 @@ Internal function for weak and controlled transform. """ function iterated_quotients(I::T, J::T, b::Int=0) where T <: MPolyAnyIdeal R = base_ring(I) - R == base_ring(J) || error("Ideals do not live in the same ring.") + R === base_ring(J) || error("Ideals do not live in the same ring.") b > -1 || error("negative multiplicity not allowed") Itemp = I @@ -2061,7 +2063,7 @@ function vector_space(kk::Field, W::MPolyQuoLocRing{<:Field, <:FieldElem, shift, backshift = base_ring_shifts(L) function im(a::Generic.FreeModuleElem) - @assert parent(a) == V + @assert parent(a) === V b = R(0) for k=1:length(V_gens) c = a[k] diff --git a/src/Serialization/Rings.jl b/src/Serialization/Rings.jl index b9a2b2910d7b..8364f8d2caf5 100644 --- a/src/Serialization/Rings.jl +++ b/src/Serialization/Rings.jl @@ -570,3 +570,61 @@ function load_object(s::DeserializerState, ::Type{<: Union{Generic.LaurentSeries scale = parse(Int, dict[:scale]) return parent_ring(loaded_terms, pol_length, precision, valuation, scale) end + +### Affine algebras +@register_serialization_type MPolyQuoRing uses_id + +function save_object(s::SerializerState, A::MPolyQuoRing) + save_data_dict(s) do # Saves stuff in a JSON dictionary. This opens a `{`, puts stuff + # inside there for the various keys and then closes it with `}`. + # It's not using Julia Dicts. + save_typed_object(s, modulus(A), :modulus) + save_typed_object(s, ordering(A), :ordering) # Does this already serialize??? + end +end + +function load_object(s::DeserializerState, ::Type{MPolyQuoRing}, dict::Dict) + I = load_typed_object(s, dict[:modulus]) + R = base_ring(I) + o = load_typed_object(s, dict[:ordering]) + return MPolyQuoRing(R, I, o) +end + +### Serialization of Monomial orderings +@register_serialization_type MonomialOrdering + +function save_object(s::SerializerState, o::MonomialOrdering) + save_data_dict(s) do + save_typed_object(s, base_ring(o), :ring) + save_typed_object(s, o.o, :internal_ordering) # TODO: Is there a getter for this? + if isdefined(o, :is_total) + save_typed_object(s, o.is_total, :is_total) + end + end +end + +function load_object(s::DeserializerState, ::Type{MonomialOrdering}, dict::Dict) + the_ring = load_typed_object(s, dict[:ring]) + the_ordering = load_typed_object(s, dict[:internal_ordering]) + result = MonomialOrdering(the_ring, the_ordering) + if haskey(dict, :is_total) + result.is_total = load_typed_object(s, dict[:is_total]) + end + return result +end + +@register_serialization_type Orderings.SymbOrdering + +function save_object(s::SerializerState, o::Orderings.SymbOrdering{S}) where {S} + save_data_dict(s) do + save_typed_object(s, S, :ordering_symbol_as_type) + save_typed_object(s, o.vars, :vars) # TODO: Is there a getter? + end +end + +function load_object(s::DeserializerState, ::Type{Orderings.SymbOrdering}, dict::Dict) + S = load_typed_object(s, dict[:ordering_symbol_as_type]) + vars = load_typed_object(s, dict[:vars]) + return Orderings.SymbOrdering(S, vars) +end + diff --git a/src/Serialization/containers.jl b/src/Serialization/containers.jl index 993b9e98ac45..e7aaabfbe158 100644 --- a/src/Serialization/containers.jl +++ b/src/Serialization/containers.jl @@ -43,14 +43,23 @@ end function save_object(s::SerializerState, x::Vector) save_data_array(s) do for elem in x - save_object(s, elem) + if serialize_with_id(typeof(elem)) + ref = save_as_ref(s, elem) + save_object(s, ref) + else + save_object(s, elem) + end end end end function load_object(s::DeserializerState, ::Type{<: Vector}, v::Vector, params::Type) - loaded_v = params[load_object(s, params, x) for x in v] + if serialize_with_id(params) + loaded_v = params[load_ref(s, x) for x in v] + else + loaded_v = params[load_object(s, params, x) for x in v] + end return loaded_v end @@ -58,7 +67,11 @@ end function load_object(s::DeserializerState, ::Type{<: Vector}, v::Vector, params::Tuple) T = params[1] - return T[load_object(s, T, x, params[2]) for x in v] + if isempty(v) + return T[] + else + return [load_object(s, T, x, params[2]) for x in v] + end end function load_object(s::DeserializerState, ::Type{<: Vector}, @@ -104,7 +117,12 @@ end function save_object(s::SerializerState, obj::Tuple) save_data_array(s) do for entry in obj - save_object(s, entry) + if serialize_with_id(typeof(entry)) + ref = save_as_ref(s, entry) + save_object(s, ref) + else + save_object(s, entry) + end end end end @@ -130,11 +148,21 @@ function get_tuple_type(params::Vector) end function load_object(s::DeserializerState, ::Type{<:Tuple}, - v::Vector{Any}, params::Vector) - return Tuple( - params[i] isa Type ? load_object(s, params[i], v[i]) : - load_object(s, params[i][1], v[i], params[i][2]) for i in 1:length(v) - ) + v::Vector{Any}, params::Vector) + entries = [] + for i in 1:length(v) + if params[i] isa Type + if serialize_with_id(params[i]) + loaded_obj = load_ref(s, v[i]) + else + loaded_obj = load_object(s, params[i], v[i]) + end + else + loaded_obj = load_object(s, params[i][1], v[i], params[i][2]) + end + push!(entries, loaded_obj) + end + return Tuple(entries) end ################################################################################ @@ -185,7 +213,6 @@ function load_object(s::DeserializerState, ::Type{<: NamedTuple}, return NamedTuple{Tuple(keys), typeof(tuple)}(tuple) end - ################################################################################ # Saving and loading matrices @register_serialization_type Matrix uses_params diff --git a/src/Serialization/main.jl b/src/Serialization/main.jl index 0c8063d921cb..95dde799d91c 100644 --- a/src/Serialization/main.jl +++ b/src/Serialization/main.jl @@ -127,7 +127,6 @@ # the only parameter needed for such types is their parent. using JSON -using UUIDs include("serializers.jl") @@ -146,15 +145,42 @@ function metadata(;args...) end ################################################################################ -# Version info +# Serialization info -function get_version_info() - result = Dict{Symbol, Any}( - :Oscar => ["https://github.com/oscar-system/Oscar.jl", VERSION_NUMBER] - ) - return result +function serialization_version_info(dict::Dict{Symbol, Any}) + ns = dict[:_ns] + version_info = ns[:Oscar][2] + return version_number(version_info) +end + +function version_number(v_number::String) + return VersionNumber(v_number) +end + +# needed for older versions +function version_number(dict::Dict) + return VersionNumber(dict[:major], dict[:minor], dict[:patch]) +end + +const oscar_serialization_version = Ref{Dict{Symbol, Any}}() + +function get_oscar_serialization_version() + if isassigned(oscar_serialization_version) + return oscar_serialization_version[] + end + if is_dev + commit_hash = get(_get_oscar_git_info(), :commit, "unknown") + version_info = "$VERSION_NUMBER-$commit_hash" + result = Dict{Symbol, Any}( + :Oscar => ["https://github.com/oscar-system/Oscar.jl", version_info] + ) + else + result = Dict{Symbol, Any}( + :Oscar => ["https://github.com/oscar-system/Oscar.jl", VERSION_NUMBER] + ) + end + return oscar_serialization_version[] = result end -const oscar_serialization_version = get_version_info() ################################################################################ # (De|En)coding types @@ -354,6 +380,8 @@ import Serialization.deserialize import Serialization.serialize_type import Distributed.AbstractSerializer +serialize_with_id(::Type) = false + function register_serialization_type(ex::Any, str::String, uses_id::Bool, uses_params::Bool) return esc( quote @@ -425,26 +453,8 @@ include("polymake.jl") include("TropicalGeometry.jl") include("QuadForm.jl") -################################################################################ -# Include upgrade scripts - include("upgrades/main.jl") -function get_file_version(dict::Dict{Symbol, Any}) - ns = dict[:_ns] - version_info = ns[:Oscar][2] - return get_version_number(version_info) -end - -function get_version_number(v_number::String) - return VersionNumber(v_number) -end - -# needed for older versions -function get_version_number(dict::Dict) - return VersionNumber(dict[:major], dict[:minor], dict[:patch]) -end - ################################################################################ # Interacting with IO streams and files @@ -474,7 +484,7 @@ function save(io::IO, obj::T; metadata::Union{MetaData, Nothing}=nothing, s = state(serializer_open(io, serializer_type)) save_data_dict(s) do # write out the namespace first - save_header(s, oscar_serialization_version, :_ns) + save_header(s, get_oscar_serialization_version(), :_ns) save_typed_object(s, obj) @@ -542,7 +552,7 @@ See [`save`](@ref). ```jldoctest julia> save("/tmp/fourtitwo.json", 42); - + julia> load("/tmp/fourtitwo.json") 42 @@ -598,46 +608,55 @@ function load(io::IO; params::Any = nothing, type::Any = nothing, @req haskey(_ns, :Oscar) "Not an Oscar object" # deal with upgrades - file_version = get_file_version(jsondict) + file_version = serialization_version_info(jsondict) if file_version < VERSION_NUMBER jsondict = upgrade(jsondict, file_version) end - # add refs to state for referencing during recursion - if haskey(jsondict, refs_key) - merge!(s.refs, jsondict[refs_key]) - end + try + # add refs to state for referencing during recursion + if haskey(jsondict, refs_key) + merge!(s.refs, jsondict[refs_key]) + end - if type !== nothing - # Decode the stored type, and compare it to the type `T` supplied by the caller. - # If they are identical, just proceed. If not, then we assume that either - # `T` is concrete, in which case `T <: U` should hold; or else `U` is - # concrete, and `U <: T` should hold. - # - # This check should maybe change to a check on the whole type tree? - U = decode_type(jsondict[type_key]) - U <: type || U >: type || error("Type in file doesn't match target type: $(dict[type_key]) not a subtype of $T") - - if serialize_with_params(type) - if isnothing(params) - params = load_type_params(s, type, jsondict[type_key][:params]) - end + if type !== nothing + # Decode the stored type, and compare it to the type `T` supplied by the caller. + # If they are identical, just proceed. If not, then we assume that either + # `T` is concrete, in which case `T <: U` should hold; or else `U` is + # concrete, and `U <: T` should hold. + # + # This check should maybe change to a check on the whole type tree? + U = decode_type(jsondict[type_key]) + U <: type || U >: type || error("Type in file doesn't match target type: $(dict[type_key]) not a subtype of $T") + + if serialize_with_params(type) + if isnothing(params) + params = load_type_params(s, type, jsondict[type_key][:params]) + end - loaded = load_object(s, type, jsondict[:data], params) + loaded = load_object(s, type, jsondict[:data], params) + else + Base.issingletontype(type) && return type() + loaded = load_object(s, type, jsondict[:data]) + end else - Base.issingletontype(type) && return type() - loaded = load_object(s, type, jsondict[:data]) + loaded = load_typed_object(s, jsondict; override_params=params) end - else - loaded = load_typed_object(s, jsondict; override_params=params) - end - if haskey(jsondict, :id) - global_serializer_state.obj_to_id[loaded] = UUID(jsondict[:id]) - global_serializer_state.id_to_obj[UUID(jsondict[:id])] = loaded + if haskey(jsondict, :id) + global_serializer_state.obj_to_id[loaded] = UUID(jsondict[:id]) + global_serializer_state.id_to_obj[UUID(jsondict[:id])] = loaded + end + return loaded + catch e + println(e.msg) + + if contains(string(file_version), "DEV") + commit = split(string(file_version), "-")[end] + @warn "Attempting to load file stored using a DEV version with commit $commit" + end end - return loaded end function load(filename::String; params::Any = nothing, type::Any = nothing) diff --git a/src/Serialization/upgrades/main.jl b/src/Serialization/upgrades/main.jl index 6525c4015c61..541f6e4b61c8 100644 --- a/src/Serialization/upgrades/main.jl +++ b/src/Serialization/upgrades/main.jl @@ -84,6 +84,6 @@ function upgrade(dict::Dict{Symbol, Any}, dict_version::VersionNumber) upgraded_dict = upgrade_script(s, upgraded_dict) end end - upgraded_dict[:_ns] = oscar_serialization_version + upgraded_dict[:_ns] = get_oscar_serialization_version() return upgraded_dict end diff --git a/src/aliases.jl b/src/aliases.jl index 8eb8498918f9..bddadf0246ad 100644 --- a/src/aliases.jl +++ b/src/aliases.jl @@ -1,90 +1,88 @@ -@alias has_isfinite has_is_finite -@alias SymmetricGroup symmetric_group - # make some Julia names compatible with our naming conventions @alias is_subset issubset @alias is_valid isvalid # for backwards compatibility -@alias hall_subgroups_representatives hall_subgroup_reps -@alias hasrelshp has_relshp -@alias hastorusfactor has_torusfactor -@alias inner_automorphisms_group inner_automorphism_group -#@alias isabsolutely_irreducible is_absolutely_irreducible -@alias isaffine is_affine -@alias isalmostsimple is_almostsimple -@alias isample is_ample -@alias isbicoset is_bicoset -@alias isbinomial is_binomial -@alias isbounded is_bounded -@alias iscartier is_cartier -@alias iscellular is_cellular -@alias iscomplete is_complete -@alias iscongruent is_congruent -@alias isconjugate_subgroup is_conjugate_subgroup -#@alias isdecomposable is_decomposable -@alias isdecorated is_decorated -@alias isdihedral_group is_dihedral_group -@alias isfano is_fano -@alias isfeasible is_feasible -@alias isfiltered is_filtered -@alias isfinite_order is_finiteorder -@alias isfinitelygenerated is_finitelygenerated -@alias isfull_direct_product is_full_direct_product -@alias isfull_semidirect_product is_full_semidirect_product -@alias isfull_wreath_product is_full_wreath_product -@alias isfulldimensional is_fulldimensional -@alias isgenerated_by_standard_unit_vectors is_generated_by_standard_unit_vectors -@alias isglobal is_global -@alias isgraded is_graded -@alias isinner_automorphism is_inner_automorphism -@alias isinvariant is_invariant -@alias isisomorphic_with_alternating_group is_isomorphic_with_alternating_group -@alias isisomorphic_with_symmetric_group is_isomorphic_with_symmetric_group -@alias isleft is_left -@alias islocal is_local -@alias ismixed is_mixed -@alias ismolien_series_implemented is_molien_series_implemented -@alias isnatural_alternating_group is_natural_alternating_group -@alias isnatural_symmetric_group is_natural_symmetric_group -@alias isnef is_nef -@alias isobviouslyabelian is_obviouslyabelian -@alias isorbifold is_orbifold -@alias isperfect is_perfect -@alias ispgroup is_pgroup -@alias ispointed is_pointed -@alias isprojective is_projective -@alias ispure is_pure -@alias isquaternion_group is_quaternion_group -@alias isright is_right -@alias issemiregular is_semiregular -@alias issemisimple is_semisimple -@alias issimplicial is_simplicial -@alias issingular is_singular -@alias issmooth_curve is_smooth_curve -@alias issolvable is_solvable -@alias issupersolvable is_supersolvable -@alias istransitive is_transitive -@alias isunipotent is_unipotent -@alias isunital is_unital -@alias iswelldefined is_welldefined -@alias representative_action is_conjugate_with_data -@alias representative_action_in_gl_or_sl is_conjugate_with_data_in_gl_or_sl +Base.@deprecate_binding hall_subgroups_representatives hall_subgroup_reps +Base.@deprecate_binding hasrelshp has_relshp +Base.@deprecate_binding hastorusfactor has_torusfactor +Base.@deprecate_binding inner_automorphisms_group inner_automorphism_group +Base.@deprecate_binding isaffine is_affine +Base.@deprecate_binding isalmostsimple is_almostsimple +Base.@deprecate_binding isample is_ample +Base.@deprecate_binding isbicoset is_bicoset +Base.@deprecate_binding isbinomial is_binomial +Base.@deprecate_binding isbounded is_bounded +Base.@deprecate_binding iscartier is_cartier +Base.@deprecate_binding iscellular is_cellular +Base.@deprecate_binding iscomplete is_complete +Base.@deprecate_binding iscongruent is_congruent +Base.@deprecate_binding isconjugate_subgroup is_conjugate_subgroup +Base.@deprecate_binding isdecorated is_decorated +Base.@deprecate_binding isdihedral_group is_dihedral_group +Base.@deprecate_binding isfano is_fano +Base.@deprecate_binding isfeasible is_feasible +Base.@deprecate_binding isfiltered is_filtered +Base.@deprecate_binding isfinite_order is_finiteorder +Base.@deprecate_binding isfinitelygenerated is_finitelygenerated +Base.@deprecate_binding isfull_direct_product is_full_direct_product +Base.@deprecate_binding isfull_semidirect_product is_full_semidirect_product +Base.@deprecate_binding isfull_wreath_product is_full_wreath_product +Base.@deprecate_binding isfulldimensional is_fulldimensional +Base.@deprecate_binding isgenerated_by_standard_unit_vectors is_generated_by_standard_unit_vectors +Base.@deprecate_binding isglobal is_global +Base.@deprecate_binding isgraded is_graded +Base.@deprecate_binding isinner_automorphism is_inner_automorphism +Base.@deprecate_binding isinvariant is_invariant +Base.@deprecate_binding isisomorphic_with_alternating_group is_isomorphic_with_alternating_group +Base.@deprecate_binding isisomorphic_with_symmetric_group is_isomorphic_with_symmetric_group +Base.@deprecate_binding isleft is_left +Base.@deprecate_binding islocal is_local +Base.@deprecate_binding ismixed is_mixed +Base.@deprecate_binding ismolien_series_implemented is_molien_series_implemented +Base.@deprecate_binding isnatural_alternating_group is_natural_alternating_group +Base.@deprecate_binding isnatural_symmetric_group is_natural_symmetric_group +Base.@deprecate_binding isnef is_nef +Base.@deprecate_binding isobviouslyabelian is_obviouslyabelian +Base.@deprecate_binding isorbifold is_orbifold +Base.@deprecate_binding isperfect is_perfect +Base.@deprecate_binding ispgroup is_pgroup +Base.@deprecate_binding ispointed is_pointed +Base.@deprecate_binding isprojective is_projective +Base.@deprecate_binding ispure is_pure +Base.@deprecate_binding isquaternion_group is_quaternion_group +Base.@deprecate_binding isright is_right +Base.@deprecate_binding issemiregular is_semiregular +Base.@deprecate_binding issemisimple is_semisimple +Base.@deprecate_binding issimplicial is_simplicial +Base.@deprecate_binding issingular is_singular +Base.@deprecate_binding issmooth_curve is_smooth_curve +Base.@deprecate_binding issolvable is_solvable +Base.@deprecate_binding issupersolvable is_supersolvable +Base.@deprecate_binding istransitive is_transitive +Base.@deprecate_binding isunipotent is_unipotent +Base.@deprecate_binding isunital is_unital +Base.@deprecate_binding iswelldefined is_welldefined +Base.@deprecate_binding representative_action is_conjugate_with_data +Base.@deprecate_binding representative_action_in_gl_or_sl is_conjugate_with_data_in_gl_or_sl + +Base.@deprecate_binding has_isfinite has_is_finite +Base.@deprecate_binding SymmetricGroup symmetric_group # Allow backwards compatibility after removal of Oscar.Graphs module. const Graphs = Oscar # Compatibility with pre-0.12.x -@alias MPolyElem_dec MPolyDecRingElem -@alias MPolyRing_dec MPolyDecRing -@alias MPolyLocalizedRingElem MPolyLocRingElem -@alias MPolyLocalizedRing MPolyLocRing -@alias MPolyQuoElem MPolyQuoRingElem -@alias MPolyQuo MPolyQuoRing -@alias MPolyQuoLocalizedRingElem MPolyQuoLocRingElem -@alias MPolyQuoLocalizedRing MPolyQuoLocRing -@alias SubQuoElem SubquoModuleElem -@alias SubQuo SubquoModule +Base.@deprecate_binding MPolyElem_dec MPolyDecRingElem +Base.@deprecate_binding MPolyRing_dec MPolyDecRing +Base.@deprecate_binding MPolyLocalizedRingElem MPolyLocRingElem +Base.@deprecate_binding MPolyLocalizedRing MPolyLocRing +Base.@deprecate_binding MPolyQuoElem MPolyQuoRingElem +Base.@deprecate_binding MPolyQuo MPolyQuoRing +Base.@deprecate_binding MPolyQuoLocalizedRingElem MPolyQuoLocRingElem +Base.@deprecate_binding MPolyQuoLocalizedRing MPolyQuoLocRing +Base.@deprecate_binding SubQuoElem SubquoModuleElem +Base.@deprecate_binding SubQuo SubquoModule #@alias SubQuoElem_dec SubquoDecModuleElem #@alias SubQuo_dec SubquoDecModule -@alias GradedPolynomialRing graded_polynomial_ring +Base.@deprecate_binding GradedPolynomialRing graded_polynomial_ring diff --git a/src/exports.jl b/src/exports.jl index 09a294a11bb2..3cbc8930e045 100644 --- a/src/exports.jl +++ b/src/exports.jl @@ -186,6 +186,8 @@ export Undirected export WreathProductGroup export ZZ export abelian_group +export abelian_invariants +export abelian_invariants_schur_multiplier export absolute_primary_decomposition export acting_domain export acting_group @@ -1296,6 +1298,7 @@ export save_mps export scalar_product export scheme export schur_index +export schur_multiplier export secondary_cone export secondary_invariants export secondary_polytope @@ -1316,7 +1319,7 @@ export set_relative_order! export set_relative_orders! export set_theoretic_intersection export sets -export sheaf_cohomology_bgg +export sheaf_cohomology export short_right_transversal export shortest_path_dijkstra export show_morphism diff --git a/src/imports.jl b/src/imports.jl index ffde3fd5702f..3c52c0ff3907 100644 --- a/src/imports.jl +++ b/src/imports.jl @@ -2,6 +2,7 @@ using Pkg using Random using RandomExtensions +using UUIDs # our packages import AbstractAlgebra diff --git a/src/utils/versioninfo.jl b/src/utils/versioninfo.jl index eeb71af21ed5..df8494bcc608 100644 --- a/src/utils/versioninfo.jl +++ b/src/utils/versioninfo.jl @@ -3,55 +3,77 @@ # In a bare repo HEAD will not point to the correct commit so we use the git # tree-hash that Pkg.jl provides and manually map this to a corresponding # commit. -function _lookup_commit_from_cache(url::AbstractString, tree::AbstractString) - if Sys.which("git") !== nothing - try - path = Pkg.Types.add_repo_cache_path(url) - if isdir(path) - commit = readchomp(`sh -c "git -C $path log --oneline --all --pretty='tree %T;%H' | grep \"^tree $tree\" | cut -d\; -f2 | head -n1"`) - return readchomp(`git -C $path show -s --format=", %h -- %ci" $commit`) - end - catch +function _lookup_commit_from_cache!(info::Dict, url::AbstractString, tree::AbstractString) + if Sys.which("git") !== nothing + try + path = Pkg.Types.add_repo_cache_path(url) + if isdir(path) + commit = readchomp(`sh -c "git -C $path log --oneline --all --pretty='tree %T;%H' | grep \"^tree $tree\" | cut -d\; -f2 | head -n1"`) + c = readchomp(`git -C $path show -s --format="%H#%ci" $commit`) + (info[:commit], info[:date]) = split(c, "#") end - end - return "" + catch + end + end end -function _lookup_git_branch(dir::AbstractString; commit=false) - info = "" - if Sys.which("git") !== nothing && - isdir(joinpath(dir,".git")) - try - ref = readchomp(`git -C $dir rev-parse --abbrev-ref HEAD`) - info = " - #$(ref)" - if commit - c = readchomp(`git -C $dir show -s --format="%h -- %ci" HEAD`) - info = "$info, $c" - end - catch - end - end - return info +function _lookup_git_branch!(info::Dict, dir::AbstractString) + # the .git entry might be a file instead of a dir when using git worktrees + if Sys.which("git") !== nothing && + ispath(joinpath(dir, ".git")) + try + ref = readchomp(`git -C $dir rev-parse --abbrev-ref HEAD`) + info[:branch] = ref + c = readchomp(`git -C $dir show -s --format="%H#%ci" HEAD`) + (info[:commit], info[:date]) = split(c, "#") + catch + end + end +end + +function _get_git_info(dep::Union{Pkg.API.PackageInfo,AbstractString}) + info = Dict{Symbol,String}() + if dep isa Pkg.API.PackageInfo && dep.is_tracking_repo + _lookup_commit_from_cache!(info, dep.git_source, dep.tree_hash) + # this might be a branch, tag, or commit hash + info[:branch] = dep.git_revision + elseif dep isa Pkg.API.PackageInfo && dep.is_tracking_path + _lookup_git_branch!(info, dep.source) + elseif dep isa AbstractString + _lookup_git_branch!(info, dep) + end + return info +end + +function _get_oscar_git_info() + # Oscar is either one of the dependencies or the active project. + # For the active project we try to use the Oscar path as git directory. + oscarinfo = get(Pkg.dependencies(), PROJECT_UUID, Oscar.oscardir) + return _get_git_info(oscarinfo) end -function _deps_git_info(dep::Pkg.API.PackageInfo; commit=false) - if dep.is_tracking_repo - info = commit ? _lookup_commit_from_cache(dep.git_source, dep.tree_hash) : "" - return " - #$(dep.git_revision)$info" - elseif dep.is_tracking_path - return _lookup_git_branch(dep.source; commit=commit) - end - return "" +function _format_git_info(info::Dict; branch=true, commit=false) + val = String[] + if branch && haskey(info, :branch) + push!(val, "#$(info[:branch])") + end + if commit && haskey(info, :commit) + push!(val, "$(info[:commit][1:10]) -- $(info[:date])") + end + return length(val) > 0 ? " - $(join(val, ", "))" : "" end function _print_dependency_versions(io::IO, deps::AbstractArray{<:AbstractString}; padding=" ", suffix="", branch=false, commit=false) - width = maximum(length.(deps))+length(suffix)+2 - deps = filter(d->d.name in deps, collect(values(Pkg.dependencies()))) - deps = sort!(deps; by=x->x.name) - for dep in deps - print(io, "$(padding)$(rpad(dep.name*suffix, width, ' ')) v$(dep.version)") - println(io, branch ? _deps_git_info(dep; commit=commit) : "") - end + width = maximum(length.(deps))+length(suffix)+2 + deps = filter(d->d.name in deps, collect(values(Pkg.dependencies()))) + deps = sort!(deps; by=x->x.name) + for dep in deps + print(io, "$(padding)$(rpad(dep.name*suffix, width, ' ')) v$(dep.version)") + if branch || commit + print(io, _format_git_info(_get_git_info(dep); branch=branch, commit=commit)) + end + println(io) + end end @doc raw""" @@ -67,22 +89,25 @@ Print the versions of all Oscar-related dependencies. - `full::Bool=false` : include all of the above """ function versioninfo(io::IO=stdout; branch=false, jll=false, julia=false, commit=false, full=false) - if full - branch = jll = julia = commit = true - end - print(io, "OSCAR version $(VERSION_NUMBER)") - println(io, branch ? _lookup_git_branch(Oscar.oscardir; commit=commit) : "") - println(io, " combining:") - _print_dependency_versions(io, cornerstones; suffix=".jl", branch=branch, commit=commit) - if jll - println(io, " building on:") - _print_dependency_versions(io, jll_deps; branch=branch, commit=commit) - println(io, "See `]st -m` for a full list of dependencies.") - end - if julia - println(io, "") - Main.InteractiveUtils.versioninfo(io) - println(io, Base.TAGGED_RELEASE_BANNER) - end + if full + branch = jll = julia = commit = true + end + print(io, "OSCAR version $(VERSION_NUMBER)") + if branch || commit + print(io, _format_git_info(_get_oscar_git_info(); branch=branch, commit=commit)) + end + println(io) + println(io, " combining:") + _print_dependency_versions(io, cornerstones; suffix=".jl", branch=branch, commit=commit) + if jll + println(io, " building on:") + _print_dependency_versions(io, jll_deps; branch=branch, commit=commit) + println(io, "See `]st -m` for a full list of dependencies.") + end + if julia + println(io, "") + Main.InteractiveUtils.versioninfo(io) + println(io, Base.TAGGED_RELEASE_BANNER) + end end diff --git a/system/Build.jl b/system/Build.jl index 7c6d86c30929..8c8b81336e35 100644 --- a/system/Build.jl +++ b/system/Build.jl @@ -26,7 +26,12 @@ Oscar.system("precompile.jl") """) sysimage=joinpath(tmp, "Oscar.$(Libdl.dlext)") -PackageCompiler.create_sysimage([:Oscar], sysimage_path=sysimage, precompile_execution_file=CO) +if !("JULIA_CPU_TARGET" in keys(ENV)) || (ENV["JULIA_CPU_TARGET"] == "") + PackageCompiler.create_sysimage([:Oscar], sysimage_path=sysimage, precompile_execution_file=CO) +else + target = ENV["JULIA_CPU_TARGET"] + PackageCompiler.create_sysimage([:Oscar], sysimage_path=sysimage, precompile_execution_file=CO; cpu_target=target) +end println("(re)start julia as") println("\tjulia -J $(sysimage)") diff --git a/test/AlgebraicGeometry/Schemes/SpecOpen.jl b/test/AlgebraicGeometry/Schemes/SpecOpen.jl index f62f6d6f96a3..1440ca326209 100644 --- a/test/AlgebraicGeometry/Schemes/SpecOpen.jl +++ b/test/AlgebraicGeometry/Schemes/SpecOpen.jl @@ -64,8 +64,8 @@ end @test f^2 == f*f @test f^2 == f^ZZRingElem(2) @test isone(divexact(f,f)) - @test isunit(one(OU)) - @test !isunit(OU(x)) + @test is_unit(one(OU)) + @test !is_unit(OU(x)) g = OU(2) @test isone(g*inv(g)) @test isone(OU(1)) diff --git a/test/Groups/GrpAb.jl b/test/Groups/GrpAb.jl index c690117e5cdf..51afd6afad6b 100644 --- a/test/Groups/GrpAb.jl +++ b/test/Groups/GrpAb.jl @@ -64,6 +64,8 @@ end sg1 = small_generating_set(G1) @test order(sub(G1, sg1)[1]) == order(G1) @test length(sg1) <= length(para) + @test abelian_invariants(G1) == abelian_invariants(G2) + @test abelian_invariants(Int, G1) isa Vector{Int} # conjugacy classes of elements cc = conjugacy_classes(G1) @@ -143,3 +145,28 @@ end @test [images(iso, S)[1] for S in sylow_system(G1)] == sylow_system(G2) end end + +@testset "conversions between formats of abelian invariants" begin + @test Oscar.elementary_divisors_of_vector(Int, []) == [] + @test Oscar.elementary_divisors_of_vector(Int, [0, 3, 2]) == [6, 0] + @test Oscar.abelian_invariants_of_vector(Int, []) == [] + @test Oscar.abelian_invariants_of_vector(Int, [0, 6]) == [0, 2, 3] + for i in 1:100 + v = rand(-5:30, 10) + elab = Oscar.elementary_divisors_of_vector(Int, v) + abinv = Oscar.abelian_invariants_of_vector(Int, v) + @test Oscar.elementary_divisors_of_vector(Int, abinv) == elab + @test Oscar.abelian_invariants_of_vector(Int, elab) == abinv + @test elementary_divisors(abelian_group([abs(x) for x in v])) == elab + end +end + +@testset "abelian_invariants_schur_multiplier for GrpAbFinGen" begin + for g in all_small_groups(1:50, is_abelian) + gg = codomain(isomorphism(GrpAbFinGen, g)) + @test abelian_invariants_schur_multiplier(g) == abelian_invariants_schur_multiplier(gg) + @test abelian_invariants(schur_multiplier(g)) == abelian_invariants_schur_multiplier(g) + end + + @test schur_multiplier(PcGroup, abelian_group([2, 3, 4])) isa PcGroup +end diff --git a/test/Groups/homomorphisms.jl b/test/Groups/homomorphisms.jl index b920e0b0af71..a367ed3465e6 100644 --- a/test/Groups/homomorphisms.jl +++ b/test/Groups/homomorphisms.jl @@ -284,7 +284,7 @@ end G = Hecke.small_group(64, 14, DB = Hecke.DefaultSmallGroupDB()) H = small_group(64, 14) - @test isisomorphic(G, H) + @test is_isomorphic(G, H) f = isomorphism(G, H) for x in gens(G), y in gens(G) @test f(x) * f(y) == f(x * y) @@ -299,7 +299,7 @@ end @test preimage(f, f(y)) == y end - @test isisomorphic(H, G) + @test is_isomorphic(H, G) f = isomorphism(H, G) for x in gens(H), y in gens(H) @test f(x) * f(y) == f(x * y) @@ -315,11 +315,11 @@ end end H = cyclic_group(2) - @test !isisomorphic(G, H) + @test !is_isomorphic(G, H) @test_throws ArgumentError isomorphism(G, H) fl, _ = is_isomorphic_with_map(G, H) @test !fl - @test !isisomorphic(H, G) + @test !is_isomorphic(H, G) @test_throws ArgumentError isomorphism(H, G) fl, _ = is_isomorphic_with_map(H, G) @test !fl diff --git a/test/Groups/quotients.jl b/test/Groups/quotients.jl index c2cfe80f93f3..5f50d1475524 100644 --- a/test/Groups/quotients.jl +++ b/test/Groups/quotients.jl @@ -66,6 +66,11 @@ end @test maximal_abelian_quotient(G)[1] isa FPGroup @test maximal_abelian_quotient(FPGroup, G)[1] isa FPGroup @test_throws MethodError quo(PcGroup, G) + + # `abelian_invariants` + @test abelian_invariants(free_group(2)) == [0, 0] + @test abelian_invariants(alternating_group(5)) == [] + @test abelian_invariants(small_group(8, 5)) == [2, 2, 2] end @testset "Finitely presented groups" begin diff --git a/test/Groups/subgroups_and_cosets.jl b/test/Groups/subgroups_and_cosets.jl index 457a5891f76c..19c553829f80 100644 --- a/test/Groups/subgroups_and_cosets.jl +++ b/test/Groups/subgroups_and_cosets.jl @@ -283,6 +283,16 @@ end @test_throws ArgumentError nilpotency_class(symmetric_group(4)) end +@testset "Schur multiplier" begin + @test abelian_invariants(schur_multiplier(cyclic_group(1))) == [] + @test abelian_invariants(schur_multiplier(cyclic_group(5))) == [] + @test abelian_invariants(schur_multiplier(symmetric_group(4))) == [2] + @test abelian_invariants(schur_multiplier(alternating_group(6))) == [2, 3] + + @test schur_multiplier(symmetric_group(4)) isa GrpAbFinGen + @test schur_multiplier(PcGroup, symmetric_group(4)) isa PcGroup +end + @testset "Sylow and Hall subgroups" begin G = symmetric_group(4) diff --git a/test/Modules/ExteriorPowers.jl b/test/Modules/ExteriorPowers.jl index 349fda9be1e5..8030b98c2004 100644 --- a/test/Modules/ExteriorPowers.jl +++ b/test/Modules/ExteriorPowers.jl @@ -45,8 +45,7 @@ end @testset "exterior powers of graded modules" begin - R, (x, y, u, v, w) = QQ[:x, :y, :u, :v, :w] - S, (x, y, u, v, w) = grade(R) + S, _ = graded_polynomial_ring(QQ, 5) F = graded_free_module(S, [1, 1, 1, 1, -2]) Fwedge1, _ = Oscar.exterior_power(F, 1) Fwedge2, _ = Oscar.exterior_power(F, 2) diff --git a/test/Modules/ModulesGraded.jl b/test/Modules/ModulesGraded.jl index 0f5949ea51bf..92d940049744 100644 --- a/test/Modules/ModulesGraded.jl +++ b/test/Modules/ModulesGraded.jl @@ -7,9 +7,8 @@ RNG = Random.MersenneTwister(42) ################################################################## @testset "Graded free modules constructors" begin - R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]) - Z = abelian_group(0) - Rg = grade(R,[Z[1], Z[1], Z[1]])[1] + Rg, _ = graded_polynomial_ring(QQ, ["x", "y", "z"]) + Z = grading_group(Rg) M1 = graded_free_module(Rg, 2) @test degrees(M1) == [Z[0], Z[0]] M2 = graded_free_module(Rg, [2,2,4,3,3,5]) @@ -389,7 +388,7 @@ end W = [x*M[1], y*M[2]]; a = hom(M, M, W); @test degree(a) == Z[1] - @test iswelldefined(a) + @test is_welldefined(a) m = homomorphism_to_element(H, a) @test m == y*H[2] end @@ -535,9 +534,8 @@ end @testset "Resolution and Betti tables 2" begin K = GF(31991) - R, _ = polynomial_ring(K, ["x", "y", "z", "u", "v"]) - Z = abelian_group(0) - Rg, (x,y,z,u,v) = grade(R, [Z[1],Z[1],Z[1],Z[1],Z[1]]) + Rg, (x,y,z,u,v) = graded_polynomial_ring(K, ["x", "y", "z", "u", "v"]) + Z = grading_group(Rg) I = ideal([10000*x^3-8565*x^2*y-7937*x*y^2+14060*x^2*z+1416*x*y*z-3771*x*z^2-15712*x^2*u-5990*x*y*u+3271*x*z*u-6141*x*u^2-14457*x^2*v-194*x*y*v-15529*y^2*v+12735*x*z*v+11618*y*z*v+9223*z^2*v+14387*x*u*v+7102*y*u*v+13097*z*u*v+3485*u^2*v+12211*x*v^2-4061*y*v^2+2878*z*v^2-6247*u*v^2-1256*v^3,-10000*x^2*y+8565*x*y^2+7937*y^3-14060*x*y*z-1416*y^2*z+3771*y*z^2+15712*x*y*u+5990*y^2*u-3271*y*z*u+6141*y*u^2-x^2*v+3340*x*y*v-797*y^2*v-7781*x*z*v+14337*y*z*v+7675*z^2*v+9192*x*u*v+1747*y*u*v-13195*z*u*v+9126*u^2*v-5013*x*v^2+15010*y*v^2-6899*z*v^2-6373*u*v^2-6580*v^3,-10000*x^2*z+8565*x*y*z+7937*y^2*z-14060*x*z^2-1416*y*z^2+3771*z^3+15712*x*z*u+5990*y*z*u-3271*z^2*u+6141*z*u^2+12149*x^2*v+669*x*y*v+9621*y^2*v+1543*x*z*v+8614*y*z*v-649*z^2*v-12278*x*u*v+14655*y*u*v+10594*z*u*v+10462*u^2*v-2455*x*v^2-10875*y*v^2-7761*z*v^2-10318*u*v^2-6636*v^3,-10000*x^2*u+8565*x*y*u+7937*y^2*u-14060*x*z*u-1416*y*z*u+3771*z^2*u+15712*x*u^2+5990*y*u^2-3271*z*u^2+6141*u^3-9289*x^2*v+13297*x*y*v+13024*y^2*v-12477*x*z*v+9258*y*z*v+10372*z^2*v-4128*x*u*v-3551*y*u*v+4570*z*u*v+15473*u^2*v+4446*x*v^2-7043*y*v^2-14100*z*v^2+5002*u*v^2+9799*v^3,-9289*x^3+13297*x^2*y+13024*x*y^2-12477*x^2*z+9258*x*y*z+10372*x*z^2+13406*x^2*u-3745*x*y*u-15529*y^2*u-14686*x*z*u+11618*y*z*u+9223*z^2*u-2131*x*u^2+7102*y*u^2+13097*z*u^2+3485*u^3+4446*x^2*v-7043*x*y*v-14100*x*z*v-14778*x*u*v-4061*y*u*v+2878*z*u*v-6247*u^2*v+9799*x*v^2-1256*u*v^2,9289*x^2*y-13297*x*y^2-13024*y^3+12477*x*y*z-9258*y^2*z-10372*y*z^2-x^2*u+7468*x*y*u+2754*y^2*u-7781*x*z*u+9767*y*z*u+7675*z^2*u+9192*x*u^2-13726*y*u^2-13195*z*u^2+9126*u^3-4446*x*y*v+7043*y^2*v+14100*y*z*v-5013*x*u*v+10008*y*u*v-6899*z*u*v-6373*u^2*v-9799*y*v^2-6580*u*v^2,9289*x^2*z-13297*x*y*z-13024*y^2*z+12477*x*z^2-9258*y*z^2-10372*z^3+12149*x^2*u+669*x*y*u+9621*y^2*u+5671*x*z*u+12165*y*z*u-5219*z^2*u-12278*x*u^2+14655*y*u^2-4879*z*u^2+10462*u^3-4446*x*z*v+7043*y*z*v+14100*z^2*v-2455*x*u*v-10875*y*u*v-12763*z*u*v-10318*u^2*v-9799*z*v^2-6636*u*v^2,12149*x^3+669*x^2*y+9621*x*y^2-12914*x^2*z+8420*x*y*z-15529*y^2*z+12086*x*z^2+11618*y*z^2+9223*z^3-12278*x^2*u+14655*x*y*u-7010*x*z*u+7102*y*z*u+13097*z^2*u+10462*x*u^2+3485*z*u^2-2455*x^2*v-10875*x*y*v+4450*x*z*v-4061*y*z*v+2878*z^2*v-10318*x*u*v-6247*z*u*v-6636*x*v^2-1256*z*v^2,-12149*x^2*y-669*x*y^2-9621*y^3-x^2*z+1797*x*y*z-9411*y^2*z-7781*x*z^2+14986*y*z^2+7675*z^3+12278*x*y*u-14655*y^2*u+9192*x*z*u-8847*y*z*u-13195*z^2*u-10462*y*u^2+9126*z*u^2+2455*x*y*v+10875*y^2*v-5013*x*z*v-9220*y*z*v-6899*z^2*v+10318*y*u*v-6373*z*u*v+6636*y*v^2-6580*z*v^2,x^3+11117*x^2*y+991*x*y^2+15529*y^3+7781*x^2*z+4919*x*y*z-11618*y^2*z-7675*x*z^2-9223*y*z^2-9192*x^2*u+15857*x*y*u-7102*y^2*u+13195*x*z*u-13097*y*z*u-9126*x*u^2-3485*y*u^2+5013*x^2*v+4770*x*y*v+4061*y^2*v+6899*x*z*v-2878*y*z*v+6373*x*u*v+6247*y*u*v+6580*x*v^2+1256*y*v^2]) V = gens(I) F = graded_free_module(Rg,1) @@ -743,9 +741,7 @@ end lp = lex(gens(base_ring(F)))*lex(gens(F)) M = SubquoModule(F, [(x^2*y^2*F[1]+y*z^3*F[2]), x*z*F[1]+z^2*F[2]]) @test leading_module(M,lp) == SubquoModule(F, [x*z*F[1], x^2*y^2*F[1], x*y^2*z^2*F[2]]) - R, _ = polynomial_ring(QQ, ["x_"*string(i) for i=1:4]) - Z = abelian_group(0) - Rg, x = grade(R, [Z[1],Z[1],Z[1],Z[1]]) + Rg, x = graded_polynomial_ring(QQ, "x#" => 1:4) F = graded_free_module(Rg, 1) lp = lex(gens(base_ring(F)))*lex(gens(F)) J = SubquoModule(F, [(x[1]+x[2])*F[1], (x[1]+x[2]+2*x[3]+2*x[4])*F[1],(x[1]+x[2]+x[3]+x[4])*F[1]]) @@ -914,9 +910,7 @@ end @testset "Coordinates" begin Z3, a = finite_field(3,1,"a") - R, (x,y) = polynomial_ring(Z3, ["x", "y"]) - Z = abelian_group(0) - Rg, (x, y) = grade(R, [Z[1],Z[1]]) + Rg, (x,y) = graded_polynomial_ring(Z3, ["x", "y"]) coeffs = [Z3(i) for i=0:1] A = Rg[x*y x^2+y^2; y^2 x*y; x^2+y^2 y^2] B = Rg[2*x^2 (x+y)^2; x^2+y^2 x^2+2*x*y] @@ -936,12 +930,10 @@ end @testset "Presentations 3" begin - R, _ = polynomial_ring(QQ, ["x", "y", "z"]); - Z = abelian_group(0); - Rg, (x, y, z) = grade(R, [-Z[1],Z[1],-Z[1]]); - F = graded_free_module(Rg, 1); - B = Rg[x^2; y^3; z^4]; - M,inc = sub(F,B) + Rg, (x, y, z) = graded_polynomial_ring(QQ, ["x", "y", "z"]; weights=[-1,1,-1]) + F = graded_free_module(Rg, 1) + B = Rg[x^2; y^3; z^4] + M, inc = sub(F,B) M = cokernel(inc) fr = free_resolution(M) phi = map(fr,4) @@ -987,8 +979,7 @@ end @test D[2*decoration(R)[1]] == x[2]^2*F[2] g = abelian_group(2,0) - Qx, x = polynomial_ring(QQ, 2) - R, x = grade(Qx, [g[1], g[2]]) + R, x = graded_polynomial_ring(QQ, 2; weights=[g[1], g[2]]) F = FreeMod_dec(R, [g[2], g[1], g[1]-2*g[2]]) @test degree(F[1]) == g[2] @@ -1013,8 +1004,7 @@ end @testset "Tensor product of decorated free modules" begin Z = abelian_group(0) - Qx, x = polynomial_ring(QQ, 3) - R, x = grade(Qx, [Z[1], 5*Z[1], -Z[1]]) + R, x = graded_polynomial_ring(QQ, 3; weights=[Z[1], 5*Z[1], -Z[1]]) F2 = FreeMod_dec(R, [Z[0], Z[1]]) F3 = FreeMod_dec(R, [Z[1], -2*Z[1], Z[0]]) @@ -1066,43 +1056,40 @@ end @test "$(Oscar.minimal_betti_table(I))" == "$(Oscar.minimal_betti_table(sub_F))" # small example due to Janko - R, x = polynomial_ring(QQ, :x => 1:7) - R, x = grade(R) + R, x = graded_polynomial_ring(QQ, :x => 1:7) I = ideal(R, [x[1]*x[2]*x[5], x[1]*x[2]*x[6], x[3]*x[4]*x[6], x[3]*x[4]*x[7], x[5]*x[7]]) A, _ = quo(R, I) @test "$(Oscar.minimal_betti_table(A))" == " 0 1 2 3\n------------------\n0 : 1 - - -\n1 : - 1 - -\n2 : - 4 4 -\n3 : - - 1 -\n4 : - - - 1\n------------------\ntotal: 1 5 5 1\n" # another example due to Wolfram - R, _ = polynomial_ring(QQ, [:x, :y, :z, :w]) - R, (x, y, z, w) = grade(R) + R, (x, y, z, w) = graded_polynomial_ring(QQ, [:x, :y, :z, :w]) I = ideal(R, [w^2 - x*z, w*x - y*z, x^2 - w*y, x*y - z^2, y^2 - w*z]) A, _ = quo(R, I) @test "$(Oscar.minimal_betti_table(free_resolution(A)))" == " 0 1 2 3\n------------------\n0 : 1 - - -\n1 : - 5 5 -\n2 : - - - 1\n------------------\ntotal: 1 5 5 1\n" end @testset "sheaf cohomology" begin - R, x = polynomial_ring(QQ, "x" => 1:4) - S, _ = grade(R) + S, _ = graded_polynomial_ring(QQ, "x" => 1:4) I = ideal(S, gens(S)) FI = free_resolution(I) M = cokernel(map(FI, 2)) - tbl = sheaf_cohomology_bgg(M, -6, 2) + tbl = Oscar._sheaf_cohomology_bgg(M, -6, 2) + lbt = sheaf_cohomology(M, -6, 2, algorithm = :bgg) + @test tbl.values == lbt.values @test tbl[0, -6] == 70 @test tbl[2, 0] == 1 @test iszero(tbl[2, -2]) F = free_module(S, 1) - @test_throws AssertionError sheaf_cohomology_bgg(F, -6, 2) + @test_throws AssertionError Oscar._sheaf_cohomology_bgg(F, -6, 2) - R, x = polynomial_ring(QQ, "x" => 1:4) - S, _ = grade(R, [1,2,3,4]) + S, _ = graded_polynomial_ring(QQ, "x" => 1:4; weights=[1,2,3,4]) F = graded_free_module(S, 1) - @test_throws AssertionError sheaf_cohomology_bgg(F, -6, 2) + @test_throws AssertionError Oscar._sheaf_cohomology_bgg(F, -6, 2) - R, x = polynomial_ring(QQ, "x" => 1:5) - S, _ = grade(R) + S, _ = graded_polynomial_ring(QQ, "x" => 1:5) F = graded_free_module(S, 1) - tbl = sheaf_cohomology_bgg(F, -7, 2) + tbl = sheaf_cohomology(F, -7, 2) a = tbl.values b = transpose(a) * a @test is_symmetric(b) diff --git a/test/PolyhedralGeometry/polyhedron.jl b/test/PolyhedralGeometry/polyhedron.jl index d968984f506b..a360946cab05 100644 --- a/test/PolyhedralGeometry/polyhedron.jl +++ b/test/PolyhedralGeometry/polyhedron.jl @@ -433,7 +433,7 @@ let rnorm = rand_normal_polytope(3, 4, seed = 213) @test rnorm isa Polyhedron{T} - @test isbounded(rnorm) + @test is_bounded(rnorm) @test size(Oscar.pm_object(rnorm).POINTS, 1) == 4 end diff --git a/test/Serialization/IPC.jl b/test/Serialization/IPC.jl index 96beebe75a29..352b52ac1792 100644 --- a/test/Serialization/IPC.jl +++ b/test/Serialization/IPC.jl @@ -29,9 +29,9 @@ end put!(rings, (Qx, F, MR)) end - n = 5 + n = 3 for i in 1:n - put!(jobs, MR([a a^i; F(0) a])) + put!(jobs, MR([a^i F(1); F(0) F(1)])) end for p in workers() # start tasks on the workers to process requests in parallel @@ -46,7 +46,7 @@ end total *= determinant end - @test total == a + @test total == a^6 end diff --git a/test/Serialization/PolynomialsSeries.jl b/test/Serialization/PolynomialsSeries.jl index d689fbf987c6..0ab609957eea 100644 --- a/test/Serialization/PolynomialsSeries.jl +++ b/test/Serialization/PolynomialsSeries.jl @@ -38,7 +38,7 @@ cases = [ @testset "Empty Ideal" begin i = Oscar.ideal(QQ[:x, :y][1], []) test_save_load_roundtrip(path, i) do loaded - loaded == i + @test loaded == i end end diff --git a/test/Serialization/containers.jl b/test/Serialization/containers.jl index 45d80eb59325..9907031c8ccd 100644 --- a/test/Serialization/containers.jl +++ b/test/Serialization/containers.jl @@ -16,6 +16,14 @@ @test nt == loaded end end + + @testset "ids in containers" begin + R, x = QQ[:x] + test_save_load_roundtrip(path, (x^2, x + 1, R)) do loaded + @test loaded[3] == R + @test parent(loaded[1]) == parent(loaded[2]) == loaded[3] + end + end @testset "Vector{LinearProgram}" begin c = cube(3) diff --git a/test/Serialization/session.jl b/test/Serialization/session.jl index f7a2be86b471..142edda0bac6 100644 --- a/test/Serialization/session.jl +++ b/test/Serialization/session.jl @@ -25,7 +25,6 @@ loaded_poly = load(poly_path) loaded_R = load(R_path) - @test loaded_R == parent(loaded_poly) end diff --git a/test/Serialization/setup_tests.jl b/test/Serialization/setup_tests.jl index 558e4401859e..57e17ccdb4bd 100644 --- a/test/Serialization/setup_tests.jl +++ b/test/Serialization/setup_tests.jl @@ -10,11 +10,8 @@ function test_save_load_roundtrip(func, path, original::T; params=nothing) where filename = joinpath(path, "original.json") save(filename, original) loaded = load(filename; params=params) - if T <: Vector - @test loaded isa Vector - else - @test loaded isa T - end + + @test loaded isa T func(loaded) # save and load from an IO buffer @@ -23,11 +20,7 @@ function test_save_load_roundtrip(func, path, original::T; params=nothing) where seekstart(io) loaded = load(io; params=params) - if T <: Vector - @test loaded isa Vector - else - @test loaded isa T - end + @test loaded isa T func(loaded) # save and load from an IO buffer, with prescribed type @@ -35,11 +28,8 @@ function test_save_load_roundtrip(func, path, original::T; params=nothing) where save(io, original) seekstart(io) loaded = load(io; type=T, params=params) - if T <: Vector - @test loaded isa Vector - else - @test loaded isa T - end + + @test loaded isa T func(loaded) # test loading on a empty state diff --git a/test/Serialization/upgrades/file_version<=0.11.2.json b/test/Serialization/upgrades/file_version_less_than_0.11.2.json similarity index 100% rename from test/Serialization/upgrades/file_version<=0.11.2.json rename to test/Serialization/upgrades/file_version_less_than_0.11.2.json diff --git a/test/Serialization/upgrades/file_version<=0.12.0.json b/test/Serialization/upgrades/file_version_less_than_0.12.0.json similarity index 100% rename from test/Serialization/upgrades/file_version<=0.12.0.json rename to test/Serialization/upgrades/file_version_less_than_0.12.0.json diff --git a/test/Serialization/upgrades/file_version<=0.12.1.json b/test/Serialization/upgrades/file_version_less_than_0.12.1.json similarity index 100% rename from test/Serialization/upgrades/file_version<=0.12.1.json rename to test/Serialization/upgrades/file_version_less_than_0.12.1.json diff --git a/test/Serialization/upgrades/polynomial_file_version<=0.12.1.json b/test/Serialization/upgrades/polynomial_file_version_less_than_0.12.1.json similarity index 100% rename from test/Serialization/upgrades/polynomial_file_version<=0.12.1.json rename to test/Serialization/upgrades/polynomial_file_version_less_than_0.12.1.json diff --git a/test/Serialization/upgrades/runtests.jl b/test/Serialization/upgrades/runtests.jl index b90332ec38b6..b9fdbc7a76fe 100644 --- a/test/Serialization/upgrades/runtests.jl +++ b/test/Serialization/upgrades/runtests.jl @@ -3,7 +3,7 @@ L = ones(QQFieldElem, 15) R, x = QQ["x"] p = R(L) - loaded_p = load(joinpath(@__DIR__, "file_version<=0.11.2.json"); params=R); + loaded_p = load(joinpath(@__DIR__, "file_version_less_than_0.11.2.json"); params=R); @test p == loaded_p end @@ -12,7 +12,7 @@ Fin, d = finite_field(t^2 + t + 1) Rx, x = Fin["x"] p = x^2 + d * x + 1 - loaded_p = load(joinpath(@__DIR__, "file_version<=0.12.0.json"); params=Rx); + loaded_p = load(joinpath(@__DIR__, "file_version_less_than_0.12.0.json"); params=Rx); @test p == loaded_p end end diff --git a/test/TropicalGeometry/groebner_fan.jl b/test/TropicalGeometry/groebner_fan.jl index d12429ac2047..9fb4c32a9efa 100644 --- a/test/TropicalGeometry/groebner_fan.jl +++ b/test/TropicalGeometry/groebner_fan.jl @@ -9,8 +9,8 @@ Sigma = groebner_fan(I) @test isequal(f_vector(Sigma),[19,70,92,40]) - @test issimplicial(Sigma) - @test !issmooth(Sigma) + @test is_simplicial(Sigma) + @test !is_smooth(Sigma) end @testset "nonregular Groebner fan" begin @@ -20,6 +20,6 @@ a*d^4 + a*c]) Sigma = groebner_fan(I) @test isequal(f_vector(Sigma),[63,206,225,81]) - @test !issimplicial(Sigma) + @test !is_simplicial(Sigma) end end