001/*
002 * $Id: GenWordPolynomialTest.java 5046 2014-12-30 16:46:04Z kredel $
003 */
004
005package edu.jas.poly;
006
007
008import java.util.List;
009
010import junit.framework.Test;
011import junit.framework.TestCase;
012import junit.framework.TestSuite;
013
014import org.apache.log4j.BasicConfigurator;
015
016import edu.jas.arith.BigInteger;
017import edu.jas.arith.BigRational;
018import edu.jas.arith.BigComplex;
019import edu.jas.structure.RingElem;
020
021
022/**
023 * GenWordPolynomial tests with JUnit.
024 * @author Heinz Kredel.
025 */
026
027public class GenWordPolynomialTest extends TestCase {
028
029
030    /**
031     * main
032     */
033    public static void main(String[] args) {
034        BasicConfigurator.configure();
035        junit.textui.TestRunner.run(suite());
036    }
037
038
039    /**
040     * Constructs a <CODE>GenWordPolynomialTest</CODE> object.
041     * @param name String.
042     */
043    public GenWordPolynomialTest(String name) {
044        super(name);
045    }
046
047
048    /**
049     * suite.
050     */
051    public static Test suite() {
052        TestSuite suite = new TestSuite(GenWordPolynomialTest.class);
053        return suite;
054    }
055
056
057    int rl = 6;
058
059
060    int kl = 10;
061
062
063    int ll = 7;
064
065
066    int el = 5;
067
068
069    @Override
070    protected void setUp() {
071    }
072
073
074    @Override
075    protected void tearDown() {
076    }
077
078
079    /**
080     * Test constructors and factory.
081     */
082    public void testConstructors() {
083        // integers
084        BigInteger rf = new BigInteger();
085        //System.out.println("rf = " + rf);
086
087        // non-commuting vars: abcdef
088        WordFactory wf = new WordFactory("abcdef");
089        //System.out.println("wf = " + wf);
090
091        // polynomials over integers
092        GenWordPolynomialRing<BigInteger> pf = new GenWordPolynomialRing<BigInteger>(rf, wf);
093        //System.out.println("pf = " + pf);
094        assertFalse("not commutative",pf.isCommutative());
095        assertTrue("associative",pf.isAssociative());
096        assertFalse("not field",pf.isField());
097
098        GenWordPolynomial<BigInteger> p = pf.getONE();
099        //System.out.println("p = " + p);
100        assertTrue("p == 1", p.isONE());
101        p = pf.getZERO();
102        assertTrue("p == 0", p.isZERO());
103        //System.out.println("p = " + p);
104        //p = pf.random(9);
105        //System.out.println("p = " + p);
106
107        List<GenWordPolynomial<BigInteger>> gens = pf.generators();
108        //System.out.println("gens = " + gens);
109        assertTrue("#gens == 7", gens.size() == 7);
110
111        RingElem<GenWordPolynomial<BigInteger>> pe = new GenWordPolynomial<BigInteger>(pf);
112        //System.out.println("pe = " + pe);
113        //System.out.println("p.equals(pe) = " + p.equals(pe) );
114        //System.out.println("p.equals(p) = " + p.equals(p) );
115        assertTrue("p.equals(pe) = ", p.equals(pe));
116        assertTrue("p.equals(p) = ", p.equals(p));
117
118        pe = pe.sum(p);
119        //System.out.println("pe = " + pe);
120        assertTrue("pe.isZERO() = ", pe.isZERO());
121        p = pf.random(9);
122        p = p.subtract(p);
123        //System.out.println("p = " + p);
124        //System.out.println("p.isZERO() = " + p.isZERO());
125        assertTrue("p.isZERO() = ", p.isZERO());
126
127        // polynomials over (polynomials over integers)
128        // non-commuting vars: xyz
129        WordFactory wf2 = new WordFactory("xyz");
130        //System.out.println("wf2 = " + wf2);
131
132        GenWordPolynomialRing<GenWordPolynomial<BigInteger>> 
133           ppf = new GenWordPolynomialRing<GenWordPolynomial<BigInteger>>(pf, wf2);
134        //System.out.println("ppf = " + ppf);
135
136        GenWordPolynomial<GenWordPolynomial<BigInteger>> pp = ppf.getONE();
137        //System.out.println("pp = " + pp);
138        assertTrue("pp == 1", pp.isONE());
139        //pp = ppf.random(2);
140        //System.out.println("pp = " + pp);
141        pp = ppf.getZERO();
142        //System.out.println("pp = " + pp);
143        assertTrue("pp == 0", pp.isZERO());
144
145        List<GenWordPolynomial<GenWordPolynomial<BigInteger>>> pgens = ppf.generators();
146        //System.out.println("pgens = " + pgens);
147        assertTrue("#pgens == 7+3", pgens.size() == 10);
148
149        RingElem<GenWordPolynomial<GenWordPolynomial<BigInteger>>> 
150            ppe = new GenWordPolynomial<GenWordPolynomial<BigInteger>>(ppf);
151        //System.out.println("ppe = " + ppe);
152        //System.out.println("pp.equals(ppe) = " + pp.equals(ppe) );
153        //System.out.println("pp.equals(pp) = " + pp.equals(pp) );
154        assertTrue("pp.equals(ppe) = ", pp.equals(ppe));
155        assertTrue("pp.equals(pp) = ", pp.equals(pp));
156
157        ppe = ppe.sum(pp); // why not pp = pp.add(ppe) ?
158        //System.out.println("ppe = " + ppe);
159        assertTrue("ppe.isZERO() = ", ppe.isZERO());
160        pp = ppf.random(2);
161        pp = pp.subtract(pp);
162        //System.out.println("pp = " + pp);
163        //System.out.println("pp.isZERO() = " + pp.isZERO());
164        assertTrue("pp.isZERO() = ", pp.isZERO());
165
166        // polynomials over (polynomials over (polynomials over integers))
167        // non-commuting vars: uvw
168        WordFactory wf3 = new WordFactory("uvw");
169        //System.out.println("wf3 = " + wf3);
170        GenWordPolynomialRing<GenWordPolynomial<GenWordPolynomial<BigInteger>>> 
171           pppf = new GenWordPolynomialRing<GenWordPolynomial<GenWordPolynomial<BigInteger>>>(ppf, wf3);
172        //System.out.println("pppf = " + pppf);
173
174        GenWordPolynomial<GenWordPolynomial<GenWordPolynomial<BigInteger>>> ppp = pppf.getONE();
175        //System.out.println("ppp = " + ppp);
176        assertTrue("ppp == 1", ppp.isONE());
177        //ppp = pppf.random(2);
178        //System.out.println("ppp = " + ppp);
179        ppp = pppf.getZERO();
180        //System.out.println("ppp = " + ppp);
181        assertTrue("ppp == 0", ppp.isZERO());
182
183        List<GenWordPolynomial<GenWordPolynomial<GenWordPolynomial<BigInteger>>>> ppgens = pppf.generators();
184        //System.out.println("ppgens = " + ppgens);
185        assertTrue("#ppgens == 7+3+3", ppgens.size() == 13);
186
187        RingElem<GenWordPolynomial<GenWordPolynomial<GenWordPolynomial<BigInteger>>>> 
188            pppe = new GenWordPolynomial<GenWordPolynomial<GenWordPolynomial<BigInteger>>>(pppf);
189        //System.out.println("pppe = " + pppe);
190        // System.out.println("ppp.equals(pppe) = " + ppp.equals(pppe) );
191        // System.out.println("ppp.equals(ppp) = " + ppp.equals(ppp) );
192        assertTrue("ppp.equals(pppe) = ", ppp.equals(pppe));
193        assertTrue("ppp.equals(ppp) = ", ppp.equals(ppp));
194
195        pppe = pppe.sum(ppp);
196        //System.out.println("pppe = " + pppe);
197        assertTrue("pppe.isZERO() = ", pppe.isZERO());
198        //ppp = pppf.random(2);
199        ppp = ppp.subtract(ppp);
200        //System.out.println("ppp = " + ppp);
201        //System.out.println("ppp.isZERO() = " + ppp.isZERO());
202        assertTrue("ppp.isZERO() = ", ppp.isZERO());
203    }
204
205
206    /**
207     * Test accessors.
208     */
209    public void testAccessors() {
210        // integers
211        BigInteger rf = new BigInteger();
212        // System.out.println("rf = " + rf);
213
214        // non-commuting vars: abcdef
215        WordFactory wf = new WordFactory("abcdef");
216        //System.out.println("wf = " + wf);
217
218        // polynomials over integers
219        GenWordPolynomialRing<BigInteger> pf = new GenWordPolynomialRing<BigInteger>(rf, wf);
220        //System.out.println("pf = " + pf);
221
222        // test 1
223        GenWordPolynomial<BigInteger> p = pf.getONE();
224        //System.out.println("p = " + p);
225
226        Word e = p.leadingWord();
227        BigInteger c = p.leadingBaseCoefficient();
228
229        GenWordPolynomial<BigInteger> f = new GenWordPolynomial<BigInteger>(pf, c, e);
230        assertEquals("1 == 1 ", p, f);
231
232        GenWordPolynomial<BigInteger> r = p.reductum();
233        assertTrue("red(1) == 0 ", r.isZERO());
234
235        // test 0
236        p = pf.getZERO();
237        // System.out.println("p = " + p);
238        e = p.leadingWord();
239        c = p.leadingBaseCoefficient();
240
241        f = new GenWordPolynomial<BigInteger>(pf, c, e);
242        assertEquals("0 == 0 ", p, f);
243
244        r = p.reductum();
245        assertTrue("red(0) == 0 ", r.isZERO());
246
247        // test random
248        p = pf.random(kl, ll, el);
249        // System.out.println("p = " + p);
250        e = p.leadingWord();
251        c = p.leadingBaseCoefficient();
252        r = p.reductum();
253
254        f = new GenWordPolynomial<BigInteger>(pf, c, e);
255        f = r.sum(f);
256        assertEquals("p == lm(f)+red(f) ", p, f);
257
258        // test iteration over random
259        GenWordPolynomial<BigInteger> g;
260        g = p;
261        f = pf.getZERO();
262        while (!g.isZERO()) {
263            e = g.leadingWord();
264            c = g.leadingBaseCoefficient();
265            //System.out.println("c e = " + c + " " + e);
266            r = g.reductum();
267            f = f.sum(c, e);
268            g = r;
269        }
270        assertEquals("p == lm(f)+lm(red(f))+... ", p, f);
271    }
272
273
274    /**
275     * Test addition.
276     */
277    public void testAddition() {
278        // integers
279        BigInteger rf = new BigInteger();
280        // System.out.println("rf = " + rf);
281
282        // non-commuting vars: abcdef
283        WordFactory wf = new WordFactory("abcdef");
284        //System.out.println("wf = " + wf);
285
286        // polynomials over integers
287        GenWordPolynomialRing<BigInteger> fac = new GenWordPolynomialRing<BigInteger>(rf, wf);
288        //System.out.println("fac = " + fac);
289
290        GenWordPolynomial<BigInteger> a = fac.random(kl, ll, el);
291        GenWordPolynomial<BigInteger> b = fac.random(kl, ll, el);
292
293        GenWordPolynomial<BigInteger> c = a.sum(b);
294        GenWordPolynomial<BigInteger> d = c.subtract(b);
295        GenWordPolynomial<BigInteger> e;
296        assertEquals("a+b-b = a", a, d);
297        //System.out.println("a = " + a);
298        //System.out.println("b = " + b);
299        //System.out.println("c = " + c);
300        //System.out.println("d = " + d);
301
302        c = fac.random(kl, ll, el);
303        //System.out.println("\nc = " + c);
304        d = a.sum(b.sum(c));
305        e = (a.sum(b)).sum(c);
306
307        //System.out.println("d = " + d);
308        //System.out.println("e = " + e);
309        //System.out.println("d-e = " + d.subtract(e) );
310        assertEquals("a+(b+c) = (a+b)+c", d, e);
311
312        Word u = wf.random(rl);
313        BigInteger x = rf.random(kl);
314
315        b = new GenWordPolynomial<BigInteger>(fac, x, u);
316        c = a.sum(b);
317        d = a.sum(x, u);
318        assertEquals("a+p(x,u) = a+(x,u)", c, d);
319        //System.out.println("\nc = " + c);
320        //System.out.println("d = " + d);
321
322        c = a.subtract(b);
323        d = a.subtract(x, u);
324        assertEquals("a-p(x,u) = a-(x,u)", c, d);
325        //System.out.println("c = " + c);
326        //System.out.println("d = " + d);
327
328        //a = new GenWordPolynomial<BigInteger>(fac);
329        b = new GenWordPolynomial<BigInteger>(fac, x, u);
330        c = b.sum(a);
331        d = a.sum(x, u);
332        assertEquals("a+p(x,u) = a+(x,u)", c, d);
333        //System.out.println("a = " + a);
334        //System.out.println("b = " + b);
335        //System.out.println("c = " + c);
336        //System.out.println("d = " + d);
337
338        c = a.subtract(b);
339        d = a.subtract(x, u);
340        assertEquals("a-p(x,u) = a-(x,u)", c, d);
341        //System.out.println("c = " + c);
342        //System.out.println("d = " + d);
343    }
344
345
346    /**
347     * Test multiplication.
348     */
349    public void testMultiplication() {
350        // integers
351        BigInteger rf = new BigInteger();
352        // System.out.println("rf = " + rf);
353
354        // non-commuting vars: abcdef
355        WordFactory wf = new WordFactory("abcdef");
356        //System.out.println("wf = " + wf);
357
358        // polynomials over integers
359        GenWordPolynomialRing<BigInteger> fac = new GenWordPolynomialRing<BigInteger>(rf, wf);
360        //System.out.println("fac = " + fac);
361
362        GenWordPolynomial<BigInteger> a = fac.random(kl, ll, el);
363        GenWordPolynomial<BigInteger> b = fac.random(kl, ll, el);
364
365        GenWordPolynomial<BigInteger> c = a.multiply(b);
366        GenWordPolynomial<BigInteger> d = b.multiply(a);
367        GenWordPolynomial<BigInteger> e;
368        assertFalse("a*b != b*a", c.equals(d));
369        //System.out.println("a = " + a);
370        //System.out.println("b = " + b);
371        //System.out.println("c = " + c);
372        //System.out.println("d = " + d);
373
374        c = fac.random(kl, ll, el);
375        //System.out.println("c = " + c);
376        d = a.multiply(b.multiply(c));
377        e = (a.multiply(b)).multiply(c);
378
379        //System.out.println("d = " + d);
380        //System.out.println("e = " + e);
381        //System.out.println("d-e = " + d.subtract(c) );
382        assertEquals("a*(b*c) = (a*b)*c", d, e);
383
384        Word u = wf.random(rl);
385        BigInteger x = rf.random(kl);
386
387        b = new GenWordPolynomial<BigInteger>(fac, x, u);
388        c = a.multiply(b);
389        d = a.multiply(x, u);
390        assertEquals("a+p(x,u) = a+(x,u)", c, d);
391        //System.out.println("c = " + c);
392        //System.out.println("d = " + d);
393
394        //a = new GenWordPolynomial<BigInteger>(fac);
395        b = new GenWordPolynomial<BigInteger>(fac, x, u);
396        c = a.multiply(b);
397        d = a.multiply(x, u);
398        assertEquals("a+p(x,u) = a+(x,u)", c, d);
399        //System.out.println("a = " + a);
400        //System.out.println("b = " + b);
401        //System.out.println("c = " + c);
402        //System.out.println("d = " + d);
403    }
404
405
406    /**
407     * Test distributive law.
408     */
409    public void testDistributive() {
410        // integers
411        BigInteger rf = new BigInteger();
412        // System.out.println("rf = " + rf);
413
414        // non-commuting vars: abcdef
415        WordFactory wf = new WordFactory("abcdef");
416        //System.out.println("wf = " + wf);
417
418        // polynomials over integers
419        GenWordPolynomialRing<BigInteger> fac = new GenWordPolynomialRing<BigInteger>(rf, wf);
420        //System.out.println("fac = " + fac);
421
422        GenWordPolynomial<BigInteger> a = fac.random(kl, ll, el);
423        GenWordPolynomial<BigInteger> b = fac.random(kl, ll, el);
424        GenWordPolynomial<BigInteger> c = fac.random(kl, ll, el);
425        GenWordPolynomial<BigInteger> d, e;
426
427        d = a.multiply(b.sum(c));
428        e = a.multiply(b).sum(a.multiply(c));
429
430        assertEquals("a(b+c) = ab+ac", d, e);
431    }
432
433
434    /**
435     * Test univariate division.
436     */
437    public void testUnivDivision() {
438        // rational numbers
439        BigRational rf = new BigRational();
440        //System.out.println("rf = " + rf);
441
442        // non-commuting vars: x
443        WordFactory wf = new WordFactory("x");
444        //System.out.println("wf = " + wf);
445
446        // polynomials over rational numbers
447        GenWordPolynomialRing<BigRational> fac = new GenWordPolynomialRing<BigRational>(rf, wf);
448        //System.out.println("fac = " + fac);
449
450        GenWordPolynomial<BigRational> a = fac.random(7, ll, el).monic();
451        GenWordPolynomial<BigRational> b = fac.random(7, ll, el).monic();
452
453        GenWordPolynomial<BigRational> c = a.multiply(b);
454        GenWordPolynomial<BigRational> d = b.multiply(a);
455        GenWordPolynomial<BigRational> e, f;
456        assertTrue("a*b == b*a", c.equals(d)); // since univariate
457        //System.out.println("a = " + a);
458        //System.out.println("b = " + b);
459        //System.out.println("c = " + c);
460        //System.out.println("d = " + d);
461
462        e = c.divide(a);
463        //System.out.println("e = " + e);
464        assertTrue("a*b/a == b", b.equals(e));
465        d = c.divide(b);
466        //System.out.println("d = " + d);
467        assertTrue("a*b/b == a", a.equals(d));
468
469        d = c.gcd(a);
470        //System.out.println("d = " + d);
471        assertTrue("gcd(a*b,a) == a", a.equals(d));
472
473        d = a.gcd(b);
474        //System.out.println("d = " + d);
475        if (d.isConstant()) {
476            assertTrue("gcd(b,a) == 1", d.isONE());
477        } else {
478            return;
479        }
480        d = a.modInverse(b);
481        //System.out.println("d = " + d);
482        e = d.multiply(a);
483        //System.out.println("e = " + e);
484        f = e.remainder(b);
485        //System.out.println("f = " + f);
486        assertTrue("d * a == 1 mod b ", f.isONE());
487    }
488
489
490    /**
491     * Test multivariate 2 division.
492     */
493    public void testMulti2Division() {
494        // rational numbers
495        BigRational rf = new BigRational();
496        // System.out.println("rf = " + rf);
497
498        // non-commuting vars: xy
499        WordFactory wf = new WordFactory("xy");
500        //System.out.println("wf = " + wf);
501
502        // polynomials over rational numbers
503        GenWordPolynomialRing<BigRational> fac = new GenWordPolynomialRing<BigRational>(rf, wf);
504        //System.out.println("fac = " + fac);
505
506        GenWordPolynomial<BigRational> a = fac.random(7, ll, el).monic();
507        GenWordPolynomial<BigRational> b = fac.random(7, ll, el).monic();
508
509        GenWordPolynomial<BigRational> c = a.multiply(b);
510        GenWordPolynomial<BigRational> d = b.multiply(a);
511        GenWordPolynomial<BigRational> e, f;
512        assertFalse("a*b == b*a", c.equals(d));
513        //System.out.println("a = " + a);
514        //System.out.println("b = " + b);
515        //System.out.println("c = " + c);
516        //System.out.println("d = " + d);
517
518        e = c.divide(a);
519        //System.out.println("e = " + e);
520        assertTrue("a*b/a == b", b.equals(e));
521        f = d.divide(b);
522        //System.out.println("f = " + f);
523        assertTrue("a*b/b == a", a.equals(f));
524
525        try {
526            f = a.divide(b);
527            //System.out.println("f = " + f);
528        } catch (RuntimeException re) {
529            System.out.println("a divide b fail: " + a + ", " + b);
530            return;
531        }
532        WordFactory.WordComparator cmp = fac.alphabet.getDescendComparator();
533        f = a.remainder(b);
534        //System.out.println("a = " + a);
535        //System.out.println("f = " + f);
536        assertTrue("a rem2 b <= a", cmp.compare(a.leadingWord(), f.leadingWord()) <= 0);
537    }
538
539
540    /**
541     * Test multivariate 3 division.
542     */
543    public void testMulti3Division() {
544        // rational numbers
545        BigRational rf = new BigRational();
546        // System.out.println("rf = " + rf);
547
548        // non-commuting vars: xyz
549        WordFactory wf = new WordFactory("xyz");
550        //System.out.println("wf = " + wf);
551
552        // polynomials over rational numbers
553        GenWordPolynomialRing<BigRational> fac = new GenWordPolynomialRing<BigRational>(rf, wf);
554        //System.out.println("fac = " + fac);
555
556        GenWordPolynomial<BigRational> a = fac.random(7, ll, el).monic();
557        GenWordPolynomial<BigRational> b = fac.random(7, ll, el).monic();
558
559        GenWordPolynomial<BigRational> c = a.multiply(b);
560        GenWordPolynomial<BigRational> d = b.multiply(a);
561        GenWordPolynomial<BigRational> e, f;
562        assertFalse("a*b == b*a", c.equals(d));
563        //System.out.println("a = " + a);
564        //System.out.println("b = " + b);
565        //System.out.println("c = " + c);
566        //System.out.println("d = " + d);
567
568        e = c.divide(a);
569        //System.out.println("e = " + e);
570        assertTrue("a*b/a == b", b.equals(e));
571        f = d.divide(b);
572        //System.out.println("f = " + f);
573        assertTrue("a*b/b == a", a.equals(f));
574
575        try {
576            f = a.divide(b);
577            //System.out.println("f = " + f);
578        } catch (RuntimeException re) {
579            System.out.println("a divide b fail: " + a + ", " + b);
580            return;
581        }
582        WordFactory.WordComparator cmp = fac.alphabet.getDescendComparator();
583        f = a.remainder(b);
584        //System.out.println("a = " + a);
585        //System.out.println("f = " + f);
586        assertTrue("a rem3 b <= a: " + a.leadingWord() + ", " + f.leadingWord(),
587                        cmp.compare(a.leadingWord(), f.leadingWord()) <= 0);
588    }
589
590
591    /**
592     * Test polynomial and solvable coefficients.
593     */
594    public void testCoefficients() {
595        // integers
596        BigComplex rf = new BigComplex();
597        //System.out.println("rf = " + rf);
598
599        // commuting vars: uvw
600        String[] cvar = new String[] { "u", "v", "w" };
601        GenPolynomialRing<BigComplex> cf = new GenPolynomialRing<BigComplex>(rf, cvar);
602        //System.out.println("cf = " + cf);
603
604        // solvable vars: x1 x2 y1 y2
605        String[] svar = new String[] { "x1", "x2", "y1", "y2" };
606        GenSolvablePolynomialRing<GenPolynomial<BigComplex>> sf;
607        sf = new GenSolvablePolynomialRing<GenPolynomial<BigComplex>>(cf, svar);
608        //System.out.println("sf = " + sf);
609        RelationGenerator<GenPolynomial<BigComplex>> wr = new WeylRelations<GenPolynomial<BigComplex>>();
610        wr.generate(sf);
611        //System.out.println("sf = " + sf);
612
613        // non-commuting vars: abcdef
614        WordFactory wf = new WordFactory("abcdef");
615        //System.out.println("wf = " + wf);
616        // non-commuting polynomials over commuting and solvable coefficients
617        GenWordPolynomialRing<GenPolynomial<GenPolynomial<BigComplex>>> nf;
618        nf = new GenWordPolynomialRing<GenPolynomial<GenPolynomial<BigComplex>>>(sf, wf);
619        //want: GenWordPolynomialRing<GenSolvablePolynomial<GenPolynomial<BigComplex>>> nf;
620        //System.out.println("nf = " + nf.toScript());
621
622        assertFalse("not commutative",nf.isCommutative());
623        assertTrue("associative",nf.isAssociative());
624        assertFalse("not field",nf.isField());
625
626        GenWordPolynomial<GenPolynomial<GenPolynomial<BigComplex>>> p = nf.getONE();
627        //System.out.println("p = " + p);
628        assertTrue("p == 1", p.isONE());
629        p = nf.getZERO();
630        //System.out.println("p = " + p);
631        assertTrue("p == 0", p.isZERO());
632        p = nf.random(3);
633        //System.out.println("p = " + p);
634        //p = p.sum(p);
635        p = p.multiply(p);
636        //System.out.println("p = " + p);
637        p = p.subtract(p);
638        //System.out.println("p = " + p);
639        assertTrue("p == 0", p.isZERO());
640
641        List<GenWordPolynomial<GenPolynomial<GenPolynomial<BigComplex>>>> gens = nf.generators();
642        //System.out.println("gens = " + gens);
643        assertTrue("#gens == 2+3+4+6", gens.size() == 15);
644    }
645
646}