001/* 002 * $Id$ 003 */ 004 005package edu.jas.application; 006 007 008import java.io.BufferedReader; 009import java.io.IOException; 010import java.io.InputStreamReader; 011import java.io.Reader; 012import java.io.StreamTokenizer; 013import java.nio.charset.Charset; 014import java.util.ArrayList; 015import java.util.Arrays; 016import java.util.Iterator; 017import java.util.List; 018import java.util.Scanner; 019 020import org.apache.logging.log4j.Logger; 021import org.apache.logging.log4j.LogManager; 022 023import edu.jas.arith.BigComplex; 024import edu.jas.arith.BigDecimal; 025import edu.jas.arith.BigInteger; 026import edu.jas.arith.BigQuaternion; 027import edu.jas.arith.BigQuaternionRing; 028import edu.jas.arith.BigRational; 029import edu.jas.arith.ModInteger; 030import edu.jas.arith.ModIntegerRing; 031import edu.jas.arith.ModIntRing; 032import edu.jas.arith.ModLongRing; 033import edu.jas.poly.AlgebraicNumberRing; 034import edu.jas.poly.ExpVector; 035import edu.jas.poly.GenPolynomial; 036import edu.jas.poly.GenPolynomialRing; 037import edu.jas.poly.GenPolynomialTokenizer; 038import edu.jas.poly.GenSolvablePolynomial; 039import edu.jas.poly.GenSolvablePolynomialRing; 040import edu.jas.poly.InvalidExpressionException; 041import edu.jas.poly.RelationTable; 042import edu.jas.poly.TermOrder; 043import edu.jas.poly.ModuleList; 044import edu.jas.poly.PolynomialList; 045import edu.jas.structure.RingFactory; 046import edu.jas.ufd.Quotient; 047import edu.jas.ufd.QuotientRing; 048 049 050/** 051 * RingFactory Tokenizer. Used to read ring factories from input streams. It can 052 * also read QuotientRing factory. 053 * @see edu.jas.poly.GenPolynomialTokenizer 054 * @author Heinz Kredel 055 */ 056public class RingFactoryTokenizer { 057 058 059 private static final Logger logger = LogManager.getLogger(RingFactoryTokenizer.class); 060 061 062 private static final boolean debug = logger.isDebugEnabled(); 063 064 065 private String[] vars; 066 067 068 private int nvars = 1; 069 070 071 private TermOrder tord; 072 073 074 private RelationTable table; 075 076 077 private final StreamTokenizer tok; 078 079 080 private final Reader reader; 081 082 083 private RingFactory fac; 084 085 086 private static enum coeffType { 087 BigRat, BigInt, ModInt, BigC, BigQ, BigD, ANrat, ANmod, RatFunc, ModFunc, IntFunc 088 }; 089 090 091 private coeffType parsedCoeff = coeffType.BigRat; 092 093 094 private GenPolynomialRing pfac; 095 096 097 private static enum polyType { 098 PolBigRat, PolBigInt, PolModInt, PolBigC, PolBigD, PolBigQ, PolANrat, PolANmod, PolRatFunc, PolModFunc, PolIntFunc 099 }; 100 101 102 @SuppressWarnings("unused") 103 private polyType parsedPoly = polyType.PolBigRat; 104 105 106 private GenSolvablePolynomialRing spfac; 107 108 109 /** 110 * No-args constructor reads from System.in. 111 */ 112 public RingFactoryTokenizer() { 113 this(new BufferedReader(new InputStreamReader(System.in, Charset.forName("UTF8")))); 114 } 115 116 117 /** 118 * Constructor with Ring and Reader. 119 * @param rf ring factory. 120 * @param r reader stream. 121 */ 122 public RingFactoryTokenizer(GenPolynomialRing rf, Reader r) { 123 this(r); 124 if (rf == null) { 125 return; 126 } 127 if (rf instanceof GenSolvablePolynomialRing) { 128 pfac = rf; 129 spfac = (GenSolvablePolynomialRing) rf; 130 } else { 131 pfac = rf; 132 spfac = null; 133 } 134 fac = rf.coFac; 135 vars = rf.getVars(); 136 if (vars != null) { 137 nvars = vars.length; 138 } 139 tord = rf.tord; 140 // relation table 141 if (spfac != null) { 142 table = spfac.table; 143 } else { 144 table = null; 145 } 146 } 147 148 149 /** 150 * Constructor with Reader. 151 * @param r reader stream. 152 */ 153 @SuppressWarnings("unchecked") 154 public RingFactoryTokenizer(Reader r) { 155 vars = null; 156 tord = new TermOrder(); 157 nvars = 1; 158 fac = new BigRational(1); 159 160 pfac = new GenPolynomialRing<BigRational>(fac, nvars, tord, vars); 161 spfac = new GenSolvablePolynomialRing<BigRational>(fac, nvars, tord, vars); 162 163 reader = r; 164 tok = new StreamTokenizer(reader); 165 tok.resetSyntax(); 166 // tok.eolIsSignificant(true); no more 167 tok.eolIsSignificant(false); 168 tok.wordChars('0', '9'); 169 tok.wordChars('a', 'z'); 170 tok.wordChars('A', 'Z'); 171 tok.wordChars('_', '_'); // for subscripts x_i 172 tok.wordChars('/', '/'); // wg. rational numbers 173 tok.wordChars('.', '.'); // wg. floats 174 tok.wordChars('~', '~'); // wg. quaternions // unused in this class 175 tok.wordChars(128 + 32, 255); 176 tok.whitespaceChars(0, ' '); 177 tok.commentChar('#'); 178 tok.quoteChar('"'); 179 tok.quoteChar('\''); 180 //tok.slashStarComments(true); does not work 181 182 } 183 184 185 /** 186 * Initialize coefficient and polynomial factories. 187 * @param rf ring factory. 188 * @param ct coefficient type. 189 */ 190 @SuppressWarnings("unchecked") 191 public void initFactory(RingFactory rf, coeffType ct) { 192 fac = rf; 193 parsedCoeff = ct; 194 195 switch (ct) { 196 case BigRat: 197 pfac = new GenPolynomialRing<BigRational>(fac, nvars, tord, vars); 198 parsedPoly = polyType.PolBigRat; 199 break; 200 case BigInt: 201 pfac = new GenPolynomialRing<BigInteger>(fac, nvars, tord, vars); 202 parsedPoly = polyType.PolBigInt; 203 break; 204 case ModInt: 205 pfac = new GenPolynomialRing<ModInteger>(fac, nvars, tord, vars); 206 parsedPoly = polyType.PolModInt; 207 break; 208 case BigC: 209 pfac = new GenPolynomialRing<BigComplex>(fac, nvars, tord, vars); 210 parsedPoly = polyType.PolBigC; 211 break; 212 case BigQ: 213 pfac = new GenPolynomialRing<BigQuaternion>(fac, nvars, tord, vars); 214 parsedPoly = polyType.PolBigQ; 215 break; 216 case BigD: 217 pfac = new GenPolynomialRing<BigDecimal>(fac, nvars, tord, vars); 218 parsedPoly = polyType.PolBigD; 219 break; 220 case RatFunc: 221 pfac = new GenPolynomialRing<Quotient<BigInteger>>(fac, nvars, tord, vars); 222 parsedPoly = polyType.PolRatFunc; 223 break; 224 case ModFunc: 225 pfac = new GenPolynomialRing<Quotient<ModInteger>>(fac, nvars, tord, vars); 226 parsedPoly = polyType.PolModFunc; 227 break; 228 case IntFunc: 229 pfac = new GenPolynomialRing<GenPolynomial<BigRational>>(fac, nvars, tord, vars); 230 parsedPoly = polyType.PolIntFunc; 231 break; 232 default: 233 pfac = new GenPolynomialRing<BigRational>(fac, nvars, tord, vars); 234 parsedPoly = polyType.PolBigRat; 235 } 236 } 237 238 239 /** 240 * Initialize coefficient and solvable polynomial factories. 241 * @param rf ring factory. 242 * @param ct coefficient type. 243 */ 244 @SuppressWarnings("unchecked") 245 public void initSolvableFactory(RingFactory rf, coeffType ct) { 246 fac = rf; 247 parsedCoeff = ct; 248 249 switch (ct) { 250 case BigRat: 251 spfac = new GenSolvablePolynomialRing<BigRational>(fac, nvars, tord, vars); 252 parsedPoly = polyType.PolBigRat; 253 break; 254 case BigInt: 255 spfac = new GenSolvablePolynomialRing<BigInteger>(fac, nvars, tord, vars); 256 parsedPoly = polyType.PolBigInt; 257 break; 258 case ModInt: 259 spfac = new GenSolvablePolynomialRing<ModInteger>(fac, nvars, tord, vars); 260 parsedPoly = polyType.PolModInt; 261 break; 262 case BigC: 263 spfac = new GenSolvablePolynomialRing<BigComplex>(fac, nvars, tord, vars); 264 parsedPoly = polyType.PolBigC; 265 break; 266 case BigQ: 267 spfac = new GenSolvablePolynomialRing<BigQuaternion>(fac, nvars, tord, vars); 268 parsedPoly = polyType.PolBigQ; 269 break; 270 case BigD: 271 spfac = new GenSolvablePolynomialRing<BigDecimal>(fac, nvars, tord, vars); 272 parsedPoly = polyType.PolBigD; 273 break; 274 case RatFunc: 275 spfac = new GenSolvablePolynomialRing<Quotient<BigInteger>>(fac, nvars, tord, vars); 276 parsedPoly = polyType.PolRatFunc; 277 break; 278 case ModFunc: 279 spfac = new GenSolvablePolynomialRing<Quotient<ModInteger>>(fac, nvars, tord, vars); 280 parsedPoly = polyType.PolModFunc; 281 break; 282 case IntFunc: 283 spfac = new GenSolvablePolynomialRing<GenPolynomial<BigRational>>(fac, nvars, tord, vars); 284 parsedPoly = polyType.PolIntFunc; 285 break; 286 default: 287 spfac = new GenSolvablePolynomialRing<BigRational>(fac, nvars, tord, vars); 288 parsedPoly = polyType.PolBigRat; 289 } 290 } 291 292 293 /** 294 * Parsing method for variable list. Syntax: 295 * 296 * <pre> 297 * (a, b c, de) 298 * </pre> 299 * 300 * gives <code>[ "a", "b", "c", "de" ]</code> 301 * @return the next variable list. 302 * @throws IOException 303 */ 304 public String[] nextVariableList() throws IOException { 305 List<String> l = new ArrayList<String>(); 306 int tt; 307 tt = tok.nextToken(); 308 //System.out.println("vList tok = " + tok); 309 if (tt == '(' || tt == '{') { 310 logger.debug("variable list"); 311 tt = tok.nextToken(); 312 while (true) { 313 if (tt == StreamTokenizer.TT_EOF) 314 break; 315 if (tt == ')' || tt == '}') 316 break; 317 if (tt == StreamTokenizer.TT_WORD) { 318 //System.out.println("TT_WORD: " + tok.sval); 319 l.add(tok.sval); 320 } 321 tt = tok.nextToken(); 322 } 323 } else { 324 tok.pushBack(); 325 } 326 Object[] ol = l.toArray(); 327 String[] v = new String[ol.length]; 328 for (int i = 0; i < v.length; i++) { 329 v[i] = (String) ol[i]; 330 } 331 return v; 332 } 333 334 335 /** 336 * Parsing method for coefficient ring. Syntax: 337 * 338 * <pre> 339 * Rat | Q | Int | Z | Mod modul | Complex | C | D | Quat | 340 AN[ (var) ( poly ) | AN[ modul (var) ( poly ) ] | 341 RatFunc (var_list) | ModFunc modul (var_list) | IntFunc (var_list) 342 * </pre> 343 * 344 * @return the next coefficient factory. 345 * @throws IOException 346 */ 347 @SuppressWarnings({ "unchecked", "cast" }) 348 public RingFactory nextCoefficientRing() throws IOException { 349 RingFactory coeff = null; 350 coeffType ct = null; 351 int tt; 352 tt = tok.nextToken(); 353 if (tok.sval != null) { 354 if (tok.sval.equalsIgnoreCase("Q")) { 355 coeff = new BigRational(0); 356 ct = coeffType.BigRat; 357 } else if (tok.sval.equalsIgnoreCase("Rat")) { 358 coeff = new BigRational(0); 359 ct = coeffType.BigRat; 360 } else if (tok.sval.equalsIgnoreCase("D")) { 361 coeff = new BigDecimal(0); 362 ct = coeffType.BigD; 363 } else if (tok.sval.equalsIgnoreCase("Z")) { 364 coeff = new BigInteger(0); 365 ct = coeffType.BigInt; 366 } else if (tok.sval.equalsIgnoreCase("Int")) { 367 coeff = new BigInteger(0); 368 ct = coeffType.BigInt; 369 } else if (tok.sval.equalsIgnoreCase("C")) { 370 coeff = new BigComplex(0); 371 ct = coeffType.BigC; 372 } else if (tok.sval.equalsIgnoreCase("Complex")) { 373 coeff = new BigComplex(0); 374 ct = coeffType.BigC; 375 } else if (tok.sval.equalsIgnoreCase("Quat")) { 376 logger.warn("parse of quaternion coefficients may fail for negative components (use ~ for -)"); 377 coeff = new BigQuaternionRing(); 378 ct = coeffType.BigQ; 379 } else if (tok.sval.equalsIgnoreCase("Mod")) { 380 tt = tok.nextToken(); 381 boolean openb = false; 382 if (tt == '[') { // optional 383 openb = true; 384 tt = tok.nextToken(); 385 } 386 if (tok.sval != null && tok.sval.length() > 0) { 387 if (digit(tok.sval.charAt(0))) { 388 BigInteger mo = new BigInteger(tok.sval); 389 BigInteger lm = new BigInteger(ModLongRing.MAX_LONG); //wrong: Long.MAX_VALUE); 390 if (mo.compareTo(lm) < 0) { 391 if (mo.compareTo(new BigInteger(ModIntRing.MAX_INT)) < 0) { 392 coeff = new ModIntRing(mo.getVal()); 393 } else { 394 coeff = new ModLongRing(mo.getVal()); 395 } 396 } else { 397 coeff = new ModIntegerRing(mo.getVal()); 398 } 399 //System.out.println("coeff = " + coeff + " :: " + coeff.getClass()); 400 ct = coeffType.ModInt; 401 } else { 402 tok.pushBack(); 403 } 404 } else { 405 tok.pushBack(); 406 } 407 if (tt == ']' && openb) { // optional 408 tt = tok.nextToken(); 409 } 410 } else if (tok.sval.equalsIgnoreCase("RatFunc")) { 411 String[] rfv = nextVariableList(); 412 //System.out.println("rfv = " + rfv.length + " " + rfv[0]); 413 int vr = rfv.length; 414 BigInteger bi = new BigInteger(); 415 TermOrder to = new TermOrder(TermOrder.INVLEX); 416 GenPolynomialRing<BigInteger> pcf = new GenPolynomialRing<BigInteger>(bi, vr, to, rfv); 417 coeff = new QuotientRing(pcf); 418 ct = coeffType.RatFunc; 419 } else if (tok.sval.equalsIgnoreCase("ModFunc")) { 420 tt = tok.nextToken(); 421 RingFactory mi = new ModIntegerRing("19"); 422 if (tok.sval != null && tok.sval.length() > 0) { 423 if (digit(tok.sval.charAt(0))) { 424 mi = new ModIntegerRing(tok.sval); 425 } else { 426 tok.pushBack(); 427 } 428 } else { 429 tok.pushBack(); 430 } 431 String[] rfv = nextVariableList(); 432 //System.out.println("rfv = " + rfv.length + " " + rfv[0]); 433 int vr = rfv.length; 434 TermOrder to = new TermOrder(TermOrder.INVLEX); 435 GenPolynomialRing<ModInteger> pcf = new GenPolynomialRing<ModInteger>(mi, vr, to, rfv); 436 coeff = new QuotientRing(pcf); 437 ct = coeffType.ModFunc; 438 } else if (tok.sval.equalsIgnoreCase("IntFunc")) { 439 String[] rfv = nextVariableList(); 440 //System.out.println("rfv = " + rfv.length + " " + rfv[0]); 441 int vr = rfv.length; 442 BigRational bi = new BigRational(); 443 TermOrder to = new TermOrder(TermOrder.INVLEX); 444 GenPolynomialRing<BigRational> pcf = new GenPolynomialRing<BigRational>(bi, vr, to, rfv); 445 coeff = pcf; 446 ct = coeffType.IntFunc; 447 } else if (tok.sval.equalsIgnoreCase("AN")) { 448 tt = tok.nextToken(); 449 if (tt == '[') { 450 tt = tok.nextToken(); 451 RingFactory tcfac = new ModIntegerRing("19"); 452 if (tok.sval != null && tok.sval.length() > 0) { 453 if (digit(tok.sval.charAt(0))) { 454 tcfac = new ModIntegerRing(tok.sval); 455 } else { 456 tcfac = new BigRational(); 457 tok.pushBack(); 458 } 459 } else { 460 tcfac = new BigRational(); 461 tok.pushBack(); 462 } 463 String[] anv = nextVariableList(); 464 //System.out.println("anv = " + anv.length + " " + anv[0]); 465 int vs = anv.length; 466 if (vs != 1) { 467 throw new InvalidExpressionException( 468 "AlgebraicNumber only for univariate polynomials " 469 + Arrays.toString(anv)); 470 } 471 String[] ovars = vars; 472 vars = anv; 473 GenPolynomialRing tpfac = pfac; 474 RingFactory tfac = fac; 475 fac = tcfac; 476 // pfac and fac used in nextPolynomial() 477 if (tcfac instanceof ModIntegerRing) { 478 pfac = new GenPolynomialRing<ModInteger>(tcfac, vs, new TermOrder(), anv); 479 } else { 480 pfac = new GenPolynomialRing<BigRational>(tcfac, vs, new TermOrder(), anv); 481 } 482 logger.debug("pfac = {}", pfac); 483 GenPolynomialTokenizer ptok = new GenPolynomialTokenizer(pfac, reader); 484 GenPolynomial mod = ptok.nextPolynomial(); 485 ptok = null; 486 logger.debug("mod = {}", mod); 487 pfac = tpfac; 488 fac = tfac; 489 vars = ovars; 490 if (tcfac instanceof ModIntegerRing) { 491 GenPolynomial<ModInteger> gfmod; 492 gfmod = (GenPolynomial<ModInteger>) mod; 493 coeff = new AlgebraicNumberRing<ModInteger>(gfmod); 494 ct = coeffType.ANmod; 495 } else { 496 GenPolynomial<BigRational> anmod; 497 anmod = (GenPolynomial<BigRational>) mod; 498 coeff = new AlgebraicNumberRing<BigRational>(anmod); 499 ct = coeffType.ANrat; 500 } 501 logger.debug("coeff = {}", coeff); 502 tt = tok.nextToken(); 503 if (tt == ']') { 504 //ok, no nextToken(); 505 } else { 506 tok.pushBack(); 507 } 508 } else { 509 tok.pushBack(); 510 } 511 } 512 } 513 if (coeff == null) { 514 tok.pushBack(); 515 coeff = new BigRational(); 516 ct = coeffType.BigRat; 517 } 518 parsedCoeff = ct; 519 return coeff; 520 } 521 522 523 /** 524 * Parsing method for weight list. Syntax: 525 * 526 * <pre> 527 * (w1, w2, w3, ..., wn) 528 * </pre> 529 * 530 * @return the next weight list. 531 * @throws IOException 532 */ 533 public long[] nextWeightList() throws IOException { 534 List<Long> l = new ArrayList<Long>(); 535 long e; 536 char first; 537 int tt; 538 tt = tok.nextToken(); 539 if (tt == '(') { 540 logger.debug("weight list"); 541 tt = tok.nextToken(); 542 while (true) { 543 if (tt == StreamTokenizer.TT_EOF) 544 break; 545 if (tt == ')') 546 break; 547 if (tok.sval != null) { 548 first = tok.sval.charAt(0); 549 if (digit(first)) { 550 e = Long.parseLong(tok.sval); 551 l.add(Long.valueOf(e)); 552 //System.out.println("w: " + e); 553 } 554 } 555 tt = tok.nextToken(); // also comma 556 } 557 } else { 558 tok.pushBack(); 559 } 560 Long[] ol = new Long[1]; 561 ol = l.toArray(ol); 562 long[] w = new long[ol.length]; 563 for (int i = 0; i < w.length; i++) { 564 w[i] = ol[ol.length - i - 1].longValue(); 565 } 566 return w; 567 } 568 569 570 /** 571 * Parsing method for weight array. Syntax: 572 * 573 * <pre> 574 * ( (w11, ...,w1n), ..., (wm1, ..., wmn) ) 575 * </pre> 576 * 577 * @return the next weight array. 578 * @throws IOException 579 */ 580 public long[][] nextWeightArray() throws IOException { 581 List<long[]> l = new ArrayList<long[]>(); 582 long[][] w = null; 583 long[] e; 584 char first; 585 int tt; 586 tt = tok.nextToken(); 587 if (tt == '(') { 588 logger.debug("weight array"); 589 tt = tok.nextToken(); 590 while (true) { 591 if (tt == StreamTokenizer.TT_EOF) 592 break; 593 if (tt == ')') 594 break; 595 if (tt == '(') { 596 tok.pushBack(); 597 e = nextWeightList(); 598 l.add(e); 599 //System.out.println("wa: " + e); 600 } else if (tok.sval != null) { 601 first = tok.sval.charAt(0); 602 if (digit(first)) { 603 tok.pushBack(); 604 tok.pushBack(); 605 e = nextWeightList(); 606 l.add(e); 607 break; 608 //System.out.println("w: " + e); 609 } 610 } 611 tt = tok.nextToken(); // also comma 612 } 613 } else { 614 tok.pushBack(); 615 } 616 Object[] ol = l.toArray(); 617 w = new long[ol.length][]; 618 for (int i = 0; i < w.length; i++) { 619 w[i] = (long[]) ol[i]; 620 } 621 return w; 622 } 623 624 625 /** 626 * Parsing method for split index. Syntax: 627 * 628 * <pre> 629 * |i| 630 * </pre> 631 * 632 * @return the next split index. 633 * @throws IOException 634 */ 635 public int nextSplitIndex() throws IOException { 636 int e = -1; // =unknown 637 int e0 = -1; // =unknown 638 char first; 639 int tt; 640 tt = tok.nextToken(); 641 if (tt == '|') { 642 logger.debug("split index"); 643 tt = tok.nextToken(); 644 if (tt == StreamTokenizer.TT_EOF) { 645 return e; 646 } 647 if (tok.sval != null) { 648 first = tok.sval.charAt(0); 649 if (digit(first)) { 650 e = Integer.parseInt(tok.sval); 651 //System.out.println("w: " + i); 652 } 653 tt = tok.nextToken(); 654 if (tt != '|') { 655 tok.pushBack(); 656 } 657 } 658 } else if (tt == '[') { 659 logger.debug("split index"); 660 tt = tok.nextToken(); 661 if (tt == StreamTokenizer.TT_EOF) { 662 return e; 663 } 664 if (tok.sval != null) { 665 first = tok.sval.charAt(0); 666 if (digit(first)) { 667 e0 = Integer.parseInt(tok.sval); 668 //System.out.println("w: " + i); 669 } 670 tt = tok.nextToken(); 671 if (tt == ',') { 672 tt = tok.nextToken(); 673 if (tt == StreamTokenizer.TT_EOF) { 674 return e0; 675 } 676 if (tok.sval != null) { 677 first = tok.sval.charAt(0); 678 if (digit(first)) { 679 e = Integer.parseInt(tok.sval); 680 //System.out.println("w: " + i); 681 } 682 } 683 if (tt != ']') { 684 tok.pushBack(); 685 } 686 } 687 } 688 } else { 689 tok.pushBack(); 690 } 691 return e; 692 } 693 694 695 /** 696 * Parsing method for term order name. Syntax: 697 * 698 * <pre> 699 * L | IL | LEX | G | IG | GRLEX | W(weights) | '|'split index'|' 700 * </pre> 701 * 702 * @return the next term order. 703 * @throws IOException 704 */ 705 public TermOrder nextTermOrder() throws IOException { 706 int evord = TermOrder.DEFAULT_EVORD; 707 int tt; 708 tt = tok.nextToken(); 709 if (tt == StreamTokenizer.TT_EOF) { /* nop */ 710 } else if (tt == StreamTokenizer.TT_WORD) { 711 // System.out.println("TT_WORD: " + tok.sval); 712 if (tok.sval != null) { 713 if (tok.sval.equalsIgnoreCase("L")) { 714 evord = TermOrder.INVLEX; 715 } else if (tok.sval.equalsIgnoreCase("IL")) { 716 evord = TermOrder.INVLEX; 717 } else if (tok.sval.equalsIgnoreCase("INVLEX")) { 718 evord = TermOrder.INVLEX; 719 } else if (tok.sval.equalsIgnoreCase("LEX")) { 720 evord = TermOrder.LEX; 721 } else if (tok.sval.equalsIgnoreCase("G")) { 722 evord = TermOrder.IGRLEX; 723 } else if (tok.sval.equalsIgnoreCase("IG")) { 724 evord = TermOrder.IGRLEX; 725 } else if (tok.sval.equalsIgnoreCase("IGRLEX")) { 726 evord = TermOrder.IGRLEX; 727 } else if (tok.sval.equalsIgnoreCase("GRLEX")) { 728 evord = TermOrder.GRLEX; 729 } else if (tok.sval.equalsIgnoreCase("REVITDG")) { 730 evord = TermOrder.REVITDG; 731 } else if (tok.sval.equalsIgnoreCase("W")) { 732 long[][] w = nextWeightArray(); 733 return new TermOrder(w); 734 } 735 } 736 } else { 737 tok.pushBack(); 738 } 739 int s = nextSplitIndex(); 740 if (s <= 0) { 741 return new TermOrder(evord); 742 } 743 return new TermOrder(evord, evord, nvars, s); 744 } 745 746 747 /** 748 * Parsing method for solvable polynomial relation table. Syntax: 749 * 750 * <pre> 751 * ( p_1, p_2, p_3, ..., p_{n+1}, p_{n+2}, p_{n+3} ) 752 * </pre> 753 * 754 * semantics: <code>p_{n+1} * p_{n+2} = p_{n+3}</code>. The next relation 755 * table is stored into the solvable polynomial factory. 756 * @throws IOException 757 */ 758 @SuppressWarnings("unchecked") 759 public void nextRelationTable() throws IOException { 760 if (spfac == null) { 761 return; 762 } 763 RelationTable table = spfac.table; 764 List<GenPolynomial> rels = null; 765 GenPolynomial p; 766 GenSolvablePolynomial sp; 767 int tt; 768 tt = tok.nextToken(); 769 logger.debug("start relation table: {}", tt); 770 if (tok.sval != null) { 771 if (tok.sval.equalsIgnoreCase("RelationTable")) { 772 GenPolynomialTokenizer ptok = new GenPolynomialTokenizer(pfac, reader); 773 rels = ptok.nextPolynomialList(); 774 ptok = null; 775 } 776 } 777 if (rels == null) { 778 tok.pushBack(); 779 return; 780 } 781 for (Iterator<GenPolynomial> it = rels.iterator(); it.hasNext();) { 782 p = it.next(); 783 ExpVector e = p.leadingExpVector(); 784 if (it.hasNext()) { 785 p = it.next(); 786 ExpVector f = p.leadingExpVector(); 787 if (it.hasNext()) { 788 p = it.next(); 789 sp = new GenSolvablePolynomial(spfac); 790 sp.doPutToMap(p.getMap()); 791 table.update(e, f, sp); 792 } 793 } 794 } 795 if (debug) { 796 logger.info("table = {}", table); 797 } 798 return; 799 } 800 801 802 /** 803 * Parsing method for polynomial ring. Syntax: 804 * 805 * <pre> 806 * coeffRing varList termOrderName (no polyList) 807 * </pre> 808 * 809 * @return the next polynomial ring. 810 * @throws IOException 811 */ 812 @SuppressWarnings("unchecked") 813 public GenPolynomialRing nextPolynomialRing() throws IOException { 814 //String comments = ""; 815 //comments += nextComment(); 816 //if (debug) logger.debug("comment = {}", comments); 817 818 RingFactory coeff = nextCoefficientRing(); 819 logger.info("coeff = {}", coeff); 820 821 vars = nextVariableList(); 822 final var vv = vars; 823 logger.info("vars = {}", () -> Arrays.toString(vv)); 824 if (vars != null) { 825 nvars = vars.length; 826 } 827 828 tord = nextTermOrder(); 829 logger.info("tord = {}", tord); 830 // check more TOs 831 832 initFactory(coeff, parsedCoeff); // global: nvars, tord, vars 833 // now pfac is initialized 834 return pfac; 835 } 836 837 838 /** 839 * Parsing method for solvable polynomial ring. Syntax: 840 * 841 * <pre> 842 * varList termOrderName relationTable (no polyList) 843 * </pre> 844 * 845 * @return the next solvable polynomial ring. 846 * @throws IOException 847 */ 848 @SuppressWarnings("unchecked") 849 public GenSolvablePolynomialRing nextSolvablePolynomialRing() throws IOException { 850 //String comments = ""; 851 //comments += nextComment(); 852 //if (debug) logger.debug("comment = {}", comments); 853 854 RingFactory coeff = nextCoefficientRing(); 855 logger.info("coeff = {}", coeff.getClass().getSimpleName()); 856 857 vars = nextVariableList(); 858 logger.info("vars = {}", Arrays.toString(vars)); 859 if (vars != null) { 860 nvars = vars.length; 861 } 862 863 tord = nextTermOrder(); 864 logger.info("tord = {}", tord); 865 // check more TOs 866 867 initFactory(coeff, parsedCoeff); // must be because of symmetric read 868 initSolvableFactory(coeff, parsedCoeff); // global: nvars, tord, vars 869 //System.out.println("pfac = " + pfac); 870 //System.out.println("spfac = " + spfac); 871 872 nextRelationTable(); 873 if (logger.isInfoEnabled()) { 874 logger.info("table = {}", table + ", tok = {}", tok); 875 } 876 // now spfac is initialized 877 return spfac; 878 } 879 880 881 static boolean digit(char x) { 882 return '0' <= x && x <= '9'; 883 } 884 885 886 //static boolean letter(char x) { 887 // return ('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z'); 888 //} 889 890 891 // unused 892 public void nextComma() throws IOException { 893 int tt; 894 if (tok.ttype == ',') { 895 tt = tok.nextToken(); 896 if (debug) { 897 logger.debug("after comma: {}", tt); 898 } 899 } 900 } 901 902 903 /** 904 * Parsing method for module ring. Syntax: 905 * 906 * <pre> 907 * coeffRing varList termOrderName (no moduleList) 908 * </pre> 909 * 910 * @return the next module ring. 911 * @throws IOException 912 */ 913 @SuppressWarnings("unchecked") 914 public GenPolynomialRing nextSubModuleRing() throws IOException { 915 //String comments = ""; 916 //comments += nextComment(); 917 //if (debug) logger.debug("comment = {}", comments); 918 919 RingFactory coeff = nextCoefficientRing(); 920 logger.info("coeff = {}", coeff.getClass().getSimpleName()); 921 922 vars = nextVariableList(); 923 logger.info("vars = {}", Arrays.toString(vars)); 924 if (vars != null) { 925 nvars = vars.length; 926 } 927 928 tord = nextTermOrder(); 929 logger.info("tord = {}", tord); 930 // check more TOs 931 932 initFactory(coeff, parsedCoeff); // global: nvars, tord, vars 933 //List<List<GenPolynomial>> m = null; 934 //m = nextSubModuleList(); 935 //logger.info("m = {}", m); 936 937 return pfac; 938 } 939 940 941 /** 942 * Parsing method for solvable module ring. Syntax: 943 * 944 * <pre> 945 * varList termOrderName relationTable (no moduleList*) 946 * </pre> 947 * 948 * @return the next solvable module ring. 949 * @throws IOException 950 */ 951 @SuppressWarnings("unchecked") 952 public GenSolvablePolynomialRing nextSolvableSubModuleRing() throws IOException { 953 //String comments = ""; 954 //comments += nextComment(); 955 //if (debug) logger.debug("comment = {}", comments); 956 957 RingFactory coeff = nextCoefficientRing(); 958 logger.info("coeff = {}", coeff.getClass().getSimpleName()); 959 960 vars = nextVariableList(); 961 logger.info("vars = {}", Arrays.toString(vars)); 962 if (vars != null) { 963 nvars = vars.length; 964 } 965 966 tord = nextTermOrder(); 967 logger.info("tord = {}", tord); 968 // check more TOs 969 970 initFactory(coeff, parsedCoeff); // must be because of symmetric read 971 initSolvableFactory(coeff, parsedCoeff); // global: nvars, tord, vars 972 973 //System.out.println("spfac = " + spfac); 974 975 nextRelationTable(); 976 logger.info("table = {}", table); 977 978 //List<List<GenSolvablePolynomial>> s = null; 979 //s = nextSolvableSubModuleList(); 980 //logger.info("s = {}", s); 981 //return new OrderedModuleList(spfac, s); // Ordered 982 983 return spfac; 984 } 985 986}