001/*
002 * $Id: QuotSolvablePolynomialTest.java 5905 2018-08-24 10:23:58Z kredel $
003 */
004
005package edu.jas.fd;
006
007
008import java.util.List;
009
010
011import edu.jas.arith.BigRational;
012import edu.jas.poly.ExpVector;
013import edu.jas.poly.GenPolynomial;
014import edu.jas.poly.GenSolvablePolynomial;
015import edu.jas.poly.GenSolvablePolynomialRing;
016import edu.jas.poly.RecSolvablePolynomial;
017import edu.jas.poly.RelationGenerator;
018import edu.jas.poly.TermOrder;
019import edu.jas.poly.WeylRelations;
020import edu.jas.kern.ComputerThreads;
021
022import junit.framework.Test;
023import junit.framework.TestCase;
024import junit.framework.TestSuite;
025
026
027/**
028 * BigRational coefficients QuotSolvablePolynomial tests with JUnit.
029 * @author Heinz Kredel
030 */
031
032public class QuotSolvablePolynomialTest extends TestCase {
033
034
035    /**
036     * main.
037     */
038    public static void main(String[] args) {
039        junit.textui.TestRunner.run(suite());
040        ComputerThreads.terminate();
041    }
042
043
044    /**
045     * Constructs a <CODE>QuotSolvablePolynomialTest</CODE> object.
046     * @param name String.
047     */
048    public QuotSolvablePolynomialTest(String name) {
049        super(name);
050    }
051
052
053    /**
054     */
055    public static Test suite() {
056        TestSuite suite = new TestSuite(QuotSolvablePolynomialTest.class);
057        return suite;
058    }
059
060
061    QuotSolvablePolynomial<BigRational> a, b, c, d, e, f, x1, x2;
062
063
064    int rl = 4;
065
066
067    int kl = 1;
068
069
070    int ll = 4;
071
072
073    int el = 3;
074
075
076    float q = 0.2f;
077
078
079    String[] cvars = new String[] { "a", "b" };
080
081
082    String[] vars = new String[] { "w", "x", "y", "z" };
083
084
085    QuotSolvablePolynomialRing<BigRational> ring;
086
087
088    BigRational cfac;
089
090
091    GenSolvablePolynomialRing<SolvableQuotient<BigRational>> sring;
092
093
094    GenSolvablePolynomialRing<BigRational> cring;
095
096
097    SolvableQuotientRing<BigRational> qcring;
098
099
100    TermOrder tord = new TermOrder(TermOrder.INVLEX);
101
102
103    @Override
104    protected void setUp() {
105        cfac = new BigRational(1);
106        cring = new GenSolvablePolynomialRing<BigRational>(cfac, tord, cvars);
107        qcring = new SolvableQuotientRing<BigRational>(cring);
108        ring = new QuotSolvablePolynomialRing<BigRational>(qcring, tord, vars);
109        RelationGenerator<SolvableQuotient<BigRational>> wl = new WeylRelations<SolvableQuotient<BigRational>>();
110        ring.addRelations(wl); //wl.generate(ring);
111        a = b = c = d = e = null;
112    }
113
114
115    @Override
116    protected void tearDown() {
117        ring = null;
118        a = b = c = d = e = null;
119    }
120
121
122    /**
123     * Test constructor, generators and properties.
124     */
125    public void testConstructor() {
126        assertFalse("not commutative", ring.isCommutative());
127        assertTrue("associative", ring.isAssociative());
128
129        a = new QuotSolvablePolynomial<BigRational>(ring);
130        assertTrue("length( a ) = 0", a.length() == 0);
131        assertTrue("isZERO( a )", a.isZERO());
132        assertTrue("isONE( a )", !a.isONE());
133
134        c = ring.getONE();
135        assertTrue("length( c ) = 1", c.length() == 1);
136        assertTrue("isZERO( c )", !c.isZERO());
137        assertTrue("isONE( c )", c.isONE());
138
139        d = ring.getZERO();
140        assertTrue("length( d ) = 0", d.length() == 0);
141        assertTrue("isZERO( d )", d.isZERO());
142        assertTrue("isONE( d )", !d.isONE());
143        //System.out.println("d = " + d);
144
145        //System.out.println("");
146        for (GenPolynomial<SolvableQuotient<BigRational>> g : ring.generators()) {
147            //System.out.print("g = " + g + ", ");
148            assertFalse("not isZERO( g )", g.isZERO());
149        }
150        //System.out.println("");
151        assertTrue("isAssociative: ", ring.isAssociative());
152    }
153
154
155    /**
156     * Test random polynomial.
157     */
158    public void testRandom() {
159        for (int i = 0; i < 3; i++) {
160            // a = ring.random(ll+2*i);
161            a = ring.random(kl * (i + 1), ll + 2 * i, el + i, q);
162            //System.out.println("a = " + a);
163            assertTrue("length( a" + i + " ) <> 0", a.length() >= 0);
164            assertTrue(" not isZERO( a" + i + " )", !a.isZERO());
165            assertTrue(" not isONE( a" + i + " )", !a.isONE());
166        }
167    }
168
169
170    /**
171     * Test addition.
172     */
173    public void testAddition() {
174        a = ring.random(kl, ll, el, q);
175        c = (QuotSolvablePolynomial<BigRational>) a.subtract(a);
176        assertTrue("a-a = 0", c.isZERO());
177
178        b = (QuotSolvablePolynomial<BigRational>) a.sum(a);
179        c = (QuotSolvablePolynomial<BigRational>) b.subtract(a);
180        assertEquals("a+a-a = a", c, a);
181
182        b = ring.random(kl, ll, el, q);
183        c = (QuotSolvablePolynomial<BigRational>) b.sum(a);
184        d = (QuotSolvablePolynomial<BigRational>) a.sum(b);
185        assertEquals("a+b = b+a", c, d);
186
187        c = ring.random(kl, ll, el, q);
188        d = (QuotSolvablePolynomial<BigRational>) a.sum(b.sum(c));
189        e = (QuotSolvablePolynomial<BigRational>) a.sum(b).sum(c);
190        assertEquals("a+(b+c) = (a+b)+c", d, e);
191        //System.out.println("a = " + a);
192        //System.out.println("b = " + b);
193        //System.out.println("c = " + c);
194        //System.out.println("d = " + d);
195        //System.out.println("e = " + e);
196
197        ExpVector u = ExpVector.random(rl, el, q);
198        SolvableQuotient<BigRational> x = qcring.random(kl);
199        //System.out.println("x = " + x);
200        //System.out.println("u = " + u);
201
202        b = ring.getONE().multiply(x, u);
203        c = (QuotSolvablePolynomial<BigRational>) a.sum(b);
204        d = (QuotSolvablePolynomial<BigRational>) a.sum(x, u);
205        //System.out.println("a = " + a);
206        //System.out.println("b = " + b);
207        //System.out.println("c = " + c);
208        //System.out.println("d = " + d);
209        assertEquals("a+p(x,u) = a+(x,u)", c, d);
210
211        c = (QuotSolvablePolynomial<BigRational>) a.subtract(b);
212        d = (QuotSolvablePolynomial<BigRational>) a.subtract(x, u);
213        assertEquals("a-p(x,u) = a-(x,u)", c, d);
214
215        a = ring.getZERO();
216        b = ring.getONE().multiply(x, u);
217        c = (QuotSolvablePolynomial<BigRational>) b.sum(a);
218        d = (QuotSolvablePolynomial<BigRational>) a.sum(x, u);
219        assertEquals("a+p(x,u) = a+(x,u)", c, d);
220
221        c = (QuotSolvablePolynomial<BigRational>) a.subtract(b);
222        d = (QuotSolvablePolynomial<BigRational>) a.subtract(x, u);
223        assertEquals("a-p(x,u) = a-(x,u)", c, d);
224    }
225
226
227    /**
228     * Test multiplication.
229     */
230    public void testMultiplication() {
231        //System.out.println("ring = " + ring);
232        a = ring.random(kl, ll - 1, el - 1, q);
233        //a = ring.parse(" b y z + a w z ");  
234        b = ring.random(kl, ll - 1, el - 1, q);
235        //b = ring.parse(" w x - b x "); 
236
237        c = b.multiply(a);
238        d = a.multiply(b);
239        //System.out.println("a = " + a);
240        //System.out.println("b = " + b);
241        //System.out.println("c = " + c);
242        //System.out.println("d = " + d);
243        assertTrue("a*b != b*a", c.equals(d) || c.leadingExpVector().equals(d.leadingExpVector()));
244
245        c = ring.random(kl, ll - 1, el - 1, q);
246        d = a.multiply(b.multiply(c));
247        e = a.multiply(b).multiply(c);
248        assertEquals("a(bc) = (ab)c", d, e);
249        //System.out.println("a = " + a);
250        //System.out.println("b = " + b);
251        //System.out.println("c = " + c);
252        //System.out.println("d = " + d);
253        //System.out.println("e = " + e);
254
255        SolvableQuotient<BigRational> xp = a.leadingBaseCoefficient().inverse();
256        d = a.multiply(xp);
257        assertTrue("monic(a) = a*(1/ldcf(ldcf(a)))", d.leadingBaseCoefficient().isONE());
258
259        d = (QuotSolvablePolynomial<BigRational>) a.monic();
260        assertTrue("a.monic(): ", d.leadingBaseCoefficient().isONE());
261    }
262
263
264    /**
265     * Test commutative ring.
266     */
267    public void testCommutative() {
268        //System.out.println("table = " + table.toString(vars));
269        //System.out.println("table = " + table.toScript());
270        //System.out.println("ring = " + ring);
271        //System.out.println("ring.table = " + ring.table.toScript());
272        //assertEquals("table == ring.table: ", table, ring.table); // ?
273        assertTrue("# relations == 2", ring.table.size() == 2);
274
275        ring = new QuotSolvablePolynomialRing<BigRational>(qcring, ring);
276        //System.out.println("ring = " + ring);
277
278        assertTrue("isCommutative()", ring.isCommutative());
279        assertTrue("isAssociative()", ring.isAssociative());
280
281        a = ring.random(kl, ll, el, q);
282        //a = ring.parse(" b x y z + a w z ");
283        //System.out.println("a = " + a);
284        b = ring.random(kl, ll, el, q);
285        //b = ring.parse(" w y z - b x ");
286        //System.out.println("b = " + b);
287
288        // commutative
289        c = b.multiply(a);
290        //System.out.println("c = " + c);
291        d = a.multiply(b);
292        //d = ring.getONE(); 
293        //System.out.println("d = " + d);
294        assertEquals("b*a == a*b: ", c, d);
295    }
296
297
298    /**
299     * Test distributive law.
300     */
301    public void testDistributive() {
302        a = ring.random(kl, ll, el, q);
303        b = ring.random(kl, ll, el, q);
304        c = ring.random(kl, ll, el, q);
305
306        d = a.multiply((QuotSolvablePolynomial<BigRational>) b.sum(c));
307        e = (QuotSolvablePolynomial<BigRational>) a.multiply(b).sum(a.multiply(c));
308        assertEquals("a*(b+c) = a*b+a*c", d, e);
309    }
310
311
312    /**
313     * Test solvable coefficient ring.
314     */
315    public void testSolvableCoeffs() {
316        GenSolvablePolynomialRing<BigRational> csring = new GenSolvablePolynomialRing<BigRational>(cfac, tord,
317                        cvars);
318        //RelationGenerator<BigRational> wlc = new WeylRelations<BigRational>(csring); 
319        //no: wlc.generate(csring);
320        //assertTrue("# relations == 1", csring.table.size() == 1);
321        assertTrue("isCommutative()", csring.isCommutative());
322        assertTrue("isAssociative()", csring.isAssociative());
323
324        SolvableQuotientRing<BigRational> qcsring = new SolvableQuotientRing<BigRational>(csring);
325        //assertFalse("isCommutative()", qcsring.isCommutative());
326        assertTrue("isAssociative()", qcsring.isAssociative());
327
328        ring = new QuotSolvablePolynomialRing<BigRational>(qcsring, ring);
329        RelationGenerator<SolvableQuotient<BigRational>> wl = new WeylRelations<SolvableQuotient<BigRational>>();
330        wl.generate(ring);
331        assertTrue("# relations == 2", ring.table.size() == 2);
332        assertFalse("isCommutative()", ring.isCommutative());
333        assertTrue("isAssociative()", ring.isAssociative());
334        //System.out.println("ring = " + ring);
335
336        RecSolvablePolynomial<BigRational> r1 = ring.polCoeff.parse("x");
337        GenSolvablePolynomial<BigRational> r2 = csring.parse("b");
338        RecSolvablePolynomial<BigRational> rp = ring.polCoeff.parse("b x + a"); // + a
339        //System.out.println("r1 = " + r1);
340        //System.out.println("r2 = " + r2);
341        //System.out.println("rp = " + rp);
342        ring.polCoeff.coeffTable.update(r1.leadingExpVector(), r2.leadingExpVector(), rp);
343        //System.out.println("ring.polCoeff = " + ring.polCoeff);
344
345        assertFalse("isCommutative()", ring.isCommutative());
346        assertTrue("isAssociative()", ring.isAssociative());
347
348        List<GenPolynomial<SolvableQuotient<BigRational>>> gens = ring.generators();
349        //gens = new ArrayList<GenPolynomial<SolvableQuotient<BigRational>>>();
350
351        for (GenPolynomial<SolvableQuotient<BigRational>> x : gens) {
352            GenSolvablePolynomial<SolvableQuotient<BigRational>> xx = (GenSolvablePolynomial<SolvableQuotient<BigRational>>) x;
353            a = new QuotSolvablePolynomial<BigRational>(ring, xx);
354            //System.out.println("a = " + a);
355            for (GenPolynomial<SolvableQuotient<BigRational>> y : gens) {
356                GenSolvablePolynomial<SolvableQuotient<BigRational>> yy = (GenSolvablePolynomial<SolvableQuotient<BigRational>>) y;
357                b = new QuotSolvablePolynomial<BigRational>(ring, yy);
358                //System.out.println("b = " + b);
359                c = a.multiply(b);
360                //System.out.println("gens: " + a + " * " + b + " = " + c);
361                ExpVector ev = a.leadingExpVector().sum(b.leadingExpVector());
362                assertTrue("LT(a)*LT(b) == LT(c)", c.leadingExpVector().equals(ev));
363            }
364        }
365
366        //a = ring.random(kl, ll, el, q);
367        //a = ring.getONE();
368        a = ring.parse("x^2 + a b");
369        //System.out.println("a = " + a.toScript());
370        //b = ring.random(kl, ll, el, q);
371        //b = ring.getONE();
372        b = ring.parse("a b^2 + a"); // + a 
373        b = (QuotSolvablePolynomial<BigRational>) b.inverse();
374        //System.out.println("b = " + b.toScript());
375
376        // non-commutative
377        c = b.multiply(a);
378        d = a.multiply(b);
379        //System.out.println("a = " + a.toScript());
380        //System.out.println("b = " + b.toScript());
381        //System.out.println("c = " + c.toScript());
382        //System.out.println("d = " + d.toScript());
383        assertTrue("a*b != b*a", c.equals(d) || c.leadingExpVector().equals(d.leadingExpVector()));
384
385        e = (QuotSolvablePolynomial<BigRational>) b.inverse();
386        //System.out.println("e = " + e.toScript());
387        assertTrue("b*b^-1 == 1", e.multiply(b).isONE());
388
389        c = e.multiply(c);
390        d = d.multiply(e);
391        //System.out.println("a = " + a.toScript());
392        //System.out.println("b = " + b.toScript());
393        //System.out.println("c = " + c.toScript());
394        //System.out.println("d = " + d.toScript());
395        assertTrue("a == b * 1/b * a", a.equals(c));
396        assertTrue("a == a * 1/b * b", a.equals(d));
397    }
398
399
400    /*
401     * Test extension and contraction for Weyl relations. public void
402     * testExtendContractWeyl() { GenSolvablePolynomialRing<BigRational> csring
403     * = new GenSolvablePolynomialRing<BigRational>(cfac, tord, cvars);
404     * RelationGenerator<BigRational> wlc = new WeylRelations<BigRational>();
405     * wlc.generate(csring); assertFalse("isCommutative()", csring.isCommutative());
406     * assertTrue("isAssociative()", csring.isAssociative());
407     * 
408     * QuotSolvablePolynomial<BigRational> r1 = ring.parse("x");
409     * GenSolvablePolynomial<BigRational> r2 = csring.parse("b");
410     * QuotSolvablePolynomial<BigRational> rp = ring.parse("b x + a");
411     * ring.polCoeff.coeffTable.update(r1.leadingExpVector(), r2.leadingExpVector(), rp);
412     * 
413     * int k = rl; QuotSolvablePolynomialRing<BigRational> pfe = ring.extend(k);
414     * //System.out.println("pfe = " + pfe);
415     * QuotSolvablePolynomialRing<BigRational> pfec = pfe.contract(k);
416     * //System.out.println("pfec = " + pfec); assertEquals("ring == pfec",
417     * ring, pfec);
418     * 
419     * QuotSolvablePolynomial<BigRational> a = ring.random(kl, ll, el, q);
420     * //System.out.println("a = " + a);
421     * 
422     * QuotSolvablePolynomial<BigRational> ae =
423     * (QuotSolvablePolynomial<BigRational>) a.extend(pfe, 0, 0);
424     * //System.out.println("ae = " + ae);
425     * 
426     * Map<ExpVector, GenPolynomial<GenPolynomial<BigRational>>> m =
427     * ae.contract(pfec); List<GenPolynomial<GenPolynomial<BigRational>>> ml =
428     * new ArrayList<GenPolynomial<GenPolynomial<BigRational>>>( m.values());
429     * GenPolynomial<GenPolynomial<BigRational>> aec = ml.get(0);
430     * //System.out.println("ae  = " + ae); //System.out.println("aec = " +
431     * aec); assertEquals("a == aec", a, aec); }
432     */
433
434
435    /*
436     * Test reversion for Weyl relations. public void testReverseWeyl() {
437     * GenSolvablePolynomialRing<BigRational> csring = new
438     * GenSolvablePolynomialRing<BigRational>(cfac, tord, cvars);
439     * RelationGenerator<BigRational> wlc = new WeylRelations<BigRational>();
440     * wlc.generate(csring); assertFalse("isCommutative()", csring.isCommutative());
441     * assertTrue("isAssociative()", csring.isAssociative());
442     * 
443     * QuotSolvablePolynomial<BigRational> r1 = ring.parse("x");
444     * GenSolvablePolynomial<BigRational> r2 = csring.parse("b");
445     * QuotSolvablePolynomial<BigRational> rp = ring.parse("b x + a");
446     * ring.polCoeff.coeffTable.update(r1.leadingExpVector(), r2.leadingExpVector(), rp);
447     * 
448     * QuotSolvablePolynomialRing<BigRational> pfr = ring.reverse();
449     * QuotSolvablePolynomialRing<BigRational> pfrr = pfr.reverse();
450     * assertEquals("pf == pfrr", ring, pfrr); //System.out.println("ring = " +
451     * ring); //System.out.println("pfr = " + pfr);
452     * 
453     * QuotSolvablePolynomial<BigRational> a = ring.random(kl, ll, el, q);
454     * //System.out.println("a = " + a);
455     * 
456     * QuotSolvablePolynomial<BigRational> ar =
457     * (QuotSolvablePolynomial<BigRational>) a.reverse(pfr);
458     * QuotSolvablePolynomial<BigRational> arr =
459     * (QuotSolvablePolynomial<BigRational>) ar.reverse(pfrr);
460     * assertEquals("a == arr", a, arr); //System.out.println("ar = " + ar);
461     * //System.out.println("arr = " + arr); }
462     */
463
464
465    /*
466     * Test recursive for Weyl relations. public void testRecursiveWeyl() {
467     * String[] svars = new String[] { "w", "x", "y", "z" };
468     * GenSolvablePolynomialRing<BigRational> sring = new
469     * GenSolvablePolynomialRing<BigRational>(cfac, tord, svars);
470     * RelationGenerator<BigRational> wlc = new WeylRelations<BigRational>();
471     * wlc.generate(sring); assertFalse("isCommutative()", sring.isCommutative());
472     * assertTrue("isAssociative()", sring.isAssociative());
473     * //System.out.println("sring = " + sring.toScript());
474     * 
475     * GenSolvablePolynomialRing<GenPolynomial<BigRational>> rsring =
476     * sring.recursive(2); // 1,2,3 //System.out.println("rsring = " + rsring);
477     * //.toScript()); System.out.println("rsring = " + rsring.toScript());
478     * 
479     * GenSolvablePolynomial<BigRational> ad, bd, cd, dd;
480     * QuotSolvablePolynomial<BigRational> ar, br, cr, dr; ad = sring.random(kl,
481     * ll, el, q); bd = sring.random(kl, ll, el, q); //ad =
482     * sring.parse("7/2 y^2 * z"); // - 15/2 w^2 + 262/225"); //bd =
483     * sring.parse("-10/13 x "); //+ 413/150"); //ad =
484     * (GenSolvablePolynomial<BigRational>) ad.monic(); //bd =
485     * (GenSolvablePolynomial<BigRational>) bd.monic();
486     * 
487     * //System.out.println("ad = " + ad); //System.out.println("bd = " + bd);
488     * 
489     * cd = ad.multiply(bd); //System.out.println("cd = " + cd);
490     * 
491     * ar = (QuotSolvablePolynomial<BigRational>) PolyUtil.<BigRational>
492     * recursive(rsring, ad); br = (QuotSolvablePolynomial<BigRational>)
493     * PolyUtil.<BigRational> recursive(rsring, bd);
494     * //System.out.println("ar = " + ar); //System.out.println("br = " + br);
495     * 
496     * cr = ar.multiply(br); //System.out.println("cr = " + cr);
497     * //System.out.println("cr.ring = " + cr.ring.toScript());
498     * 
499     * dr = (QuotSolvablePolynomial<BigRational>) PolyUtil.<BigRational>
500     * recursive(rsring, cd); //System.out.println("dr = " + dr);
501     * 
502     * assertEquals("dr.ring == cr.ring", dr.ring, cr.ring);
503     * assertEquals("dr == cr", dr, cr);
504     * 
505     * dd = (GenSolvablePolynomial<BigRational>) PolyUtil.<BigRational>
506     * distribute(sring, cr); //System.out.println("dd = " + dd);
507     * assertEquals("dd == cd", dd, cd); }
508     */
509
510
511    /*
512     * Test recursive for iterated Weyl relations. public void
513     * testRecursiveIteratedWeyl() { String[] svars = new String[] { "w", "x",
514     * "y", "z" }; GenSolvablePolynomialRing<BigRational> sring = new
515     * GenSolvablePolynomialRing<BigRational>(cfac, tord, svars);
516     * RelationGenerator<BigRational> wlc = new WeylRelationsIterated<BigRational>();
517     * wlc.generate(sring); assertFalse("isCommutative()",
518     * sring.isCommutative()); assertTrue("isAssociative()",
519     * sring.isAssociative()); //System.out.println("sring = " +
520     * sring.toScript());
521     * 
522     * GenSolvablePolynomialRing<GenPolynomial<BigRational>> rsring =
523     * sring.recursive(2); // 1,2,3 //System.out.println("rsring = " + rsring);
524     * //.toScript()); System.out.println("rsring = " + rsring.toScript());
525     * 
526     * GenSolvablePolynomial<BigRational> ad, bd, cd, dd;
527     * QuotSolvablePolynomial<BigRational> ar, br, cr, dr; ad = sring.random(kl,
528     * ll, el, q); bd = sring.random(kl, ll, el, q); //ad =
529     * (GenSolvablePolynomial<BigRational>) ad.monic(); //bd =
530     * (GenSolvablePolynomial<BigRational>) bd.monic();
531     * 
532     * //System.out.println("ad = " + ad); //System.out.println("bd = " + bd);
533     * 
534     * cd = ad.multiply(bd); //System.out.println("cd = " + cd);
535     * 
536     * ar = (QuotSolvablePolynomial<BigRational>) PolyUtil.<BigRational>
537     * recursive(rsring, ad); br = (QuotSolvablePolynomial<BigRational>)
538     * PolyUtil.<BigRational> recursive(rsring, bd);
539     * //System.out.println("ar = " + ar); //System.out.println("br = " + br);
540     * 
541     * cr = ar.multiply(br); //System.out.println("cr = " + cr);
542     * 
543     * dr = (QuotSolvablePolynomial<BigRational>) PolyUtil.<BigRational>
544     * recursive(rsring, cd); //System.out.println("dr = " + dr);
545     * 
546     * assertEquals("dr.ring == cr.ring", dr.ring, cr.ring);
547     * assertEquals("dr == cr", dr, cr);
548     * 
549     * dd = (GenSolvablePolynomial<BigRational>) PolyUtil.<BigRational>
550     * distribute(sring, cr); //System.out.println("dd = " + dd);
551     * assertEquals("dd == cd", dd, cd); }
552     */
553
554}