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: h!=0, " + h);
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 arbitrary 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        if (oc == null) {
625            throw new IllegalArgumentException("oc array must be non null");
626        }
627        return isLeftOreCond(a, b, oc[0], oc[1]);
628    }
629
630
631
632    /**
633     * Is left Ore condition. Test left Ore condition of two solvable
634     * polynomials.
635     * @param a solvable polynomial
636     * @param b solvable polynomial
637     * @param p solvable polynomial
638     * @param q solvable polynomial
639     * @return true, if p*a = q*b, else false
640     */
641    public boolean isLeftOreCond(GenSolvablePolynomial<C> a, GenSolvablePolynomial<C> b, GenSolvablePolynomial<C> p, GenSolvablePolynomial<C> q) {
642        if (a == null || a.isZERO() || b == null || b.isZERO()) {
643            throw new IllegalArgumentException("a and b must be non zero");
644        }
645        GenSolvablePolynomial<C> pa = p.multiply(a);
646        GenSolvablePolynomial<C> qb = q.multiply(b);
647        return pa.equals(qb);
648    }
649
650
651    /**
652     * Test right Ore condition.
653     * @param a solvable polynomial
654     * @param b solvable polynomial
655     * @param oc = [p,q] two solvable polynomials
656     * @return true if a*p = b*q, else false
657     */
658    public boolean isRightOreCond(GenSolvablePolynomial<C> a, GenSolvablePolynomial<C> b,
659                    GenSolvablePolynomial<C>[] oc) {
660        if (oc == null) {
661            throw new IllegalArgumentException("oc array must be non null");
662        }
663        return isRightOreCond(a, b, oc[0], oc[1]);
664    }
665
666
667    /**
668     * Is right Ore condition. Test right Ore condition of two solvable
669     * polynomials.
670     * @param a solvable polynomial
671     * @param b solvable polynomial
672     * @param p solvable polynomial
673     * @param q solvable polynomial
674     * @return true, if a*p = b*q, else false
675     */
676    public boolean isRightOreCond(GenSolvablePolynomial<C> a, GenSolvablePolynomial<C> b, GenSolvablePolynomial<C> p, GenSolvablePolynomial<C> q) {
677        if (a == null || a.isZERO() || b == null || b.isZERO()) {
678            throw new IllegalArgumentException("a and b must be non zero");
679        }
680        GenSolvablePolynomial<C> ap = a.multiply(p);
681        GenSolvablePolynomial<C> bq = b.multiply(q);
682        return ap.equals(bq);
683    }
684
685
686    /**
687     * Left simplifier. Method of Apel &amp; Lassner (1987).
688     * @param a solvable polynomial
689     * @param b solvable polynomial
690     * @return [p,q] with a/b = p/q and q is minimal and monic
691     */
692    public abstract GenSolvablePolynomial<C>[] leftSimplifier(GenSolvablePolynomial<C> a,
693                    GenSolvablePolynomial<C> b);
694
695
696    /**
697     * Comparison like SolvableLocal or SolvableQuotient.
698     * @param num SolvablePolynomial.
699     * @param den SolvablePolynomial.
700     * @param n SolvablePolynomial.
701     * @param d SolvablePolynomial.
702     * @return sign((num/den)-(n/d)).
703     */
704    public int compare(GenSolvablePolynomial<C> num, GenSolvablePolynomial<C> den,
705                    GenSolvablePolynomial<C> n, GenSolvablePolynomial<C> d) {
706        if (n == null || n.isZERO()) {
707            return num.signum();
708        }
709        if (num.isZERO()) {
710            return -n.signum();
711        }
712        // assume sign(den,b.den) > 0
713        int s1 = num.signum();
714        int s2 = n.signum();
715        int t = (s1 - s2) / 2;
716        if (t != 0) {
717            System.out.println("compareTo: t = " + t);
718            //return t;
719        }
720        if (den.compareTo(d) == 0) {
721            return num.compareTo(n);
722        }
723        GenSolvablePolynomial<C> r, s;
724        // if (den.isONE()) { }
725        // if (b.den.isONE()) { }
726        GenSolvablePolynomial<C>[] oc = leftOreCond(den, d);
727        if (debug) {
728            System.out.println("oc[0] den =<>= oc[1] d: (" + oc[0] + ") (" + den + ") = (" + oc[1] + ") ("
729                            + d + ")");
730        }
731        //System.out.println("oc[0] = " + oc[0]);
732        //System.out.println("oc[1] = " + oc[1]);
733        r = oc[0].multiply(num);
734        s = oc[1].multiply(n);
735        logger.info("compare: r = {}, s = {}", r, s);
736        return r.compareTo(s);
737    }
738
739}
740
741
742/**
743 * Container for module resolution components.
744 * @param <C> coefficient type
745 */
746class SolvResPart<C extends RingElem<C>> implements Serializable {
747
748
749    public final ModuleList<C> module;
750
751
752    public final ModuleList<C> GB;
753
754
755    public final ModuleList<C> syzygy;
756
757
758    /**
759     * SolvResPart.
760     * @param m a module list.
761     * @param g a module list GB.
762     * @param z a syzygy module list.
763     */
764    public SolvResPart(ModuleList<C> m, ModuleList<C> g, ModuleList<C> z) {
765        module = m;
766        GB = g;
767        syzygy = z;
768    }
769
770
771    /**
772     * toString.
773     */
774    @Override
775    public String toString() {
776        StringBuffer s = new StringBuffer("SolvResPart(\n");
777        s.append("module = " + module);
778        s.append("\n GB = " + GB);
779        s.append("\n syzygy = " + syzygy);
780        s.append(")");
781        return s.toString();
782    }
783}
784
785
786/**
787 * Container for polynomial resolution components.
788 * @param <C> coefficient type
789 */
790class SolvResPolPart<C extends RingElem<C>> implements Serializable {
791
792
793    public final PolynomialList<C> ideal;
794
795
796    public final PolynomialList<C> GB;
797
798
799    public final ModuleList<C> syzygy;
800
801
802    /**
803     * SolvResPolPart.
804     * @param m a polynomial list.
805     * @param g a polynomial list GB.
806     * @param z a syzygy module list.
807     */
808    public SolvResPolPart(PolynomialList<C> m, PolynomialList<C> g, ModuleList<C> z) {
809        ideal = m;
810        GB = g;
811        syzygy = z;
812    }
813
814
815    /**
816     * toString.
817     */
818    @Override
819    public String toString() {
820        StringBuffer s = new StringBuffer("SolvResPolPart(\n");
821        s.append("ideal = " + ideal);
822        s.append("\n GB = " + GB);
823        s.append("\n syzygy = " + syzygy);
824        s.append(")");
825        return s.toString();
826    }
827
828}