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