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