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