001/*
002 * $Id: GenSolvablePolynomialRing.java 5909 2018-08-25 19:04:06Z kredel $
003 */
004
005package edu.jas.poly;
006
007
008import java.io.IOException;
009import java.io.Reader;
010import java.io.StringReader;
011import java.math.BigInteger;
012import java.util.ArrayList;
013import java.util.List;
014import java.util.Random;
015
016import org.apache.logging.log4j.Logger;
017import org.apache.logging.log4j.LogManager; 
018
019import edu.jas.kern.PrettyPrint;
020import edu.jas.kern.Scripting;
021import edu.jas.structure.RingElem;
022import edu.jas.structure.RingFactory;
023
024
025/**
026 * GenSolvablePolynomialRing generic solvable polynomial factory implementing
027 * RingFactory and extending GenPolynomialRing factory. Factory for n-variate
028 * ordered solvable polynomials over C. The non-commutative multiplication
029 * relations are maintained in a relation table. Almost immutable object, except
030 * variable names and relation table contents.
031 * @param <C> coefficient type.
032 * @author Heinz Kredel
033 */
034
035public class GenSolvablePolynomialRing<C extends RingElem<C>> extends GenPolynomialRing<C> {
036
037
038    //  implements RingFactory< GenSolvablePolynomial<C> > {
039
040
041    /**
042     * The solvable multiplication relations.
043     */
044    public final RelationTable<C> table;
045
046
047    /**
048     * The constant polynomial 0 for this ring. Hides super ZERO.
049     */
050    public final GenSolvablePolynomial<C> ZERO;
051
052
053    /**
054     * The constant polynomial 1 for this ring. Hides super ONE.
055     */
056    public final GenSolvablePolynomial<C> ONE;
057
058
059    private static final Logger logger = LogManager.getLogger(GenSolvablePolynomialRing.class);
060
061
062    private static final boolean debug = logger.isDebugEnabled();
063
064
065    /**
066     * The constructor creates a solvable polynomial factory object with the
067     * default term order and commutative relations.
068     * @param cf factory for coefficients of type C.
069     * @param n number of variables.
070     */
071    public GenSolvablePolynomialRing(RingFactory<C> cf, int n) {
072        this(cf, n, new TermOrder(), null, null);
073    }
074
075
076    /**
077     * The constructor creates a solvable polynomial factory object with the
078     * default term order.
079     * @param cf factory for coefficients of type C.
080     * @param n number of variables.
081     * @param rt solvable multiplication relations.
082     */
083    public GenSolvablePolynomialRing(RingFactory<C> cf, int n, RelationTable<C> rt) {
084        this(cf, n, new TermOrder(), null, rt);
085    }
086
087
088    /**
089     * The constructor creates a solvable polynomial factory object with the
090     * given term order and commutative relations.
091     * @param cf factory for coefficients of type C.
092     * @param n number of variables.
093     * @param t a term order.
094     */
095    public GenSolvablePolynomialRing(RingFactory<C> cf, int n, TermOrder t) {
096        this(cf, n, t, null, null);
097    }
098
099
100    /**
101     * The constructor creates a solvable polynomial factory object with the
102     * given term order.
103     * @param cf factory for coefficients of type C.
104     * @param n number of variables.
105     * @param t a term order.
106     * @param rt solvable multiplication relations.
107     */
108    public GenSolvablePolynomialRing(RingFactory<C> cf, int n, TermOrder t, RelationTable<C> rt) {
109        this(cf, n, t, null, rt);
110    }
111
112
113    /**
114     * The constructor creates a solvable polynomial factory object with the
115     * given term order and commutative relations.
116     * @param cf factory for coefficients of type C.
117     * @param n number of variables.
118     * @param t a term order.
119     * @param v names for the variables.
120     */
121    public GenSolvablePolynomialRing(RingFactory<C> cf, int n, TermOrder t, String[] v) {
122        this(cf, n, t, v, null);
123    }
124
125
126    /**
127     * The constructor creates a solvable polynomial factory object with the
128     * given term order and commutative relations.
129     * @param cf factory for coefficients of type C.
130     * @param t a term order.
131     * @param v names for the variables.
132     */
133    public GenSolvablePolynomialRing(RingFactory<C> cf, TermOrder t, String[] v) {
134        this(cf, v.length, t, v, null);
135    }
136
137
138    /**
139     * The constructor creates a solvable polynomial factory object with the
140     * default term order.
141     * @param cf factory for coefficients of type C.
142     * @param v names for the variables.
143     */
144    public GenSolvablePolynomialRing(RingFactory<C> cf, String[] v) {
145        this(cf, v.length, new TermOrder(), v, null);
146    }
147
148
149    /**
150     * The constructor creates a solvable polynomial factory object with the
151     * given term order.
152     * @param cf factory for coefficients of type C.
153     * @param n number of variables.
154     * @param t a term order.
155     * @param v names for the variables.
156     * @param rt solvable multiplication relations.
157     */
158    public GenSolvablePolynomialRing(RingFactory<C> cf, int n, TermOrder t, String[] v, RelationTable<C> rt) {
159        super(cf, n, t, v);
160        if (rt == null) {
161            table = new RelationTable<C>(this);
162        } else {
163            table = rt;
164        }
165        ZERO = new GenSolvablePolynomial<C>(this);
166        C coeff = coFac.getONE();
167        //evzero = ExpVector.create(nvar); // from super
168        ONE = new GenSolvablePolynomial<C>(this, coeff, evzero);
169    }
170
171
172    /**
173     * The constructor creates a solvable polynomial factory object with the the
174     * same term order, number of variables and variable names as the given
175     * polynomial factory, only the coefficient factories differ and the
176     * solvable multiplication relations are <b>empty</b>.
177     * @param cf factory for coefficients of type C.
178     * @param o other (solvable) polynomial ring.
179     */
180    public GenSolvablePolynomialRing(RingFactory<C> cf, GenPolynomialRing o) {
181        this(cf, o.nvar, o.tord, o.getVars(), null);
182    }
183
184
185    /**
186     * Generate the relation table of the solvable polynomial ring from a
187     * relation generator.
188     * @param rg relation generator.
189     */
190    public void addRelations(RelationGenerator<C> rg) {
191        rg.generate(this);
192    }
193
194
195    /**
196     * Generate the relation table of the solvable polynomial ring from a
197     * polynomial list of relations.
198     * @param rel polynomial list of relations [..., ei, fj, pij, ... ] with ei
199     *            * fj = pij.
200     */
201    public void addRelations(List<GenPolynomial<C>> rel) {
202        table.addRelations(rel);
203    }
204
205
206    /**
207     * Generate the relation table of the solvable polynomial ring from a
208     * solvable polynomial list of relations.
209     * @param rel solvable polynomial list of relations [..., ei, fj, pij, ... ]
210     *            with ei * fj = pij.
211     */
212    public void addSolvRelations(List<GenSolvablePolynomial<C>> rel) {
213        table.addSolvRelations(rel);
214    }
215
216
217    /**
218     * Get the String representation.
219     * @see java.lang.Object#toString()
220     */
221    @Override
222    public String toString() {
223        String res = super.toString();
224        if (PrettyPrint.isTrue()) {
225            res += "\n" + table.toString(vars);
226        } else {
227            res += ", #rel = " + table.size();
228        }
229        return res;
230    }
231
232
233    /**
234     * Get a scripting compatible string representation.
235     * @return script compatible representation for this Element.
236     * @see edu.jas.structure.Element#toScript()
237     */
238    @Override
239    public String toScript() {
240        StringBuffer s = new StringBuffer();
241        switch (Scripting.getLang()) {
242        case Ruby:
243            s.append("SolvPolyRing.new(");
244            break;
245        case Python:
246        default:
247            s.append("SolvPolyRing(");
248        }
249        if (coFac instanceof RingElem) {
250            s.append(((RingElem<C>) coFac).toScriptFactory());
251        } else {
252            s.append(coFac.toScript().trim());
253        }
254        s.append(",\"" + varsToString() + "\",");
255        String to = tord.toScript();
256        s.append(to);
257        if (table.size() > 0) {
258            String rel = table.toScript();
259            s.append(",rel=");
260            s.append(rel);
261        }
262        s.append(")");
263        return s.toString();
264    }
265
266
267    /**
268     * Comparison with any other object.
269     * @see java.lang.Object#equals(java.lang.Object)
270     */
271    @Override
272    @SuppressWarnings("unchecked")
273    public boolean equals(Object other) {
274        if (other == null) {
275            return false;
276        }
277        if (!(other instanceof GenSolvablePolynomialRing)) {
278            return false;
279        }
280        GenSolvablePolynomialRing<C> oring = (GenSolvablePolynomialRing<C>) other;
281        // do a super.equals( )
282        if (!super.equals(other)) {
283            return false;
284        }
285        // check same base relations
286        if (!table.equals(oring.table)) {
287            return false;
288        }
289        return true;
290    }
291
292
293    /**
294     * Hash code for this polynomial ring.
295     * @see java.lang.Object#hashCode()
296     */
297    @Override
298    public int hashCode() {
299        int h;
300        h = super.hashCode();
301        h = 37 * h + table.hashCode();
302        return h;
303    }
304
305
306    /**
307     * Get the zero element.
308     * @return 0 as GenSolvablePolynomial<C>.
309     */
310    @Override
311    public GenSolvablePolynomial<C> getZERO() {
312        return ZERO;
313    }
314
315
316    /**
317     * Get the one element.
318     * @return 1 as GenSolvablePolynomial<C>.
319     */
320    @Override
321    public GenSolvablePolynomial<C> getONE() {
322        return ONE;
323    }
324
325
326    /**
327     * Query if this ring is commutative.
328     * @return true if this ring is commutative, else false.
329     */
330    @Override
331    public boolean isCommutative() {
332        if (table.isEmpty()) {
333            return super.isCommutative();
334        }
335        return false;
336    }
337
338
339    /**
340     * Query if this ring is associative. Test if the relations define an
341     * associative solvable ring.
342     * @return true, if this ring is associative, else false.
343     */
344    @SuppressWarnings("unused")
345    @Override
346    public boolean isAssociative() {
347        GenSolvablePolynomial<C> Xi, Xj, Xk, p, q;
348        for (int i = 0; i < nvar; i++) {
349            Xi = univariate(i);
350            for (int j = i + 1; j < nvar; j++) {
351                Xj = univariate(j);
352                for (int k = j + 1; k < nvar; k++) {
353                    Xk = univariate(k);
354                    p = Xk.multiply(Xj).multiply(Xi);
355                    q = Xk.multiply(Xj.multiply(Xi));
356                    if (!p.equals(q)) {
357                        if (true || debug) {
358                            logger.info("Xi = " + Xi + ", Xj = " + Xj + ", Xk = " + Xk);
359                            logger.info("p = ( Xk * Xj ) * Xi = " + p);
360                            logger.info("q = Xk * ( Xj * Xi ) = " + q);
361                        }
362                        return false;
363                    }
364                }
365            }
366        }
367        return coFac.isAssociative();
368    }
369
370
371    /**
372     * Get a (constant) GenPolynomial&lt;C&gt; element from a coefficient value.
373     * @param a coefficient.
374     * @return a GenPolynomial&lt;C&gt;.
375     */
376    @Override
377    public GenSolvablePolynomial<C> valueOf(C a) {
378        return new GenSolvablePolynomial<C>(this, a);
379    }
380
381
382    /**
383     * Get a GenPolynomial&lt;C&gt; element from an exponent vector.
384     * @param e exponent vector.
385     * @return a GenPolynomial&lt;C&gt;.
386     */
387    @Override
388    public GenSolvablePolynomial<C> valueOf(ExpVector e) {
389        return new GenSolvablePolynomial<C>(this, coFac.getONE(), e);
390    }
391
392
393    /**
394     * Get a GenPolynomial&lt;C&gt; element from a coeffcient and an exponent
395     * vector.
396     * @param a coefficient.
397     * @param e exponent vector.
398     * @return a GenPolynomial&lt;C&gt;.
399     */
400    @Override
401    public GenSolvablePolynomial<C> valueOf(C a, ExpVector e) {
402        return new GenSolvablePolynomial<C>(this, a, e);
403    }
404
405
406    /**
407     * Get a (constant) GenSolvablePolynomial&lt;C&gt; element from a long
408     * value.
409     * @param a long.
410     * @return a GenSolvablePolynomial&lt;C&gt;.
411     */
412    @Override
413    public GenSolvablePolynomial<C> fromInteger(long a) {
414        return new GenSolvablePolynomial<C>(this, coFac.fromInteger(a), evzero);
415    }
416
417
418    /**
419     * Get a (constant) GenSolvablePolynomial&lt;C&gt; element from a BigInteger
420     * value.
421     * @param a BigInteger.
422     * @return a GenSolvablePolynomial&lt;C&gt;.
423     */
424    @Override
425    public GenSolvablePolynomial<C> fromInteger(BigInteger a) {
426        return new GenSolvablePolynomial<C>(this, coFac.fromInteger(a), evzero);
427    }
428
429
430    /**
431     * Random solvable polynomial. Generates a random solvable polynomial with k
432     * = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3.
433     * @param n number of terms.
434     * @return a random solvable polynomial.
435     */
436    @Override
437    public GenSolvablePolynomial<C> random(int n) {
438        return random(n, random);
439    }
440
441
442    /**
443     * Random solvable polynomial. Generates a random solvable polynomial with k
444     * = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3.
445     * @param n number of terms.
446     * @param rnd is a source for random bits.
447     * @return a random solvable polynomial.
448     */
449    @Override
450    public GenSolvablePolynomial<C> random(int n, Random rnd) {
451        if (nvar == 1) {
452            return random(5, n, n, 0.7f, rnd);
453        }
454        return random(5, n, 3, 0.3f, rnd);
455    }
456
457
458    /**
459     * Generate a random solvable polynomial.
460     * @param k bitsize of random coefficients.
461     * @param l number of terms.
462     * @param d maximal degree in each variable.
463     * @param q density of nozero exponents.
464     * @return a random solvable polynomial.
465     */
466    @Override
467    public GenSolvablePolynomial<C> random(int k, int l, int d, float q) {
468        return random(k, l, d, q, random);
469    }
470
471
472    /**
473     * Random solvable polynomial.
474     * @param k size of random coefficients.
475     * @param l number of terms.
476     * @param d maximal degree in each variable.
477     * @param q density of nozero exponents.
478     * @param rnd is a source for random bits.
479     * @return a random solvable polynomial.
480     */
481    @Override
482    public GenSolvablePolynomial<C> random(int k, int l, int d, float q, Random rnd) {
483        GenSolvablePolynomial<C> r = getZERO(); //.clone();
484        // copy( ZERO ); 
485        // new GenPolynomial<C>( this, getZERO().val );
486        ExpVector e;
487        C a;
488        // add random coeffs and exponents
489        for (int i = 0; i < l; i++) {
490            e = ExpVector.random(nvar, d, q, rnd);
491            a = coFac.random(k, rnd);
492            r = (GenSolvablePolynomial<C>) r.sum(a, e);
493            // somewhat inefficient but clean
494        }
495        return r;
496    }
497
498
499    /**
500     * Copy polynomial c.
501     * @param c
502     * @return a copy of c.
503     */
504    public GenSolvablePolynomial<C> copy(GenSolvablePolynomial<C> c) {
505        return new GenSolvablePolynomial<C>(this, c.val);
506    }
507
508
509    /**
510     * Parse a solvable polynomial with the use of GenPolynomialTokenizer
511     * @param s String.
512     * @return GenSolvablePolynomial from s.
513     */
514    @Override
515    public GenSolvablePolynomial<C> parse(String s) {
516        //return getZERO();
517        return parse(new StringReader(s));
518    }
519
520
521    /**
522     * Parse a solvable polynomial with the use of GenPolynomialTokenizer
523     * @param r Reader.
524     * @return next GenSolvablePolynomial from r.
525     */
526    @Override
527    @SuppressWarnings({ "unchecked", "cast" })
528    public GenSolvablePolynomial<C> parse(Reader r) {
529        GenPolynomialTokenizer pt = new GenPolynomialTokenizer(this, r);
530        GenSolvablePolynomial<C> p = null;
531        try {
532            p = (GenSolvablePolynomial<C>) pt.nextSolvablePolynomial();
533        } catch (IOException e) {
534            logger.error(e.toString() + " parse " + this);
535            p = ZERO;
536        }
537        return p;
538    }
539
540
541    /**
542     * Generate univariate solvable polynomial in a given variable.
543     * @param i the index of the variable.
544     * @return X_i as solvable univariate polynomial.
545     */
546    @Override
547    public GenSolvablePolynomial<C> univariate(int i) {
548        return (GenSolvablePolynomial<C>) super.univariate(i);
549    }
550
551
552    /**
553     * Generate univariate solvable polynomial in a given variable with given
554     * exponent.
555     * @param i the index of the variable.
556     * @param e the exponent of the variable.
557     * @return X_i^e as solvable univariate polynomial.
558     */
559    @Override
560    public GenSolvablePolynomial<C> univariate(int i, long e) {
561        return (GenSolvablePolynomial<C>) super.univariate(i, e);
562    }
563
564
565    /**
566     * Generate univariate solvable polynomial in a given variable with given
567     * exponent.
568     * @param modv number of module variables.
569     * @param i the index of the variable.
570     * @param e the exponent of the variable.
571     * @return X_i^e as solvable univariate polynomial.
572     */
573    @Override
574    public GenSolvablePolynomial<C> univariate(int modv, int i, long e) {
575        return (GenSolvablePolynomial<C>) super.univariate(modv, i, e);
576    }
577
578
579    /**
580     * Generate list of univariate polynomials in all variables.
581     * @return List(X_1,...,X_n) a list of univariate polynomials.
582     */
583    @Override
584    public List<? extends GenSolvablePolynomial<C>> univariateList() {
585        //return castToSolvableList( super.univariateList() );
586        return univariateList(0, 1L);
587    }
588
589
590    /**
591     * Generate list of univariate polynomials in all variables.
592     * @param modv number of module variables.
593     * @return List(X_1,...,X_n) a list of univariate polynomials.
594     */
595    @Override
596    public List<? extends GenSolvablePolynomial<C>> univariateList(int modv) {
597        return univariateList(modv, 1L);
598    }
599
600
601    /**
602     * Generate list of univariate polynomials in all variables with given
603     * exponent.
604     * @param modv number of module variables.
605     * @param e the exponent of the variables.
606     * @return List(X_1^e,...,X_n^e) a list of univariate polynomials.
607     */
608    @Override
609    public List<? extends GenSolvablePolynomial<C>> univariateList(int modv, long e) {
610        List<GenSolvablePolynomial<C>> pols = new ArrayList<GenSolvablePolynomial<C>>(nvar);
611        int nm = nvar - modv;
612        for (int i = 0; i < nm; i++) {
613            GenSolvablePolynomial<C> p = univariate(modv, nm - 1 - i, e);
614            pols.add(p);
615        }
616        return pols;
617    }
618
619
620    /**
621     * Extend variables. Used e.g. in module embedding. Extend number of
622     * variables by i. New variables commute with the exiting variables.
623     * @param i number of variables to extend.
624     * @return extended solvable polynomial ring factory.
625     */
626    @Override
627    public GenSolvablePolynomialRing<C> extend(int i) {
628        return extend(i,false);
629    }
630
631    
632    /**
633     * Extend variables. Used e.g. in module embedding. Extend number of
634     * variables by i. New variables commute with the exiting variables.
635     * @param i number of variables to extend.
636     * @param top true for TOP term order, false for POT term order.
637     * @return extended solvable polynomial ring factory.
638     */
639    @Override
640    public GenSolvablePolynomialRing<C> extend(int i, boolean top) {
641        GenPolynomialRing<C> pfac = super.extend(i, top);
642        GenSolvablePolynomialRing<C> spfac = new GenSolvablePolynomialRing<C>(pfac.coFac, pfac.nvar,
643                        pfac.tord, pfac.vars);
644        spfac.table.extend(this.table);
645        return spfac;
646    }
647
648
649    /**
650     * Extend variables. Used e.g. in module embedding. Extend number of
651     * variables by length(vn). New variables commute with the exiting
652     * variables.
653     * @param vn names for extended variables.
654     * @return extended polynomial ring factory.
655     */
656    @Override
657    public GenSolvablePolynomialRing<C> extend(String[] vn) {
658        return extend(vn, false);
659    }
660
661    
662    /**
663     * Extend variables. Used e.g. in module embedding. Extend number of
664     * variables by length(vn). New variables commute with the exiting
665     * variables.
666     * @param vn names for extended variables.
667     * @param top true for TOP term order, false for POT term order.
668     * @return extended polynomial ring factory.
669     */
670    @Override
671    public GenSolvablePolynomialRing<C> extend(String[] vn, boolean top) {
672        GenPolynomialRing<C> pfac = super.extend(vn, top);
673        GenSolvablePolynomialRing<C> spfac = new GenSolvablePolynomialRing<C>(pfac.coFac, pfac.nvar,
674                        pfac.tord, pfac.vars);
675        //GenSolvablePolynomialRing<C> spfac = new GenSolvablePolynomialRing<C>(pfac.coFac, pfac);
676        spfac.table.extend(this.table);
677        return spfac;
678    }
679
680
681    /**
682     * Contract variables. Used e.g. in module embedding. Contract number of
683     * variables by i.
684     * @param i number of variables to remove.
685     * @return contracted solvable polynomial ring factory.
686     */
687    @Override
688    public GenSolvablePolynomialRing<C> contract(int i) {
689        GenPolynomialRing<C> pfac = super.contract(i);
690        GenSolvablePolynomialRing<C> spfac = new GenSolvablePolynomialRing<C>(pfac.coFac, pfac.nvar,
691                        pfac.tord, pfac.vars);
692        spfac.table.contract(this.table);
693        return spfac;
694    }
695
696
697    /**
698     * Reverse variables. Used e.g. in opposite rings.
699     * @return solvable polynomial ring factory with reversed variables.
700     */
701    @Override
702    public GenSolvablePolynomialRing<C> reverse() {
703        return reverse(false);
704    }
705
706
707    /**
708     * Reverse variables. Used e.g. in opposite rings.
709     * @param partial true for partialy reversed term orders.
710     * @return solvable polynomial ring factory with reversed variables.
711     */
712    @Override
713    public GenSolvablePolynomialRing<C> reverse(boolean partial) {
714        GenPolynomialRing<C> pfac = super.reverse(partial);
715        GenSolvablePolynomialRing<C> spfac = new GenSolvablePolynomialRing<C>(pfac.coFac, pfac.nvar,
716                        pfac.tord, pfac.vars);
717        spfac.partial = partial;
718        spfac.table.reverse(this.table);
719        return spfac;
720    }
721
722
723    /**
724     * Recursive representation as polynomial ring with i main variables.
725     * @param i number of main variables.
726     * @return recursive polynomial ring factory.
727     */
728    @Override
729    public GenSolvablePolynomialRing<GenPolynomial<C>> recursive(int i) {
730        if (i <= 0 || i >= nvar) {
731            throw new IllegalArgumentException("wrong: 0 < " + i + " < " + nvar);
732        }
733        GenSolvablePolynomialRing<C> cfac = contract(i);
734        //System.out.println("cvars = " + Arrays.toString(cfac.vars));
735        //System.out.println("vars = " + Arrays.toString(vars));
736        String[] v = null;
737        if (vars != null) {
738            v = new String[i];
739            int k = 0;
740            for (int j = nvar - i; j < nvar; j++) {
741                v[k++] = vars[j];
742            }
743        }
744        //System.out.println("v = " + Arrays.toString(v));
745        TermOrder to = tord.contract(0, i); // ??
746        RecSolvablePolynomialRing<C> pfac = new RecSolvablePolynomialRing<C>(cfac, i, to, v);
747        //System.out.println("pfac = " + pfac.toScript());
748        pfac.table.recursive(table);
749        pfac.coeffTable.recursive(table);
750        return pfac;
751    }
752
753
754    /**
755     * Distributive representation as polynomial with all main variables.
756     * @return distributive polynomial ring factory.
757     */
758    @SuppressWarnings({ "unchecked", "cast" })
759    @Override
760    public GenSolvablePolynomialRing<C> distribute() {
761        if (!(coFac instanceof GenPolynomialRing)) {
762            return this;
763        }
764        RingFactory cf = coFac;
765        RingFactory<GenPolynomial<C>> cfp = (RingFactory<GenPolynomial<C>>) cf;
766        GenPolynomialRing cr = (GenPolynomialRing) cfp;
767        //System.out.println("cr = " + cr.toScript());
768        GenPolynomialRing<C> fac;
769        if (cr.vars != null) {
770            fac = cr.extend(vars);
771        } else {
772            fac = cr.extend(nvar);
773        }
774        //System.out.println("fac = " + fac.toScript());
775        // fac could be a commutative polynomial ring, coefficient relations
776        GenSolvablePolynomialRing<C> pfac = new GenSolvablePolynomialRing<C>(fac.coFac, fac.nvar, this.tord,
777                        fac.vars);
778        //System.out.println("pfac = " + pfac.toScript());
779        if (fac instanceof GenSolvablePolynomialRing) {
780            GenSolvablePolynomialRing<C> sfac = (GenSolvablePolynomialRing<C>) fac;
781            List<GenSolvablePolynomial<C>> rlc = sfac.table.relationList();
782            pfac.table.addSolvRelations(rlc);
783            //System.out.println("pfac = " + pfac.toScript());
784        }
785        // main relations
786        List<GenPolynomial<GenPolynomial<C>>> rl = (List<GenPolynomial<GenPolynomial<C>>>) (List) PolynomialList
787                        .castToList(table.relationList());
788        List<GenPolynomial<C>> rld = PolyUtil.<C> distribute(pfac, rl);
789        pfac.table.addRelations(rld);
790        //System.out.println("pfac = " + pfac.toScript());
791        // coeffTable not avaliable here
792        return pfac;
793    }
794
795
796    /**
797     * Permutation of polynomial ring variables.
798     * @param P permutation, must be compatible with the commutator relations.
799     * @return P(this).
800     */
801    @Override
802    public GenPolynomialRing<C> permutation(List<Integer> P) {
803        GenPolynomialRing<C> pfac = super.permutation(P);
804        GenSolvablePolynomialRing<C> spfac;
805        spfac = new GenSolvablePolynomialRing<C>(pfac.coFac, pfac.nvar, pfac.tord, pfac.vars);
806        List<GenSolvablePolynomial<C>> rl = this.table.relationList();
807        PolynomialList<C> prl = new PolynomialList<C>(spfac,rl);
808        List<GenPolynomial<C>> pl = prl.getList();
809        pl = TermOrderOptimization.permutation(P, spfac, pl);
810        spfac.table.addRelations(pl);
811        return spfac;
812    }
813
814}