001/*
002 * $Id: SGBFactory.java 5902 2018-08-22 21:25:06Z kredel $
003 */
004
005package edu.jas.gbufd;
006
007
008import org.apache.logging.log4j.Logger;
009import org.apache.logging.log4j.LogManager; 
010
011import edu.jas.arith.BigInteger;
012import edu.jas.arith.BigRational;
013import edu.jas.arith.ModInteger;
014import edu.jas.arith.ModIntegerRing;
015import edu.jas.arith.ModLong;
016import edu.jas.arith.ModLongRing;
017import edu.jas.gb.OrderedMinPairlist;
018import edu.jas.gb.OrderedPairlist;
019import edu.jas.gb.OrderedSyzPairlist;
020import edu.jas.gb.PairList;
021import edu.jas.gb.SGBProxy;
022import edu.jas.gb.SolvableGroebnerBaseAbstract;
023import edu.jas.gb.SolvableGroebnerBaseParallel;
024import edu.jas.gb.SolvableGroebnerBaseSeq;
025import edu.jas.gb.SolvableReductionSeq;
026import edu.jas.kern.ComputerThreads;
027import edu.jas.poly.GenPolynomial;
028import edu.jas.poly.GenPolynomialRing;
029import edu.jas.structure.GcdRingElem;
030import edu.jas.structure.QuotPairFactory;
031import edu.jas.structure.RingFactory;
032import edu.jas.structure.ValueFactory;
033import edu.jas.ufd.Quotient;
034import edu.jas.ufd.QuotientRing;
035
036
037// import edu.jas.application.SolvableResidueRing; // package cycle
038
039
040/**
041 * Solvable Groebner bases algorithms factory. Select appropriate Solvable
042 * Groebner bases engine based on the coefficient types.
043 * @author Heinz Kredel
044 * @usage To create objects that implement the <code>SolvableGroebnerBase</code>
045 *        interface use the <code>SGBFactory</code>. It will select an
046 *        appropriate implementation based on the types of polynomial
047 *        coefficients C. The method to obtain an implementation is
048 *        <code>getImplementation()</code>. It returns an object of a class
049 *        which implements the <code>SolvableGroebnerBase</code> interface, more
050 *        precisely an object of abstract class
051 *        <code>SolvableGroebnerBaseAbstract</code>.
052 * 
053 *        <pre>
054 * 
055 * SolvableGroebnerBase&lt;CT&gt; engine;
056 * engine = SGBFactory.&lt;CT&gt; getImplementation(cofac);
057 * c = engine.GB(A);
058 * </pre>
059 * 
060 *        For example, if the coefficient type is BigInteger, the usage looks
061 *        like
062 * 
063 *        <pre>
064 * 
065 * BigInteger cofac = new BigInteger();
066 * SolvableGroebnerBase&lt;BigInteger&gt; engine;
067 * engine = SGBFactory.getImplementation(cofac);
068 * c = engine.GB(A);
069 * </pre>
070 * 
071 * @see edu.jas.gb.GroebnerBase
072 * @see edu.jas.gb.SolvableGroebnerBase
073 * @see edu.jas.application.GBAlgorithmBuilder
074 */
075
076public class SGBFactory {
077
078
079    private static final Logger logger = LogManager.getLogger(SGBFactory.class);
080
081
082    private static final boolean debug = logger.isDebugEnabled();
083
084
085    /**
086     * Protected factory constructor.
087     */
088    protected SGBFactory() {
089    }
090
091
092    /**
093     * Determine suitable implementation of GB algorithms, no factory case.
094     * @return GB algorithm implementation for field coefficients.
095     */
096    public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<C> getImplementation() {
097        logger.warn("no coefficent factory given, assuming field coeffcients");
098        SolvableGroebnerBaseAbstract<C> bba = new SolvableGroebnerBaseSeq<C>();
099        return bba;
100    }
101
102
103    /**
104     * Determine suitable implementation of GB algorithms, case ModLong.
105     * @param fac ModLongRing.
106     * @return GB algorithm implementation.
107     */
108    public static SolvableGroebnerBaseAbstract<ModLong> getImplementation(ModLongRing fac) {
109        return getImplementation(fac, new OrderedPairlist<ModLong>());
110    }
111
112
113    /**
114     * Determine suitable implementation of GB algorithms, case ModLong.
115     * @param fac ModLongRing.
116     * @param pl pair selection strategy
117     * @return GB algorithm implementation.
118     */
119    public static SolvableGroebnerBaseAbstract<ModLong> getImplementation(ModLongRing fac,
120                    PairList<ModLong> pl) {
121        SolvableGroebnerBaseAbstract<ModLong> bba;
122        if (fac.isField()) {
123            bba = new SolvableGroebnerBaseSeq<ModLong>(pl);
124        } else {
125            bba = new SolvableGroebnerBasePseudoSeq<ModLong>(fac, pl);
126        }
127        return bba;
128    }
129
130
131    /**
132     * Determine suitable implementation of GB algorithms, case ModInteger.
133     * @param fac ModIntegerRing.
134     * @return GB algorithm implementation.
135     */
136    public static SolvableGroebnerBaseAbstract<ModInteger> getImplementation(ModIntegerRing fac) {
137        return getImplementation(fac, new OrderedPairlist<ModInteger>());
138    }
139
140
141    /**
142     * Determine suitable implementation of GB algorithms, case ModInteger.
143     * @param fac ModIntegerRing.
144     * @param pl pair selection strategy
145     * @return GB algorithm implementation.
146     */
147    public static SolvableGroebnerBaseAbstract<ModInteger> getImplementation(ModIntegerRing fac,
148                    PairList<ModInteger> pl) {
149        SolvableGroebnerBaseAbstract<ModInteger> bba;
150        if (fac.isField()) {
151            bba = new SolvableGroebnerBaseSeq<ModInteger>(pl);
152        } else {
153            bba = new SolvableGroebnerBasePseudoSeq<ModInteger>(fac, pl);
154        }
155        return bba;
156    }
157
158
159    /**
160     * Determine suitable implementation of GB algorithms, case BigInteger.
161     * @param fac BigInteger.
162     * @return GB algorithm implementation.
163     */
164    public static SolvableGroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac) {
165        return getImplementation(fac, GBFactory.Algo.igb);
166    }
167
168
169    /**
170     * Determine suitable implementation of GB algorithms, case BigInteger.
171     * @param fac BigInteger.
172     * @param a algorithm, a = igb, egb, dgb.
173     * @return GB algorithm implementation.
174     */
175    public static SolvableGroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac, GBFactory.Algo a) {
176        return getImplementation(fac, a, new OrderedPairlist<BigInteger>());
177    }
178
179
180    /**
181     * Determine suitable implementation of GB algorithms, case BigInteger.
182     * @param fac BigInteger.
183     * @param pl pair selection strategy
184     * @return GB algorithm implementation.
185     */
186    public static SolvableGroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac,
187                    PairList<BigInteger> pl) {
188        return getImplementation(fac, GBFactory.Algo.igb, pl);
189    }
190
191
192    /**
193     * Determine suitable implementation of GB algorithms, case BigInteger.
194     * @param fac BigInteger.
195     * @param a algorithm, a = igb, egb, dgb.
196     * @param pl pair selection strategy
197     * @return GB algorithm implementation.
198     */
199    public static SolvableGroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac,
200                    GBFactory.Algo a, PairList<BigInteger> pl) {
201        SolvableGroebnerBaseAbstract<BigInteger> bba;
202        switch (a) {
203        case igb:
204            bba = new SolvableGroebnerBasePseudoSeq<BigInteger>(fac, pl);
205            break;
206        case egb:
207            throw new UnsupportedOperationException("egb algorithm not available for BigInteger " + a);
208        case dgb:
209            throw new UnsupportedOperationException("dgb algorithm not available for BigInteger " + a);
210        default:
211            throw new IllegalArgumentException("algorithm not available for BigInteger " + a);
212        }
213        return bba;
214    }
215
216
217    /**
218     * Determine suitable implementation of GB algorithms, case BigRational.
219     * @param fac BigRational.
220     * @return GB algorithm implementation.
221     */
222    public static SolvableGroebnerBaseAbstract<BigRational> getImplementation(BigRational fac) {
223        return getImplementation(fac, GBFactory.Algo.qgb);
224    }
225
226
227    /**
228     * Determine suitable implementation of GB algorithms, case BigRational.
229     * @param fac BigRational.
230     * @param a algorithm, a = qgb, ffgb.
231     * @return GB algorithm implementation.
232     */
233    public static SolvableGroebnerBaseAbstract<BigRational> getImplementation(BigRational fac,
234                    GBFactory.Algo a) {
235        return getImplementation(fac, a, new OrderedPairlist<BigRational>());
236    }
237
238
239    /**
240     * Determine suitable implementation of GB algorithms, case BigRational.
241     * @param fac BigRational.
242     * @param pl pair selection strategy
243     * @return GB algorithm implementation.
244     */
245    public static SolvableGroebnerBaseAbstract<BigRational> getImplementation(BigRational fac,
246                    PairList<BigRational> pl) {
247        return getImplementation(fac, GBFactory.Algo.qgb, pl);
248    }
249
250
251    /**
252     * Determine suitable implementation of GB algorithms, case BigRational.
253     * @param fac BigRational.
254     * @param a algorithm, a = qgb, ffgb.
255     * @param pl pair selection strategy
256     * @return GB algorithm implementation.
257     */
258    public static SolvableGroebnerBaseAbstract<BigRational> getImplementation(BigRational fac,
259                    GBFactory.Algo a, PairList<BigRational> pl) {
260        SolvableGroebnerBaseAbstract<BigRational> bba;
261        switch (a) {
262        case qgb:
263            bba = new SolvableGroebnerBaseSeq<BigRational>(pl);
264            break;
265        case ffgb:
266            throw new UnsupportedOperationException("ffgb algorithm not available for BigRational " + a);
267            //PairList<BigInteger> pli;
268            //if (pl instanceof OrderedMinPairlist) {
269            //    pli = new OrderedMinPairlist<BigInteger>();
270            //} else if (pl instanceof OrderedSyzPairlist) {
271            //    pli = new OrderedSyzPairlist<BigInteger>();
272            //} else {
273            //    pli = new OrderedPairlist<BigInteger>();
274            //}
275            //bba = new SolvableGroebnerBaseRational<BigRational>(pli); // pl not possible
276            //break;
277        default:
278            throw new IllegalArgumentException("algorithm not available for " + fac.toScriptFactory()
279                            + ", Algo = " + a);
280        }
281        return bba;
282    }
283
284
285    /**
286     * Determine suitable implementation of GB algorithms, case Quotient
287     * coefficients.
288     * @param fac QuotientRing.
289     * @return GB algorithm implementation.
290     */
291    public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<Quotient<C>> getImplementation(
292                    QuotientRing<C> fac) {
293        return getImplementation(fac, GBFactory.Algo.qgb);
294    }
295
296
297    /**
298     * Determine suitable implementation of GB algorithms, case Quotient
299     * coefficients.
300     * @param fac QuotientRing.
301     * @param a algorithm, a = qgb, ffgb.
302     * @return GB algorithm implementation.
303     */
304    public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<Quotient<C>> getImplementation(
305                    QuotientRing<C> fac, GBFactory.Algo a) {
306        return getImplementation(fac, a, new OrderedPairlist<Quotient<C>>());
307    }
308
309
310    /**
311     * Determine suitable implementation of GB algorithms, case Quotient
312     * coefficients.
313     * @param fac QuotientRing.
314     * @param pl pair selection strategy
315     * @return GB algorithm implementation.
316     */
317    public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<Quotient<C>> getImplementation(
318                    QuotientRing<C> fac, PairList<Quotient<C>> pl) {
319        return getImplementation(fac, GBFactory.Algo.qgb, pl);
320    }
321
322
323    /**
324     * Determine suitable implementation of GB algorithms, case Quotient
325     * coefficients.
326     * @param fac QuotientRing.
327     * @param a algorithm, a = qgb, ffgb.
328     * @param pl pair selection strategy
329     * @return GB algorithm implementation.
330     */
331    public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<Quotient<C>> getImplementation(
332                    QuotientRing<C> fac, GBFactory.Algo a, PairList<Quotient<C>> pl) {
333        SolvableGroebnerBaseAbstract<Quotient<C>> bba;
334        if (logger.isInfoEnabled()) {
335            logger.info("QuotientRing, fac = " + fac);
336        }
337        switch (a) {
338        case qgb:
339            bba = new SolvableGroebnerBaseSeq<Quotient<C>>(new SolvableReductionSeq<Quotient<C>>(), pl);
340            break;
341        case ffgb:
342            throw new UnsupportedOperationException("ffgb algorithm not available for " + a);
343            //PairList<GenPolynomial<C>> pli;
344            //if (pl instanceof OrderedMinPairlist) {
345            //    pli = new OrderedMinPairlist<GenPolynomial<C>>();
346            //} else if (pl instanceof OrderedSyzPairlist) {
347            //    pli = new OrderedSyzPairlist<GenPolynomial<C>>();
348            //} else {
349            //    pli = new OrderedPairlist<GenPolynomial<C>>();
350            //}
351            //bba = new SolvableGroebnerBaseQuotient<C>(fac, pli); // pl not possible
352            //break;
353        default:
354            throw new IllegalArgumentException("algorithm not available for Quotient " + a);
355        }
356        return bba;
357    }
358
359
360    /**
361     * Determine suitable implementation of GB algorithms, case (recursive)
362     * polynomial.
363     * @param fac GenPolynomialRing&lt;C&gt;.
364     * @return GB algorithm implementation.
365     */
366    public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<GenPolynomial<C>> getImplementation(
367                    GenPolynomialRing<C> fac) {
368        return getImplementation(fac, GBFactory.Algo.igb);
369    }
370
371
372    /**
373     * Determine suitable implementation of GB algorithms, case (recursive)
374     * polynomial.
375     * @param fac GenPolynomialRing&lt;C&gt;.
376     * @param a algorithm, a = igb or egb, dgb if fac is univariate over a
377     *            field.
378     * @return GB algorithm implementation.
379     */
380    public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<GenPolynomial<C>> getImplementation(
381                    GenPolynomialRing<C> fac, GBFactory.Algo a) {
382        return getImplementation(fac, a, new OrderedPairlist<GenPolynomial<C>>());
383    }
384
385
386    /**
387     * Determine suitable implementation of GB algorithms, case (recursive)
388     * polynomial.
389     * @param fac GenPolynomialRing&lt;C&gt;.
390     * @param pl pair selection strategy
391     * @return GB algorithm implementation.
392     */
393    public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<GenPolynomial<C>> getImplementation(
394                    GenPolynomialRing<C> fac, PairList<GenPolynomial<C>> pl) {
395        return getImplementation(fac, GBFactory.Algo.igb, pl);
396    }
397
398
399    /**
400     * Determine suitable implementation of GB algorithms, case (recursive)
401     * polynomial.
402     * @param fac GenPolynomialRing&lt;C&gt;.
403     * @param a algorithm, a = igb or egb, dgb if fac is univariate over a
404     *            field.
405     * @param pl pair selection strategy
406     * @return GB algorithm implementation.
407     */
408    public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<GenPolynomial<C>> getImplementation(
409                    GenPolynomialRing<C> fac, GBFactory.Algo a, PairList<GenPolynomial<C>> pl) {
410        SolvableGroebnerBaseAbstract<GenPolynomial<C>> bba;
411        switch (a) {
412        case igb:
413            bba = new SolvableGroebnerBasePseudoRecSeq<C>(fac, pl);
414            break;
415        case egb:
416            throw new UnsupportedOperationException("egb algorithm not available for " + a);
417            //if (fac.nvar > 1 || !fac.coFac.isField()) {
418            //    throw new IllegalArgumentException("coefficients not univariate or not over a field" + fac);
419            //}
420            //bba = new ESolvableGroebnerBaseSeq<GenPolynomial<C>>(); // pl not suitable
421            //break;
422        case dgb:
423            throw new UnsupportedOperationException("dgb algorithm not available for " + a);
424            //if (fac.nvar > 1 || !fac.coFac.isField()) {
425            //    throw new IllegalArgumentException("coefficients not univariate or not over a field" + fac);
426            //}
427            //bba = new DSolvableGroebnerBaseSeq<GenPolynomial<C>>(); // pl not suitable
428            //break;
429        default:
430            throw new IllegalArgumentException("algorithm not available for GenPolynomial<C> " + a);
431        }
432        return bba;
433    }
434
435
436    /*
437     * Determine suitable implementation of GB algorithms, case regular rings.
438     * @param fac RegularRing.
439     * @return GB algorithm implementation.
440    public static <C extends RingElem<C>> SolvableGroebnerBaseAbstract<Product<C>> getImplementation(
441                    ProductRing<C> fac) {
442        SolvableGroebnerBaseAbstract<Product<C>> bba;
443        if (fac.onlyFields()) {
444            bba = new RSolvableGroebnerBaseSeq<Product<C>>();
445        } else {
446            bba = new RSolvableGroebnerBasePseudoSeq<Product<C>>(fac);
447        }
448        return bba;
449    }
450     */
451
452
453    /**
454     * Determine suitable implementation of GB algorithms, other cases.
455     * @param fac RingFactory&lt;C&gt;.
456     * @return GB algorithm implementation.
457     */
458    public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 
459    SolvableGroebnerBaseAbstract<C> getImplementation(RingFactory<C> fac) {
460        return getImplementation(fac, new OrderedPairlist<C>());
461    }
462
463
464    /**
465     * Determine suitable implementation of GB algorithms, other cases.
466     * @param fac RingFactory&lt;C&gt;.
467     * @param pl pair selection strategy
468     * @return GB algorithm implementation.
469     */
470    @SuppressWarnings({ "cast", "unchecked" })
471    public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 
472    SolvableGroebnerBaseAbstract<C> getImplementation(RingFactory<C> fac, PairList<C> pl) {
473        if (debug) {
474           logger.debug("fac = " + fac.getClass().getName()); // + ", fac = " + fac.toScript());
475        }
476        if (fac.isField()) {
477            return new SolvableGroebnerBaseSeq<C>(pl);
478        }
479        if (fac instanceof ValueFactory) {
480            return new SolvableGroebnerBasePseudoSeq<C>(fac, pl);
481        }
482        if (fac instanceof QuotPairFactory) {
483            return new SolvableGroebnerBaseSeq<C>(pl);
484        }
485        SolvableGroebnerBaseAbstract bba = null;
486        Object ofac = fac;
487        if (ofac instanceof GenPolynomialRing) {
488            PairList<GenPolynomial<C>> pli;
489            if (pl instanceof OrderedMinPairlist) {
490                pli = new OrderedMinPairlist<GenPolynomial<C>>();
491            } else if (pl instanceof OrderedSyzPairlist) {
492                pli = new OrderedSyzPairlist<GenPolynomial<C>>();
493            } else {
494                pli = new OrderedPairlist<GenPolynomial<C>>();
495            }
496            GenPolynomialRing<C> rofac = (GenPolynomialRing<C>) ofac;
497            SolvableGroebnerBaseAbstract<GenPolynomial<C>> bbr = new SolvableGroebnerBasePseudoRecSeq<C>(
498                            rofac, pli); // not pl
499            bba = (SolvableGroebnerBaseAbstract) bbr;
500            //} else if (ofac instanceof ProductRing) {
501            //    ProductRing pfac = (ProductRing) ofac;
502            //    if (pfac.onlyFields()) {
503            //        bba = new RSolvableGroebnerBaseSeq<Product<C>>();
504            //    } else {
505            //        bba = new RSolvableGroebnerBasePseudoSeq<Product<C>>(pfac);
506            //    }
507        } else {
508            bba = new SolvableGroebnerBasePseudoSeq<C>(fac, pl);
509        }
510        logger.info("bba = " + bba.getClass().getName());
511        return bba;
512    }
513
514
515    /**
516     * Determine suitable parallel/concurrent implementation of GB algorithms if
517     * possible.
518     * @param fac RingFactory&lt;C&gt;.
519     * @return GB proxy algorithm implementation.
520     */
521    public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 
522    SolvableGroebnerBaseAbstract<C> getProxy(RingFactory<C> fac) {
523        return getProxy(fac, new OrderedPairlist<C>());
524    }
525
526
527    /**
528     * Determine suitable parallel/concurrent implementation of GB algorithms if
529     * possible.
530     * @param fac RingFactory&lt;C&gt;.
531     * @param pl pair selection strategy
532     * @return GB proxy algorithm implementation.
533     */
534    @SuppressWarnings({ "unchecked" })
535    public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 
536    SolvableGroebnerBaseAbstract<C> getProxy(RingFactory<C> fac, PairList<C> pl) {
537        if (ComputerThreads.NO_THREADS) {
538            return SGBFactory.<C> getImplementation(fac, pl);
539        }
540        if (debug) {
541            logger.debug("proxy fac = " + fac.getClass().getName());
542        }
543        int th = (ComputerThreads.N_CPUS > 2 ? ComputerThreads.N_CPUS - 1 : 2);
544        if (fac.isField()) {
545            SolvableGroebnerBaseAbstract<C> e1 = new SolvableGroebnerBaseSeq<C>(pl);
546            SolvableGroebnerBaseAbstract<C> e2 = new SolvableGroebnerBaseParallel<C>(th, pl);
547            return new SGBProxy<C>(e1, e2);
548        } else if (fac.characteristic().signum() == 0) {
549            if (fac instanceof GenPolynomialRing) {
550                GenPolynomialRing pfac = (GenPolynomialRing) fac;
551                OrderedPairlist ppl = new OrderedPairlist<GenPolynomial<C>>();
552                SolvableGroebnerBaseAbstract e1 = new SolvableGroebnerBasePseudoRecSeq<C>(pfac, ppl);
553                logger.warn("no parallel version available, returning sequential version");
554                return e1;
555                //SolvableGroebnerBaseAbstract e2 = new SolvableGroebnerBasePseudoRecParallel<C>(th, pfac, ppl);
556                //return new SGBProxy<C>(e1, e2);
557            }
558            SolvableGroebnerBaseAbstract<C> e1 = new SolvableGroebnerBasePseudoSeq<C>(fac, pl);
559            logger.warn("no parallel version available, returning sequential version");
560            return e1;
561            //SolvableGroebnerBaseAbstract<C> e2 = new SolvableGroebnerBasePseudoParallel<C>(th, fac, pl);
562            //return new SGBProxy<C>(e1, e2);
563        }
564        return getImplementation(fac, pl);
565    }
566
567
568    /**
569     * Determine suitable parallel/concurrent implementation of GB algorithms if
570     * possible.
571     * @param fac RingFactory&lt;C&gt;.
572     * @return GB proxy algorithm implementation.
573     */
574    public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 
575    SolvableGroebnerBaseAbstract<GenPolynomial<C>> getProxy(GenPolynomialRing<C> fac) {
576        if (ComputerThreads.NO_THREADS) {
577            //return SGBFactory.<GenPolynomial<C>> getImplementation(fac);
578            return SGBFactory.getImplementation(fac);
579        }
580        if (debug) {
581            logger.debug("fac = " + fac.getClass().getName());
582        }
583        //int th = (ComputerThreads.N_CPUS > 2 ? ComputerThreads.N_CPUS - 1 : 2);
584        OrderedPairlist<GenPolynomial<C>> ppl = new OrderedPairlist<GenPolynomial<C>>();
585        SolvableGroebnerBaseAbstract<GenPolynomial<C>> e1 = new SolvableGroebnerBasePseudoRecSeq<C>(fac, ppl);
586        logger.warn("no parallel version available, returning sequential version");
587        return e1;
588        //SolvableGroebnerBaseAbstract<GenPolynomial<C>> e2 = new SolvableGroebnerBasePseudoRecParallel<C>(th, fac, ppl);
589        //return new SGBProxy<GenPolynomial<C>>(e1, e2);
590        //return new SGBProxy(e1, e2);
591    }
592
593}