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 }