001/*
002 * $Id: ComprehensiveGroebnerBaseSeq.java 5223 2015-04-19 10:02:41Z 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    @SuppressWarnings("unused")
166    public boolean isGBsys(int modv, List<ColoredSystem<C>> CS) {
167        if (CS == null || CS.size() == 0) {
168            return true;
169        }
170        ColorPolynomial<C> p, q, h, hp;
171        for (ColoredSystem<C> cs : CS) {
172            if (debug) {
173                if (!cs.isDetermined()) {
174                    System.out.println("not determined, cs = " + cs);
175                    return false;
176                }
177                if (!cs.checkInvariant()) {
178                    System.out.println("not invariant, cs = " + cs);
179                    return false;
180                }
181            }
182            Condition<C> cond = cs.condition;
183            List<ColorPolynomial<C>> S = cs.list;
184            int k = S.size();
185            for (int j = 0; j < k; j++) {
186                p = S.get(j);
187                for (int l = j + 1; l < k; l++) {
188                    q = S.get(l);
189                    h = cred.SPolynomial(p, q);
190                    // System.out.println("spol(a,b) = " + h);
191                    h = cred.normalform(cond, S, h);
192                    // System.out.println("NF(spol(a,b)) = " + h);
193                    if (debug) {
194                        if (!cred.isNormalform(S, h)) {
195                            System.out.println("not normalform, h = " + h);
196                            System.out.println("cs = " + cs);
197                            return false;
198                        }
199                    }
200                    if (!h.isZERO()) {
201                        hp = cond.reDetermine(h);
202                        if (!hp.isZERO()) {
203                            System.out.println("p = " + p);
204                            System.out.println("q = " + q);
205                            System.out.println("not zero:   NF(spol(p,q))  = " + h);
206                            System.out.println("redetermine(NF(spol(p,q))) = " + hp);
207                            System.out.println("cs = " + cs);
208                            return false;
209                        }
210                    }
211                }
212            }
213        }
214        return true;
215    }
216
217
218    /**
219     * Comprehensive-Groebner base test using substitution.
220     * @param F polynomial list.
221     * @return true, if F is a Comprehensive-Groebner base, else false.
222     */
223    // @Override
224    public boolean isGBsubst(List<GenPolynomial<GenPolynomial<C>>> F) {
225        return isGBsubst(0, F);
226    }
227
228
229    /**
230     * Comprehensive-Groebner base test using substitution.
231     * @param modv module variable number, unused.
232     * @param F polynomial list.
233     * @return true, if F is a Comprehensive-Groebner base, else false.
234     */
235    // @Override
236    public boolean isGBsubst(int modv, List<GenPolynomial<GenPolynomial<C>>> F) {
237        if (F == null || F.isEmpty()) {
238            return true;
239        }
240        GenPolynomial<GenPolynomial<C>> f = F.get(0); // assert non Zero
241        GenPolynomialRing<GenPolynomial<C>> cf = f.ring;
242
243        List<ColoredSystem<C>> CS = cred.determine(F);
244        if (logger.isDebugEnabled()) {
245            logger.info("determined polynomials =\n" + CS);
246        }
247        // substitute zero conditions into parameter coefficients and test
248        for (ColoredSystem<C> cs : CS) {
249            Ideal<C> id = cs.condition.zero;
250            ResidueRing<C> r = new ResidueRing<C>(id);
251            //GroebnerBase<Residue<C>> bb = new GroebnerBasePseudoSeq<Residue<C>>(r);
252            List<GenPolynomial<Residue<C>>> list;
253            boolean t;
254            if (cf instanceof GenSolvablePolynomialRing) {
255                GenSolvablePolynomialRing<Residue<C>> rf = new GenSolvablePolynomialRing<Residue<C>>(r, cf);
256                List<GenSolvablePolynomial<GenPolynomial<C>>> rel = ((GenSolvablePolynomialRing<GenPolynomial<C>>) cf).table
257                                .relationList();
258                List<GenPolynomial<Residue<C>>> relres = PolyUtilApp.<C> toResidue(rf,
259                                PolynomialList.<GenPolynomial<C>> castToList(rel));
260                rf.addRelations(relres);
261                //System.out.println("rf = " + rf.toScript());
262                list = PolyUtilApp.<C> toResidue(rf, F);
263                SolvableGroebnerBase<Residue<C>> bb = SGBFactory.getImplementation(r);
264                t = bb.isLeftGB(PolynomialList.<Residue<C>> castToSolvableList(list));
265            } else {
266                GenPolynomialRing<Residue<C>> rf = new GenPolynomialRing<Residue<C>>(r, cf);
267                //System.out.println("rf = " + rf.toScript());
268                list = PolyUtilApp.<C> toResidue(rf, F);
269                GroebnerBase<Residue<C>> bb = GBFactory.getImplementation(r);
270                t = bb.isGB(list);
271            }
272            if (!t) {
273                System.out.println("test condition = " + cs.condition);
274                System.out.println("test ideal     = " + id.toScript());
275                System.out.println("test F         = " + F);
276                System.out.println("no GB for residue coefficients = " + list);
277                return false;
278            }
279        }
280
281        // substitute random ideal into parameter coefficients and test
282        GenPolynomialRing<C> ccf = (GenPolynomialRing<C>) cf.coFac;
283        int nv = ccf.nvar - 2;
284        if (nv < 1) {
285            nv = 1;
286        }
287        List<GenPolynomial<C>> il = new ArrayList<GenPolynomial<C>>();
288        int i = 0;
289        //int j = 1;
290        while (i < nv) {
291            //j++;
292            GenPolynomial<C> p = ccf.random(3, 3, 3, 0.3f); //j + 1);
293            // System.out.println("p = " + p);
294            if (p.isConstant()) {
295                continue;
296            }
297            if (p.isZERO()) {
298                continue;
299            }
300            p = engine.squarefreePart(p);
301            il.add(p);
302            i++;
303        }
304        logger.info("random ideal = " + il);
305        Ideal<C> id = new Ideal<C>(ccf, il);
306        ResidueRing<C> r = new ResidueRing<C>(id);
307        //GroebnerBase<Residue<C>> bb = new GroebnerBasePseudoSeq<Residue<C>>(r);
308        List<GenPolynomial<Residue<C>>> list;
309        boolean t;
310        if (cf instanceof GenSolvablePolynomialRing) {
311            GenSolvablePolynomialRing<Residue<C>> rf = new GenSolvablePolynomialRing<Residue<C>>(r, cf);
312            List<GenSolvablePolynomial<GenPolynomial<C>>> rel = ((GenSolvablePolynomialRing<GenPolynomial<C>>) cf).table
313                            .relationList();
314            List<GenPolynomial<Residue<C>>> relres = PolyUtilApp.<C> toResidue(rf,
315                            PolynomialList.<GenPolynomial<C>> castToList(rel));
316            rf.addRelations(relres);
317            //System.out.println("rf = " + rf.toScript());
318            list = PolyUtilApp.<C> toResidue(rf, F);
319            SolvableGroebnerBase<Residue<C>> bb = SGBFactory.getImplementation(r);
320            t = bb.isLeftGB(PolynomialList.<Residue<C>> castToSolvableList(list));
321        } else {
322            GenPolynomialRing<Residue<C>> rf = new GenPolynomialRing<Residue<C>>(r, cf);
323            //System.out.println("rf = " + rf.toScript());
324            list = PolyUtilApp.<C> toResidue(rf, F);
325            GroebnerBase<Residue<C>> bb = GBFactory.getImplementation(r);
326            t = bb.isGB(list);
327        }
328        if (!t) {
329            System.out.println("test random ideal = " + id.toScript());
330            System.out.println("no GB for residue coefficients = " + list);
331            return false;
332        }
333        return true;
334    }
335
336
337    /**
338     * Comprehensive-Groebner system test.
339     * @param F Groebner system.
340     * @return true, if F is a Comprehensive-Groebner system, else false.
341     */
342    // @Override
343    public boolean isGBsys(GroebnerSystem<C> F) {
344        return isGBsys(0, F.list);
345    }
346
347
348    /**
349     * Comprehensive-Groebner base test.
350     * @param F Groebner system.
351     * @return true, if F is a Comprehensive-Groebner base, else false.
352     */
353    // @Override
354    public boolean isCGB(GroebnerSystem<C> F) {
355        return isGB(F.getCGB());
356    }
357
358
359    /**
360     * Comprehensive-Groebner system and base test.
361     * @param F Groebner system.
362     * @return true, if F is a Comprehensive-Groebner system and base, else
363     *         false.
364     */
365    // @Override
366    public boolean isGB(GroebnerSystem<C> F) {
367        return isGBsys(0, F.list) && isGB(F.getCGB());
368    }
369
370
371    /**
372     * Comprehensive Groebner base system using pairlist class.
373     * @param F polynomial list.
374     * @return GBsys(F) a Comprehensive Groebner system of F.
375     */
376    // @Override
377    // @SuppressWarnings("unchecked")
378    public GroebnerSystem<C> GBsys(List<GenPolynomial<GenPolynomial<C>>> F) {
379        if (F == null) {
380            return null;
381        }
382        List<ColoredSystem<C>> CSp = new ArrayList<ColoredSystem<C>>();
383        if (F.size() == 0) {
384            return new GroebnerSystem<C>(CSp);
385        }
386        // extract coefficient factory
387        GenPolynomial<GenPolynomial<C>> f = F.get(0);
388        GenPolynomialRing<GenPolynomial<C>> fac = f.ring;
389        // determine polynomials
390        List<ColoredSystem<C>> CS = cred.determine(F);
391        // System.out.println("CS = " + CS);
392        // CS.remove(0); // empty colored system
393        if (logger.isInfoEnabled()) {
394            logger.info("determined polynomials =\n" + CS);
395        }
396
397        // setup pair lists
398        List<ColoredSystem<C>> CSs = new ArrayList<ColoredSystem<C>>();
399        ColoredSystem<C> css;
400        for (ColoredSystem<C> cs : CS) {
401            OrderedCPairlist<C> pairlist = new OrderedCPairlist<C>(fac);
402            for (ColorPolynomial<C> p : cs.list) {
403                // System.out.println("p = " + p);
404                pairlist.put(p);
405            }
406            css = new ColoredSystem<C>(cs.condition, cs.list, pairlist);
407            CSs.add(css);
408        }
409
410        // main loop
411        List<ColoredSystem<C>> CSb = new ArrayList<ColoredSystem<C>>();
412        List<ColoredSystem<C>> ncs;
413        List<ColoredSystem<C>> CSh; //, CSbh;
414        ColoredSystem<C> cs;
415        List<ColorPolynomial<C>> G;
416        OrderedCPairlist<C> pairlist;
417        Condition<C> cond;
418        int si = 0;
419        while (CSs.size() > 0) {
420            cs = CSs.get(0); // remove(0);
421            si++;
422            logger.info("poped GBsys number    " + si + " with condition = " + cs.condition);
423            logger.info("poped GBsys (remaining " + (CSs.size() - 1) + ") with pairlist  = " + cs.pairlist);
424            if (!cs.isDetermined()) {
425                cs = cs.reDetermine();
426            }
427            pairlist = cs.pairlist;
428            G = cs.list;
429            cond = cs.condition;
430            // logger.info( pairlist.toString() );
431
432            CPair<C> pair;
433            ColorPolynomial<C> pi;
434            ColorPolynomial<C> pj;
435            ColorPolynomial<C> S;
436            // GenPolynomial<GenPolynomial<C>> H;
437            ColorPolynomial<C> H;
438            while (pairlist.hasNext()) {
439                pair = pairlist.removeNext();
440                if (pair == null)
441                    continue;
442
443                pi = pair.pi;
444                pj = pair.pj;
445                if (debug) {
446                    logger.info("pi    = " + pi);
447                    logger.info("pj    = " + pj);
448                }
449
450                S = cred.SPolynomial(pi, pj);
451                if (S.isZERO()) {
452                    pair.setZero();
453                    continue;
454                }
455                if (debug) {
456                    // logger.info("ht(S) = " + S.leadingExpVector() );
457                    logger.info("S = " + S);
458                }
459
460                H = cred.normalform(cond, G, S);
461                if (H.isZERO()) {
462                    pair.setZero();
463                    continue;
464                }
465                if (debug) {
466                    logger.info("ht(H) = " + H.leadingExpVector());
467                }
468
469                H = H.abs();
470                if (debug) {
471                    logger.debug("H = " + H);
472                }
473                logger.info("H = " + H);
474                if (!H.isZERO()) {
475                    //CSh = new ArrayList<ColoredSystem<C>>();
476                    ncs = determineAddPairs(cs, H);
477                    if (ncs.size() == 0) {
478                        continue;
479                    }
480                    cs = ncs.remove(0); // remove other?
481                    pairlist = cs.pairlist;
482                    G = cs.list;
483                    cond = cs.condition;
484                    logger.info("replaced main branch = " + cond);
485                    logger.info("#new systems       = " + ncs.size());
486                    int yi = CSs.size();
487                    for (ColoredSystem<C> x : ncs) {
488                        if (!x.isDetermined()) {
489                            x = x.reDetermine();
490                        }
491                        CSs = x.addToList(CSs);
492                    }
493                    logger.info("#new systems added = " + (CSs.size() - yi));
494                }
495            }
496            // all s-pols reduce to zero in this branch
497            if (!cs.isDetermined()) {
498                cs = cs.reDetermine();
499            }
500            CSb.add(cs);
501            CSs.remove(0);
502            logger.info("done with = " + cs.condition);
503        }
504        // all branches done
505        CSh = new ArrayList<ColoredSystem<C>>();
506        for (ColoredSystem<C> x : CSb) {
507            // System.out.println("G = " + x.list );
508            if (!x.isDetermined()) {
509                x = x.reDetermine();
510            }
511            cs = minimalGB(x);
512            // System.out.println("min(G) = " + cs.list );
513            if (!cs.isDetermined()) {
514                cs = cs.reDetermine();
515            }
516            // cs = new ColoredSystem<C>( x.condition, G, x.pairlist );
517            CSh.add(cs);
518            logger.info("#sequential done = " + x.condition);
519            logger.info(x.pairlist.toString());
520        }
521        CSb = new ArrayList<ColoredSystem<C>>(CSh);
522        return new GroebnerSystem<C>(CSb);
523    }
524
525
526    /**
527     * Determine polynomial relative to a condition of a colored system and add
528     * pairs.
529     * @param cs a colored system.
530     * @param A color polynomial.
531     * @return list of colored systems, the conditions extending the condition
532     *         of cs.
533     */
534    public List<ColoredSystem<C>> determineAddPairs(ColoredSystem<C> cs, ColorPolynomial<C> A) {
535        List<ColoredSystem<C>> NCS = new ArrayList<ColoredSystem<C>>();
536        if (A == null || A.isZERO()) {
537            // NCS.add( cs );
538            return NCS;
539        }
540        List<ColorPolynomial<C>> S = cs.list;
541        Condition<C> cond = cs.condition; // .clone(); done in Condition
542        // itself
543        OrderedCPairlist<C> pl = cs.pairlist;
544
545        List<ColorPolynomial<C>> Sp;
546        ColorPolynomial<C> nz;
547        ColoredSystem<C> NS;
548        // if ( A.isDetermined() ) { ... } // dont use this
549        // System.out.println("to determine = " + A);
550        GenPolynomial<GenPolynomial<C>> Ap = A.getPolynomial();
551        List<Condition<C>> cd = cred.caseDistinction(cond, Ap);
552        logger.info("# cases = " + cd.size());
553        for (Condition<C> cnd : cd) {
554            //nz = cnd.determine(Ap);
555            nz = cnd.reDetermine(A);
556            if (nz.isZERO()) {
557                logger.info("zero determined nz = " + nz);
558                Sp = new ArrayList<ColorPolynomial<C>>(S);
559                OrderedCPairlist<C> PL = pl.copy();
560                NS = new ColoredSystem<C>(cnd, Sp, PL);
561                try {
562                    if (!NS.isDetermined()) {
563                        NS = NS.reDetermine();
564                    }
565                } catch (RuntimeException e) {
566                    System.out.println("Contradiction in NS_0 = " + NS);
567                    //e.printStackTrace();
568                    continue;
569                }
570                NCS = NS.addToList(NCS);
571                continue;
572            }
573            if (S.contains(nz)) {
574                System.out.println("*** S.contains(nz) ***");
575                continue;
576            }
577            logger.info("new determined nz = " + nz);
578            Sp = new ArrayList<ColorPolynomial<C>>(S);
579            Sp.add(nz);
580            OrderedCPairlist<C> PL = pl.copy();
581            PL.put(nz);
582            NS = new ColoredSystem<C>(cnd, Sp, PL);
583            try {
584                if (!NS.isDetermined()) {
585                    NS = NS.reDetermine();
586                }
587            } catch (RuntimeException e) {
588                System.out.println("Contradiction in NS = " + NS);
589                //e.printStackTrace();
590                continue;
591            }
592            NCS = NS.addToList(NCS);
593        }
594        // System.out.println("new determination = " + NCS);
595        return NCS;
596    }
597
598
599    /**
600     * Comprehensive Groebner base via Groebner system.
601     * @param F polynomial list.
602     * @return GB(F) a Comprehensive Groebner base of F.
603     */
604    // @Override
605    // @SuppressWarnings("unchecked")
606    public List<GenPolynomial<GenPolynomial<C>>> GB(List<GenPolynomial<GenPolynomial<C>>> F) {
607        if (F == null) {
608            return F;
609        }
610        // compute Groebner system
611        GroebnerSystem<C> gs = GBsys(F);
612        // System.out.println("\n\nGBsys = " + gs);
613        return gs.getCGB();
614    }
615
616
617    /**
618     * Minimal ordered Groebner basis.
619     * @param cs colored system.
620     * @return a reduced Groebner base of Gp.
621     */
622    // @Override
623    public ColoredSystem<C> minimalGB(ColoredSystem<C> cs) {
624        // List<ColorPolynomial<C>> Gp ) {
625        if (cs == null || cs.list == null || cs.list.size() <= 1) {
626            return cs;
627        }
628        // remove zero polynomials
629        List<ColorPolynomial<C>> G = new ArrayList<ColorPolynomial<C>>(cs.list.size());
630        for (ColorPolynomial<C> a : cs.list) {
631            if (a != null && !a.isZERO()) { // always true in GB()
632                // already positive a = a.abs();
633                G.add(a);
634            }
635        }
636        if (G.size() <= 1) {
637            return new ColoredSystem<C>(cs.condition, G, cs.pairlist);
638        }
639        // System.out.println("G check " + G);
640        // remove top reducible polynomials
641        Condition<C> cond = cs.condition;
642        ColorPolynomial<C> a, b;
643        List<ColorPolynomial<C>> F;
644        F = new ArrayList<ColorPolynomial<C>>(G.size());
645        while (G.size() > 0) {
646            a = G.remove(0);
647            b = a;
648            // System.out.println("check " + b);
649            //if (false) {
650            //    if (a.red.leadingBaseCoefficient().isConstant()) { // dont drop
651            //        // these
652            //        F.add(a);
653            //        continue;
654            //    }
655            //}
656            if (cred.isTopReducible(G, a) || cred.isTopReducible(F, a)) {
657                // drop polynomial
658                if (debug) {
659                    // System.out.println("trying to drop " + a);
660                    List<ColorPolynomial<C>> ff;
661                    ff = new ArrayList<ColorPolynomial<C>>(G);
662                    ff.addAll(F);
663                    a = cred.normalform(cond, ff, a);
664                    try {
665                        a = cond.reDetermine(a);
666                    } catch (RuntimeException ignored) {
667                    }
668                    if (!a.isZERO()) {
669                        logger.error("nf(a) != 0 " + b + ", " + a);
670                        F.add(b);
671                    }
672                }
673            } else {
674                F.add(a);
675            }
676        }
677        G = F;
678        if (G.size() <= 1) {
679            return new ColoredSystem<C>(cs.condition, G, cs.pairlist);
680        }
681        Collections.reverse(G); // important for lex GB
682        // reduce remaining polynomials
683        int len = G.size();
684        int i = 0;
685        while (i < len) {
686            a = G.remove(0);
687            b = a;
688            ExpVector e = a.red.leadingExpVector();
689            // System.out.println("reducing " + a);
690            a = cred.normalform(cond, G, a); // unchanged by top reduction
691            // System.out.println("reduced " + a);
692            try {
693                a = cond.reDetermine(a);
694            } catch (RuntimeException ignored) {
695            }
696            ExpVector f = a.red.leadingExpVector();
697            // a = ##engine.basePrimitivePart(a); //a.monic(); was not required
698            // a = a.abs();
699            // a = red.normalform( F, a );
700            if (e.equals(f)) {
701                G.add(a); // adds as last
702            } else { // should not happen
703                if (debug) {
704                    logger.error("nf(a) not determined " + b + ", " + a);
705                }
706                G.add(b); // adds as last
707            }
708            i++;
709        }
710        return new ColoredSystem<C>(cs.condition, G, cs.pairlist);
711    }
712
713}