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