@@ -584,16 +584,32 @@ end
584584function groebner_basis_buchberger (
585585 g:: Vector{FreeAssociativeAlgebraElem{T}} ,
586586 reduction_bound:: Int = typemax (Int),
587- remove_redundancies:: Bool = false
587+ remove_redundancies:: Bool = false ;
588+ obstruction_free_set:: Vector{FreeAssociativeAlgebraElem{T}} = FreeAssociativeAlgebraElem{T}[]
588589) where T<: FieldElement
589- g = copy (g)
590+
591+ if isempty (obstruction_free_set)
592+ g = copy (g)
593+ obstruction_queue = get_obstructions (g)
594+ else
595+ temp_g = copy (obstruction_free_set)
596+ obstruction_queue = PriorityQueue {Obstruction{T},FreeAssociativeAlgebraElem{T}} ()
597+ sizehint! (temp_g, length (g)+ length (obstruction_free_set))
598+
599+ for p in g
600+ push! (temp_g,p)
601+ add_obstructions! (obstruction_queue,temp_g)
602+ end
603+ g = temp_g
604+ end
605+
590606 # interreduce!(g) # on some small examples, this increases running time, so it might not be optimal to use this here
591607 nonzero_reductions = 0
592608 # compute the aho corasick automaton
593609 # to make normal form computation more efficient
594610 aut = AhoCorasickAutomaton ([g_i. exps[1 ] for g_i in g])
595611 # step 1 from Thm. 5.2.12 Noncommutative Groebner Bases and Applications, Xingqiang Xiu
596- obstruction_queue = get_obstructions (g)
612+
597613 while ! isempty (obstruction_queue) # step 2
598614 obstruction = popfirst! (obstruction_queue)[1 ]
599615 # step3
@@ -607,6 +623,7 @@ function groebner_basis_buchberger(
607623 push! (g, Sp)
608624 insert_keyword! (aut, Sp. exps[1 ], length (g))
609625 if nonzero_reductions >= reduction_bound
626+ @warn " The computation terminated because it exceeded the limit of $reduction_bound reduction steps."
610627 return g
611628 end
612629 add_obstructions! (obstruction_queue, g)
@@ -618,7 +635,7 @@ function groebner_basis_buchberger(
618635end
619636
620637@doc """
621- groebner_basis(g::Vector{FreeAssociativeAlgebraElem{T}}, reduction_bound::Int = typemax(Int), remove_redundancies::Bool = false)
638+ groebner_basis(g::Vector{FreeAssociativeAlgebraElem{T}}, reduction_bound::Int = typemax(Int), remove_redundancies::Bool = false; obstruction_free_set::Vector{FreeAssociativeAlgebraElem{T}} )
622639
623640Compute a Groebner basis for the ideal generated by `g`. Stop when `reduction_bound` many
624641non-zero entries have been added to the Groebner basis. If the computation stops due to the bound being exceeded,
@@ -627,11 +644,42 @@ respect to this incomplete Groebner basis is `0`, it will also be `0` with respe
627644
628645If `remove_redundancies` is set to true, some redundant obstructions will be removed during the computation, which might save
629646time, however in practice it seems to inflate the running time regularly.
647+
648+ One can provide the keyword argument `obstruction_free_set` with a precomputed partial Groebner basis.
649+ It is assumed (but not checked) that all entries of `obstruction_free_set` are indeed contained in the ideal generated by `g`.
650+
651+ # Example
652+
653+ ```jldoctest
654+ julia> R, (a, b) = free_associative_algebra(QQ, ["a", "b"]);
655+
656+ julia> f1 = a^2 -1;
657+
658+ julia> f2 = b^3 -1;
659+
660+ julia> f3 = a*b*a*b^2*a*b*a - b;
661+
662+ julia> g = AbstractAlgebra.groebner_basis([(a*b*a*b^2)^2 - 1]; obstruction_free_set = [f1,f2,f3])
663+ 12-element Vector{AbstractAlgebra.Generic.FreeAssociativeAlgebraElem{Rational{BigInt}}}:
664+ a^2 - 1
665+ b^3 - 1
666+ a*b*a*b^2*a*b*a - b
667+ a*b*a*b^2*a*b*a*b^2 - 1
668+ -b*a*b^2*a*b*a*b^2 + a
669+ -b*a*b^2*a*b*a + a*b
670+ -b*a*b^2*a*b + a*b*a
671+ -a*b^2*a*b + b^2*a*b*a
672+ b^2*a*b*a*b^2 - a*b^2*a
673+ -a*b*a*b^2 + b*a*b^2*a
674+ b^2*a*b*a*b*a*b - a*b*a*b*a
675+ -a*b*a*b*a*b + b*a*b*a*b*a
676+ ```
630677"""
631678function groebner_basis (
632679 g:: Vector{FreeAssociativeAlgebraElem{T}} ,
633680 reduction_bound:: Int = typemax (Int),
634- remove_redundancies:: Bool = false
681+ remove_redundancies:: Bool = false ;
682+ obstruction_free_set:: Vector{FreeAssociativeAlgebraElem{T}} = FreeAssociativeAlgebraElem{T}[]
635683) where T<: FieldElement
636- return groebner_basis_buchberger (g, reduction_bound, remove_redundancies)
684+ return groebner_basis_buchberger (g, reduction_bound, remove_redundancies; obstruction_free_set = obstruction_free_set )
637685end
0 commit comments