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