diff --git a/src/Rings/mpoly-ideals.jl b/src/Rings/mpoly-ideals.jl index 2ac686fad00..44148c4bfb2 100644 --- a/src/Rings/mpoly-ideals.jl +++ b/src/Rings/mpoly-ideals.jl @@ -1068,6 +1068,12 @@ julia> L = minimal_primes(I) function minimal_primes(I::MPolyIdeal; algorithm::Symbol = :GTZ, cache::Bool=true) has_attribute(I, :minimal_primes) && return get_attribute(I, :minimal_primes)::Vector{typeof(I)} R = base_ring(I) + if coefficient_ring(R) isa QQField && is_zero(dim(I)) + L = Singular.LibAssprimeszerodim.assPrimes(singular_generators(I)) + result = typeof(I)[ideal(R, q) for q in L] + cache && set_attribute!(I, :minimal_primes=>result) + return result + end if isa(base_ring(R), NumField) && !isa(base_ring(R), AbsSimpleNumField) A, mA = absolute_simple_field(base_ring(R)) mp = minimal_primes(map_coefficients(pseudo_inv(mA), I); algorithm = algorithm) @@ -1133,18 +1139,34 @@ function minimal_primes( # This will in many cases lead to an easy simplification of the problem if factor_generators - J = typeof(I)[ideal(R, elem_type(R)[])] + J = [ideal(R, gens(I))] # A copy of I as initialization for g in gens(I) K = typeof(I)[] is_zero(g) && continue for (b, k) in factor(g) + # Split the already collected components with b for j in J push!(K, j + ideal(R, b)) end end J = K end - result = unique!(filter!(!is_one, vcat([minimal_primes(j; algorithm, factor_generators=false) for j in J]...))) + + unique_comp = typeof(I)[] + for q in J + is_one(q) && continue + q in unique_comp && continue + push!(unique_comp, q) + end + J = unique_comp + result = typeof(I)[] + # `unique!` does not work for lists of ideals. I don't know why, but for the moment we need the + # following workaround. + for p in filter!(!is_one, vcat([minimal_primes(j; algorithm, factor_generators=false) for j in J]...)) + p in result && continue + push!(result, p) + end + # The list might not consist of minimal primes only. We have to discard the embedded ones final_list = typeof(I)[] for p in result @@ -2033,7 +2055,8 @@ function small_generating_set( computed_gb = IdealGens(ring, sing_gb, true) if !haskey(I.gb,computed_gb.ord) # if not yet present, store gb for later use - I.gb[computed_gb.ord] = computed_gb + I.gb[computed_gb.ord] = computed_gb + I.gb[computed_gb.ord].isGB = true end # we do not have a notion of minimal generating set in this context! @@ -2242,3 +2265,4 @@ function flag_pluecker_ideal(ring::MPolyRing{<: FieldElem}, dimensions::Vector{I isReduced=true, isGB=true)) end + diff --git a/test/Rings/mpoly.jl b/test/Rings/mpoly.jl index e37ecce6ca3..060d6f56694 100644 --- a/test/Rings/mpoly.jl +++ b/test/Rings/mpoly.jl @@ -220,6 +220,19 @@ end R, (x, y) = polynomial_ring(QQ, ["x", "y"]) I = ideal(R, [one(R)]) @test is_prime(I) == false + + J = ideal(R, [x*(x-1), y*(y-1), x*y]) + l = minimal_primes(J) + @test length(l) == 3 + + QQt, t = QQ[:t] + kk, a = extension_field(t^2 + 1) + + R, (x, y) = kk[:x, :y] + J = ideal(R, [x^2 + 1, y^2 + 1, (x - a)*(y - a)]) + l = minimal_primes(J) + @test length(l) == 3 + end @testset "Groebner" begin @@ -580,4 +593,3 @@ end I = ideal(P, elem_type(P)[]) @test !radical_membership(x, I) end -