001/*
002 * $Id: RecSolvablePolynomialRing.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 * 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 main variables are maintained in a coefficient relation
032 * table. Almost immutable object, except variable names and relation table
033 * contents.
034 * @param <C> coefficient type.
035 * @author Heinz Kredel
036 */
037
038public class RecSolvablePolynomialRing<C extends RingElem<C>> extends
039                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     * Get the String representation.
188     * @see java.lang.Object#toString()
189     */
190    @Override
191    public String toString() {
192        String res = super.toString();
193        if (PrettyPrint.isTrue()) {
194            //res += "\n" + table.toString(vars);
195            res += "\n" + coeffTable.toString(vars);
196        } else {
197            res += ", #rel = " + table.size() + " + " + coeffTable.size();
198        }
199        return res;
200    }
201
202
203    /**
204     * Get a scripting compatible string representation.
205     * @return script compatible representation for this Element.
206     * @see edu.jas.structure.Element#toScript()
207     */
208    @Override
209    public String toScript() {
210        StringBuffer s = new StringBuffer();
211        switch (Scripting.getLang()) {
212        case Ruby:
213            s.append("SolvPolyRing.new(");
214            break;
215        case Python:
216        default:
217            s.append("SolvPolyRing(");
218        }
219        if (coFac instanceof RingElem) {
220            s.append(((RingElem<GenPolynomial<C>>) coFac).toScriptFactory());
221        } else {
222            s.append(coFac.toScript().trim());
223        }
224        s.append(",\"" + varsToString() + "\",");
225        String to = tord.toScript();
226        s.append(to);
227        if (table.size() > 0) {
228            String rel = table.toScript();
229            s.append(",rel=");
230            s.append(rel);
231        }
232        if (coeffTable.size() > 0) {
233            String rel = coeffTable.toScript();
234            s.append(",coeffrel=");
235            s.append(rel);
236        }
237        s.append(")");
238        return s.toString();
239    }
240
241
242    /**
243     * Comparison with any other object.
244     * @see java.lang.Object#equals(java.lang.Object)
245     */
246    @Override
247    @SuppressWarnings("unchecked")
248    public boolean equals(Object other) {
249        if (other == null) {
250            return false;
251        }
252        if (!(other instanceof RecSolvablePolynomialRing)) {
253            return false;
254        }
255        // do a super.equals( )
256        if (!super.equals(other)) {
257            return false;
258        }
259        RecSolvablePolynomialRing<C> oring = (RecSolvablePolynomialRing<C>) other;
260        // check same base relations
261        //if ( ! table.equals(oring.table) ) { // done in super
262        //    return false;
263        //}
264        if (!coeffTable.equals(oring.coeffTable)) {
265            return false;
266        }
267        return true;
268    }
269
270
271    /**
272     * Hash code for this polynomial ring.
273     * @see java.lang.Object#hashCode()
274     */
275    @Override
276    public int hashCode() {
277        int h;
278        h = super.hashCode();
279        h = 37 * h + table.hashCode(); // may be different after some computations
280        h = 37 * h + coeffTable.hashCode(); // may be different
281        return h;
282    }
283
284
285    /**
286     * Get the zero element.
287     * @return 0 as RecSolvablePolynomial<C>.
288     */
289    @Override
290    public RecSolvablePolynomial<C> getZERO() {
291        return ZERO;
292    }
293
294
295    /**
296     * Get the one element.
297     * @return 1 as RecSolvablePolynomial<C>.
298     */
299    @Override
300    public RecSolvablePolynomial<C> getONE() {
301        return ONE;
302    }
303
304
305    /**
306     * Query if this ring is commutative.
307     * @return true if this ring is commutative, else false.
308     */
309    @Override
310    public boolean isCommutative() {
311        if (coeffTable.isEmpty()) {
312            return super.isCommutative();
313        }
314        return false;
315    }
316
317
318    /**
319     * Query if this ring is associative. Test if the relations between the mian
320     * variables and the coefficient generators define an associative solvable
321     * ring.
322     * @return true, if this ring is associative, else false.
323     */
324    @SuppressWarnings("unused")
325    @Override
326    public boolean isAssociative() {
327        if (!coFac.isAssociative()) {
328            return false;
329        }
330        RecSolvablePolynomial<C> Xi, Xj, Xk, p, q;
331        List<GenPolynomial<GenPolynomial<C>>> gens = generators();
332        //System.out.println("Rec gens = " + gens);
333        int ngen = gens.size();
334        for (int i = 0; i < ngen; i++) {
335            Xi = (RecSolvablePolynomial<C>) gens.get(i);
336            for (int j = i + 1; j < ngen; j++) {
337                Xj = (RecSolvablePolynomial<C>) gens.get(j);
338                for (int k = j + 1; k < ngen; k++) {
339                    Xk = (RecSolvablePolynomial<C>) gens.get(k);
340                    p = Xk.multiply(Xj).multiply(Xi);
341                    q = Xk.multiply(Xj.multiply(Xi));
342                    if (!p.equals(q)) {
343                        if (true || debug) {
344                            logger.info("Xk = " + Xk + ", Xj = " + Xj + ", Xi = " + Xi);
345                            logger.info("p = ( Xk * Xj ) * Xi = " + p);
346                            logger.info("q = Xk * ( Xj * Xi ) = " + q);
347                        }
348                        return false;
349                    }
350                }
351            }
352        }
353        return true;
354    }
355
356
357    /**
358     * Get a (constant) RecSolvablePolynomial&lt;C&gt; element from a coefficient value.
359     * @param a coefficient.
360     * @return a RecSolvablePolynomial&lt;C&gt;.
361     */
362    @Override
363    public RecSolvablePolynomial<C> valueOf(GenPolynomial<C> a) {
364        return new RecSolvablePolynomial<C>(this, a);
365    }
366
367
368    /**
369     * Get a RecSolvablePolynomial&lt;C&gt; element from an exponent vector.
370     * @param e exponent vector.
371     * @return a RecSolvablePolynomial&lt;C&gt;.
372     */
373    @Override
374    public RecSolvablePolynomial<C> valueOf(ExpVector e) {
375        return new RecSolvablePolynomial<C>(this, coFac.getONE(), e);
376    }
377
378
379    /**
380     * Get a RecSolvablePolynomial&lt;C&gt; element from a coeffcient and an exponent
381     * vector.
382     * @param a coefficient.
383     * @param e exponent vector.
384     * @return a RecSolvablePolynomial&lt;C&gt;.
385     */
386    @Override
387    public RecSolvablePolynomial<C> valueOf(GenPolynomial<C> a, ExpVector e) {
388        return new RecSolvablePolynomial<C>(this, a, e);
389    }
390
391
392    /**
393     * Get a (constant) RecSolvablePolynomial&lt;C&gt; element from a long
394     * value
395     * @param a long.
396     * @return a RecSolvablePolynomial&lt;C&gt;.
397     */
398    @Override
399    public RecSolvablePolynomial<C> fromInteger(long a) {
400        return new RecSolvablePolynomial<C>(this, coFac.fromInteger(a), evzero);
401    }
402
403
404    /**
405     * Get a (constant) RecSolvablePolynomial&lt;C&gt; element from a BigInteger
406     * value.
407     * @param a BigInteger.
408     * @return a RecSolvablePolynomial&lt;C&gt;.
409     */
410    @Override
411    public RecSolvablePolynomial<C> fromInteger(BigInteger a) {
412        return new RecSolvablePolynomial<C>(this, coFac.fromInteger(a), evzero);
413    }
414
415
416    /**
417     * Random solvable polynomial. Generates a random solvable polynomial with k
418     * = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3.
419     * @param n number of terms.
420     * @return a random solvable polynomial.
421     */
422    @Override
423    public RecSolvablePolynomial<C> random(int n) {
424        return random(n, random);
425    }
426
427
428    /**
429     * Random solvable polynomial. Generates a random solvable polynomial with k
430     * = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3.
431     * @param n number of terms.
432     * @param rnd is a source for random bits.
433     * @return a random solvable polynomial.
434     */
435    @Override
436    public RecSolvablePolynomial<C> random(int n, Random rnd) {
437        if (nvar == 1) {
438            return random(5, n, n, 0.7f, rnd);
439        }
440        return random(5, n, 3, 0.3f, rnd);
441    }
442
443
444    /**
445     * Generate a random solvable polynomial.
446     * @param k bitsize of random coefficients.
447     * @param l number of terms.
448     * @param d maximal degree in each variable.
449     * @param q density of nozero exponents.
450     * @return a random solvable polynomial.
451     */
452    @Override
453    public RecSolvablePolynomial<C> random(int k, int l, int d, float q) {
454        return random(k, l, d, q, random);
455    }
456
457
458    /**
459     * Random solvable polynomial.
460     * @param k size 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     * @param rnd is a source for random bits.
465     * @return a random solvable polynomial.
466     */
467    @Override
468    public RecSolvablePolynomial<C> random(int k, int l, int d, float q, Random rnd) {
469        RecSolvablePolynomial<C> r = getZERO(); // copy( ZERO ); 
470        ExpVector e;
471        GenPolynomial<C> a;
472        // add random coeffs and exponents
473        for (int i = 0; i < l; i++) {
474            e = ExpVector.random(nvar, d, q, rnd);
475            a = coFac.random(k, rnd);
476            r = (RecSolvablePolynomial<C>) r.sum(a, e);
477            // somewhat inefficient but clean
478        }
479        return r;
480    }
481
482
483    /**
484     * Copy polynomial c.
485     * @param c
486     * @return a copy of c.
487     */
488    public RecSolvablePolynomial<C> copy(RecSolvablePolynomial<C> c) {
489        return new RecSolvablePolynomial<C>(this, c.val);
490    }
491
492
493    /**
494     * Parse a solvable polynomial with the use of GenPolynomialTokenizer
495     * @param s String.
496     * @return RecSolvablePolynomial from s.
497     */
498    @Override
499    public RecSolvablePolynomial<C> parse(String s) {
500        return parse(new StringReader(s));
501    }
502
503
504    /**
505     * Parse a solvable polynomial with the use of GenPolynomialTokenizer
506     * @param r Reader.
507     * @return next RecSolvablePolynomial from r.
508     */
509    @Override
510    @SuppressWarnings("unchecked")
511    public RecSolvablePolynomial<C> parse(Reader r) {
512        GenPolynomialTokenizer pt = new GenPolynomialTokenizer(this, r);
513        RecSolvablePolynomial<C> p = null;
514        try {
515            GenSolvablePolynomial<GenPolynomial<C>> s = pt.nextSolvablePolynomial();
516            p = new RecSolvablePolynomial<C>(this, s);
517        } catch (IOException e) {
518            logger.error(e.toString() + " parse " + this);
519            p = ZERO;
520        }
521        return p;
522    }
523
524
525    /**
526     * Generate univariate solvable polynomial in a given variable.
527     * @param i the index of the variable.
528     * @return X_i as solvable univariate polynomial.
529     */
530    @Override
531    public RecSolvablePolynomial<C> univariate(int i) {
532        return (RecSolvablePolynomial<C>) super.univariate(i);
533    }
534
535
536    /**
537     * Generate univariate solvable polynomial in a given variable with given
538     * exponent.
539     * @param i the index of the variable.
540     * @param e the exponent of the variable.
541     * @return X_i^e as solvable univariate polynomial.
542     */
543    @Override
544    public RecSolvablePolynomial<C> univariate(int i, long e) {
545        return (RecSolvablePolynomial<C>) super.univariate(i, e);
546    }
547
548
549    /**
550     * Generate univariate solvable polynomial in a given variable with given
551     * exponent.
552     * @param modv number of module variables.
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 RecSolvablePolynomial<C> univariate(int modv, int i, long e) {
559        return (RecSolvablePolynomial<C>) super.univariate(modv, i, e);
560    }
561
562
563    /**
564     * Generate list of univariate polynomials in all variables.
565     * @return List(X_1,...,X_n) a list of univariate polynomials.
566     */
567    @Override
568    public List<RecSolvablePolynomial<C>> univariateList() {
569        //return castToSolvableList( super.univariateList() );
570        return univariateList(0, 1L);
571    }
572
573
574    /**
575     * Generate list of univariate polynomials in all variables.
576     * @param modv number of module variables.
577     * @return List(X_1,...,X_n) a list of univariate polynomials.
578     */
579    @Override
580    public List<RecSolvablePolynomial<C>> univariateList(int modv) {
581        return univariateList(modv, 1L);
582    }
583
584
585    /**
586     * Generate list of univariate polynomials in all variables with given
587     * exponent.
588     * @param modv number of module variables.
589     * @param e the exponent of the variables.
590     * @return List(X_1^e,...,X_n^e) a list of univariate polynomials.
591     */
592    @Override
593    public List<RecSolvablePolynomial<C>> univariateList(int modv, long e) {
594        List<RecSolvablePolynomial<C>> pols = new ArrayList<RecSolvablePolynomial<C>>(nvar);
595        int nm = nvar - modv;
596        for (int i = 0; i < nm; i++) {
597            RecSolvablePolynomial<C> p = univariate(modv, nm - 1 - i, e);
598            pols.add(p);
599        }
600        return pols;
601    }
602
603
604    /**
605     * Extend variables. Used e.g. in module embedding. Extend number of
606     * variables by i.
607     * @param i number of variables to extend.
608     * @return extended solvable polynomial ring factory.
609     */
610    @Override
611    public RecSolvablePolynomialRing<C> extend(int i) {
612        return extend(i,false);
613    }
614
615
616    /**
617     * Extend variables. Used e.g. in module embedding. Extend number of
618     * variables by i.
619     * @param i number of variables to extend.
620     * @param top true for TOP term order, false for POT term order.
621     * @return extended solvable polynomial ring factory.
622     */
623    @Override
624    public RecSolvablePolynomialRing<C> extend(int i, boolean top) {
625        GenSolvablePolynomialRing<GenPolynomial<C>> pfac = super.extend(i, top);
626        RecSolvablePolynomialRing<C> spfac = new RecSolvablePolynomialRing<C>(pfac.coFac, pfac.nvar,
627                        pfac.tord, pfac.vars, pfac.table);
628        //spfac.table.extend(this.table); // pfac.table
629        spfac.coeffTable.extend(this.coeffTable);
630        return spfac;
631    }
632
633
634    /**
635     * Extend variables. Used e.g. in module embedding. Extend number of
636     * variables by length(vn). New variables commute with the exiting
637     * variables.
638     * @param vs names for extended variables.
639     * @return extended polynomial ring factory.
640     */
641    @Override
642    public RecSolvablePolynomialRing<C> extend(String[] vs) {
643        return extend(vs, false);
644    }
645
646    
647    /**
648     * Extend variables. Used e.g. in module embedding. Extend number of
649     * variables by length(vn). New variables commute with the exiting
650     * variables.
651     * @param vs names for extended variables.
652     * @param top true for TOP term order, false for POT term order.
653     * @return extended polynomial ring factory.
654     */
655    @Override
656    public RecSolvablePolynomialRing<C> extend(String[] vs, boolean top) {
657        GenSolvablePolynomialRing<GenPolynomial<C>> pfac = super.extend(vs, top);
658        RecSolvablePolynomialRing<C> spfac = new RecSolvablePolynomialRing<C>(pfac.coFac, pfac.nvar,
659                        pfac.tord, pfac.vars, pfac.table);
660        //spfac.table.extend(this.table); // is in pfac.table
661        spfac.coeffTable.extend(this.coeffTable);
662        return spfac;
663    }
664
665
666    /**
667     * Contract variables. Used e.g. in module embedding. Contract number of
668     * variables by i.
669     * @param i number of variables to remove.
670     * @return contracted solvable polynomial ring factory.
671     */
672    @Override
673    public RecSolvablePolynomialRing<C> contract(int i) {
674        GenPolynomialRing<GenPolynomial<C>> pfac = super.contract(i);
675        RecSolvablePolynomialRing<C> spfac = new RecSolvablePolynomialRing<C>(pfac.coFac, pfac.nvar,
676                        pfac.tord, pfac.vars);
677        spfac.table.contract(this.table);
678        spfac.coeffTable.contract(this.coeffTable);
679        return spfac;
680    }
681
682
683    /**
684     * Reverse variables. Used e.g. in opposite rings.
685     * @return solvable polynomial ring factory with reversed variables.
686     */
687    @Override
688    public RecSolvablePolynomialRing<C> reverse() {
689        return reverse(false);
690    }
691
692
693    /**
694     * Reverse variables. Used e.g. in opposite rings.
695     * @param partial true for partialy reversed term orders.
696     * @return solvable polynomial ring factory with reversed variables.
697     */
698    @Override
699    public RecSolvablePolynomialRing<C> reverse(boolean partial) {
700        GenPolynomialRing<GenPolynomial<C>> pfac = super.reverse(partial);
701        RecSolvablePolynomialRing<C> spfac = new RecSolvablePolynomialRing<C>(pfac.coFac, pfac.nvar,
702                        pfac.tord, pfac.vars);
703        spfac.partial = partial;
704        spfac.table.reverse(this.table);
705        spfac.coeffTable.reverse(this.coeffTable);
706        return spfac;
707    }
708
709
710    /**
711     * Distributive representation as polynomial with all main variables.
712     * @return distributive polynomial ring factory.
713     */
714    @SuppressWarnings({"cast","unchecked"})
715    public static <C extends RingElem<C>> // must be static because of types
716    GenSolvablePolynomialRing<C> distribute(RecSolvablePolynomialRing<C> rf) {
717        // setup solvable polynomial ring
718        GenSolvablePolynomialRing<C> fring = (GenSolvablePolynomialRing<C>) (GenSolvablePolynomialRing) rf;
719        GenSolvablePolynomialRing<C> pfd = fring.distribute();
720        // add coefficient relations:
721        List<GenPolynomial<GenPolynomial<C>>> rl = (List<GenPolynomial<GenPolynomial<C>>>) (List) PolynomialList
722                        .castToList(rf.coeffTable.relationList());
723        List<GenPolynomial<C>> rld = PolyUtil.<C> distribute(pfd, rl);
724        pfd.table.addRelations(rld);
725        //System.out.println("pfd = " + pfd.toScript());
726        return pfd;
727    }
728
729
730    /**
731     * Permutation of polynomial ring variables.
732     * @param P permutation.
733     * @return P(this).
734     */
735    @Override
736    public GenSolvablePolynomialRing<GenPolynomial<C>> permutation(List<Integer> P) {
737        if (!coeffTable.isEmpty()) {
738            throw new UnsupportedOperationException("permutation with coeff relations: " + this);
739        }
740        GenSolvablePolynomialRing<GenPolynomial<C>> pfac = (GenSolvablePolynomialRing<GenPolynomial<C>>) super.permutation(P);
741        return pfac;
742    }
743
744}