001/*
002 * $Id$
003 */
004
005package edu.jas.poly;
006
007
008import java.io.Serializable;
009import java.util.Arrays;
010import java.util.Comparator;
011import java.util.List;
012
013import org.apache.logging.log4j.LogManager;
014import org.apache.logging.log4j.Logger;
015
016import edu.jas.kern.Scripting;
017
018
019/**
020 * Term order class for ordered polynomials. Implements the most used term
021 * orders: graded, lexicographical, weight array and block orders. For the
022 * definitions see for example the articles
023 * <a href="http://doi.acm.org/10.1145/43882.43887">Kredel "Admissible term
024 * orderings used in computer algebra systems"</a> and
025 * <a href="http://doi.acm.org/10.1145/70936.70941">Sit, "Some comments on
026 * term-ordering in Gr&ouml;bner basis computations"</a>. <b>Note: </b> the
027 * naming is not quite easy to understand: in case of doubt use the term orders
028 * with "I" in the name, like IGRLEX (the default) or INVLEX. Not all algorithms
029 * may work with all term orders since not all are well-founded, so watch your
030 * step. This class does not implement orders by linear forms over Q[t]. Objects
031 * of this class are immutable.
032 * 
033 * @author Heinz Kredel
034 */
035
036public final class TermOrder implements Serializable {
037
038
039    private static final Logger logger = LogManager.getLogger(TermOrder.class);
040
041
042    private static final boolean debug = logger.isDebugEnabled();
043
044
045    // TermOrder index values
046
047    public static final int LEX = 1;
048
049
050    public final static int MIN_EVORD = LEX;
051
052
053    public static final int INVLEX = 2;
054
055
056    public static final int GRLEX = 3;
057
058
059    public static final int IGRLEX = 4;
060
061
062    public static final int REVLEX = 5;
063
064
065    public static final int REVILEX = 6;
066
067
068    public static final int REVTDEG = 7;
069
070
071    public static final int REVITDG = 8;
072
073
074    public static final int ITDEGLEX = 9;
075
076
077    public static final int REVITDEG = 10;
078
079
080    public final static int MAX_EVORD = REVITDEG;
081
082
083    public final static int DEFAULT_EVORD = IGRLEX;
084
085
086    //public final static int DEFAULT_EVORD = INVLEX;
087
088
089    // instance variables
090
091    private final int evord;
092
093
094    // for split termorders
095    private final int evord2;
096
097
098    private final int evbeg1;
099
100
101    private final int evend1;
102
103
104    private final int evbeg2;
105
106
107    private final int evend2;
108
109
110    /**
111     * Defined array of weight vectors.
112     */
113    private final long[][] weight;
114
115
116    /**
117     * Defined descending order comparator. Sorts the highest terms first.
118     */
119    private final EVComparator horder;
120
121
122    /**
123     * Defined ascending order comparator. Sorts the lowest terms first.
124     */
125    private final EVComparator lorder;
126
127
128    /**
129     * Defined sugar order comparator. Sorts the graded lowest terms first.
130     */
131    private final EVComparator sugar;
132
133
134    /**
135     * Termorders for modules: TOP or POT. POT: position over term (default)
136     * TOP: term over position (new)
137     */
138    public final boolean TOP;
139
140
141    /**
142     * Comparator for ExpVectors.
143     */
144    public static abstract class EVComparator implements Comparator<ExpVector>, Serializable {
145
146
147        public abstract int compare(ExpVector e1, ExpVector e2);
148    }
149
150
151    /**
152     * Constructor for default term order.
153     */
154    public TermOrder() {
155        this(DEFAULT_EVORD);
156    }
157
158
159    /**
160     * Constructor for given term order.
161     * @param evord requested term order indicator / enumerator.
162     */
163    public TermOrder(int evord) {
164        if (evord < MIN_EVORD || MAX_EVORD < evord) {
165            throw new IllegalArgumentException("invalid term order: " + evord);
166        }
167        this.evord = evord;
168        this.evord2 = 0;
169        weight = null;
170        evbeg1 = 0;
171        evend1 = Integer.MAX_VALUE;
172        evbeg2 = evend1;
173        evend2 = evend1;
174        TOP = false;
175        switch (evord) { // horder = new EVhorder();
176        case TermOrder.LEX: {
177            horder = new EVComparator() {
178
179
180                @Override
181                public int compare(ExpVector e1, ExpVector e2) {
182                    return e1.invLexCompareTo(e2);
183                }
184            };
185            break;
186        }
187        case TermOrder.INVLEX: {
188            horder = new EVComparator() {
189
190
191                @Override
192                public int compare(ExpVector e1, ExpVector e2) {
193                    return -e1.invLexCompareTo(e2);
194                }
195            };
196            break;
197        }
198        case TermOrder.GRLEX: {
199            horder = new EVComparator() {
200
201
202                @Override
203                public int compare(ExpVector e1, ExpVector e2) {
204                    return e1.invGradCompareTo(e2);
205                }
206            };
207            break;
208        }
209        case TermOrder.IGRLEX: {
210            horder = new EVComparator() {
211
212
213                @Override
214                public int compare(ExpVector e1, ExpVector e2) {
215                    return -e1.invGradCompareTo(e2);
216                }
217            };
218            break;
219        }
220        case TermOrder.REVLEX: {
221            horder = new EVComparator() {
222
223
224                @Override
225                public int compare(ExpVector e1, ExpVector e2) {
226                    return e1.revInvLexCompareTo(e2);
227                }
228            };
229            break;
230        }
231        case TermOrder.REVILEX: {
232            horder = new EVComparator() {
233
234
235                @Override
236                public int compare(ExpVector e1, ExpVector e2) {
237                    return -e1.revInvLexCompareTo(e2);
238                }
239            };
240            break;
241        }
242        case TermOrder.REVTDEG: {
243            horder = new EVComparator() {
244
245
246                @Override
247                public int compare(ExpVector e1, ExpVector e2) {
248                    return e1.revInvGradCompareTo(e2);
249                }
250            };
251            break;
252        }
253        case TermOrder.REVITDG: {
254            horder = new EVComparator() {
255
256
257                @Override
258                public int compare(ExpVector e1, ExpVector e2) {
259                    return -e1.revInvGradCompareTo(e2);
260                }
261            };
262            break;
263        }
264        case TermOrder.ITDEGLEX: {
265            horder = new EVComparator() {
266
267
268                @Override
269                public int compare(ExpVector e1, ExpVector e2) {
270                    return -e1.invTdegCompareTo(e2); // okay +/-
271                }
272            };
273            break;
274        }
275        case TermOrder.REVITDEG: {
276            horder = new EVComparator() {
277
278
279                @Override
280                public int compare(ExpVector e1, ExpVector e2) {
281                    return e1.revLexInvTdegCompareTo(e2); // okay +/-
282                }
283            };
284            break;
285        }
286        default: {
287            horder = null;
288        }
289        }
290        if (horder == null) {
291            throw new IllegalArgumentException("invalid term order: " + evord);
292        }
293
294        // lorder = new EVlorder();
295        lorder = new EVComparator() {
296
297
298            @Override
299            public int compare(ExpVector e1, ExpVector e2) {
300                return -horder.compare(e1, e2);
301            }
302        };
303
304        // sugar = new EVsugar();
305        sugar = new EVComparator() {
306
307
308            @Override
309            public int compare(ExpVector e1, ExpVector e2) {
310                return e1.invGradCompareTo(e2);
311            }
312        };
313    }
314
315
316    /**
317     * Constructor for given exponent weights.
318     * @param w weight vector of longs.
319     */
320    public TermOrder(long[] w) {
321        this(new long[][] { w });
322    }
323
324
325    /**
326     * Constructor for given exponent weights.
327     * @param w weight array of longs.
328     */
329    public TermOrder(long[][] w) {
330        if (w == null || w.length == 0) {
331            throw new IllegalArgumentException("invalid term order weight");
332        }
333        weight = Arrays.copyOf(w, w.length); // > Java-5
334        this.evord = 0;
335        this.evord2 = 0;
336        evbeg1 = 0;
337        evend1 = weight[0].length;
338        evbeg2 = evend1;
339        evend2 = evend1;
340        TOP = false;
341
342        horder = new EVComparator() {
343
344
345            @Override
346            public int compare(ExpVector e1, ExpVector e2) {
347                return -e1.invWeightCompareTo(weight, e2);
348            }
349        };
350
351        // lorder = new EVlorder();
352        lorder = new EVComparator() {
353
354
355            @Override
356            public int compare(ExpVector e1, ExpVector e2) {
357                return +e1.invWeightCompareTo(weight, e2);
358                // return - horder.compare( e1, e2 );
359            }
360        };
361
362        // sugar = new EVsugar();
363        sugar = horder;
364    }
365
366
367    /**
368     * Test if this term order is a split order.
369     * @return true if this is a split term order, else false.
370     */
371    public boolean isSplit() {
372        //System.out.println("isSplit: " + evend2 + " == " + evbeg2);
373        if (evend2 == evbeg2 || evend1 == Integer.MAX_VALUE) {
374            return false;
375        }
376        return true;
377    }
378
379
380    /**
381     * Constructor for given split order.
382     * @param ev1 requested term order indicator for first block.
383     * @param ev2 requested term order indicator for second block.
384     * @param r max number of exponents to compare.
385     * @param split index.
386     */
387    public TermOrder(int ev1, int ev2, int r, int split) {
388        this(ev1, ev2, r, split, false);
389    }
390
391
392    /**
393     * Constructor for given split order.
394     * @param ev1 requested term order indicator for first block.
395     * @param ev2 requested term order indicator for second block.
396     * @param r max number of exponents to compare.
397     * @param split index.
398     * @param top module termorder, if true, default false.
399     */
400    public TermOrder(int ev1, int ev2, int r, int split, boolean top) {
401        if (ev1 < MIN_EVORD || MAX_EVORD - 2 < ev1) {
402            throw new IllegalArgumentException("invalid split term order 1: " + ev1);
403        }
404        if (ev2 < MIN_EVORD || MAX_EVORD - 2 < ev2) {
405            throw new IllegalArgumentException("invalid split term order 2: " + ev2);
406        }
407        this.evord = ev1;
408        this.evord2 = ev2;
409        weight = null;
410        evbeg1 = 0;
411        evend1 = split; // excluded
412        evbeg2 = split;
413        evend2 = r;
414        if (evbeg2 < 0 || evbeg2 > evend2) {
415            throw new IllegalArgumentException("invalid term order split, r = " + r + ", split = " + split);
416        }
417        //System.out.println("evbeg2 " + evbeg2 + ", evend2 " + evend2);
418        TOP = top;
419        if (debug) {
420            logger.info("module TermOrder is {}. split = {}, evord = {}, evord2 = {}", (TOP ? "TOP" : "POT"),
421                        split, toScriptOrder(evord), toScriptOrder(evord2));
422        }
423        switch (evord) { // horder = new EVhorder();
424        case TermOrder.LEX: {
425            switch (evord2) {
426            case TermOrder.LEX: {
427                horder = new EVComparator() {
428
429
430                    @Override
431                    public int compare(ExpVector e1, ExpVector e2) {
432                        int t = e1.invLexCompareTo(e2, evbeg1, evend1);
433                        if (t != 0) {
434                            return t;
435                        }
436                        return e1.invLexCompareTo(e2, evbeg2, evend2);
437                    }
438                };
439                break;
440            }
441            case TermOrder.INVLEX: {
442                horder = new EVComparator() {
443
444
445                    @Override
446                    public int compare(ExpVector e1, ExpVector e2) {
447                        int t = e1.invLexCompareTo(e2, evbeg1, evend1);
448                        if (t != 0) {
449                            return t;
450                        }
451                        return -e1.invLexCompareTo(e2, evbeg2, evend2);
452                    }
453                };
454                break;
455            }
456            case TermOrder.GRLEX: {
457                horder = new EVComparator() {
458
459
460                    @Override
461                    public int compare(ExpVector e1, ExpVector e2) {
462                        int t = e1.invLexCompareTo(e2, evbeg1, evend1);
463                        if (t != 0) {
464                            return t;
465                        }
466                        return e1.invGradCompareTo(e2, evbeg2, evend2);
467                    }
468                };
469                break;
470            }
471            case TermOrder.IGRLEX: {
472                horder = new EVComparator() {
473
474
475                    @Override
476                    public int compare(ExpVector e1, ExpVector e2) {
477                        int t = e1.invLexCompareTo(e2, evbeg1, evend1);
478                        if (t != 0) {
479                            return t;
480                        }
481                        return -e1.invGradCompareTo(e2, evbeg2, evend2);
482                    }
483                };
484                break;
485            }
486            default: {
487                horder = null;
488            }
489            }
490            break;
491        }
492        case TermOrder.INVLEX: {
493            switch (evord2) {
494            case TermOrder.LEX: {
495                horder = new EVComparator() {
496
497
498                    @Override
499                    public int compare(ExpVector e1, ExpVector e2) {
500                        int t = -e1.invLexCompareTo(e2, evbeg1, evend1);
501                        if (t != 0) {
502                            return t;
503                        }
504                        return e1.invLexCompareTo(e2, evbeg2, evend2);
505                    }
506                };
507                break;
508            }
509            case TermOrder.INVLEX: {
510                if (!TOP) {
511                    horder = new EVComparator() { // POT
512
513
514                        @Override
515                        public int compare(ExpVector e1, ExpVector e2) {
516                            int t = -e1.invLexCompareTo(e2, evbeg1, evend1);
517                            if (t != 0) {
518                                return t;
519                            }
520                            return -e1.invLexCompareTo(e2, evbeg2, evend2);
521                        }
522                    };
523                    break;
524                }
525                horder = new EVComparator() { // TOP
526
527
528                    @Override
529                    public int compare(ExpVector e1, ExpVector e2) {
530                        int t = -e1.invLexCompareTo(e2, evbeg2, evend2);
531                        if (t != 0) {
532                            return t;
533                        }
534                        return -e1.invLexCompareTo(e2, evbeg1, evend1);
535                    }
536                };
537                break;
538            }
539            case TermOrder.GRLEX: {
540                horder = new EVComparator() {
541
542
543                    @Override
544                    public int compare(ExpVector e1, ExpVector e2) {
545                        int t = -e1.invLexCompareTo(e2, evbeg1, evend1);
546                        if (t != 0) {
547                            return t;
548                        }
549                        return e1.invGradCompareTo(e2, evbeg2, evend2);
550                    }
551                };
552                break;
553            }
554            case TermOrder.IGRLEX: {
555                if (!TOP) {
556                    horder = new EVComparator() { // POT
557
558
559                        @Override
560                        public int compare(ExpVector e1, ExpVector e2) {
561                            int t = -e1.invLexCompareTo(e2, evbeg1, evend1);
562                            if (t != 0) {
563                                return t;
564                            }
565                            return -e1.invGradCompareTo(e2, evbeg2, evend2);
566                        }
567                    };
568                    break;
569                }
570                horder = new EVComparator() { // TOP
571
572
573                    @Override
574                    public int compare(ExpVector e1, ExpVector e2) {
575                        int t = -e1.invGradCompareTo(e2, evbeg2, evend2);
576                        if (t != 0) {
577                            return t;
578                        }
579                        return -e1.invLexCompareTo(e2, evbeg1, evend1);
580                    }
581                };
582                break;
583            }
584            case TermOrder.REVLEX: {
585                horder = new EVComparator() {
586
587
588                    @Override
589                    public int compare(ExpVector e1, ExpVector e2) {
590                        int t = -e1.invLexCompareTo(e2, evbeg1, evend1);
591                        if (t != 0) {
592                            return t;
593                        }
594                        return e1.revInvLexCompareTo(e2, evbeg2, evend2);
595                    }
596                };
597                break;
598            }
599            case TermOrder.REVILEX: {
600                horder = new EVComparator() {
601
602
603                    @Override
604                    public int compare(ExpVector e1, ExpVector e2) {
605                        int t = -e1.invLexCompareTo(e2, evbeg1, evend1);
606                        if (t != 0) {
607                            return t;
608                        }
609                        return -e1.revInvLexCompareTo(e2, evbeg2, evend2);
610                    }
611                };
612                break;
613            }
614            case TermOrder.REVTDEG: {
615                horder = new EVComparator() {
616
617
618                    @Override
619                    public int compare(ExpVector e1, ExpVector e2) {
620                        int t = -e1.invLexCompareTo(e2, evbeg1, evend1);
621                        if (t != 0) {
622                            return t;
623                        }
624                        return e1.revInvGradCompareTo(e2, evbeg2, evend2);
625                    }
626                };
627                break;
628            }
629            case TermOrder.REVITDG: {
630                horder = new EVComparator() {
631
632
633                    @Override
634                    public int compare(ExpVector e1, ExpVector e2) {
635                        int t = -e1.invLexCompareTo(e2, evbeg1, evend1);
636                        if (t != 0) {
637                            return t;
638                        }
639                        return -e1.revInvGradCompareTo(e2, evbeg2, evend2);
640                    }
641                };
642                break;
643            }
644            default: {
645                horder = null;
646            }
647            }
648            break;
649        }
650        case TermOrder.GRLEX: {
651            switch (evord2) {
652            case TermOrder.LEX: {
653                horder = new EVComparator() {
654
655
656                    @Override
657                    public int compare(ExpVector e1, ExpVector e2) {
658                        int t = e1.invGradCompareTo(e2, evbeg1, evend1);
659                        if (t != 0) {
660                            return t;
661                        }
662                        return e1.invLexCompareTo(e2, evbeg2, evend2);
663                    }
664                };
665                break;
666            }
667            case TermOrder.INVLEX: {
668                horder = new EVComparator() {
669
670
671                    @Override
672                    public int compare(ExpVector e1, ExpVector e2) {
673                        int t = e1.invGradCompareTo(e2, evbeg1, evend1);
674                        if (t != 0) {
675                            return t;
676                        }
677                        return -e1.invLexCompareTo(e2, evbeg2, evend2);
678                    }
679                };
680                break;
681            }
682            case TermOrder.GRLEX: {
683                horder = new EVComparator() {
684
685
686                    @Override
687                    public int compare(ExpVector e1, ExpVector e2) {
688                        int t = e1.invGradCompareTo(e2, evbeg1, evend1);
689                        if (t != 0) {
690                            return t;
691                        }
692                        return e1.invGradCompareTo(e2, evbeg2, evend2);
693                    }
694                };
695                break;
696            }
697            case TermOrder.IGRLEX: {
698                horder = new EVComparator() {
699
700
701                    @Override
702                    public int compare(ExpVector e1, ExpVector e2) {
703                        int t = e1.invGradCompareTo(e2, evbeg1, evend1);
704                        if (t != 0) {
705                            return t;
706                        }
707                        return -e1.invGradCompareTo(e2, evbeg2, evend2);
708                    }
709                };
710                break;
711            }
712            default: {
713                horder = null;
714            }
715            }
716            break;
717        }
718        case TermOrder.IGRLEX: {
719            switch (evord2) {
720            case TermOrder.LEX: {
721                horder = new EVComparator() {
722
723
724                    @Override
725                    public int compare(ExpVector e1, ExpVector e2) {
726                        int t = -e1.invGradCompareTo(e2, evbeg1, evend1);
727                        if (t != 0) {
728                            return t;
729                        }
730                        return e1.invLexCompareTo(e2, evbeg2, evend2);
731                    }
732                };
733                break;
734            }
735            case TermOrder.INVLEX: {
736                if (!TOP) {
737                    horder = new EVComparator() { // POT
738
739
740                        @Override
741                        public int compare(ExpVector e1, ExpVector e2) {
742                            int t = -e1.invGradCompareTo(e2, evbeg1, evend1);
743                            if (t != 0) {
744                                return t;
745                            }
746                            return -e1.invLexCompareTo(e2, evbeg2, evend2);
747                        }
748                    };
749                    break;
750                }
751                horder = new EVComparator() { // TOP
752
753
754                    @Override
755                    public int compare(ExpVector e1, ExpVector e2) {
756                        int t = -e1.invLexCompareTo(e2, evbeg2, evend2);
757                        if (t != 0) {
758                            return t;
759                        }
760                        return -e1.invGradCompareTo(e2, evbeg1, evend1);
761                    }
762                };
763                break;
764            }
765            case TermOrder.GRLEX: {
766                horder = new EVComparator() {
767
768
769                    @Override
770                    public int compare(ExpVector e1, ExpVector e2) {
771                        int t = -e1.invGradCompareTo(e2, evbeg1, evend1);
772                        if (t != 0) {
773                            return t;
774                        }
775                        return e1.invGradCompareTo(e2, evbeg2, evend2);
776                    }
777                };
778                break;
779            }
780            case TermOrder.IGRLEX: {
781                if (!TOP) {
782                    horder = new EVComparator() { // POT
783
784
785                        @Override
786                        public int compare(ExpVector e1, ExpVector e2) {
787                            int t = -e1.invGradCompareTo(e2, evbeg1, evend1);
788                            if (t != 0) {
789                                return t;
790                            }
791                            return -e1.invGradCompareTo(e2, evbeg2, evend2);
792                        }
793                    };
794                    break;
795                }
796                horder = new EVComparator() { // TOP
797
798
799                    @Override
800                    public int compare(ExpVector e1, ExpVector e2) {
801                        int t = -e1.invGradCompareTo(e2, evbeg2, evend2);
802                        if (t != 0) {
803                            return t;
804                        }
805                        return -e1.invGradCompareTo(e2, evbeg1, evend1);
806                    }
807                };
808                break;
809            }
810            case TermOrder.REVLEX: {
811                horder = new EVComparator() {
812
813
814                    @Override
815                    public int compare(ExpVector e1, ExpVector e2) {
816                        int t = -e1.invGradCompareTo(e2, evbeg1, evend1);
817                        if (t != 0) {
818                            return t;
819                        }
820                        return e1.revInvLexCompareTo(e2, evbeg2, evend2);
821                    }
822                };
823                break;
824            }
825            case TermOrder.REVILEX: {
826                horder = new EVComparator() {
827
828
829                    @Override
830                    public int compare(ExpVector e1, ExpVector e2) {
831                        int t = -e1.invGradCompareTo(e2, evbeg1, evend1);
832                        if (t != 0) {
833                            return t;
834                        }
835                        return -e1.revInvLexCompareTo(e2, evbeg2, evend2);
836                    }
837                };
838                break;
839            }
840            case TermOrder.REVTDEG: {
841                horder = new EVComparator() {
842
843
844                    @Override
845                    public int compare(ExpVector e1, ExpVector e2) {
846                        int t = -e1.invGradCompareTo(e2, evbeg1, evend1);
847                        if (t != 0) {
848                            return t;
849                        }
850                        return e1.revInvGradCompareTo(e2, evbeg2, evend2);
851                    }
852                };
853                break;
854            }
855            case TermOrder.REVITDG: {
856                horder = new EVComparator() {
857
858
859                    @Override
860                    public int compare(ExpVector e1, ExpVector e2) {
861                        int t = -e1.invGradCompareTo(e2, evbeg1, evend1);
862                        if (t != 0) {
863                            return t;
864                        }
865                        return -e1.revInvGradCompareTo(e2, evbeg2, evend2);
866                    }
867                };
868                break;
869            }
870            default: {
871                horder = null;
872            }
873            }
874            break;
875        }
876        //----- begin reversed -----------
877        case TermOrder.REVLEX: {
878            switch (evord2) {
879            case TermOrder.LEX: {
880                horder = new EVComparator() {
881
882
883                    @Override
884                    public int compare(ExpVector e1, ExpVector e2) {
885                        int t = e1.revInvLexCompareTo(e2, evbeg1, evend1);
886                        if (t != 0) {
887                            return t;
888                        }
889                        return e1.invLexCompareTo(e2, evbeg2, evend2);
890                    }
891                };
892                break;
893            }
894            case TermOrder.INVLEX: {
895                horder = new EVComparator() {
896
897
898                    @Override
899                    public int compare(ExpVector e1, ExpVector e2) {
900                        int t = e1.revInvLexCompareTo(e2, evbeg1, evend1);
901                        if (t != 0) {
902                            return t;
903                        }
904                        return -e1.invLexCompareTo(e2, evbeg2, evend2);
905                    }
906                };
907                break;
908            }
909            case TermOrder.GRLEX: {
910                horder = new EVComparator() {
911
912
913                    @Override
914                    public int compare(ExpVector e1, ExpVector e2) {
915                        int t = e1.revInvLexCompareTo(e2, evbeg1, evend1);
916                        if (t != 0) {
917                            return t;
918                        }
919                        return e1.invGradCompareTo(e2, evbeg2, evend2);
920                    }
921                };
922                break;
923            }
924            case TermOrder.IGRLEX: {
925                horder = new EVComparator() {
926
927
928                    @Override
929                    public int compare(ExpVector e1, ExpVector e2) {
930                        int t = e1.revInvLexCompareTo(e2, evbeg1, evend1);
931                        if (t != 0) {
932                            return t;
933                        }
934                        return -e1.invGradCompareTo(e2, evbeg2, evend2);
935                    }
936                };
937                break;
938            }
939            case TermOrder.REVLEX: {
940                horder = new EVComparator() {
941
942
943                    @Override
944                    public int compare(ExpVector e1, ExpVector e2) {
945                        int t = e1.revInvLexCompareTo(e2, evbeg1, evend1);
946                        if (t != 0) {
947                            return t;
948                        }
949                        return e1.revInvLexCompareTo(e2, evbeg2, evend2);
950                    }
951                };
952                break;
953            }
954            case TermOrder.REVILEX: {
955                horder = new EVComparator() {
956
957
958                    @Override
959                    public int compare(ExpVector e1, ExpVector e2) {
960                        int t = e1.revInvLexCompareTo(e2, evbeg1, evend1);
961                        if (t != 0) {
962                            return t;
963                        }
964                        return -e1.revInvLexCompareTo(e2, evbeg2, evend2);
965                    }
966                };
967                break;
968            }
969            case TermOrder.REVTDEG: {
970                horder = new EVComparator() {
971
972
973                    @Override
974                    public int compare(ExpVector e1, ExpVector e2) {
975                        int t = e1.revInvLexCompareTo(e2, evbeg1, evend1);
976                        if (t != 0) {
977                            return t;
978                        }
979                        return e1.revInvGradCompareTo(e2, evbeg2, evend2);
980                    }
981                };
982                break;
983            }
984            case TermOrder.REVITDG: {
985                horder = new EVComparator() {
986
987
988                    @Override
989                    public int compare(ExpVector e1, ExpVector e2) {
990                        int t = e1.revInvLexCompareTo(e2, evbeg1, evend1);
991                        if (t != 0) {
992                            return t;
993                        }
994                        return -e1.revInvGradCompareTo(e2, evbeg2, evend2);
995                    }
996                };
997                break;
998            }
999            default: {
1000                horder = null;
1001            }
1002            }
1003            break;
1004        }
1005        case TermOrder.REVILEX: {
1006            switch (evord2) {
1007            case TermOrder.LEX: {
1008                horder = new EVComparator() {
1009
1010
1011                    @Override
1012                    public int compare(ExpVector e1, ExpVector e2) {
1013                        int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1);
1014                        if (t != 0) {
1015                            return t;
1016                        }
1017                        return e1.invLexCompareTo(e2, evbeg2, evend2);
1018                    }
1019                };
1020                break;
1021            }
1022            case TermOrder.INVLEX: {
1023                horder = new EVComparator() {
1024
1025
1026                    @Override
1027                    public int compare(ExpVector e1, ExpVector e2) {
1028                        int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1);
1029                        if (t != 0) {
1030                            return t;
1031                        }
1032                        return -e1.invLexCompareTo(e2, evbeg2, evend2);
1033                    }
1034                };
1035                break;
1036            }
1037            case TermOrder.GRLEX: {
1038                horder = new EVComparator() {
1039
1040
1041                    @Override
1042                    public int compare(ExpVector e1, ExpVector e2) {
1043                        int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1);
1044                        if (t != 0) {
1045                            return t;
1046                        }
1047                        return e1.revInvGradCompareTo(e2, evbeg2, evend2);
1048                    }
1049                };
1050                break;
1051            }
1052            case TermOrder.IGRLEX: {
1053                horder = new EVComparator() {
1054
1055
1056                    @Override
1057                    public int compare(ExpVector e1, ExpVector e2) {
1058                        int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1);
1059                        if (t != 0) {
1060                            return t;
1061                        }
1062                        return -e1.invGradCompareTo(e2, evbeg2, evend2);
1063                    }
1064                };
1065                break;
1066            }
1067            case TermOrder.REVLEX: {
1068                horder = new EVComparator() {
1069
1070
1071                    @Override
1072                    public int compare(ExpVector e1, ExpVector e2) {
1073                        int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1);
1074                        if (t != 0) {
1075                            return t;
1076                        }
1077                        return e1.revInvLexCompareTo(e2, evbeg2, evend2);
1078                    }
1079                };
1080                break;
1081            }
1082            case TermOrder.REVILEX: {
1083                horder = new EVComparator() {
1084
1085
1086                    @Override
1087                    public int compare(ExpVector e1, ExpVector e2) {
1088                        int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1);
1089                        if (t != 0) {
1090                            return t;
1091                        }
1092                        return -e1.revInvLexCompareTo(e2, evbeg2, evend2);
1093                    }
1094                };
1095                break;
1096            }
1097            case TermOrder.REVTDEG: {
1098                horder = new EVComparator() {
1099
1100
1101                    @Override
1102                    public int compare(ExpVector e1, ExpVector e2) {
1103                        int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1);
1104                        if (t != 0) {
1105                            return t;
1106                        }
1107                        return e1.revInvGradCompareTo(e2, evbeg2, evend2);
1108                    }
1109                };
1110                break;
1111            }
1112            case TermOrder.REVITDG: {
1113                horder = new EVComparator() {
1114
1115
1116                    @Override
1117                    public int compare(ExpVector e1, ExpVector e2) {
1118                        int t = -e1.revInvLexCompareTo(e2, evbeg1, evend1);
1119                        if (t != 0) {
1120                            return t;
1121                        }
1122                        return -e1.revInvGradCompareTo(e2, evbeg2, evend2);
1123                    }
1124                };
1125                break;
1126            }
1127            default: {
1128                horder = null;
1129            }
1130            }
1131            break;
1132        }
1133        case TermOrder.REVTDEG: {
1134            switch (evord2) {
1135            case TermOrder.LEX: {
1136                horder = new EVComparator() {
1137
1138
1139                    @Override
1140                    public int compare(ExpVector e1, ExpVector e2) {
1141                        int t = e1.revInvGradCompareTo(e2, evbeg1, evend1);
1142                        if (t != 0) {
1143                            return t;
1144                        }
1145                        return e1.invLexCompareTo(e2, evbeg2, evend2);
1146                    }
1147                };
1148                break;
1149            }
1150            case TermOrder.INVLEX: {
1151                horder = new EVComparator() {
1152
1153
1154                    @Override
1155                    public int compare(ExpVector e1, ExpVector e2) {
1156                        int t = e1.revInvGradCompareTo(e2, evbeg1, evend1);
1157                        if (t != 0) {
1158                            return t;
1159                        }
1160                        return -e1.invLexCompareTo(e2, evbeg2, evend2);
1161                    }
1162                };
1163                break;
1164            }
1165            case TermOrder.GRLEX: {
1166                horder = new EVComparator() {
1167
1168
1169                    @Override
1170                    public int compare(ExpVector e1, ExpVector e2) {
1171                        int t = e1.revInvGradCompareTo(e2, evbeg1, evend1);
1172                        if (t != 0) {
1173                            return t;
1174                        }
1175                        return e1.invGradCompareTo(e2, evbeg2, evend2);
1176                    }
1177                };
1178                break;
1179            }
1180            case TermOrder.IGRLEX: {
1181                horder = new EVComparator() {
1182
1183
1184                    @Override
1185                    public int compare(ExpVector e1, ExpVector e2) {
1186                        int t = e1.revInvGradCompareTo(e2, evbeg1, evend1);
1187                        if (t != 0) {
1188                            return t;
1189                        }
1190                        return -e1.invGradCompareTo(e2, evbeg2, evend2);
1191                    }
1192                };
1193                break;
1194            }
1195            case TermOrder.REVLEX: {
1196                horder = new EVComparator() {
1197
1198
1199                    @Override
1200                    public int compare(ExpVector e1, ExpVector e2) {
1201                        int t = e1.revInvGradCompareTo(e2, evbeg1, evend1);
1202                        if (t != 0) {
1203                            return t;
1204                        }
1205                        return e1.revInvLexCompareTo(e2, evbeg2, evend2);
1206                    }
1207                };
1208                break;
1209            }
1210            case TermOrder.REVILEX: {
1211                horder = new EVComparator() {
1212
1213
1214                    @Override
1215                    public int compare(ExpVector e1, ExpVector e2) {
1216                        int t = e1.revInvGradCompareTo(e2, evbeg1, evend1);
1217                        if (t != 0) {
1218                            return t;
1219                        }
1220                        return -e1.revInvLexCompareTo(e2, evbeg2, evend2);
1221                    }
1222                };
1223                break;
1224            }
1225            case TermOrder.REVTDEG: {
1226                horder = new EVComparator() {
1227
1228
1229                    @Override
1230                    public int compare(ExpVector e1, ExpVector e2) {
1231                        int t = e1.revInvGradCompareTo(e2, evbeg1, evend1);
1232                        if (t != 0) {
1233                            return t;
1234                        }
1235                        return e1.revInvGradCompareTo(e2, evbeg2, evend2);
1236                    }
1237                };
1238                break;
1239            }
1240            case TermOrder.REVITDG: {
1241                horder = new EVComparator() {
1242
1243
1244                    @Override
1245                    public int compare(ExpVector e1, ExpVector e2) {
1246                        int t = e1.revInvGradCompareTo(e2, evbeg1, evend1);
1247                        if (t != 0) {
1248                            return t;
1249                        }
1250                        return -e1.revInvGradCompareTo(e2, evbeg2, evend2);
1251                    }
1252                };
1253                break;
1254            }
1255            default: {
1256                horder = null;
1257            }
1258            }
1259            break;
1260        }
1261        case TermOrder.REVITDG: {
1262            switch (evord2) {
1263            case TermOrder.LEX: {
1264                horder = new EVComparator() {
1265
1266
1267                    @Override
1268                    public int compare(ExpVector e1, ExpVector e2) {
1269                        int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1);
1270                        if (t != 0) {
1271                            return t;
1272                        }
1273                        return e1.invLexCompareTo(e2, evbeg2, evend2);
1274                    }
1275                };
1276                break;
1277            }
1278            case TermOrder.INVLEX: {
1279                horder = new EVComparator() {
1280
1281
1282                    @Override
1283                    public int compare(ExpVector e1, ExpVector e2) {
1284                        int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1);
1285                        if (t != 0) {
1286                            return t;
1287                        }
1288                        return -e1.invLexCompareTo(e2, evbeg2, evend2);
1289                    }
1290                };
1291                break;
1292            }
1293            case TermOrder.GRLEX: {
1294                horder = new EVComparator() {
1295
1296
1297                    @Override
1298                    public int compare(ExpVector e1, ExpVector e2) {
1299                        int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1);
1300                        if (t != 0) {
1301                            return t;
1302                        }
1303                        return e1.invGradCompareTo(e2, evbeg2, evend2);
1304                    }
1305                };
1306                break;
1307            }
1308            case TermOrder.IGRLEX: {
1309                horder = new EVComparator() {
1310
1311
1312                    @Override
1313                    public int compare(ExpVector e1, ExpVector e2) {
1314                        int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1);
1315                        if (t != 0) {
1316                            return t;
1317                        }
1318                        return -e1.invGradCompareTo(e2, evbeg2, evend2);
1319                    }
1320                };
1321                break;
1322            }
1323            case TermOrder.REVLEX: {
1324                horder = new EVComparator() {
1325
1326
1327                    @Override
1328                    public int compare(ExpVector e1, ExpVector e2) {
1329                        int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1);
1330                        if (t != 0) {
1331                            return t;
1332                        }
1333                        return e1.revInvLexCompareTo(e2, evbeg2, evend2);
1334                    }
1335                };
1336                break;
1337            }
1338            case TermOrder.REVILEX: {
1339                horder = new EVComparator() {
1340
1341
1342                    @Override
1343                    public int compare(ExpVector e1, ExpVector e2) {
1344                        int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1);
1345                        if (t != 0) {
1346                            return t;
1347                        }
1348                        return -e1.revInvLexCompareTo(e2, evbeg2, evend2);
1349                    }
1350                };
1351                break;
1352            }
1353            case TermOrder.REVTDEG: {
1354                horder = new EVComparator() {
1355
1356
1357                    @Override
1358                    public int compare(ExpVector e1, ExpVector e2) {
1359                        int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1);
1360                        if (t != 0) {
1361                            return t;
1362                        }
1363                        return e1.revInvGradCompareTo(e2, evbeg2, evend2);
1364                    }
1365                };
1366                break;
1367            }
1368            case TermOrder.REVITDG: {
1369                horder = new EVComparator() {
1370
1371
1372                    @Override
1373                    public int compare(ExpVector e1, ExpVector e2) {
1374                        int t = -e1.revInvGradCompareTo(e2, evbeg1, evend1);
1375                        if (t != 0) {
1376                            return t;
1377                        }
1378                        return -e1.revInvGradCompareTo(e2, evbeg2, evend2);
1379                    }
1380                };
1381                break;
1382            }
1383            default: {
1384                horder = null;
1385            }
1386            }
1387            break;
1388        }
1389        //----- end reversed-----------
1390        default: {
1391            horder = null;
1392        }
1393        }
1394        if (horder == null) {
1395            throw new IllegalArgumentException("invalid term order: " + evord + " 2 " + evord2);
1396        }
1397
1398        lorder = new EVComparator() {
1399
1400
1401            @Override
1402            public int compare(ExpVector e1, ExpVector e2) {
1403                return -horder.compare(e1, e2);
1404            }
1405        };
1406
1407        // sugar = new EVsugar();
1408        sugar = new EVComparator() {
1409
1410
1411            @Override
1412            public int compare(ExpVector e1, ExpVector e2) {
1413                return e1.invGradCompareTo(e2);
1414            }
1415        };
1416    }
1417
1418
1419    /*
1420     * Constructor for default split order.
1421     * @param r max number of exponents to compare.
1422     * @param split index.
1423    public TermOrder(int r, int split) {
1424        this(DEFAULT_EVORD, DEFAULT_EVORD, r, split);
1425    }
1426     */
1427
1428
1429    /**
1430     * Create block term order at split index.
1431     * @param s split index.
1432     * @return block TermOrder with split index.
1433     */
1434    public TermOrder blockOrder(int s) {
1435        return blockOrder(s, Integer.MAX_VALUE);
1436    }
1437
1438
1439    /**
1440     * Create block term order at split index.
1441     * @param s split index.
1442     * @param len length of ExpVectors to compare
1443     * @return block TermOrder with split index.
1444     */
1445    public TermOrder blockOrder(int s, int len) {
1446        return new TermOrder(evord, evord, len, s);
1447    }
1448
1449
1450    /**
1451     * Create block term order at split index.
1452     * @param s split index.
1453     * @param t second term order.
1454     * @return block TermOrder with split index.
1455     */
1456    public TermOrder blockOrder(int s, TermOrder t) {
1457        return blockOrder(s, t, Integer.MAX_VALUE);
1458    }
1459
1460
1461    /**
1462     * Create block term order at split index.
1463     * @param s split index.
1464     * @param t second term order.
1465     * @param len length of ExpVectors to compare
1466     * @return block TermOrder with split index.
1467     */
1468    public TermOrder blockOrder(int s, TermOrder t, int len) {
1469        return new TermOrder(evord, t.evord, len, s);
1470    }
1471
1472
1473    /**
1474     * Get the first defined order indicator.
1475     * @return evord.
1476     */
1477    public int getEvord() {
1478        return evord;
1479    }
1480
1481
1482    /**
1483     * Get the second defined order indicator.
1484     * @return evord2.
1485     */
1486    public int getEvord2() {
1487        return evord2;
1488    }
1489
1490
1491    /**
1492     * Get the split index.
1493     * @return split.
1494     */
1495    public int getSplit() {
1496        return evend1; // = evbeg2
1497    }
1498
1499
1500    /**
1501     * Get the exponent vector size. <b>Note:</b> can be INTEGER.MAX_VALUE.
1502     * @return size.
1503     */
1504    public int getSize() {
1505        return evend2; // can be INTEGER.MAX_VALUE
1506    }
1507
1508
1509    /**
1510     * Get the weight array.
1511     * @return weight.
1512     */
1513    public long[][] getWeight() {
1514        if (weight == null) {
1515            return null;
1516        }
1517        return Arrays.copyOf(weight, weight.length); // > Java-5
1518    }
1519
1520
1521    /**
1522     * Get the descending order comparator. Sorts the highest terms first.
1523     * @return horder.
1524     */
1525    public EVComparator getDescendComparator() {
1526        return horder;
1527    }
1528
1529
1530    /**
1531     * Get the ascending order comparator. Sorts the lowest terms first.
1532     * @return lorder.
1533     */
1534    public EVComparator getAscendComparator() {
1535        return lorder;
1536    }
1537
1538
1539    /**
1540     * Get the sugar order comparator. Sorts the graded lowest terms first.
1541     * @return sugar.
1542     */
1543    public EVComparator getSugarComparator() {
1544        return sugar;
1545    }
1546
1547
1548    /**
1549     * Comparison with any other object.
1550     * @see java.lang.Object#equals(java.lang.Object)
1551     */
1552    @Override
1553    public boolean equals(Object B) {
1554        if (!(B instanceof TermOrder)) {
1555            return false;
1556        }
1557        TermOrder b = (TermOrder) B;
1558        boolean t = evord == b.getEvord() && evord2 == b.evord2 && evbeg1 == b.evbeg1 && evend1 == b.evend1
1559                        && evbeg2 == b.evbeg2 && evend2 == b.evend2;
1560        if (!t) {
1561            return t;
1562        }
1563        if (!Arrays.deepEquals(weight, b.weight)) {
1564            return false;
1565        }
1566        return true;
1567    }
1568
1569
1570    /**
1571     * Hash code.
1572     * @see java.lang.Object#hashCode()
1573     */
1574    @Override
1575    public int hashCode() {
1576        int h = evord;
1577        h = (h << 3) + evord2;
1578        h = (h << 4) + evbeg1;
1579        h = (h << 4) + evend1;
1580        h = (h << 4) + evbeg2;
1581        h = (h << 4) + evend2;
1582        if (weight == null) {
1583            return h;
1584        }
1585        h = h * 7 + Arrays.deepHashCode(weight);
1586        return h;
1587    }
1588
1589
1590    /**
1591     * String representation of weight matrix.
1592     * @return string representation of weight matrix.
1593     */
1594    public String weightToString() {
1595        StringBuffer erg = new StringBuffer();
1596        if (weight != null) {
1597            erg.append("(");
1598            for (int j = 0; j < weight.length; j++) {
1599                if (j > 0) {
1600                    erg.append(",");
1601                }
1602                long[] wj = weight[j];
1603                erg.append("(");
1604                for (int i = 0; i < wj.length; i++) {
1605                    if (i > 0) {
1606                        erg.append(",");
1607                    }
1608                    erg.append(String.valueOf(wj[wj.length - 1 - i]));
1609                }
1610                erg.append(")");
1611            }
1612            erg.append(")");
1613        }
1614        return erg.toString();
1615    }
1616
1617
1618    /**
1619     * Script representation of weight matrix.
1620     * @return script representation of weight matrix.
1621     */
1622    public String weightToScript() {
1623        // cases Python and Ruby
1624        StringBuffer erg = new StringBuffer();
1625        if (weight != null) {
1626            erg.append("[");
1627            for (int j = 0; j < weight.length; j++) {
1628                if (j > 0) {
1629                    erg.append(",");
1630                }
1631                long[] wj = weight[j];
1632                erg.append("[");
1633                for (int i = 0; i < wj.length; i++) {
1634                    if (i > 0) {
1635                        erg.append(",");
1636                    }
1637                    erg.append(String.valueOf(wj[wj.length - 1 - i]));
1638                }
1639                erg.append("]");
1640            }
1641            erg.append("]");
1642        }
1643        return erg.toString();
1644    }
1645
1646
1647    /**
1648     * String representation of TermOrder.
1649     * @return script representation of TermOrder.
1650     */
1651    public String toScript() {
1652        // cases Python and Ruby
1653        if (weight != null) {
1654            StringBuffer erg = new StringBuffer();
1655            //erg.append("TermOrder( ");
1656            erg.append(weightToScript());
1657            if (evend1 == evend2) {
1658                //erg.append(" )");
1659                return erg.toString();
1660            }
1661            erg.append("[" + evbeg1 + "," + evend1 + "]");
1662            erg.append("[" + evbeg2 + "," + evend2 + "]");
1663            //erg.append(" )");
1664            return erg.toString();
1665        }
1666        return toScriptPlain();
1667    }
1668
1669
1670    /**
1671     * String representation of TermOrder.
1672     * @see java.lang.Object#toString()
1673     */
1674    @Override
1675    public String toString() {
1676        if (weight != null) {
1677            StringBuffer erg = new StringBuffer();
1678            erg.append("W( ");
1679            erg.append(weightToString());
1680            if (evend1 == evend2) {
1681                erg.append(" )");
1682                return erg.toString();
1683            }
1684            erg.append("[" + evbeg1 + "," + evend1 + "]");
1685            erg.append("[" + evbeg2 + "," + evend2 + "]");
1686            erg.append(" )");
1687            return erg.toString();
1688        }
1689        return toStringPlain();
1690    }
1691
1692
1693    /**
1694     * String representation of TermOrder without prefix and weight matrix.
1695     */
1696    public String toStringPlain() {
1697        StringBuffer erg = new StringBuffer();
1698        if (weight != null) {
1699            return erg.toString();
1700        }
1701        erg.append(toScriptOrder(evord)); // JAS only
1702        if (evord2 <= 0) {
1703            return erg.toString();
1704        }
1705        erg.append("[" + evbeg1 + "," + evend1 + "]");
1706        erg.append(toScriptOrder(evord2)); // JAS only
1707        erg.append("[" + evbeg2 + "," + evend2 + "]");
1708        return erg.toString();
1709    }
1710
1711
1712    /**
1713     * Script representation of TermOrder without prefix and weight matrix.
1714     */
1715    public String toScriptPlain() {
1716        StringBuffer erg = new StringBuffer();
1717        if (weight != null) {
1718            return toScript();
1719        }
1720        erg.append("Order");
1721        switch (Scripting.getLang()) {
1722        case Ruby:
1723            erg.append("::");
1724            break;
1725        case Python:
1726        default:
1727            erg.append(".");
1728        }
1729        erg.append(toScriptOrder(evord));
1730        if (evord2 <= 0) {
1731            return erg.toString();
1732        }
1733        if (evord == evord2) {
1734            erg.append(".blockOrder(" + evend1 + ")");
1735            return erg.toString();
1736        }
1737        erg.append(".blockOrder(");
1738        erg.append(evend1 + ",");
1739        erg.append("Order");
1740        switch (Scripting.getLang()) {
1741        case Ruby:
1742            erg.append("::");
1743            break;
1744        case Python:
1745        default:
1746            erg.append(".");
1747        }
1748        erg.append(toScriptOrder(evord2));
1749        erg.append(")");
1750        return erg.toString();
1751    }
1752
1753
1754    /**
1755     * Script and String representation of TermOrder name.
1756     */
1757    public String toScriptOrder(int ev) {
1758        switch (Scripting.getCAS()) {
1759        case Math:
1760            switch (ev) {
1761            case LEX:
1762                return "NegativeReverseLexicographic";
1763            case INVLEX:
1764                return "ReverseLexicographic";
1765            case GRLEX:
1766                return "NegativeDegreeReverseLexicographic";
1767            case ITDEGLEX: //IGRLEX:
1768                return "DegreeReverseLexicographic";
1769            case REVLEX:
1770                return "NegativeLexicographic";
1771            case REVILEX:
1772                return "Lexicographic";
1773            case REVITDEG: //REVTDEG:
1774                return "NegativeDegreeLexicographic";
1775            case REVITDG:
1776                return "DegreeLexicographic";
1777            default:
1778                return "invalid(" + ev + ")";
1779            }
1780        case Sage:
1781            switch (ev) {
1782            case LEX:
1783                return "negrevlex";
1784            case INVLEX:
1785                return "invlex";
1786            case GRLEX:
1787                return "negdegrevlex";
1788            case ITDEGLEX: //IGRLEX:
1789                return "degrevlex";
1790            case REVLEX:
1791                return "neglex";
1792            case REVILEX:
1793                return "lex";
1794            case REVITDEG: //REVTDEG:
1795                return "negdeglex";
1796            case REVITDG:
1797                return "deglex";
1798            default:
1799                return "invalid(" + ev + ")";
1800            }
1801        case Singular:
1802            switch (ev) {
1803            //case LEX: // missing
1804            //return "negrevlex";
1805            case INVLEX:
1806                return "rp";
1807            case GRLEX:
1808                return "ds";
1809            case ITDEGLEX: //IGRLEX:
1810                return "dp";
1811            case REVLEX:
1812                return "ls";
1813            case REVILEX:
1814                return "lp";
1815            case REVITDEG: //REVTDEG:
1816                return "Ds";
1817            case REVITDG:
1818                return "Dp";
1819            default:
1820                return "invalid(" + ev + ")";
1821            }
1822        case JAS:
1823        default:
1824            switch (ev) {
1825            case LEX:
1826                return "LEX";
1827            case INVLEX:
1828                return "INVLEX";
1829            case GRLEX:
1830                return "GRLEX";
1831            case IGRLEX:
1832                return "IGRLEX";
1833            case REVLEX:
1834                return "REVLEX";
1835            case REVILEX:
1836                return "REVILEX";
1837            case REVTDEG:
1838                return "REVTDEG";
1839            case REVITDG:
1840                return "REVITDG";
1841            case ITDEGLEX:
1842                return "ITDEGLEX";
1843            case REVITDEG:
1844                return "REVITDEG";
1845            default:
1846                return "invalid(" + ev + ")";
1847            }
1848        }
1849        //return "invalid(" + ev + ")";
1850    }
1851
1852
1853    /**
1854     * Extend variables. Used e.g. in module embedding. Extend TermOrder by k
1855     * elements. <b>Note:</b> Use POT module term order.
1856     * @param r current number of variables.
1857     * @param k number of variables to extend.
1858     * @return extended TermOrder.
1859     */
1860    public TermOrder extend(int r, int k) {
1861        return extend(r, k, false);
1862    }
1863
1864
1865    /**
1866     * Extend variables. Used e.g. in module embedding. Extend TermOrder by k
1867     * elements. <b>Note:</b> Now TOP and POT orders are distinguished.
1868     * @param r current number of variables.
1869     * @param k number of variables to extend.
1870     * @param top true for TOP term order, false for POT term order.
1871     * @return extended TermOrder.
1872     */
1873    public TermOrder extend(int r, int k, boolean top) {
1874        if (weight != null) {
1875            long[][] w = new long[weight.length][];
1876            for (int i = 0; i < weight.length; i++) {
1877                long[] wi = weight[i];
1878                long max = 0;
1879                // long min = Long.MAX_VALUE;
1880                for (int j = 0; j < wi.length; j++) {
1881                    if (wi[j] > max)
1882                        max = wi[j];
1883                    //if ( wi[j] < min ) min = wi[j];
1884                }
1885                max++;
1886                long[] wj = new long[wi.length + k];
1887                for (int j = 0; j < k; j++) { //i#k
1888                    wj[j] = max;
1889                }
1890                System.arraycopy(wi, 0, wj, k, wi.length);
1891                w[i] = wj;
1892            }
1893            return new TermOrder(w);
1894        }
1895        if (evord2 != 0) {
1896            logger.debug("warn: TermOrder is already extended");
1897            if (debug) {
1898                throw new IllegalArgumentException("TermOrder is already extended: " + this);
1899            }
1900            return new TermOrder(evord, evord2, r + k, evend1 + k, top);
1901        }
1902        //System.out.println("evord         = " + evord);
1903        //System.out.println("DEFAULT_EVORD = " + DEFAULT_EVORD);
1904        //System.out.println("tord          = " + this);
1905        return new TermOrder(DEFAULT_EVORD/*evord*/, evord, r + k, k, top);
1906        // don't change to evord, cause REVITDG || set evord1 per parameter?
1907    }
1908
1909
1910    /**
1911     * Extend lower variables. Extend TermOrder by k elements. <b>Note:</b> Use
1912     * POT module term order.
1913     * @param r current number of variables.
1914     * @param k number of variables to extend.
1915     * @return extended TermOrder.
1916     */
1917    public TermOrder extendLower(int r, int k) {
1918        return extendLower(r, k, false);
1919    }
1920
1921
1922    /**
1923     * Extend lower variables. Extend TermOrder by k elements. <b>Note:</b> Now
1924     * TOP and POT orders are distinguished.
1925     * @param r current number of variables.
1926     * @param k number of variables to extend.
1927     * @param top true for TOP term order, false for POT term order.
1928     * @return extended TermOrder.
1929     */
1930    public TermOrder extendLower(int r, int k, boolean top) {
1931        if (weight != null) {
1932            long[][] w = new long[weight.length][];
1933            for (int i = 0; i < weight.length; i++) {
1934                long[] wi = weight[i];
1935                //long max = 0;
1936                long min = Long.MAX_VALUE;
1937                for (int j = 0; j < wi.length; j++) {
1938                    //if ( wi[j] > max ) max = wi[j];
1939                    if (wi[j] < min)
1940                        min = wi[j];
1941                }
1942                //max++;
1943                long[] wj = new long[wi.length + k];
1944                for (int j = 0; j < k; j++) { //i#k
1945                    wj[wi.length + j] = min;
1946                }
1947                System.arraycopy(wi, 0, wj, 0, wi.length);
1948                w[i] = wj;
1949            }
1950            return new TermOrder(w);
1951        }
1952        if (evord2 != 0) {
1953            if (debug) {
1954                logger.warn("TermOrder is already extended");
1955            }
1956            return new TermOrder(evord, evord2, r + k, evend1 + k, top);
1957        }
1958        //System.out.println("evord         = " + evord);
1959        //System.out.println("DEFAULT_EVORD = " + DEFAULT_EVORD);
1960        //System.out.println("tord          = " + this);
1961        return new TermOrder(evord, DEFAULT_EVORD, r + k, r, top);
1962        // set evord2 per parameter?
1963    }
1964
1965
1966    /**
1967     * Contract variables. Used e.g. in module embedding. Contract TermOrder to
1968     * non split status.
1969     * @param k position of first element to be copied.
1970     * @param len new length.
1971     * @return contracted TermOrder.
1972     */
1973    public TermOrder contract(int k, int len) {
1974        if (weight != null) {
1975            long[][] w = new long[weight.length][];
1976            for (int i = 0; i < weight.length; i++) {
1977                long[] wi = weight[i];
1978                long[] wj = new long[len];
1979                System.arraycopy(wi, k, wj, 0, len);
1980                w[i] = wj;
1981            }
1982            return new TermOrder(w);
1983        }
1984        if (evord2 == 0) {
1985            if (debug) {
1986                logger.warn("TermOrder is already contracted");
1987            }
1988            return new TermOrder(evord);
1989        }
1990        if (evend1 > k) { // < IntMax since evord2 != 0
1991            int el = evend1 - k;
1992            while (el > len) {
1993                el -= len;
1994            }
1995            if (el == 0L) {
1996                return new TermOrder(evord);
1997            }
1998            if (el == len) {
1999                return new TermOrder(evord);
2000            }
2001            return new TermOrder(evord, evord2, len, el);
2002        }
2003        return new TermOrder(evord2);
2004    }
2005
2006
2007    /**
2008     * Reverse variables. Used e.g. in opposite rings.
2009     * @return TermOrder for reversed variables.
2010     */
2011    public TermOrder reverse() {
2012        return reverse(false);
2013    }
2014
2015
2016    /**
2017     * Reverse variables. Used e.g. in opposite rings.
2018     * @param partial true for partially reversed term orders.
2019     * @return TermOrder for reversed variables.
2020     */
2021    public TermOrder reverse(boolean partial) {
2022        TermOrder t;
2023        if (weight != null) {
2024            if (partial) {
2025                logger.error("partial reversed weight order not implemented");
2026            }
2027            long[][] w = new long[weight.length][];
2028            for (int i = 0; i < weight.length; i++) {
2029                long[] wi = weight[i];
2030                long[] wj = new long[wi.length];
2031                for (int j = 0; j < wj.length; j++) {
2032                    wj[j] = wi[wj.length - 1 - j];
2033                }
2034                w[i] = wj;
2035            }
2036            t = new TermOrder(w);
2037            logger.info("reverse = {}, from = {}", t, this);
2038            return t;
2039        }
2040        if (evord2 == 0) {
2041            t = new TermOrder(revert(evord));
2042            return t;
2043        }
2044        if (partial) {
2045            t = new TermOrder(revert(evord), revert(evord2), evend2, evend1);
2046        } else {
2047            t = new TermOrder(revert(evord2), revert(evord), evend2, evend2 - evbeg2);
2048        }
2049        logger.info("reverse = {}, from = {}", t, this);
2050        return t;
2051    }
2052
2053
2054    /**
2055     * Revert exponent order. Used e.g. in opposite rings.
2056     * @param evord exponent order to be reverted.
2057     * @return reverted exponent order.
2058     */
2059    public static int revert(int evord) {
2060        int i = evord;
2061        switch (evord) {
2062        case LEX:
2063            i = REVLEX;
2064            break;
2065        case INVLEX:
2066            i = REVILEX;
2067            break;
2068        case GRLEX:
2069            i = REVTDEG;
2070            break;
2071        case IGRLEX:
2072            i = REVITDG;
2073            break;
2074        case REVLEX:
2075            i = LEX;
2076            break;
2077        case REVILEX:
2078            i = INVLEX;
2079            break;
2080        case REVTDEG:
2081            i = GRLEX;
2082            break;
2083        case REVITDG:
2084            i = IGRLEX;
2085            break;
2086        default: // REVITDEG, ITDEGLEX
2087            logger.error("can not revert {}", evord);
2088            break;
2089        }
2090        return i;
2091    }
2092
2093
2094    /**
2095     * Permutation of a long array.
2096     * @param a array of long.
2097     * @param P permutation.
2098     * @return P(a).
2099     */
2100    public static long[] longArrayPermutation(List<Integer> P, long[] a) {
2101        if (a == null || a.length <= 1) {
2102            return a;
2103        }
2104        long[] b = new long[a.length];
2105        int j = 0;
2106        for (Integer i : P) {
2107            b[j] = a[i];
2108            j++;
2109        }
2110        return b;
2111    }
2112
2113
2114    /**
2115     * Permutation of the termorder.
2116     * @param P permutation.
2117     * @return P(a).
2118     */
2119    public TermOrder permutation(List<Integer> P) {
2120        TermOrder tord = this;
2121        if (getEvord2() != 0) {
2122            //throw new IllegalArgumentException("split term orders not permutable");
2123            tord = new TermOrder(getEvord2());
2124            logger.warn("split term order '{}' not permutable, resetting to most base term order {}", this, tord);
2125        }
2126        long[][] weight = getWeight();
2127        if (weight != null) {
2128            long[][] w = new long[weight.length][];
2129            for (int i = 0; i < weight.length; i++) {
2130                w[i] = longArrayPermutation(P, weight[i]);
2131            }
2132            tord = new TermOrder(w);
2133        }
2134        return tord;
2135    }
2136
2137
2138    /**
2139     * Weight TermOrder with reversed weight vectors.
2140     * @param w weight matrix
2141     * @return TermOrder with reversed weight vectors
2142     */
2143    public static TermOrder reverseWeight(long[][] w) {
2144        if (w == null) {
2145            logger.warn("null weight matrix ignored");
2146            return new TermOrder();
2147        }
2148        long[][] wr = new long[w.length][];
2149        for (int j = 0; j < w.length; j++) {
2150            long[] wj = w[j];
2151            //System.out.println("reverseWeight: " + wj);
2152            long[] wrj = new long[wj.length];
2153            for (int i = 0; i < wj.length; i++) {
2154                wrj[i] = wj[wj.length - 1 - i];
2155            }
2156            wr[j] = wrj;
2157        }
2158        return new TermOrder(wr);
2159    }
2160
2161}