001/*
002 * $Id: ComprehensiveGroebnerBaseSeq.java 5414 2016-01-24 20:11:42Z kredel $
003 */
004
005package edu.jas.application;
006
007
008import java.util.ArrayList;
009import java.util.Collections;
010import java.util.List;
011
012import org.apache.log4j.Logger;
013
014import edu.jas.gb.GroebnerBase;
015import edu.jas.gb.SolvableGroebnerBase;
016import edu.jas.gbufd.GBFactory;
017import edu.jas.gbufd.SGBFactory;
018import edu.jas.poly.ExpVector;
019import edu.jas.poly.GenPolynomial;
020import edu.jas.poly.GenPolynomialRing;
021import edu.jas.poly.GenSolvablePolynomial;
022import edu.jas.poly.GenSolvablePolynomialRing;
023import edu.jas.poly.PolynomialList;
024import edu.jas.structure.GcdRingElem;
025import edu.jas.structure.RingFactory;
026import edu.jas.ufd.SquarefreeAbstract;
027import edu.jas.ufd.SquarefreeFactory;
028
029
030/**
031 * Comprehensive Groebner Base sequential algorithm. Implements faithful
032 * comprehensive Groebner bases via Groebner systems and CGB test.
033 * @param <C> coefficient type
034 * @author Heinz Kredel
035 */
036
037public class ComprehensiveGroebnerBaseSeq<C extends GcdRingElem<C>>
038/* extends GroebnerBaseAbstract<GenPolynomial<C>> */{
039
040
041    private static final Logger logger = Logger.getLogger(ComprehensiveGroebnerBaseSeq.class);
042
043
044    private static final boolean debug = logger.isDebugEnabled();
045
046
047    /**
048     * Squarefree for coefficient content and primitive parts.
049     */
050    protected final SquarefreeAbstract<C> engine;
051
052
053    /*
054     * Flag if gcd engine should be used.
055     */
056    //private final boolean notFaithfull = false;
057
058
059    /**
060     * Comprehensive reduction engine.
061     */
062    protected final CReductionSeq<C> cred;
063
064
065    /**
066     * Polynomial coefficient ring factory.
067     */
068    protected final RingFactory<C> cofac;
069
070
071    /**
072     * Constructor.
073     * @param rf base coefficient ring factory.
074     */
075    public ComprehensiveGroebnerBaseSeq(RingFactory<C> rf) {
076        this(new CReductionSeq<C>(rf), rf);
077    }
078
079
080    /**
081     * Constructor.
082     * @param red C-pseudo-Reduction engine
083     * @param rf base coefficient ring factory.
084     */
085    @SuppressWarnings("unchecked")
086    public ComprehensiveGroebnerBaseSeq(CReductionSeq<C> red, RingFactory<C> rf) {
087        // super(null); // red not possible since type of type
088        cred = red;
089        cofac = rf;
090        // selection for C but used for R:
091        //engine e = GCDFactory.<C> getImplementation(cofac);
092        engine = SquarefreeFactory.<C> getImplementation(rf);
093    }
094
095
096    /**
097     * Comprehensive-Groebner base test.
098     * @param F polynomial list.
099     * @return true, if F is a Comprehensive-Groebner base, else false.
100     */
101    // @Override
102    public boolean isGB(List<GenPolynomial<GenPolynomial<C>>> F) {
103        return isGB(0, F);
104    }
105
106
107    /**
108     * Comprehensive-Groebner base test.
109     * @param modv module variable number.
110     * @param F polynomial list.
111     * @return true, if F is a Comprehensive-Groebner base, else false.
112     */
113    // @Override
114    public boolean isGB(int modv, List<GenPolynomial<GenPolynomial<C>>> F) {
115        // return isGBcol( modv, F );
116        return isGBsubst(modv, F);
117    }
118
119
120    /**
121     * Comprehensive-Groebner base test using colored systems.
122     * @param F polynomial list.
123     * @return true, if F is a Comprehensive-Groebner base, else false.
124     */
125    // @Override
126    public boolean isGBcol(List<GenPolynomial<GenPolynomial<C>>> F) {
127        return isGBcol(0, F);
128    }
129
130
131    /**
132     * Comprehensive-Groebner base test using colored systems.
133     * @param modv module variable number.
134     * @param F polynomial list.
135     * @return true, if F is a Comprehensive-Groebner base, else false.
136     */
137    // @Override
138    public boolean isGBcol(int modv, List<GenPolynomial<GenPolynomial<C>>> F) {
139        if (F == null || F.size() == 0) {
140            return true;
141        }
142        List<ColoredSystem<C>> CS = cred.determine(F);
143        return isGBsys(modv, CS);
144    }
145
146
147    /**
148     * Comprehensive-Groebner system test.
149     * @param CS list of colored systems.
150     * @return true, if CS is a Comprehensive-Groebner system, else false.
151     */
152    // @Override
153    public boolean isGBsys(List<ColoredSystem<C>> CS) {
154        return isGBsys(0, CS);
155    }
156
157
158    /**
159     * Comprehensive-Groebner system test.
160     * @param modv module variable number, unused.
161     * @param CS list of colored systems.
162     * @return true, if CS is a Comprehensive-Groebner system, else false.
163     */
164    // @Override
165    public boolean isGBsys(int modv, List<ColoredSystem<C>> CS) {
166        if (CS == null || CS.size() == 0) {
167            return true;
168        }
169        if (modv != 0) {
170            throw new IllegalArgumentException("modv !0 not supported.");
171        }
172        ColorPolynomial<C> p, q, h, hp;
173        for (ColoredSystem<C> cs : CS) {
174            if (debug) {
175                if (!cs.isDetermined()) {
176                    System.out.println("not determined, cs = " + cs);
177                    return false;
178                }
179                if (!cs.checkInvariant()) {
180                    System.out.println("not invariant, cs = " + cs);
181                    return false;
182                }
183            }
184            Condition<C> cond = cs.condition;
185            List<ColorPolynomial<C>> S = cs.list;
186            int k = S.size();
187            for (int j = 0; j < k; j++) {
188                p = S.get(j);
189                for (int l = j + 1; l < k; l++) {
190                    q = S.get(l);
191                    h = cred.SPolynomial(p, q);
192                    // System.out.println("spol(a,b) = " + h);
193                    h = cred.normalform(cond, S, h);
194                    // System.out.println("NF(spol(a,b)) = " + h);
195                    if (debug) {
196                        if (!cred.isNormalform(S, h)) {
197                            System.out.println("not normalform, h = " + h);
198                            System.out.println("cs = " + cs);
199                            return false;
200                        }
201                    }
202                    if (!h.isZERO()) {
203                        hp = cond.reDetermine(h);
204                        if (!hp.isZERO()) {
205                            System.out.println("p = " + p);
206                            System.out.println("q = " + q);
207                            System.out.println("not zero:   NF(spol(p,q))  = " + h);
208                            System.out.println("redetermine(NF(spol(p,q))) = " + hp);
209                            System.out.println("cs = " + cs);
210                            return false;
211                        }
212                    }
213                }
214            }
215        }
216        return true;
217    }
218
219
220    /**
221     * Comprehensive-Groebner base test using substitution.
222     * @param F polynomial list.
223     * @return true, if F is a Comprehensive-Groebner base, else false.
224     */
225    // @Override
226    public boolean isGBsubst(List<GenPolynomial<GenPolynomial<C>>> F) {
227        return isGBsubst(0, F);
228    }
229
230
231    /**
232     * Comprehensive-Groebner base test using substitution.
233     * @param modv module variable number, unused.
234     * @param F polynomial list.
235     * @return true, if F is a Comprehensive-Groebner base, else false.
236     */
237    // @Override
238    public boolean isGBsubst(int modv, List<GenPolynomial<GenPolynomial<C>>> F) {
239        if (F == null || F.isEmpty()) {
240            return true;
241        }
242        if (modv != 0) {
243            throw new IllegalArgumentException("modv !0 not supported.");
244        }
245        GenPolynomial<GenPolynomial<C>> f = F.get(0); // assert non Zero
246        GenPolynomialRing<GenPolynomial<C>> cf = f.ring;
247
248        List<ColoredSystem<C>> CS = cred.determine(F);
249        if (logger.isDebugEnabled()) {
250            logger.info("determined polynomials =\n" + CS);
251        }
252        // substitute zero conditions into parameter coefficients and test
253        for (ColoredSystem<C> cs : CS) {
254            Ideal<C> id = cs.condition.zero;
255            ResidueRing<C> r = new ResidueRing<C>(id);
256            //GroebnerBase<Residue<C>> bb = new GroebnerBasePseudoSeq<Residue<C>>(r);
257            List<GenPolynomial<Residue<C>>> list;
258            boolean t;
259            if (cf instanceof GenSolvablePolynomialRing) {
260                GenSolvablePolynomialRing<Residue<C>> rf = new GenSolvablePolynomialRing<Residue<C>>(r, cf);
261                List<GenSolvablePolynomial<GenPolynomial<C>>> rel = ((GenSolvablePolynomialRing<GenPolynomial<C>>) cf).table
262                                .relationList();
263                List<GenPolynomial<Residue<C>>> relres = PolyUtilApp.<C> toResidue(rf,
264                                PolynomialList.<GenPolynomial<C>> castToList(rel));
265                rf.addRelations(relres);
266                //System.out.println("rf = " + rf.toScript());
267                list = PolyUtilApp.<C> toResidue(rf, F);
268                SolvableGroebnerBase<Residue<C>> bb = SGBFactory.getImplementation(r);
269                t = bb.isLeftGB(PolynomialList.<Residue<C>> castToSolvableList(list));
270            } else {
271                GenPolynomialRing<Residue<C>> rf = new GenPolynomialRing<Residue<C>>(r, cf);
272                //System.out.println("rf = " + rf.toScript());
273                list = PolyUtilApp.<C> toResidue(rf, F);
274                GroebnerBase<Residue<C>> bb = GBFactory.getImplementation(r);
275                t = bb.isGB(list);
276            }
277            if (!t) {
278                System.out.println("test condition = " + cs.condition);
279                System.out.println("test ideal     = " + id.toScript());
280                System.out.println("test F         = " + F);
281                System.out.println("no GB for residue coefficients = " + list);
282                return false;
283            }
284        }
285
286        // substitute random ideal into parameter coefficients and test
287        GenPolynomialRing<C> ccf = (GenPolynomialRing<C>) cf.coFac;
288        int nv = ccf.nvar - 2;
289        if (nv < 1) {
290            nv = 1;
291        }
292        List<GenPolynomial<C>> il = new ArrayList<GenPolynomial<C>>();
293        int i = 0;
294        //int j = 1;
295        while (i < nv) {
296            //j++;
297            GenPolynomial<C> p = ccf.random(3, 3, 3, 0.3f); //j + 1);
298            // System.out.println("p = " + p);
299            if (p.isConstant()) {
300                continue;
301            }
302            if (p.isZERO()) {
303                continue;
304            }
305            p = engine.squarefreePart(p);
306            il.add(p);
307            i++;
308        }
309        logger.info("random ideal = " + il);
310        Ideal<C> id = new Ideal<C>(ccf, il);
311        ResidueRing<C> r = new ResidueRing<C>(id);
312        //GroebnerBase<Residue<C>> bb = new GroebnerBasePseudoSeq<Residue<C>>(r);
313        List<GenPolynomial<Residue<C>>> list;
314        boolean t;
315        if (cf instanceof GenSolvablePolynomialRing) {
316            GenSolvablePolynomialRing<Residue<C>> rf = new GenSolvablePolynomialRing<Residue<C>>(r, cf);
317            List<GenSolvablePolynomial<GenPolynomial<C>>> rel = ((GenSolvablePolynomialRing<GenPolynomial<C>>) cf).table
318                            .relationList();
319            List<GenPolynomial<Residue<C>>> relres = PolyUtilApp.<C> toResidue(rf,
320                            PolynomialList.<GenPolynomial<C>> castToList(rel));
321            rf.addRelations(relres);
322            //System.out.println("rf = " + rf.toScript());
323            list = PolyUtilApp.<C> toResidue(rf, F);
324            SolvableGroebnerBase<Residue<C>> bb = SGBFactory.getImplementation(r);
325            t = bb.isLeftGB(PolynomialList.<Residue<C>> castToSolvableList(list));
326        } else {
327            GenPolynomialRing<Residue<C>> rf = new GenPolynomialRing<Residue<C>>(r, cf);
328            //System.out.println("rf = " + rf.toScript());
329            list = PolyUtilApp.<C> toResidue(rf, F);
330            GroebnerBase<Residue<C>> bb = GBFactory.getImplementation(r);
331            t = bb.isGB(list);
332        }
333        if (!t) {
334            System.out.println("test random ideal = " + id.toScript());
335            System.out.println("no GB for residue coefficients = " + list);
336            return false;
337        }
338        return true;
339    }
340
341
342    /**
343     * Comprehensive-Groebner system test.
344     * @param F Groebner system.
345     * @return true, if F is a Comprehensive-Groebner system, else false.
346     */
347    // @Override
348    public boolean isGBsys(GroebnerSystem<C> F) {
349        return isGBsys(0, F.list);
350    }
351
352
353    /**
354     * Comprehensive-Groebner base test.
355     * @param F Groebner system.
356     * @return true, if F is a Comprehensive-Groebner base, else false.
357     */
358    // @Override
359    public boolean isCGB(GroebnerSystem<C> F) {
360        return isGB(F.getCGB());
361    }
362
363
364    /**
365     * Comprehensive-Groebner system and base test.
366     * @param F Groebner system.
367     * @return true, if F is a Comprehensive-Groebner system and base, else
368     *         false.
369     */
370    // @Override
371    public boolean isGB(GroebnerSystem<C> F) {
372        return isGBsys(0, F.list) && isGB(F.getCGB());
373    }
374
375
376    /**
377     * Comprehensive Groebner base system using pairlist class.
378     * @param F polynomial list.
379     * @return GBsys(F) a Comprehensive Groebner system of F.
380     */
381    // @Override
382    // @SuppressWarnings("unchecked")
383    public GroebnerSystem<C> GBsys(List<GenPolynomial<GenPolynomial<C>>> F) {
384        if (F == null) {
385            return null;
386        }
387        List<ColoredSystem<C>> CSp = new ArrayList<ColoredSystem<C>>();
388        if (F.size() == 0) {
389            return new GroebnerSystem<C>(CSp);
390        }
391        // extract coefficient factory
392        GenPolynomial<GenPolynomial<C>> f = F.get(0);
393        GenPolynomialRing<GenPolynomial<C>> fac = f.ring;
394        // determine polynomials
395        List<ColoredSystem<C>> CS = cred.determine(F);
396        // System.out.println("CS = " + CS);
397        // CS.remove(0); // empty colored system
398        if (logger.isInfoEnabled()) {
399            logger.info("determined polynomials =\n" + CS);
400        }
401
402        // setup pair lists
403        List<ColoredSystem<C>> CSs = new ArrayList<ColoredSystem<C>>();
404        ColoredSystem<C> css;
405        for (ColoredSystem<C> cs : CS) {
406            OrderedCPairlist<C> pairlist = new OrderedCPairlist<C>(fac);
407            for (ColorPolynomial<C> p : cs.list) {
408                // System.out.println("p = " + p);
409                pairlist.put(p);
410            }
411            css = new ColoredSystem<C>(cs.condition, cs.list, pairlist);
412            CSs.add(css);
413        }
414
415        // main loop
416        List<ColoredSystem<C>> CSb = new ArrayList<ColoredSystem<C>>();
417        List<ColoredSystem<C>> ncs;
418        List<ColoredSystem<C>> CSh; //, CSbh;
419        ColoredSystem<C> cs;
420        List<ColorPolynomial<C>> G;
421        OrderedCPairlist<C> pairlist;
422        Condition<C> cond;
423        int si = 0;
424        while (CSs.size() > 0) {
425            cs = CSs.get(0); // remove(0);
426            si++;
427            logger.info("poped GBsys number    " + si + " with condition = " + cs.condition);
428            logger.info("poped GBsys (remaining " + (CSs.size() - 1) + ") with pairlist  = " + cs.pairlist);
429            if (!cs.isDetermined()) {
430                cs = cs.reDetermine();
431            }
432            pairlist = cs.pairlist;
433            G = cs.list;
434            cond = cs.condition;
435            // logger.info( pairlist.toString() );
436
437            CPair<C> pair;
438            ColorPolynomial<C> pi;
439            ColorPolynomial<C> pj;
440            ColorPolynomial<C> S;
441            // GenPolynomial<GenPolynomial<C>> H;
442            ColorPolynomial<C> H;
443            while (pairlist.hasNext()) {
444                pair = pairlist.removeNext();
445                if (pair == null)
446                    continue;
447
448                pi = pair.pi;
449                pj = pair.pj;
450                if (debug) {
451                    logger.info("pi    = " + pi);
452                    logger.info("pj    = " + pj);
453                }
454
455                S = cred.SPolynomial(pi, pj);
456                if (S.isZERO()) {
457                    pair.setZero();
458                    continue;
459                }
460                if (debug) {
461                    // logger.info("ht(S) = " + S.leadingExpVector() );
462                    logger.info("S = " + S);
463                }
464
465                H = cred.normalform(cond, G, S);
466                if (H.isZERO()) {
467                    pair.setZero();
468                    continue;
469                }
470                if (debug) {
471                    logger.info("ht(H) = " + H.leadingExpVector());
472                }
473
474                H = H.abs();
475                if (debug) {
476                    logger.debug("H = " + H);
477                }
478                logger.info("H = " + H);
479                if (!H.isZERO()) {
480                    //CSh = new ArrayList<ColoredSystem<C>>();
481                    ncs = determineAddPairs(cs, H);
482                    if (ncs.size() == 0) {
483                        continue;
484                    }
485                    cs = ncs.remove(0); // remove other?
486                    pairlist = cs.pairlist;
487                    G = cs.list;
488                    cond = cs.condition;
489                    logger.info("replaced main branch = " + cond);
490                    logger.info("#new systems       = " + ncs.size());
491                    int yi = CSs.size();
492                    for (ColoredSystem<C> x : ncs) {
493                        if (!x.isDetermined()) {
494                            x = x.reDetermine();
495                        }
496                        CSs = x.addToList(CSs);
497                    }
498                    logger.info("#new systems added = " + (CSs.size() - yi));
499                }
500            }
501            // all s-pols reduce to zero in this branch
502            if (!cs.isDetermined()) {
503                cs = cs.reDetermine();
504            }
505            CSb.add(cs);
506            CSs.remove(0);
507            logger.info("done with = " + cs.condition);
508        }
509        // all branches done
510        CSh = new ArrayList<ColoredSystem<C>>();
511        for (ColoredSystem<C> x : CSb) {
512            // System.out.println("G = " + x.list );
513            if (!x.isDetermined()) {
514                x = x.reDetermine();
515            }
516            cs = minimalGB(x);
517            // System.out.println("min(G) = " + cs.list );
518            if (!cs.isDetermined()) {
519                cs = cs.reDetermine();
520            }
521            // cs = new ColoredSystem<C>( x.condition, G, x.pairlist );
522            CSh.add(cs);
523            logger.info("#sequential done = " + x.condition);
524            logger.info(x.pairlist.toString());
525        }
526        CSb = new ArrayList<ColoredSystem<C>>(CSh);
527        return new GroebnerSystem<C>(CSb);
528    }
529
530
531    /**
532     * Determine polynomial relative to a condition of a colored system and add
533     * pairs.
534     * @param cs a colored system.
535     * @param A color polynomial.
536     * @return list of colored systems, the conditions extending the condition
537     *         of cs.
538     */
539    public List<ColoredSystem<C>> determineAddPairs(ColoredSystem<C> cs, ColorPolynomial<C> A) {
540        List<ColoredSystem<C>> NCS = new ArrayList<ColoredSystem<C>>();
541        if (A == null || A.isZERO()) {
542            // NCS.add( cs );
543            return NCS;
544        }
545        List<ColorPolynomial<C>> S = cs.list;
546        Condition<C> cond = cs.condition; // .clone(); done in Condition
547        // itself
548        OrderedCPairlist<C> pl = cs.pairlist;
549
550        List<ColorPolynomial<C>> Sp;
551        ColorPolynomial<C> nz;
552        ColoredSystem<C> NS;
553        // if ( A.isDetermined() ) { ... } // dont use this
554        // System.out.println("to determine = " + A);
555        GenPolynomial<GenPolynomial<C>> Ap = A.getPolynomial();
556        List<Condition<C>> cd = cred.caseDistinction(cond, Ap);
557        logger.info("# cases = " + cd.size());
558        for (Condition<C> cnd : cd) {
559            //nz = cnd.determine(Ap);
560            nz = cnd.reDetermine(A);
561            if (nz.isZERO()) {
562                logger.info("zero determined nz = " + nz);
563                Sp = new ArrayList<ColorPolynomial<C>>(S);
564                OrderedCPairlist<C> PL = pl.copy();
565                NS = new ColoredSystem<C>(cnd, Sp, PL);
566                try {
567                    if (!NS.isDetermined()) {
568                        NS = NS.reDetermine();
569                    }
570                } catch (RuntimeException e) {
571                    System.out.println("Contradiction in NS_0 = " + NS);
572                    //e.printStackTrace();
573                    continue;
574                }
575                NCS = NS.addToList(NCS);
576                continue;
577            }
578            if (S.contains(nz)) {
579                System.out.println("*** S.contains(nz) ***");
580                continue;
581            }
582            logger.info("new determined nz = " + nz);
583            Sp = new ArrayList<ColorPolynomial<C>>(S);
584            Sp.add(nz);
585            OrderedCPairlist<C> PL = pl.copy();
586            PL.put(nz);
587            NS = new ColoredSystem<C>(cnd, Sp, PL);
588            try {
589                if (!NS.isDetermined()) {
590                    NS = NS.reDetermine();
591                }
592            } catch (RuntimeException e) {
593                System.out.println("Contradiction in NS = " + NS);
594                //e.printStackTrace();
595                continue;
596            }
597            NCS = NS.addToList(NCS);
598        }
599        // System.out.println("new determination = " + NCS);
600        return NCS;
601    }
602
603
604    /**
605     * Comprehensive Groebner base via Groebner system.
606     * @param F polynomial list.
607     * @return GB(F) a Comprehensive Groebner base of F.
608     */
609    // @Override
610    // @SuppressWarnings("unchecked")
611    public List<GenPolynomial<GenPolynomial<C>>> GB(List<GenPolynomial<GenPolynomial<C>>> F) {
612        if (F == null) {
613            return F;
614        }
615        // compute Groebner system
616        GroebnerSystem<C> gs = GBsys(F);
617        // System.out.println("\n\nGBsys = " + gs);
618        return gs.getCGB();
619    }
620
621
622    /**
623     * Minimal ordered Groebner basis.
624     * @param cs colored system.
625     * @return a reduced Groebner base of Gp.
626     */
627    // @Override
628    public ColoredSystem<C> minimalGB(ColoredSystem<C> cs) {
629        // List<ColorPolynomial<C>> Gp ) {
630        if (cs == null || cs.list == null || cs.list.size() <= 1) {
631            return cs;
632        }
633        // remove zero polynomials
634        List<ColorPolynomial<C>> G = new ArrayList<ColorPolynomial<C>>(cs.list.size());
635        for (ColorPolynomial<C> a : cs.list) {
636            if (a != null && !a.isZERO()) { // always true in GB()
637                // already positive a = a.abs();
638                G.add(a);
639            }
640        }
641        if (G.size() <= 1) {
642            return new ColoredSystem<C>(cs.condition, G, cs.pairlist);
643        }
644        // System.out.println("G check " + G);
645        // remove top reducible polynomials
646        Condition<C> cond = cs.condition;
647        ColorPolynomial<C> a, b;
648        List<ColorPolynomial<C>> F;
649        F = new ArrayList<ColorPolynomial<C>>(G.size());
650        while (G.size() > 0) {
651            a = G.remove(0);
652            b = a;
653            // System.out.println("check " + b);
654            //if (false) {
655            //    if (a.red.leadingBaseCoefficient().isConstant()) { // dont drop
656            //        // these
657            //        F.add(a);
658            //        continue;
659            //    }
660            //}
661            if (cred.isTopReducible(G, a) || cred.isTopReducible(F, a)) {
662                // drop polynomial
663                if (debug) {
664                    // System.out.println("trying to drop " + a);
665                    List<ColorPolynomial<C>> ff;
666                    ff = new ArrayList<ColorPolynomial<C>>(G);
667                    ff.addAll(F);
668                    a = cred.normalform(cond, ff, a);
669                    try {
670                        a = cond.reDetermine(a);
671                    } catch (RuntimeException ignored) {
672                    }
673                    if (!a.isZERO()) {
674                        logger.error("nf(a) != 0 " + b + ", " + a);
675                        F.add(b);
676                    }
677                }
678            } else {
679                F.add(a);
680            }
681        }
682        G = F;
683        if (G.size() <= 1) {
684            return new ColoredSystem<C>(cs.condition, G, cs.pairlist);
685        }
686        Collections.reverse(G); // important for lex GB
687        // reduce remaining polynomials
688        int len = G.size();
689        int i = 0;
690        while (i < len) {
691            a = G.remove(0);
692            b = a;
693            ExpVector e = a.red.leadingExpVector();
694            // System.out.println("reducing " + a);
695            a = cred.normalform(cond, G, a); // unchanged by top reduction
696            // System.out.println("reduced " + a);
697            try {
698                a = cond.reDetermine(a);
699            } catch (RuntimeException ignored) {
700            }
701            ExpVector f = a.red.leadingExpVector();
702            // a = ##engine.basePrimitivePart(a); //a.monic(); was not required
703            // a = a.abs();
704            // a = red.normalform( F, a );
705            if (e.equals(f)) {
706                G.add(a); // adds as last
707            } else { // should not happen
708                if (debug) {
709                    logger.error("nf(a) not determined " + b + ", " + a);
710                }
711                G.add(b); // adds as last
712            }
713            i++;
714        }
715        return new ColoredSystem<C>(cs.condition, G, cs.pairlist);
716    }
717
718}