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