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