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