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<C> element from a coefficient value. 359 * @param a coefficient. 360 * @return a RecSolvablePolynomial<C>. 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<C> element from an exponent vector. 370 * @param e exponent vector. 371 * @return a RecSolvablePolynomial<C>. 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<C> element from a coeffcient and an exponent 381 * vector. 382 * @param a coefficient. 383 * @param e exponent vector. 384 * @return a RecSolvablePolynomial<C>. 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<C> element from a long 394 * value 395 * @param a long. 396 * @return a RecSolvablePolynomial<C>. 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<C> element from a BigInteger 406 * value. 407 * @param a BigInteger. 408 * @return a RecSolvablePolynomial<C>. 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}