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