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