001/*
002 * $Id: RecSolvableWordPolynomialRing.java 5205 2015-04-05 10:32:54Z 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.log4j.Logger;
017
018import edu.jas.kern.PrettyPrint;
019import edu.jas.kern.Scripting;
020import edu.jas.structure.RingElem;
021import edu.jas.structure.RingFactory;
022
023
024/**
025 * RecSolvableWordPolynomialRing generic recursive solvable polynomial factory
026 * implementing RingFactory and extending GenSolvablePolynomialRing factory.
027 * Factory for n-variate ordered solvable polynomials over non-commutative word
028 * polynomial coefficients. The non-commutative multiplication relations are
029 * maintained in a relation table and the non-commutative multiplication
030 * relations between the coefficients and the main variables are maintained in a
031 * coefficient relation table. Almost immutable object, except variable names
032 * and relation table contents.
033 * @param <C> base coefficient type.
034 * @author Heinz Kredel
035 */
036
037public class RecSolvableWordPolynomialRing<C extends RingElem<C>> extends
038                GenSolvablePolynomialRing<GenWordPolynomial<C>> {
039
040
041    /**
042     * The solvable multiplication relations between variables and coefficients.
043     */
044    public final RelationTable<GenWordPolynomial<C>> coeffTable;
045
046
047    /**
048     * The constant polynomial 0 for this ring. Hides super ZERO.
049     */
050    public final RecSolvableWordPolynomial<C> ZERO;
051
052
053    /**
054     * The constant polynomial 1 for this ring. Hides super ONE.
055     */
056    public final RecSolvableWordPolynomial<C> ONE;
057
058
059    private static final Logger logger = Logger.getLogger(RecSolvableWordPolynomialRing.class);
060
061
062    private 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 RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<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 RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, int n,
084                    RelationTable<GenWordPolynomial<C>> rt) {
085        this(cf, n, new TermOrder(), null, rt);
086    }
087
088
089    /**
090     * The constructor creates a solvable polynomial factory object with the
091     * given term order and commutative relations.
092     * @param cf factory for coefficients of type C.
093     * @param n number of variables.
094     * @param t a term order.
095     */
096    public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, int n, TermOrder t) {
097        this(cf, n, t, null, null);
098    }
099
100
101    /**
102     * The constructor creates a solvable polynomial factory object with the
103     * given term order.
104     * @param cf factory for coefficients of type C.
105     * @param n number of variables.
106     * @param t a term order.
107     * @param rt solvable multiplication relations.
108     */
109    public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, int n, TermOrder t,
110                    RelationTable<GenWordPolynomial<C>> rt) {
111        this(cf, n, t, null, rt);
112    }
113
114
115    /**
116     * The constructor creates a solvable polynomial factory object with the
117     * given term order and commutative relations.
118     * @param cf factory for coefficients of type C.
119     * @param n number of variables.
120     * @param t a term order.
121     * @param v names for the variables.
122     */
123    public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, int n, TermOrder t, String[] v) {
124        this(cf, n, t, v, null);
125    }
126
127
128    /**
129     * The constructor creates a solvable polynomial factory object with the
130     * given term order and commutative relations.
131     * @param cf factory for coefficients of type C.
132     * @param t a term order.
133     * @param v names for the variables.
134     */
135    public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, TermOrder t, String[] v) {
136        this(cf, v.length, t, v, null);
137    }
138
139
140    /**
141     * The constructor creates a solvable polynomial factory object with the
142     * default term order.
143     * @param cf factory for coefficients of type C.
144     * @param v names for the variables.
145     */
146    public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, String[] v) {
147        this(cf, v.length, new TermOrder(), v, null);
148    }
149
150
151    /**
152     * The constructor creates a solvable polynomial factory object with the
153     * given term order.
154     * @param cf factory for coefficients of type C.
155     * @param n number of variables.
156     * @param t a term order.
157     * @param v names for the variables.
158     * @param rt solvable multiplication relations.
159     */
160    public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, int n, TermOrder t,
161                    String[] v, RelationTable<GenWordPolynomial<C>> rt) {
162        super(cf, n, t, v, rt);
163        //if (rt == null) { // handled in super }
164        coeffTable = new RelationTable<GenWordPolynomial<C>>(this, true);
165        ZERO = new RecSolvableWordPolynomial<C>(this);
166        GenWordPolynomial<C> coeff = coFac.getONE();
167        //evzero = ExpVector.create(nvar); // from super
168        ONE = new RecSolvableWordPolynomial<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 RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, RecSolvableWordPolynomialRing o) {
181        this(cf, o.nvar, o.tord, o.getVars(), null);
182    }
183
184
185    /**
186     * Get the String representation.
187     * @see java.lang.Object#toString()
188     */
189    @Override
190    public String toString() {
191        String res = super.toString();
192        if (PrettyPrint.isTrue()) {
193            //res += "\n" + table.toString(vars);
194            res += "\n" + coeffTable.toString(vars);
195        } else {
196            res += ", #rel = " + table.size() + " + " + coeffTable.size();
197        }
198        return res;
199    }
200
201
202    /**
203     * Get a scripting compatible string representation.
204     * @return script compatible representation for this Element.
205     * @see edu.jas.structure.Element#toScript()
206     */
207    @Override
208    public String toScript() {
209        StringBuffer s = new StringBuffer();
210        switch (Scripting.getLang()) {
211        case Ruby:
212            s.append("SolvPolyRing.new(");
213            break;
214        case Python:
215        default:
216            s.append("SolvPolyRing(");
217        }
218        if (coFac instanceof RingElem) {
219            s.append(((RingElem<GenWordPolynomial<C>>) coFac).toScriptFactory());
220        } else {
221            s.append(coFac.toScript().trim());
222        }
223        s.append(",\"" + varsToString() + "\",");
224        String to = tord.toString();
225        if (tord.getEvord() == TermOrder.INVLEX) {
226            to = "PolyRing.lex";
227        }
228        if (tord.getEvord() == TermOrder.IGRLEX) {
229            to = "PolyRing.grad";
230        }
231        s.append(to);
232        if (table.size() > 0) {
233            String rel = table.toScript();
234            s.append(",rel=");
235            s.append(rel);
236        }
237        if (coeffTable.size() > 0) {
238            String rel = coeffTable.toScript();
239            s.append(",coeffrel=");
240            s.append(rel);
241        }
242        s.append(")");
243        return s.toString();
244    }
245
246
247    /**
248     * Comparison with any other object.
249     * @see java.lang.Object#equals(java.lang.Object)
250     */
251    @Override
252    @SuppressWarnings("unchecked")
253    public boolean equals(Object other) {
254        if (other == null) {
255            return false;
256        }
257        if (!(other instanceof RecSolvableWordPolynomialRing)) {
258            return false;
259        }
260        // do a super.equals( )
261        if (!super.equals(other)) {
262            return false;
263        }
264        RecSolvableWordPolynomialRing<C> oring = (RecSolvableWordPolynomialRing<C>) other;
265        // check same base relations
266        //if ( ! table.equals(oring.table) ) { // done in super
267        //    return false;
268        //}
269        if (!coeffTable.equals(oring.coeffTable)) {
270            return false;
271        }
272        return true;
273    }
274
275
276    /**
277     * Hash code for this polynomial ring.
278     * @see java.lang.Object#hashCode()
279     */
280    @Override
281    public int hashCode() {
282        int h;
283        h = super.hashCode();
284        h = 37 * h + table.hashCode(); // may be different after some computations
285        h = 37 * h + coeffTable.hashCode(); // may be different
286        return h;
287    }
288
289
290    /**
291     * Get the zero element.
292     * @return 0 as RecSolvableWordPolynomial<C>.
293     */
294    @Override
295    public RecSolvableWordPolynomial<C> getZERO() {
296        return ZERO;
297    }
298
299
300    /**
301     * Get the one element.
302     * @return 1 as RecSolvableWordPolynomial<C>.
303     */
304    @Override
305    public RecSolvableWordPolynomial<C> getONE() {
306        return ONE;
307    }
308
309
310    /**
311     * Query if this ring is commutative.
312     * @return true if this ring is commutative, else false.
313     */
314    @Override
315    public boolean isCommutative() {
316        if (coeffTable.isEmpty()) {
317            return super.isCommutative();
318        }
319        return false;
320    }
321
322
323    /**
324     * Query if this ring is associative. Test if the relations between the mian
325     * variables and the coefficient generators define an associative solvable
326     * ring.
327     * @return true, if this ring is associative, else false.
328     */
329    @SuppressWarnings("unused")
330    @Override
331    public boolean isAssociative() {
332        if (!coFac.isAssociative()) {
333            return false;
334        }
335        RecSolvableWordPolynomial<C> Xi, Xj, Xk, p, q;
336        List<GenPolynomial<GenWordPolynomial<C>>> gens = generators();
337        //System.out.println("Rec word gens = " + gens);
338        int ngen = gens.size();
339        for (int i = 0; i < ngen; i++) {
340            Xi = (RecSolvableWordPolynomial<C>) gens.get(i);
341            if (Xi.isONE()) {
342                continue;
343            }
344            for (int j = i + 1; j < ngen; j++) {
345                Xj = (RecSolvableWordPolynomial<C>) gens.get(j);
346                for (int k = j + 1; k < ngen; k++) {
347                    Xk = (RecSolvableWordPolynomial<C>) gens.get(k);
348                    try {
349                        p = Xk.multiply(Xj).multiply(Xi);
350                        q = Xk.multiply(Xj.multiply(Xi));
351                        if (!p.equals(q)) {
352                            if (true || debug) {
353                                logger.info("Xk = " + Xk + ", Xj = " + Xj + ", Xi = " + Xi);
354                                logger.info("p = ( Xk * Xj ) * Xi = " + p);
355                                logger.info("q = Xk * ( Xj * Xi ) = " + q);
356                            }
357                            return false;
358                        }
359                    } catch (RuntimeException e) {
360                        e.printStackTrace();
361                        System.out.println("Xk = " + Xk + ", Xj = " + Xj + ", Xi = " + Xi);
362                    }
363                }
364            }
365        }
366        return true;
367    }
368
369
370    /**
371     * Get a (constant) RecSolvableWordPolynomial&lt;C&gt; element from a
372     * coefficient value.
373     * @param a coefficient.
374     * @return a RecSolvableWordPolynomial&lt;C&gt;.
375     */
376    @Override
377    public RecSolvableWordPolynomial<C> valueOf(GenWordPolynomial<C> a) {
378        return new RecSolvableWordPolynomial<C>(this, a);
379    }
380
381
382    /**
383     * Get a RecSolvableWordPolynomial&lt;C&gt; element from an ExpVector.
384     * @param e exponent vector.
385     * @return a RecSolvableWordPolynomial&lt;C&gt;.
386     */
387    @Override
388    public RecSolvableWordPolynomial<C> valueOf(ExpVector e) {
389        return valueOf(coFac.getONE(), e);
390    }
391
392
393    /**
394     * Get a RecSolvableWordPolynomial&lt;C&gt; element from a coeffcient and an
395     * ExpVector.
396     * @param a coefficient.
397     * @param e exponent vector.
398     * @return a RecSolvableWordPolynomial&lt;C&gt;.
399     */
400    @Override
401    public RecSolvableWordPolynomial<C> valueOf(GenWordPolynomial<C> a, ExpVector e) {
402        return new RecSolvableWordPolynomial<C>(this, a, e);
403    }
404
405
406    /**
407     * Get a (constant) RecSolvableWordPolynomial&lt;C&gt; element from a long
408     * value.
409     * @param a long.
410     * @return a RecSolvableWordPolynomial&lt;C&gt;.
411     */
412    @Override
413    public RecSolvableWordPolynomial<C> fromInteger(long a) {
414        return new RecSolvableWordPolynomial<C>(this, coFac.fromInteger(a), evzero);
415    }
416
417
418    /**
419     * Get a (constant) RecSolvableWordPolynomial&lt;C&gt; element from a
420     * BigInteger value.
421     * @param a BigInteger.
422     * @return a RecSolvableWordPolynomial&lt;C&gt;.
423     */
424    @Override
425    public RecSolvableWordPolynomial<C> fromInteger(BigInteger a) {
426        return new RecSolvableWordPolynomial<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 RecSolvableWordPolynomial<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 RecSolvableWordPolynomial<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 RecSolvableWordPolynomial<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 RecSolvableWordPolynomial<C> random(int k, int l, int d, float q, Random rnd) {
483        RecSolvableWordPolynomial<C> r = getZERO(); // copy( ZERO ); 
484        ExpVector e;
485        GenWordPolynomial<C> a;
486        // add random coeffs and exponents
487        for (int i = 0; i < l; i++) {
488            e = ExpVector.EVRAND(nvar, d, q, rnd);
489            a = coFac.random(k, rnd);
490            r = (RecSolvableWordPolynomial<C>) r.sum(a, e);
491            // somewhat inefficient but clean
492        }
493        return r;
494    }
495
496
497    /**
498     * Copy polynomial c.
499     * @param c
500     * @return a copy of c.
501     */
502    public RecSolvableWordPolynomial<C> copy(RecSolvableWordPolynomial<C> c) {
503        return new RecSolvableWordPolynomial<C>(this, c.val);
504    }
505
506
507    /**
508     * Parse a solvable polynomial with the use of GenPolynomialTokenizer
509     * @param s String.
510     * @return RecSolvableWordPolynomial from s.
511     */
512    @Override
513    public RecSolvableWordPolynomial<C> parse(String s) {
514        return parse(new StringReader(s));
515    }
516
517
518    /**
519     * Parse a solvable polynomial with the use of GenPolynomialTokenizer
520     * @param r Reader.
521     * @return next RecSolvableWordPolynomial from r.
522     */
523    @Override
524    @SuppressWarnings("unchecked")
525    public RecSolvableWordPolynomial<C> parse(Reader r) {
526        GenPolynomialTokenizer pt = new GenPolynomialTokenizer(this, r);
527        RecSolvableWordPolynomial<C> p = null;
528        try {
529            GenSolvablePolynomial<GenWordPolynomial<C>> s = pt.nextSolvablePolynomial();
530            p = new RecSolvableWordPolynomial<C>(this, s);
531        } catch (IOException e) {
532            logger.error(e.toString() + " parse " + this);
533            p = ZERO;
534        }
535        return p;
536    }
537
538
539    /**
540     * Generate univariate solvable polynomial in a given variable.
541     * @param i the index of the variable.
542     * @return X_i as solvable univariate polynomial.
543     */
544    @Override
545    public RecSolvableWordPolynomial<C> univariate(int i) {
546        return (RecSolvableWordPolynomial<C>) super.univariate(i);
547    }
548
549
550    /**
551     * Generate univariate solvable polynomial in a given variable with given
552     * exponent.
553     * @param i the index of the variable.
554     * @param e the exponent of the variable.
555     * @return X_i^e as solvable univariate polynomial.
556     */
557    @Override
558    public RecSolvableWordPolynomial<C> univariate(int i, long e) {
559        return (RecSolvableWordPolynomial<C>) super.univariate(i, e);
560    }
561
562
563    /**
564     * Generate univariate solvable polynomial in a given variable with given
565     * exponent.
566     * @param modv number of module variables.
567     * @param i the index of the variable.
568     * @param e the exponent of the variable.
569     * @return X_i^e as solvable univariate polynomial.
570     */
571    @Override
572    public RecSolvableWordPolynomial<C> univariate(int modv, int i, long e) {
573        return (RecSolvableWordPolynomial<C>) super.univariate(modv, i, e);
574    }
575
576
577    /**
578     * Generate list of univariate polynomials in all variables.
579     * @return List(X_1,...,X_n) a list of univariate polynomials.
580     */
581    //todo Override
582    @SuppressWarnings("unchecked")
583    public List<RecSolvableWordPolynomial<C>> recUnivariateList() {
584        //return castToSolvableList( super.univariateList() );
585        return (List<RecSolvableWordPolynomial<C>>) (Object) univariateList(0, 1L);
586    }
587
588
589    /**
590     * Generate list of univariate polynomials in all variables.
591     * @param modv number of module variables.
592     * @return List(X_1,...,X_n) a list of univariate polynomials.
593     */
594    //todo Override
595    @SuppressWarnings("unchecked")
596    public List<RecSolvableWordPolynomial<C>> recUnivariateList(int modv) {
597        return (List<RecSolvableWordPolynomial<C>>) (Object) 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    //todo Override
609    public List<RecSolvableWordPolynomial<C>> recUnivariateList(int modv, long e) {
610        List<RecSolvableWordPolynomial<C>> pols = new ArrayList<RecSolvableWordPolynomial<C>>(nvar);
611        int nm = nvar - modv;
612        for (int i = 0; i < nm; i++) {
613            RecSolvableWordPolynomial<C> p = univariate(modv, nm - 1 - i, e);
614            pols.add(p);
615        }
616        return pols;
617    }
618
619
620    /*
621     * Generate list of univariate polynomials in all variables with given exponent.
622     * @param modv number of module variables.
623     * @param e the exponent of the variables.
624     * @return List(X_1^e,...,X_n^e) a list of univariate polynomials.
625     @Override
626     public List<RecSolvableWordPolynomial<C>> univariateList(int modv, long e) {
627        List<GenPolynomial<C>> pol = super.univariateList(modv,e);
628        UnaryFunctor<GenPolynomial<C>,RecSolvableWordPolynomial<C>> fc 
629          = new UnaryFunctor<GenPolynomial<C>,RecSolvableWordPolynomial<C>>() {
630               public RecSolvableWordPolynomial<C> eval(GenPolynomial<C> p) {
631                  if ( ! (p instanceof RecSolvableWordPolynomial) ) {
632                      throw new RuntimeException("no solvable polynomial "+p);
633                  }
634                  return (RecSolvableWordPolynomial<C>) p;
635               }
636            };
637        List<RecSolvableWordPolynomial<C>> pols 
638           = ListUtil.<GenPolynomial<C>,RecSolvableWordPolynomial<C>>map(this,pol,fc);
639        return pols;
640     }
641     */
642
643
644    /**
645     * Extend variables. Used e.g. in module embedding. Extend number of
646     * variables by i.
647     * @param i number of variables to extend.
648     * @return extended solvable polynomial ring factory.
649     */
650    @Override
651    public RecSolvableWordPolynomialRing<C> extend(int i) {
652        GenSolvablePolynomialRing<GenWordPolynomial<C>> pfac = super.extend(i);
653        RecSolvableWordPolynomialRing<C> spfac = new RecSolvableWordPolynomialRing<C>(pfac.coFac, pfac.nvar,
654                        pfac.tord, pfac.vars, pfac.table);
655        //spfac.table.extend(this.table); // pfac.table
656        spfac.coeffTable.extend(this.coeffTable);
657        return spfac;
658    }
659
660
661    /**
662     * Extend variables. Used e.g. in module embedding. Extend number of
663     * variables by length(vn). New variables commute with the exiting
664     * variables.
665     * @param vs names for extended variables.
666     * @return extended polynomial ring factory.
667     */
668    @Override
669    public RecSolvableWordPolynomialRing<C> extend(String[] vs) {
670        GenSolvablePolynomialRing<GenWordPolynomial<C>> pfac = super.extend(vs);
671        RecSolvableWordPolynomialRing<C> spfac = new RecSolvableWordPolynomialRing<C>(pfac.coFac, pfac.nvar,
672                        pfac.tord, pfac.vars, pfac.table);
673        //spfac.table.extend(this.table); // pfac.table??
674        spfac.coeffTable.extend(this.coeffTable);
675        return spfac;
676    }
677
678
679    /**
680     * Contract variables. Used e.g. in module embedding. Contract number of
681     * variables by i.
682     * @param i number of variables to remove.
683     * @return contracted solvable polynomial ring factory.
684     */
685    @Override
686    public RecSolvableWordPolynomialRing<C> contract(int i) {
687        GenPolynomialRing<GenWordPolynomial<C>> pfac = super.contract(i);
688        RecSolvableWordPolynomialRing<C> spfac = new RecSolvableWordPolynomialRing<C>(pfac.coFac, pfac.nvar,
689                        pfac.tord, pfac.vars);
690        spfac.table.contract(this.table);
691        spfac.coeffTable.contract(this.coeffTable);
692        return spfac;
693    }
694
695
696    /**
697     * Reverse variables. Used e.g. in opposite rings.
698     * @return solvable polynomial ring factory with reversed variables.
699     */
700    @Override
701    public RecSolvableWordPolynomialRing<C> reverse() {
702        return reverse(false);
703    }
704
705
706    /**
707     * Reverse variables. Used e.g. in opposite rings.
708     * @param partial true for partialy reversed term orders.
709     * @return solvable polynomial ring factory with reversed variables.
710     */
711    @Override
712    public RecSolvableWordPolynomialRing<C> reverse(boolean partial) {
713        GenPolynomialRing<GenWordPolynomial<C>> pfac = super.reverse(partial);
714        RecSolvableWordPolynomialRing<C> spfac = new RecSolvableWordPolynomialRing<C>(pfac.coFac, pfac.nvar,
715                        pfac.tord, pfac.vars);
716        spfac.partial = partial;
717        spfac.table.reverse(this.table);
718        spfac.coeffTable.reverse(this.coeffTable);
719        return spfac;
720    }
721
722
723    /* not possible:
724     * Distributive representation as polynomial with all main variables.
725     * @return distributive polynomial ring factory.
726    @SuppressWarnings({"cast","unchecked"})
727    public static <C extends RingElem<C>> // must be static because of types
728       GenSolvablePolynomialRing<C> distribute(RecSolvableWordPolynomialRing<C> rf) {
729    }
730     */
731
732
733    /**
734     * Permutation of polynomial ring variables.
735     * @param P permutation.
736     * @return P(this).
737     */
738    @Override
739    public GenSolvablePolynomialRing<GenWordPolynomial<C>> permutation(List<Integer> P) {
740        if (!coeffTable.isEmpty()) {
741            throw new UnsupportedOperationException("permutation with coeff relations: " + this);
742        }
743        GenSolvablePolynomialRing<GenWordPolynomial<C>> pfac = (GenSolvablePolynomialRing<GenWordPolynomial<C>>) super
744                        .permutation(P);
745        return pfac;
746    }
747
748}