001    /*
002     * $Id: SolvableSyzygyAbstract.java 3584 2011-03-26 11:39:39Z kredel $
003     */
004    
005    package edu.jas.gbmod;
006    
007    
008    import java.io.Serializable;
009    import java.util.ArrayList;
010    import java.util.Iterator;
011    import java.util.List;
012    import java.util.Map;
013    
014    import org.apache.log4j.Logger;
015    
016    import edu.jas.gb.Reduction;
017    import edu.jas.gb.ReductionSeq;
018    import edu.jas.gb.SolvableExtendedGB;
019    import edu.jas.gb.SolvableGroebnerBase;
020    import edu.jas.gb.SolvableGroebnerBaseSeq;
021    import edu.jas.gb.SolvableReduction;
022    import edu.jas.gb.SolvableReductionSeq;
023    import edu.jas.poly.ExpVector;
024    import edu.jas.poly.GenPolynomial;
025    import edu.jas.poly.GenSolvablePolynomial;
026    import edu.jas.poly.GenSolvablePolynomialRing;
027    import edu.jas.poly.ModuleList;
028    import edu.jas.poly.PolynomialList;
029    import edu.jas.structure.RingElem;
030    import edu.jas.vector.BasicLinAlg;
031    
032    
033    /**
034     * Syzygy class for solvable polynomials. Implements Syzygy computations and
035     * tests.
036     * @param <C> coefficient type
037     * @author Heinz Kredel
038     */
039    
040    public class SolvableSyzygyAbstract<C extends RingElem<C>> implements SolvableSyzygy<C> {
041    
042    
043        private static final Logger logger = Logger.getLogger(SolvableSyzygyAbstract.class);
044    
045    
046        private final boolean debug = logger.isDebugEnabled();
047    
048    
049        /**
050         * Solvable reduction engine.
051         */
052        protected SolvableReduction<C> sred;
053    
054    
055        /**
056         * Reduction engine.
057         */
058        protected Reduction<C> red;
059    
060    
061        /**
062         * Linear algebra engine.
063         */
064        protected BasicLinAlg<GenPolynomial<C>> blas;
065    
066    
067        /**
068         * Constructor.
069         */
070        public SolvableSyzygyAbstract() {
071            red = new ReductionSeq<C>();
072            sred = new SolvableReductionSeq<C>();
073            blas = new BasicLinAlg<GenPolynomial<C>>();
074        }
075    
076    
077        /**
078         * Left syzygy for left Groebner base.
079         * @param F a Groebner base.
080         * @return leftSyz(F), a basis for the left module of syzygies for F.
081         */
082        public List<List<GenSolvablePolynomial<C>>> leftZeroRelations(List<GenSolvablePolynomial<C>> F) {
083            return leftZeroRelations(0, F);
084        }
085    
086    
087        /**
088         * Left syzygy for left Groebner base.
089         * @param modv number of module variables.
090         * @param F a Groebner base.
091         * @return leftSyz(F), a basis for the left module of syzygies for F.
092         */
093        public List<List<GenSolvablePolynomial<C>>> leftZeroRelations(int modv, List<GenSolvablePolynomial<C>> F) {
094            List<List<GenSolvablePolynomial<C>>> Z = new ArrayList<List<GenSolvablePolynomial<C>>>();
095            ArrayList<GenSolvablePolynomial<C>> S = new ArrayList<GenSolvablePolynomial<C>>(F.size());
096            for (int i = 0; i < F.size(); i++) {
097                S.add(null);
098            }
099            GenSolvablePolynomial<C> pi, pj, s, h, zero;
100            zero = null;
101            for (int i = 0; i < F.size(); i++) {
102                pi = F.get(i);
103                if (pi != null && zero == null) {
104                    zero = pi.ring.getZERO();
105                }
106                for (int j = i + 1; j < F.size(); j++) {
107                    pj = F.get(j);
108                    //logger.info("p"+i+", p"+j+" = " + pi + ", " +pj);
109    
110                    if (!red.moduleCriterion(modv, pi, pj)) {
111                        continue;
112                    }
113                    // if ( ! red.criterion4( pi, pj ) ) continue;
114                    ArrayList<GenSolvablePolynomial<C>> row = (ArrayList<GenSolvablePolynomial<C>>) S.clone();
115    
116                    s = sred.leftSPolynomial(row, i, pi, j, pj);
117                    //logger.info("row = " + row);
118                    if (s.isZERO()) {
119                        Z.add(row);
120                        continue;
121                    }
122    
123                    h = sred.leftNormalform(row, F, s);
124                    if (!h.isZERO()) {
125                        throw new ArithmeticException("Syzygy no leftGB");
126                    }
127                    if (logger.isDebugEnabled()) {
128                        logger.info("row = " + row);
129                    }
130                    Z.add(row);
131                }
132            }
133            // set null to zero
134            for (List<GenSolvablePolynomial<C>> vr : Z) {
135                for (int j = 0; j < vr.size(); j++) {
136                    if (vr.get(j) == null) {
137                        vr.set(j, zero);
138                    }
139                }
140            }
141            return Z;
142        }
143    
144    
145        /**
146         * Left syzygy for left module Groebner base.
147         * @param M a Groebner base.
148         * @return leftSyz(M), a basis for the left module of syzygies for M.
149         */
150        public ModuleList<C> leftZeroRelations(ModuleList<C> M) {
151            ModuleList<C> N = null;
152            if (M == null || M.list == null) {
153                return N;
154            }
155            if (M.rows == 0 || M.cols == 0) {
156                return N;
157            }
158            GenSolvablePolynomial<C> zero = (GenSolvablePolynomial<C>) M.ring.getZERO();
159            //logger.info("zero = " + zero);
160    
161            //ModuleList<C> Np = null;
162            PolynomialList<C> F = M.getPolynomialList();
163            int modv = M.cols; // > 0  
164            logger.info("modv = " + modv);
165            List<List<GenSolvablePolynomial<C>>> G = leftZeroRelations(modv, F.castToSolvableList());
166            if (G == null) {
167                return N;
168            }
169            List<List<GenSolvablePolynomial<C>>> Z = new ArrayList<List<GenSolvablePolynomial<C>>>();
170            for (int i = 0; i < G.size(); i++) {
171                List<GenSolvablePolynomial<C>> Gi = G.get(i);
172                List<GenSolvablePolynomial<C>> Zi = new ArrayList<GenSolvablePolynomial<C>>();
173                // System.out.println("\nG("+i+") = " + G.get(i));
174                for (int j = 0; j < Gi.size(); j++) {
175                    //System.out.println("\nG("+i+","+j+") = " + Gi.get(j));
176                    GenSolvablePolynomial<C> p = Gi.get(j);
177                    if (p != null) {
178                        Map<ExpVector, GenPolynomial<C>> r = p.contract(M.ring);
179                        //System.out.println("map("+i+","+j+") = " + r + ", size = " + r.size() );
180                        if (r.size() == 0) {
181                            Zi.add(zero);
182                        } else if (r.size() == 1) {
183                            GenSolvablePolynomial<C> vi = (GenSolvablePolynomial<C>) (r.values().toArray())[0];
184                            Zi.add(vi);
185                        } else { // will not happen
186                            throw new RuntimeException("Map.size() > 1 = " + r.size());
187                        }
188                    }
189                }
190                //System.out.println("\nZ("+i+") = " + Zi);
191                Z.add(Zi);
192            }
193            N = new ModuleList<C>((GenSolvablePolynomialRing<C>) M.ring, Z);
194            //System.out.println("\n\nN = " + N);
195            return N;
196        }
197    
198    
199        /**
200         * Test if left syzygy.
201         * @param Z list of sysygies.
202         * @param F a polynomial list.
203         * @return true, if Z is a list of left syzygies for F, else false.
204         */
205        public boolean isLeftZeroRelation(List<List<GenSolvablePolynomial<C>>> Z, List<GenSolvablePolynomial<C>> F) {
206            List<GenPolynomial<C>> Fp = PolynomialList.<C> castToList(F);
207            for (List<GenSolvablePolynomial<C>> row : Z) {
208                // p has wrong type:
209                GenPolynomial<C> p = blas.scalarProduct(PolynomialList.<C> castToList(row), Fp);
210                if (p == null) {
211                    continue;
212                }
213                if (!p.isZERO()) {
214                    logger.info("is not ZeroRelation = " + p);
215                    return false;
216                }
217            }
218            return true;
219        }
220    
221    
222        /**
223         * Test if right syzygy.
224         * @param Z list of sysygies.
225         * @param F a polynomial list.
226         * @return true, if Z is a list of right syzygies for F, else false.
227         */
228        public boolean isRightZeroRelation(List<List<GenSolvablePolynomial<C>>> Z,
229                        List<GenSolvablePolynomial<C>> F) {
230            List<GenPolynomial<C>> Fp = PolynomialList.<C> castToList(F);
231            for (List<GenSolvablePolynomial<C>> row : Z) {
232                List<GenPolynomial<C>> yrow = PolynomialList.<C> castToList(row);
233                // p has wrong type:
234                GenPolynomial<C> p = blas.scalarProduct(Fp, yrow); // param order
235                if (p == null) {
236                    continue;
237                }
238                if (!p.isZERO()) {
239                    logger.info("is not ZeroRelation = " + p);
240                    return false;
241                }
242            }
243            return true;
244        }
245    
246    
247        /**
248         * Test if left sysygy of modules
249         * @param Z list of sysygies.
250         * @param F a module list.
251         * @return true, if Z is a list of left syzygies for F, else false.
252         */
253        public boolean isLeftZeroRelation(ModuleList<C> Z, ModuleList<C> F) {
254            if (Z == null || Z.list == null) {
255                return true;
256            }
257            for (List<GenPolynomial<C>> row : Z.list) {
258                List<GenPolynomial<C>> zr = blas.leftScalarProduct(row, F.list);
259                if (!blas.isZero(zr)) {
260                    logger.info("is not ZeroRelation (" + zr.size() + ") = " + zr);
261                    return false;
262                }
263            }
264            return true;
265        }
266    
267    
268        /**
269         * Test if right sysygy of modules
270         * @param Z list of sysygies.
271         * @param F a module list.
272         * @return true, if Z is a list of right syzygies for F, else false.
273         */
274        public boolean isRightZeroRelation(ModuleList<C> Z, ModuleList<C> F) {
275            if (Z == null || Z.list == null) {
276                return true;
277            }
278            for (List<GenPolynomial<C>> row : Z.list) {
279                List<GenPolynomial<C>> zr = blas.rightScalarProduct(row, F.list);
280                //List<GenPolynomial<C>> zr = blas.scalarProduct(row,F.list);
281                if (!blas.isZero(zr)) {
282                    logger.info("is not ZeroRelation (" + zr.size() + ") = " + zr);
283                    return false;
284                }
285            }
286            return true;
287        }
288    
289    
290        /**
291         * Resolution of a module. Only with direct GBs.
292         * @param M a module list of a Groebner basis.
293         * @return a resolution of M.
294         */
295        public List<SolvResPart<C>> resolution(ModuleList<C> M) {
296            List<SolvResPart<C>> R = new ArrayList<SolvResPart<C>>();
297            ModuleList<C> MM = M;
298            ModuleList<C> GM;
299            ModuleList<C> Z;
300            ModSolvableGroebnerBase<C> msbb = new ModSolvableGroebnerBaseAbstract<C>();
301            while (true) {
302                GM = msbb.leftGB(MM);
303                Z = leftZeroRelations(GM);
304                R.add(new SolvResPart<C>(MM, GM, Z));
305                if (Z == null || Z.list == null || Z.list.size() == 0) {
306                    break;
307                }
308                MM = Z;
309            }
310            return R;
311        }
312    
313    
314        /**
315         * Resolution of a polynomial list. Only with direct GBs.
316         * @param F a polynomial list of a Groebner basis.
317         * @return a resolution of F.
318         */
319        public List // <SolvResPart<C>|SolvResPolPart<C>> 
320        resolution(PolynomialList<C> F) {
321            List<List<GenSolvablePolynomial<C>>> Z;
322            ModuleList<C> Zm;
323            List<GenSolvablePolynomial<C>> G;
324            PolynomialList<C> Gl;
325            SolvableGroebnerBase<C> sbb = new SolvableGroebnerBaseSeq<C>();
326    
327            G = sbb.leftGB(F.castToSolvableList());
328            Z = leftZeroRelations(G);
329            Gl = new PolynomialList<C>((GenSolvablePolynomialRing<C>) F.ring, G);
330            Zm = new ModuleList<C>((GenSolvablePolynomialRing<C>) F.ring, Z);
331    
332            List R = resolution(Zm);
333            R.add(0, new SolvResPolPart<C>(F, Gl, Zm));
334            return R;
335        }
336    
337    
338        /**
339         * Resolution of a module.
340         * @param M a module list of an arbitrary basis.
341         * @return a resolution of M.
342         */
343        public List<SolvResPart<C>> resolutionArbitrary(ModuleList<C> M) {
344            List<SolvResPart<C>> R = new ArrayList<SolvResPart<C>>();
345            ModuleList<C> MM = M;
346            ModuleList<C> GM = null;
347            ModuleList<C> Z;
348            //ModSolvableGroebnerBase<C> msbb = new ModSolvableGroebnerBaseAbstract<C>();
349            while (true) {
350                //GM = msbb.leftGB(MM);
351                Z = leftZeroRelationsArbitrary(MM);
352                R.add(new SolvResPart<C>(MM, GM, Z));
353                if (Z == null || Z.list == null || Z.list.size() == 0) {
354                    break;
355                }
356                MM = Z;
357            }
358            return R;
359        }
360    
361    
362        /**
363         * Resolution of a polynomial list.
364         * @param F a polynomial list of an arbitrary basis.
365         * @return a resolution of F.
366         */
367        public List // <SolvResPart<C>|SolvResPolPart<C>> 
368        resolutionArbitrary(PolynomialList<C> F) {
369            List<List<GenSolvablePolynomial<C>>> Z;
370            ModuleList<C> Zm;
371            //List<GenSolvablePolynomial<C>> G;
372            PolynomialList<C> Gl = null;
373            //SolvableGroebnerBase<C> sbb = new SolvableGroebnerBaseSeq<C>();
374    
375            //G = sbb.leftGB( F.castToSolvableList() );
376            Z = leftZeroRelationsArbitrary(F.castToSolvableList());
377            //Gl = new PolynomialList<C>((GenSolvablePolynomialRing<C>)F.ring, G);
378            Zm = new ModuleList<C>((GenSolvablePolynomialRing<C>) F.ring, Z);
379    
380            List R = resolutionArbitrary(Zm);
381            R.add(0, new SolvResPolPart<C>(F, Gl, Zm));
382            return R;
383        }
384    
385    
386        /**
387         * Left syzygy module from arbitrary base.
388         * @param F a solvable polynomial list.
389         * @return syz(F), a basis for the module of left syzygies for F.
390         */
391        public List<List<GenSolvablePolynomial<C>>> leftZeroRelationsArbitrary(List<GenSolvablePolynomial<C>> F) {
392            return leftZeroRelationsArbitrary(0, F);
393        }
394    
395    
396        /**
397         * Left syzygy module from arbitrary base.
398         * @param modv number of module variables.
399         * @param F a solvable polynomial list.
400         * @return syz(F), a basis for the module of left syzygies for F.
401         */
402        public List<List<GenSolvablePolynomial<C>>> leftZeroRelationsArbitrary(int modv,
403                        List<GenSolvablePolynomial<C>> F) {
404            if (F == null) {
405                return null; //leftZeroRelations( modv, F );
406            }
407            if (F.size() <= 1) {
408                return leftZeroRelations(modv, F);
409            }
410            final int lenf = F.size();
411            SolvableGroebnerBaseSeq<C> sgb = new SolvableGroebnerBaseSeq<C>();
412            SolvableExtendedGB<C> exgb = sgb.extLeftGB(F);
413            if (debug) {
414                logger.info("exgb = " + exgb);
415            }
416            if (!sgb.isLeftReductionMatrix(exgb)) {
417                logger.error("is reduction matrix ? false");
418            }
419            List<GenSolvablePolynomial<C>> G = exgb.G;
420            List<List<GenSolvablePolynomial<C>>> G2F = exgb.G2F;
421            List<List<GenSolvablePolynomial<C>>> F2G = exgb.F2G;
422    
423            List<List<GenSolvablePolynomial<C>>> sg = leftZeroRelations(modv, G);
424            GenSolvablePolynomialRing<C> ring = G.get(0).ring;
425            ModuleList<C> S = new ModuleList<C>(ring, sg);
426            if (debug) {
427                logger.info("syz = " + S);
428            }
429            if (!isLeftZeroRelation(sg, G)) {
430                logger.error("is syzygy ? false");
431            }
432    
433            List<List<GenSolvablePolynomial<C>>> sf;
434            sf = new ArrayList<List<GenSolvablePolynomial<C>>>(sg.size());
435            //List<GenPolynomial<C>> row;
436    
437            for (List<GenSolvablePolynomial<C>> r : sg) {
438                Iterator<GenSolvablePolynomial<C>> it = r.iterator();
439                Iterator<List<GenSolvablePolynomial<C>>> jt = G2F.iterator();
440    
441                List<GenSolvablePolynomial<C>> rf;
442                rf = new ArrayList<GenSolvablePolynomial<C>>(lenf);
443                for (int m = 0; m < lenf; m++) {
444                    rf.add(ring.getZERO());
445                }
446                while (it.hasNext() && jt.hasNext()) {
447                    GenSolvablePolynomial<C> si = it.next();
448                    List<GenSolvablePolynomial<C>> ai = jt.next();
449                    //System.out.println("si = " + si);
450                    //System.out.println("ai = " + ai);
451                    if (si == null || ai == null) {
452                        continue;
453                    }
454                    // pi has wrong type:
455                    List<GenPolynomial<C>> pi = blas.scalarProduct(si, PolynomialList.<C> castToList(ai));
456                    //System.out.println("pi = " + pi);
457                    rf = PolynomialList.<C> castToSolvableList(blas.vectorAdd(PolynomialList.<C> castToList(rf),
458                                    pi));
459                }
460                if (it.hasNext() || jt.hasNext()) {
461                    logger.error("leftZeroRelationsArbitrary wrong sizes");
462                }
463                //System.out.println("\nrf = " + rf + "\n");
464                sf.add(rf);
465            }
466            if (!isLeftZeroRelation(sf, F)) {
467                logger.error("is partial syz sf ? false");
468            }
469    
470            List<List<GenSolvablePolynomial<C>>> M;
471            M = new ArrayList<List<GenSolvablePolynomial<C>>>(lenf);
472            for (List<GenSolvablePolynomial<C>> r : F2G) {
473                Iterator<GenSolvablePolynomial<C>> it = r.iterator();
474                Iterator<List<GenSolvablePolynomial<C>>> jt = G2F.iterator();
475    
476                List<GenSolvablePolynomial<C>> rf;
477                rf = new ArrayList<GenSolvablePolynomial<C>>(lenf);
478                for (int m = 0; m < lenf; m++) {
479                    rf.add(ring.getZERO());
480                }
481                while (it.hasNext() && jt.hasNext()) {
482                    GenSolvablePolynomial<C> si = it.next();
483                    List<GenSolvablePolynomial<C>> ai = jt.next();
484                    //System.out.println("si = " + si);
485                    //System.out.println("ai = " + ai);
486                    if (si == null || ai == null) {
487                        continue;
488                    }
489                    //pi has wrong type, should be: List<GenSolvablePolynomial<C>>
490                    List<GenPolynomial<C>> pi = blas.scalarProduct(si, PolynomialList.<C> castToList(ai));
491                    //System.out.println("pi = " + pi);
492                    rf = PolynomialList.<C> castToSolvableList(blas.vectorAdd(PolynomialList.<C> castToList(rf),
493                                    pi));
494                }
495                if (it.hasNext() || jt.hasNext()) {
496                    logger.error("zeroRelationsArbitrary wrong sizes");
497                }
498                //System.out.println("\nMg Mf = " + rf + "\n");
499                M.add(rf);
500            }
501            //ModuleList<C> ML = new ModuleList<C>( ring, M );
502            //System.out.println("syz ML = " + ML);
503            // debug only:
504            //List<GenSolvablePolynomial<C>> F2 = new ArrayList<GenSolvablePolynomial<C>>( F.size() );
505            /* not true in general
506            List<GenPolynomial<C>> Fp = PolynomialList.<C>castToList(F);
507            for ( List<GenSolvablePolynomial<C>> rr: M ) {
508                GenSolvablePolynomial<C> rrg = PolynomialList.<C>castToSolvableList(blas.scalarProduct(Fp,PolynomialList.<C>castToList(rr)));
509                F2.add( rrg );
510            }
511            PolynomialList<C> pF = new PolynomialList<C>( ring, F );
512            PolynomialList<C> pF2 = new PolynomialList<C>( ring, F2 );
513            if ( ! pF.equals( pF2 ) ) {
514               logger.error("is FAB = F ? false");
515               //System.out.println("pF  = " + pF.list.size());
516               //System.out.println("pF2 = " + pF2.list.size());
517            }
518            */
519            int sflen = sf.size();
520            List<List<GenSolvablePolynomial<C>>> M2;
521            M2 = new ArrayList<List<GenSolvablePolynomial<C>>>(lenf);
522            int i = 0;
523            for (List<GenSolvablePolynomial<C>> ri : M) {
524                List<GenSolvablePolynomial<C>> r2i;
525                r2i = new ArrayList<GenSolvablePolynomial<C>>(ri.size());
526                int j = 0;
527                for (GenSolvablePolynomial<C> rij : ri) {
528                    GenSolvablePolynomial<C> p = null;
529                    if (i == j) {
530                        p = (GenSolvablePolynomial<C>) ring.getONE().subtract(rij);
531                    } else {
532                        if (rij != null) {
533                            p = (GenSolvablePolynomial<C>) rij.negate();
534                        }
535                    }
536                    r2i.add(p);
537                    j++;
538                }
539                M2.add(r2i);
540                if (!blas.isZero(PolynomialList.<C> castToList(r2i))) {
541                    sf.add(r2i);
542                }
543                i++;
544            }
545            ModuleList<C> M2L = new ModuleList<C>(ring, M2);
546            if (debug) {
547                logger.debug("syz M2L = " + M2L);
548            }
549    
550            if (debug) {
551                ModuleList<C> SF = new ModuleList<C>(ring, sf);
552                logger.debug("syz sf = " + SF);
553                logger.debug("#syz " + sflen + ", " + sf.size());
554            }
555            if (!isLeftZeroRelation(sf, F)) {
556                logger.error("is syz sf ? false");
557            }
558            return sf;
559        }
560    
561    
562        /**
563         * Left syzygy for arbitrary left module base.
564         * @param M an arbitrary base.
565         * @return leftSyz(M), a basis for the left module of syzygies for M.
566         */
567        public ModuleList<C> leftZeroRelationsArbitrary(ModuleList<C> M) {
568            ModuleList<C> N = null;
569            if (M == null || M.list == null) {
570                return N;
571            }
572            if (M.rows == 0 || M.cols == 0) {
573                return N;
574            }
575            GenSolvablePolynomial<C> zero = (GenSolvablePolynomial<C>) M.ring.getZERO();
576            //logger.info("zero = " + zero);
577    
578            //ModuleList<C> Np = null;
579            PolynomialList<C> F = M.getPolynomialList();
580            int modv = M.cols; // > 0  
581            logger.info("modv = " + modv);
582            List<List<GenSolvablePolynomial<C>>> G = leftZeroRelationsArbitrary(modv, F.castToSolvableList());
583            if (G == null) {
584                return N;
585            }
586            List<List<GenSolvablePolynomial<C>>> Z = new ArrayList<List<GenSolvablePolynomial<C>>>();
587            for (int i = 0; i < G.size(); i++) {
588                List<GenSolvablePolynomial<C>> Gi = G.get(i);
589                List<GenSolvablePolynomial<C>> Zi = new ArrayList<GenSolvablePolynomial<C>>();
590                // System.out.println("\nG("+i+") = " + G.get(i));
591                for (int j = 0; j < Gi.size(); j++) {
592                    //System.out.println("\nG("+i+","+j+") = " + Gi.get(j));
593                    GenSolvablePolynomial<C> p = Gi.get(j);
594                    if (p != null) {
595                        Map<ExpVector, GenPolynomial<C>> r = p.contract(M.ring);
596                        //System.out.println("map("+i+","+j+") = " + r + ", size = " + r.size() );
597                        if (r.size() == 0) {
598                            Zi.add(zero);
599                        } else if (r.size() == 1) {
600                            GenSolvablePolynomial<C> vi = (GenSolvablePolynomial<C>) (r.values().toArray())[0];
601                            Zi.add(vi);
602                        } else { // will not happen
603                            throw new RuntimeException("Map.size() > 1 = " + r.size());
604                        }
605                    }
606                }
607                //System.out.println("\nZ("+i+") = " + Zi);
608                Z.add(Zi);
609            }
610            N = new ModuleList<C>((GenSolvablePolynomialRing<C>) M.ring, Z);
611            //System.out.println("\n\nN = " + N);
612            return N;
613        }
614    
615    
616        /**
617         * Right syzygy module from arbitrary base.
618         * @param F a solvable polynomial list.
619         * @return syz(F), a basis for the module of right syzygies for F.
620         */
621        public List<List<GenSolvablePolynomial<C>>> rightZeroRelationsArbitrary(List<GenSolvablePolynomial<C>> F) {
622            return rightZeroRelationsArbitrary(0, F);
623        }
624    
625    
626        /**
627         * Right syzygy module from arbitrary base.
628         * @param modv number of module variables.
629         * @param F a solvable polynomial list.
630         * @return syz(F), a basis for the module of right syzygies for F.
631         */
632        public List<List<GenSolvablePolynomial<C>>> rightZeroRelationsArbitrary(int modv,
633                        List<GenSolvablePolynomial<C>> F) {
634            GenSolvablePolynomialRing<C> ring = null;
635            for (GenSolvablePolynomial<C> p : F) {
636                if (p != null) {
637                    ring = p.ring;
638                    break;
639                }
640            }
641            List<List<GenSolvablePolynomial<C>>> Z;
642            if (ring == null) { // all null
643                Z = new ArrayList<List<GenSolvablePolynomial<C>>>(1);
644                Z.add(F);
645                return Z;
646            }
647            GenSolvablePolynomialRing<C> rring = ring.reverse(true);
648            GenSolvablePolynomial<C> q;
649            List<GenSolvablePolynomial<C>> rF;
650            rF = new ArrayList<GenSolvablePolynomial<C>>(F.size());
651            for (GenSolvablePolynomial<C> p : F) {
652                if (p != null) {
653                    q = (GenSolvablePolynomial<C>) p.reverse(rring);
654                    rF.add(q);
655                }
656            }
657            if (true || debug) {
658                PolynomialList<C> pl = new PolynomialList<C>(rring, rF);
659                //logger.info("reversed problem = " + pl);
660                System.out.println("reversed problem = " + pl);
661            }
662            List<List<GenSolvablePolynomial<C>>> rZ = leftZeroRelationsArbitrary(modv, rF);
663            if (debug) {
664                boolean isit = isLeftZeroRelation(rZ, rF);
665                logger.debug("isLeftZeroRelation = " + isit);
666            }
667            GenSolvablePolynomialRing<C> oring = rring.reverse(true);
668            if (debug) {
669                logger.debug("ring == oring: " + ring.equals(oring));
670            }
671            ring = oring;
672            Z = new ArrayList<List<GenSolvablePolynomial<C>>>(rZ.size());
673            for (List<GenSolvablePolynomial<C>> z : rZ) {
674                if (z == null) {
675                    continue;
676                }
677                List<GenSolvablePolynomial<C>> s;
678                s = new ArrayList<GenSolvablePolynomial<C>>(z.size());
679                for (GenSolvablePolynomial<C> p : z) {
680                    if (p != null) {
681                        q = (GenSolvablePolynomial<C>) p.reverse(ring);
682                        s.add(q);
683                    }
684                }
685                Z.add(s);
686            }
687            return Z;
688        }
689    
690    }
691    
692    
693    /**
694     * Container for module resolution components.
695     * @param <C> coefficient type
696     */
697    class SolvResPart<C extends RingElem<C>> implements Serializable {
698    
699    
700        public final ModuleList<C> module;
701    
702    
703        public final ModuleList<C> GB;
704    
705    
706        public final ModuleList<C> syzygy;
707    
708    
709        /**
710         * SolvResPart.
711         * @param m a module list.
712         * @param g a module list GB.
713         * @param z a syzygy module list.
714         */
715        public SolvResPart(ModuleList<C> m, ModuleList<C> g, ModuleList<C> z) {
716            module = m;
717            GB = g;
718            syzygy = z;
719        }
720    
721    
722        /**
723         * toString.
724         */
725        @Override
726        public String toString() {
727            StringBuffer s = new StringBuffer("SolvResPart(\n");
728            s.append("module = " + module);
729            s.append("\n GB = " + GB);
730            s.append("\n syzygy = " + syzygy);
731            s.append(")");
732            return s.toString();
733        }
734    }
735    
736    
737    /**
738     * Container for polynomial resolution components.
739     * @param <C> coefficient type
740     */
741    class SolvResPolPart<C extends RingElem<C>> implements Serializable {
742    
743    
744        public final PolynomialList<C> ideal;
745    
746    
747        public final PolynomialList<C> GB;
748    
749    
750        public final ModuleList<C> syzygy;
751    
752    
753        /**
754         * SolvResPolPart.
755         * @param m a polynomial list.
756         * @param g a polynomial list GB.
757         * @param z a syzygy module list.
758         */
759        public SolvResPolPart(PolynomialList<C> m, PolynomialList<C> g, ModuleList<C> z) {
760            ideal = m;
761            GB = g;
762            syzygy = z;
763        }
764    
765    
766        /**
767         * toString.
768         */
769        @Override
770        public String toString() {
771            StringBuffer s = new StringBuffer("SolvResPolPart(\n");
772            s.append("ideal = " + ideal);
773            s.append("\n GB = " + GB);
774            s.append("\n syzygy = " + syzygy);
775            s.append(")");
776            return s.toString();
777        }
778    
779    }