source: git/factory/canonicalform.cc @ ba02b1

spielwiese
Last change on this file since ba02b1 was ba02b1, checked in by Jens Schmidt <schmidt@…>, 27 years ago
* canonicalform.cc (operator ()): speeded up git-svn-id: file:///usr/local/Singular/svn/trunk@832 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 39.1 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: canonicalform.cc,v 1.22 1997-10-22 15:51:36 schmidt Exp $ */
3
4#include <config.h>
5
6#include "assert.h"
7
8#include "cf_defs.h"
9#include "cf_globals.h"
10#include "canonicalform.h"
11#include "cf_iter.h"
12#include "int_cf.h"
13#include "cf_factory.h"
14#include "imm.h"
15#include "gfops.h"
16#include "cf_binom.h"
17#if defined (USE_MEMUTIL) && ! defined (USE_OLD_MEMMAN)
18#include "memman.h"
19#endif
20
21#ifndef NOSTREAMIO
22CanonicalForm readCF( istream& );
23#endif /* NOSTREAMIO */
24
25//{{{ initialization
26int initializeGMP();
27int initializeCharacteristic();
28#ifdef SINGULAR
29int mmInit(void);
30#endif
31
32int
33initCanonicalForm( void )
34{
35    static bool initialized = false;
36    if ( ! initialized ) {
37#if (defined (USE_MEMUTIL) && ! defined (USE_OLD_MEMMAN)) || defined (SINGULAR)
38        (void)mmInit();
39#endif
40
41        (void)initializeCharacteristic();
42        (void)initializeGMP();
43        initPT();
44        initialized = true;
45    }
46    return 1;
47}
48//}}}
49
50//{{{ constructors, destructors, selectors
51CanonicalForm::CanonicalForm() : value( CFFactory::basic( (int)0 ) )
52{
53}
54
55CanonicalForm::CanonicalForm( const int i ) : value( CFFactory::basic( i ) )
56{
57}
58
59CanonicalForm::CanonicalForm( const CanonicalForm & cf ) : value( is_imm( cf.value ) ? cf.value : cf.value->copyObject() )
60{
61}
62
63CanonicalForm::CanonicalForm( InternalCF * cf ) : value( cf )
64{
65}
66
67CanonicalForm::CanonicalForm( const Variable & v ) : value( CFFactory::poly( v ) )
68{
69}
70
71CanonicalForm::CanonicalForm( const Variable & v, int e ) : value( CFFactory::poly( v, e ) )
72{
73}
74
75CanonicalForm::CanonicalForm( const char * str ) : value( CFFactory::basic( str ) )
76{
77}
78
79CanonicalForm::~CanonicalForm()
80{
81    if ( (! is_imm( value )) && value->deleteObject() )
82        delete value;
83}
84
85InternalCF*
86CanonicalForm::getval() const
87{
88    if ( is_imm( value ) )
89        return value;
90    else
91        return value->copyObject();
92}
93
94CanonicalForm
95CanonicalForm::deepCopy() const
96{
97    if ( is_imm( value ) )
98        return *this;
99    else
100        return CanonicalForm( value->deepCopyObject() );
101}
102//}}}
103
104//{{{ predicates
105bool
106CanonicalForm::isOne() const
107{
108    if ( is_imm( value ) == FFMARK )
109        return imm_isone_p( value );
110    else  if ( is_imm( value ) == GFMARK )
111        return imm_isone_gf( value );
112    else  if ( is_imm( value ) )
113        return imm_isone( value );
114    else
115        return value->isOne();
116}
117
118bool
119CanonicalForm::isZero() const
120{
121    if ( is_imm( value ) == FFMARK )
122        return imm_iszero_p( value );
123    else  if ( is_imm( value ) == GFMARK )
124        return imm_iszero_gf( value );
125    else  if ( is_imm( value ) )
126        return imm_iszero( value );
127    else
128        return value->isZero();
129}
130
131bool
132CanonicalForm::isImm() const
133{
134    return is_imm( value );
135}
136
137bool
138CanonicalForm::inZ() const
139{
140    if ( is_imm( value ) == INTMARK )
141        return true;
142    else if ( is_imm( value ) )
143        return false;
144    else
145        return value->levelcoeff() == IntegerDomain;
146}
147
148bool
149CanonicalForm::inQ() const
150{
151    if ( is_imm( value ) == INTMARK )
152        return true;
153    else if ( is_imm( value ) )
154        return false;
155    else
156        return value->levelcoeff() == IntegerDomain ||
157            value->levelcoeff() == RationalDomain;
158}
159
160bool
161CanonicalForm::inFF() const
162{
163    return is_imm( value ) == FFMARK;
164}
165
166bool
167CanonicalForm::inGF() const
168{
169    return is_imm( value ) == GFMARK;
170}
171
172bool
173CanonicalForm::inPP() const
174{
175    return ! is_imm( value ) && ( value->levelcoeff() == PrimePowerDomain );
176}
177
178bool
179CanonicalForm::inBaseDomain() const
180{
181    if ( is_imm( value ) )
182        return true;
183    else
184        return value->inBaseDomain();
185}
186
187bool
188CanonicalForm::inExtension() const
189{
190    if ( is_imm( value ) )
191        return false;
192    else
193        return value->inExtension();
194}
195
196bool
197CanonicalForm::inCoeffDomain() const
198{
199    if ( is_imm( value ) )
200        return true;
201    else
202        return value->inCoeffDomain();
203}
204
205bool
206CanonicalForm::inPolyDomain() const
207{
208    if ( is_imm( value ) )
209        return false;
210    else
211        return value->inPolyDomain();
212}
213
214bool
215CanonicalForm::inQuotDomain() const
216{
217    if ( is_imm( value ) )
218        return false;
219    else
220        return value->inQuotDomain();
221}
222
223bool
224CanonicalForm::isFFinGF() const
225{
226    return is_imm( value ) == GFMARK && gf_isff( imm2int( value ) );
227}
228
229bool
230CanonicalForm::isUnivariate() const
231{
232    if ( is_imm( value ) )
233        return false;
234    else
235        return value->isUnivariate();
236}
237//}}}
238
239//{{{ conversion functions
240int
241CanonicalForm::intval() const
242{
243    if ( is_imm( value ) )
244        return imm_intval( value );
245    else
246        return value->intval();
247}
248
249CanonicalForm
250CanonicalForm::mapinto () const
251{
252    ASSERT( is_imm( value ) ||  ! value->inExtension(), "cannot map into different Extension" );
253    if ( is_imm( value ) )
254        if ( getCharacteristic() == 0 )
255            if ( is_imm( value ) == FFMARK )
256                return CanonicalForm( int2imm( ff_symmetric( imm2int( value ) ) ) );
257            else  if ( is_imm( value ) == GFMARK )
258                return CanonicalForm( int2imm( ff_symmetric( gf_gf2ff( imm2int( value ) ) ) ) );
259            else
260                return *this;
261        else  if ( CFFactory::gettype() == PrimePowerDomain )
262            return CanonicalForm( CFFactory::basic( imm2int( value ) ) );
263        else  if ( getGFDegree() == 1 )
264            return CanonicalForm( int2imm_p( ff_norm( imm2int( value ) ) ) );
265        else
266            return CanonicalForm( int2imm_gf( gf_int2gf( imm2int( value ) ) ) );
267    else  if ( value->inBaseDomain() )
268        if ( getCharacteristic() == 0 )
269            if ( value->levelcoeff() == PrimePowerDomain )
270                return CFFactory::basic( getmpi( value, true ) );
271            else
272                return *this;
273        else  if ( CFFactory::gettype() == PrimePowerDomain ) {
274            ASSERT( value->levelcoeff() == PrimePowerDomain || value->levelcoeff() == IntegerDomain, "no proper map defined" );
275            if ( value->levelcoeff() == PrimePowerDomain )
276                return *this;
277            else
278                return CFFactory::basic( getmpi( value ) );
279        }
280        else {
281            int val;
282            if ( value->levelcoeff() == IntegerDomain )
283                val = value->intmod( ff_prime );
284            else  if ( value->levelcoeff() == RationalDomain )
285                return num().mapinto() / den().mapinto();
286            else {
287                ASSERT( 0, "illegal domain" );
288                return 0;
289            }
290            if ( getGFDegree() > 1 )
291                return CanonicalForm( int2imm_gf( gf_int2gf( val ) ) );
292            else
293                return CanonicalForm( int2imm_p( val ) );
294        }
295    else {
296        Variable x = value->variable();
297        CanonicalForm result;
298        for ( CFIterator i = *this; i.hasTerms(); i++ )
299            result += power( x, i.exp() ) * i.coeff().mapinto();
300        return result;
301    }
302}
303//}}}
304
305//{{{ CanonicalForm CanonicalForm::lc (), Lc (), LC (), LC ( v ) const
306//{{{ docu
307//
308// lc(), Lc(), LC() - leading coefficient functions.
309//
310// All methods return CO if CO is in a base domain.
311//
312// lc() returns the leading coefficient of CO with respect to
313// lexicographic ordering.  Elements in an algebraic extension
314// are considered polynomials so lc() always returns a leading
315// coefficient in a base domain.  This method is useful to get
316// the base domain over which CO is defined.
317//
318// Lc() returns the leading coefficient of CO with respect to
319// lexicographic ordering.  In contrast to lc() elements in an
320// algebraic extension are considered coefficients so Lc() always
321// returns a leading coefficient in a coefficient domain.
322//
323// LC() returns the leading coefficient of CO where CO is
324// considered a univariate polynomial in its main variable.  An
325// element of an algebraic extension is considered an univariate
326// polynomial, too.
327//
328// LC( v ) returns the leading coefficient of CO where CO is
329// considered an univariate polynomial in the polynomial variable
330// v.
331// Note: If v is less than the main variable of CO we have to
332// swap variables which may be quite expensive.
333//
334// Examples:
335// Let x < y be polynomial variables, a an algebraic variable.
336//
337// (3*a*x*y^2+y+x).lc() = 3
338// (3*a*x*y^2+y+x).Lc() = 3*a
339// (3*a*x*y^2+y+x).LC() = 3*a*x
340// (3*a*x*y^2+y+x).LC( x ) = 3*a*y^2+1
341//
342// (3*a^2+4*a).lc() = 3
343// (3*a^2+4*a).Lc() = 3*a^2+4*a
344// (3*a^2+4*a).LC() = 3
345// (3*a^2+4*a).LC( x ) = 3*a^2+4*a
346//
347// See also: InternalCF::lc(), InternalCF::Lc(), InternalCF::LC(),
348// InternalPoly::lc(), InternalPoly::Lc(), InternalPoly::LC(),
349// ::lc(), ::Lc(), ::LC(), ::LC( v )
350//
351//}}}
352CanonicalForm
353CanonicalForm::lc () const
354{
355    if ( is_imm( value ) )
356        return *this;
357    else
358        return value->lc();
359}
360
361CanonicalForm
362CanonicalForm::Lc () const
363{
364    if ( is_imm( value ) || value->inCoeffDomain() )
365        return *this;
366    else
367        return value->Lc();
368}
369
370CanonicalForm
371CanonicalForm::LC () const
372{
373    if ( is_imm( value ) )
374        return *this;
375    else
376        return value->LC();
377}
378
379CanonicalForm
380CanonicalForm::LC ( const Variable & v ) const
381{
382    if ( is_imm( value ) || value->inCoeffDomain() )
383        return *this;
384
385    Variable x = value->variable();
386    if ( v > x )
387        return *this;
388    else if ( v == x )
389        return value->LC();
390    else {
391        CanonicalForm f = swapvar( *this, v, x );
392        if ( f.mvar() == x )
393            return swapvar( f.value->LC(), v, x );
394        else
395            // v did not occur in f
396            return *this;
397    }
398}
399//}}}
400
401//{{{ int CanonicalForm::degree (), degree ( v ) const
402//{{{ docu
403//
404// degree() - degree methods.
405//
406// Both methods returns -1 for the zero polynomial and 0 if
407// CO is in a base domain.
408//
409// degree() returns the degree of CO in its main variable.
410// Elements in an algebraic extension are considered polynomials.
411//
412// degree( v ) returns the degree of CO with respect to v.
413// Elements in an algebraic extension are considered polynomials,
414// and v may be algebraic.
415//
416// See also: InternalCf::degree(), InternalPoly::degree(),
417// ::degree(), ::degree( v )
418//
419//}}}
420int
421CanonicalForm::degree() const
422{
423    int what = is_imm( value );
424    if ( what )
425        if ( what == GFMARK && imm_iszero_gf( value ) )
426            return -1;
427        else if ( what == FFMARK && imm_iszero_gf( value ) )
428            return -1;
429        else if ( what == INTMARK && imm_iszero( value ) )
430            return -1;
431        else
432            return 0;
433    else
434        return value->degree();
435}
436
437int
438CanonicalForm::degree( const Variable & v ) const
439{
440    int what = is_imm( value );
441    if ( what )
442        if ( what == GFMARK && imm_iszero_gf( value ) )
443            return -1;
444        else if ( what == FFMARK && imm_iszero_gf( value ) )
445            return -1;
446        else if ( what == INTMARK && imm_iszero( value ) )
447            return -1;
448        else
449            return 0;
450    else if ( value->inBaseDomain() )
451        return value->degree();
452
453    Variable x = value->variable();
454    if ( v == x )
455        return value->degree();
456    else  if ( v > x )
457        // relatively to v, f is in a coefficient ring
458        return 0;
459    else {
460        int coeffdeg, result = 0;
461        // search for maximum of coefficient degree
462        for ( CFIterator i = *this; i.hasTerms(); i++ ) {
463            coeffdeg = i.coeff().degree( v );
464            if ( coeffdeg > result )
465                result = coeffdeg;
466        }
467        return result;
468    }
469}
470//}}}
471
472//{{{ CanonicalForm CanonicalForm::tailcoeff (), int CanonicalForm::taildegree () const
473//{{{ docu
474//
475// tailcoeff(), taildegree() - return least coefficient and
476//   degree, resp.
477//
478// tailcoeff() returns the coefficient of the term with the least
479// degree in CO where CO is considered an univariate polynomial
480// in its main variable.  Elements in an algebraic extension are
481// considered coefficients.
482//
483// taildegree() returns -1 for the zero polynomial, 0 if CO is in
484// a base domain, otherwise the least degree of CO where CO is
485// considered a univariate polynomial in its main variable.  In
486// contrast to tailcoeff(), elements in an algebraic extension
487// are considered polynomials, not coefficients, and such may
488// have a taildegree larger than zero.
489//
490// See also: InternalCF::tailcoeff(), InternalCF::tailcoeff(),
491// InternalPoly::tailcoeff(), InternalPoly::taildegree,
492// ::tailcoeff(), ::taildegree()
493//
494//}}}
495CanonicalForm
496CanonicalForm::tailcoeff () const
497{
498    if ( is_imm( value ) || value->inCoeffDomain() )
499        return *this;
500    else
501        return value->tailcoeff();
502}
503
504int
505CanonicalForm::taildegree () const
506{
507    int what = is_imm( value );
508    if ( what )
509        if ( what == GFMARK && imm_iszero_gf( value ) )
510            return -1;
511        else if ( what == FFMARK && imm_iszero_gf( value ) )
512            return -1;
513        else if ( what == INTMARK && imm_iszero( value ) )
514            return -1;
515        else
516            return 0;
517    else
518        return value->taildegree();
519}
520//}}}
521
522//{{{ int CanonicalForm::level (), Variable CanonicalForm::mvar () const
523//{{{ docu
524//
525// level(), mvar() - return level and main variable of CO.
526//
527// level() returns the level of CO.  For a list of the levels and
528// their meanings, see cf_defs.h.
529//
530// mvar() returns the main variable of CO or Variable() if CO is
531// in a base domain.
532//
533// See also: InternalCF::level(), InternalCF::variable(),
534// InternalPoly::level(), InternalPoly::variable(), ::level(),
535// ::mvar()
536//
537//}}}
538int
539CanonicalForm::level () const
540{
541    if ( is_imm( value ) )
542        return LEVELBASE;
543    else
544        return value->level();
545}
546
547Variable
548CanonicalForm::mvar () const
549{
550    if ( is_imm( value ) )
551        return Variable();
552    else
553        return value->variable();
554}
555//}}}
556
557//{{{ CanonicalForm CanonicalForm::num (), den () const
558//{{{ docu
559//
560// num(), den() - return numinator and denominator of CO.
561//
562// num() returns the numinator of CO if CO is a rational number,
563// CO itself otherwise.
564//
565// den() returns the denominator of CO if CO is a rational
566// number, 1 (from the current domain!) otherwise.
567//
568// See also: InternalCF::num(), InternalCF::den(),
569// InternalRational::num(), InternalRational::den(), ::num(),
570// ::den()
571//
572//}}}
573CanonicalForm
574CanonicalForm::num () const
575{
576    if ( is_imm( value ) )
577        return *this;
578    else
579        return CanonicalForm( value->num() );
580}
581
582CanonicalForm
583CanonicalForm::den () const
584{
585    if ( is_imm( value ) )
586        return CanonicalForm( 1 );
587    else
588        return CanonicalForm( value->den() );
589}
590//}}}
591
592//{{{ assignment operators
593CanonicalForm &
594CanonicalForm::operator = ( const CanonicalForm & cf )
595{
596    if ( this != &cf ) {
597        if ( (! is_imm( value )) && value->deleteObject() )
598            delete value;
599        value = (is_imm( cf.value )) ? cf.value : cf.value->copyObject();
600    }
601    return *this;
602}
603
604CanonicalForm &
605CanonicalForm::operator = ( const int cf )
606{
607    if ( (! is_imm( value )) && value->deleteObject() )
608        delete value;
609    value = CFFactory::basic( cf );
610    return *this;
611}
612
613CanonicalForm &
614CanonicalForm::operator += ( const CanonicalForm & cf )
615{
616    int what = is_imm( value );
617    if ( what ) {
618        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
619        if ( (what = is_imm( cf.value )) == FFMARK )
620            value = imm_add_p( value, cf.value );
621        else  if ( what == GFMARK )
622            value = imm_add_gf( value, cf.value );
623        else  if ( what )
624            value = imm_add( value, cf.value );
625        else {
626            InternalCF * dummy = cf.value->copyObject();
627            value = dummy->addcoeff( value );
628        }
629    }
630    else  if ( is_imm( cf.value ) )
631        value = value->addcoeff( cf.value );
632    else  if ( value->level() == cf.value->level() ) {
633        if ( value->levelcoeff() == cf.value->levelcoeff() )
634            value = value->addsame( cf.value );
635        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
636            value = value->addcoeff( cf.value );
637        else {
638            InternalCF * dummy = cf.value->copyObject();
639            dummy = dummy->addcoeff( value );
640            if ( value->deleteObject() ) delete value;
641            value = dummy;
642        }
643    }
644    else  if ( level() > cf.level() )
645        value = value->addcoeff( cf.value );
646    else {
647        InternalCF * dummy = cf.value->copyObject();
648        dummy = dummy->addcoeff( value );
649        if ( value->deleteObject() ) delete value;
650        value = dummy;
651    }
652    return *this;
653}
654
655CanonicalForm &
656CanonicalForm::operator -= ( const CanonicalForm & cf )
657{
658    int what = is_imm( value );
659    if ( what ) {
660        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
661        if ( (what = is_imm( cf.value )) == FFMARK )
662            value = imm_sub_p( value, cf.value );
663        else  if ( what == GFMARK )
664            value = imm_sub_gf( value, cf.value );
665        else  if ( what )
666            value = imm_sub( value, cf.value );
667        else {
668            InternalCF * dummy = cf.value->copyObject();
669            value = dummy->subcoeff( value, true );
670        }
671    }
672    else  if ( is_imm( cf.value ) )
673        value = value->subcoeff( cf.value, false );
674    else  if ( value->level() == cf.value->level() ) {
675        if ( value->levelcoeff() == cf.value->levelcoeff() )
676            value = value->subsame( cf.value );
677        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
678            value = value->subcoeff( cf.value, false );
679        else {
680            InternalCF * dummy = cf.value->copyObject();
681            dummy = dummy->subcoeff( value, true );
682            if ( value->deleteObject() ) delete value;
683            value = dummy;
684        }
685    }
686    else  if ( level() > cf.level() )
687        value = value->subcoeff( cf.value, false );
688    else {
689        InternalCF * dummy = cf.value->copyObject();
690        dummy = dummy->subcoeff( value, true );
691        if ( value->deleteObject() ) delete value;
692        value = dummy;
693    }
694    return *this;
695}
696
697CanonicalForm &
698CanonicalForm::operator *= ( const CanonicalForm & cf )
699{
700    int what = is_imm( value );
701    if ( what ) {
702        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
703        if ( (what = is_imm( cf.value )) == FFMARK )
704            value = imm_mul_p( value, cf.value );
705        else  if ( what == GFMARK )
706            value = imm_mul_gf( value, cf.value );
707        else  if ( what )
708            value = imm_mul( value, cf.value );
709        else {
710            InternalCF * dummy = cf.value->copyObject();
711            value = dummy->mulcoeff( value );
712        }
713    }
714    else  if ( is_imm( cf.value ) )
715        value = value->mulcoeff( cf.value );
716    else  if ( value->level() == cf.value->level() ) {
717        if ( value->levelcoeff() == cf.value->levelcoeff() )
718            value = value->mulsame( cf.value );
719        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
720            value = value->mulcoeff( cf.value );
721        else {
722            InternalCF * dummy = cf.value->copyObject();
723            dummy = dummy->mulcoeff( value );
724            if ( value->deleteObject() ) delete value;
725            value = dummy;
726        }
727    }
728    else  if ( level() > cf.level() )
729        value = value->mulcoeff( cf.value );
730    else {
731        InternalCF * dummy = cf.value->copyObject();
732        dummy = dummy->mulcoeff( value );
733        if ( value->deleteObject() ) delete value;
734        value = dummy;
735    }
736    return *this;
737}
738
739CanonicalForm &
740CanonicalForm::operator /= ( const CanonicalForm & cf )
741{
742    int what = is_imm( value );
743    if ( what ) {
744        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
745        if ( (what = is_imm( cf.value )) == FFMARK )
746            value = imm_div_p( value, cf.value );
747        else  if ( what == GFMARK )
748            value = imm_div_gf( value, cf.value );
749        else  if ( what )
750            value = imm_divrat( value, cf.value );
751        else {
752            InternalCF * dummy = cf.value->copyObject();
753            value = dummy->dividecoeff( value, true );
754        }
755    }
756    else  if ( is_imm( cf.value ) )
757        value = value->dividecoeff( cf.value, false );
758    else  if ( value->level() == cf.value->level() ) {
759        if ( value->levelcoeff() == cf.value->levelcoeff() )
760            value = value->dividesame( cf.value );
761        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
762            value = value->dividecoeff( cf.value, false );
763        else {
764            InternalCF * dummy = cf.value->copyObject();
765            dummy = dummy->dividecoeff( value, true );
766            if ( value->deleteObject() ) delete value;
767            value = dummy;
768        }
769    }
770    else  if ( level() > cf.level() )
771        value = value->dividecoeff( cf.value, false );
772    else {
773        InternalCF * dummy = cf.value->copyObject();
774        dummy = dummy->dividecoeff( value, true );
775        if ( value->deleteObject() ) delete value;
776        value = dummy;
777    }
778    return *this;
779}
780
781CanonicalForm &
782CanonicalForm::div ( const CanonicalForm & cf )
783{
784    int what = is_imm( value );
785    if ( what ) {
786        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
787        if ( (what = is_imm( cf.value )) == FFMARK )
788            value = imm_div_p( value, cf.value );
789        else  if ( what == GFMARK )
790            value = imm_div_gf( value, cf.value );
791        else  if ( what )
792            value = imm_div( value, cf.value );
793        else {
794            InternalCF * dummy = cf.value->copyObject();
795            value = dummy->divcoeff( value, true );
796        }
797    }
798    else  if ( is_imm( cf.value ) )
799        value = value->divcoeff( cf.value, false );
800    else  if ( value->level() == cf.value->level() ) {
801        if ( value->levelcoeff() == cf.value->levelcoeff() )
802            value = value->divsame( cf.value );
803        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
804            value = value->divcoeff( cf.value, false );
805        else {
806            InternalCF * dummy = cf.value->copyObject();
807            dummy = dummy->divcoeff( value, true );
808            if ( value->deleteObject() ) delete value;
809            value = dummy;
810        }
811    }
812    else  if ( level() > cf.level() )
813        value = value->divcoeff( cf.value, false );
814    else {
815        InternalCF * dummy = cf.value->copyObject();
816        dummy = dummy->divcoeff( value, true );
817        if ( value->deleteObject() ) delete value;
818        value = dummy;
819    }
820    return *this;
821}
822
823CanonicalForm &
824CanonicalForm::operator %= ( const CanonicalForm & cf )
825{
826    int what = is_imm( value );
827    if ( what ) {
828        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
829        if ( (what = is_imm( cf.value )) == FFMARK )
830            value = imm_mod_p( value, cf.value );
831        else  if ( what == GFMARK )
832            value = imm_mod_gf( value, cf.value );
833        else  if ( what )
834            value = imm_mod( value, cf.value );
835        else {
836            InternalCF * dummy = cf.value->copyObject();
837            value = dummy->modulocoeff( value, true );
838        }
839    }
840    else  if ( is_imm( cf.value ) )
841        value = value->modulocoeff( cf.value, false );
842    else  if ( value->level() == cf.value->level() ) {
843        if ( value->levelcoeff() == cf.value->levelcoeff() )
844            value = value->modulosame( cf.value );
845        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
846            value = value->modulocoeff( cf.value, false );
847        else {
848            InternalCF * dummy = cf.value->copyObject();
849            dummy = dummy->modulocoeff( value, true );
850            if ( value->deleteObject() ) delete value;
851            value = dummy;
852        }
853    }
854    else  if ( level() > cf.level() )
855        value = value->modulocoeff( cf.value, false );
856    else {
857        InternalCF * dummy = cf.value->copyObject();
858        dummy = dummy->modulocoeff( value, true );
859        if ( value->deleteObject() ) delete value;
860        value = dummy;
861    }
862    return *this;
863}
864
865CanonicalForm &
866CanonicalForm::mod ( const CanonicalForm & cf )
867{
868    int what = is_imm( value );
869    if ( what ) {
870        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
871        if ( (what = is_imm( cf.value )) == FFMARK )
872            value = imm_mod_p( value, cf.value );
873        else  if ( what == GFMARK )
874            value = imm_mod_gf( value, cf.value );
875        else  if ( what )
876            value = imm_mod( value, cf.value );
877        else {
878            InternalCF * dummy = cf.value->copyObject();
879            value = dummy->modcoeff( value, true );
880        }
881    }
882    else  if ( is_imm( cf.value ) )
883        value = value->modcoeff( cf.value, false );
884    else  if ( value->level() == cf.value->level() ) {
885        if ( value->levelcoeff() == cf.value->levelcoeff() )
886            value = value->modsame( cf.value );
887        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
888            value = value->modcoeff( cf.value, false );
889        else {
890            InternalCF * dummy = cf.value->copyObject();
891            dummy = dummy->modcoeff( value, true );
892            if ( value->deleteObject() ) delete value;
893            value = dummy;
894        }
895    }
896    else  if ( level() > cf.level() )
897        value = value->modcoeff( cf.value, false );
898    else {
899        InternalCF * dummy = cf.value->copyObject();
900        dummy = dummy->modcoeff( value, true );
901        if ( value->deleteObject() ) delete value;
902        value = dummy;
903    }
904    return *this;
905}
906
907void
908divrem ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
909{
910    InternalCF * qq = 0, * rr = 0;
911    int what = is_imm( f.value );
912    if ( what )
913        if ( is_imm( g.value ) ) {
914            if ( what == FFMARK )
915                imm_divrem_p( f.value, g.value, qq, rr );
916            else  if ( what == GFMARK )
917                imm_divrem_gf( f.value, g.value, qq, rr );
918            else
919                imm_divrem( f.value, g.value, qq, rr );
920        }
921        else
922            g.value->divremcoeff( f.value, qq, rr, true );
923    else  if ( (what=is_imm( g.value )) )
924        f.value->divremcoeff( g.value, qq, rr, false );
925    else  if ( f.value->level() == g.value->level() )
926        if ( f.value->levelcoeff() == g.value->levelcoeff() )
927            f.value->divremsame( g.value, qq, rr );
928        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
929            f.value->divremcoeff( g.value, qq, rr, false );
930        else
931            g.value->divremcoeff( f.value, qq, rr, true );
932    else  if ( f.value->level() > g.value->level() )
933        f.value->divremcoeff( g.value, qq, rr, false );
934    else
935        g.value->divremcoeff( f.value, qq, rr, true );
936    ASSERT( qq != 0 && rr != 0, "error in divrem" );
937    q = CanonicalForm( qq );
938    r = CanonicalForm( rr );
939}
940
941bool
942divremt ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
943{
944    InternalCF * qq = 0, * rr = 0;
945    int what = is_imm( f.value );
946    bool result = true;
947    if ( what )
948        if ( is_imm( g.value ) ) {
949            if ( what == FFMARK )
950                imm_divrem_p( f.value, g.value, qq, rr );
951            else  if ( what == GFMARK )
952                imm_divrem_gf( f.value, g.value, qq, rr );
953            else
954                imm_divrem( f.value, g.value, qq, rr );
955        }
956        else
957            result = g.value->divremcoefft( f.value, qq, rr, true );
958    else  if ( (what=is_imm( g.value )) )
959        result = f.value->divremcoefft( g.value, qq, rr, false );
960    else  if ( f.value->level() == g.value->level() )
961        if ( f.value->levelcoeff() == g.value->levelcoeff() )
962            result = f.value->divremsamet( g.value, qq, rr );
963        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
964            result = f.value->divremcoefft( g.value, qq, rr, false );
965        else
966            result = g.value->divremcoefft( f.value, qq, rr, true );
967    else  if ( f.value->level() > g.value->level() )
968        result = f.value->divremcoefft( g.value, qq, rr, false );
969    else
970        result = g.value->divremcoefft( f.value, qq, rr, true );
971    if ( result ) {
972        ASSERT( qq != 0 && rr != 0, "error in divrem" );
973        q = CanonicalForm( qq );
974        r = CanonicalForm( rr );
975    }
976    else {
977        q = 0; r = 0;
978    }
979    return result;
980}
981//}}}
982
983//{{{ CanonicalForm CanonicalForm::operator () ( f ), operator () ( f, v ) const
984//{{{ docu
985//
986// operator ()() - evaluation operator.
987//
988// Both operators return CO if CO is in a base domain.
989//
990// operator () ( f ) returns CO with f inserted for the main
991// variable.  Elements in an algebraic extension are considered
992// polynomials.
993//
994// operator () ( f, v ) returns CO with f inserted for v.
995// Elements in an algebraic extension are considered polynomials
996// and v may be an algebraic variable.
997//
998//}}}
999CanonicalForm
1000CanonicalForm::operator () ( const CanonicalForm & f ) const
1001{
1002    if ( is_imm( value ) || value->inBaseDomain() )
1003        return *this;
1004    else {
1005        CFIterator i = *this;
1006        int lastExp = i.exp();
1007        CanonicalForm result = i.coeff();
1008        i++;
1009        while ( i.hasTerms() ) {
1010            if ( (lastExp - i.exp()) == 1 )
1011                result *= f;
1012            else
1013                result *= power( f, lastExp - i.exp() );
1014            result += i.coeff();
1015            lastExp = i.exp();
1016            i++;
1017        }
1018        if ( lastExp != 0 )
1019            result *= power( f, lastExp );
1020        return result;
1021    }
1022}
1023
1024CanonicalForm
1025CanonicalForm::operator () ( const CanonicalForm & f, const Variable & v ) const
1026{
1027    if ( is_imm( value ) || value->inBaseDomain() )
1028        return *this;
1029
1030    Variable x = value->variable();
1031    if ( v > x )
1032        return *this;
1033    else  if ( v == x )
1034        return (*this)( f );
1035    else {
1036        // v is less than main variable of f
1037        CanonicalForm result = 0;
1038        for ( CFIterator i = *this; i.hasTerms(); i++ )
1039            result += i.coeff()( f, v ) * power( x, i.exp() );
1040        return result;
1041    }
1042}
1043//}}}
1044
1045//{{{ CanonicalForm CanonicalForm::operator [] ( int i ) const
1046//{{{ docu
1047//
1048// operator []() - return i'th coefficient from CO.
1049//
1050// Returns CO if CO is in a base domain and i equals zero.
1051// Returns zero (from the current domain) if CO is in a base
1052// domain and i is larger than zero.  Otherwise, returns the
1053// coefficient to x^i in CO (if x denotes the main variable of
1054// CO) or zero if CO does not contain x^i.  Elements in an
1055// algebraic extension are considered polynomials.  i should be
1056// larger or equal zero.
1057//
1058// Note: Never use a loop like
1059//
1060// for ( int i = degree( f ); i >= 0; i-- )
1061//     foo( i, f[ i ] );
1062//
1063// This is much slower than
1064//
1065// for ( int i = degree( f ), CFIterator I = f; I.hasTerms(); I++ ) {
1066//     // fill gap with zeroes
1067//     for ( ; i > I.exp(); i-- )
1068//         foo( i, 0 );
1069//     // at this point, i == I.exp()
1070//     foo( i, i.coeff() );
1071//     i--;
1072// }
1073// // work through trailing zeroes
1074// for ( ; i >= 0; i-- )
1075//     foo( i, 0 );
1076//
1077//}}}
1078CanonicalForm
1079CanonicalForm::operator [] ( int i ) const
1080{
1081    ASSERT( i >= 0, "index to operator [] less than zero" );
1082    if ( is_imm( value ) )
1083        if ( i == 0 )
1084            return *this;
1085        else
1086            return CanonicalForm( 0 );
1087    else
1088        return value->coeff( i );
1089}
1090//}}}
1091
1092//{{{ CanonicalForm CanonicalForm::deriv (), deriv ( x )
1093//{{{ docu
1094//
1095// deriv() - return the formal derivation of CO.
1096//
1097// deriv() derives CO with respect to its main variable.  Returns
1098// zero if f is in a coefficient domain.
1099//
1100// deriv( x ) derives CO with respect to x.  x should be a
1101// polynomial variable.  Returns zero if f is in a coefficient
1102// domain.
1103//
1104// See also: ::deriv()
1105//
1106//}}}
1107CanonicalForm
1108CanonicalForm::deriv () const
1109{
1110    if ( is_imm( value ) || value->inCoeffDomain() )
1111        return CanonicalForm( 0 );
1112    else {
1113        CanonicalForm result = 0;
1114        Variable x = value->variable();
1115        for ( CFIterator i = *this; i.hasTerms(); i++ )
1116            if ( i.exp() > 0 )
1117                result += power( x, i.exp()-1 ) * i.coeff() * i.exp();
1118        return result;
1119    }
1120}
1121
1122CanonicalForm
1123CanonicalForm::deriv ( const Variable & x ) const
1124{
1125    ASSERT( x.level() > 0, "cannot derive with respect to algebraic variables" );
1126    if ( is_imm( value ) || value->inCoeffDomain() )
1127        return CanonicalForm( 0 );
1128
1129    Variable y = value->variable();
1130    if ( x > y )
1131        return CanonicalForm( 0 );
1132    else if ( x == y )
1133        return deriv();
1134    else {
1135        CanonicalForm result = 0;
1136        for ( CFIterator i = *this; i.hasTerms(); i++ )
1137            result += i.coeff().deriv( x ) * power( y, i.exp() );
1138        return result;
1139    }
1140}
1141//}}}
1142
1143//{{{ int CanonicalForm::sign () const
1144//{{{ docu
1145//
1146// sign() - return sign of CO.
1147//
1148// If CO is an integer or a rational number, the sign is defined
1149// as usual.  If CO is an element of a prime power domain or in a
1150// finite field and SW_SYMMETRIC_FF is on the sign of CO is the
1151// sign of the symmetric representation of CO.  If CO is in GF(q)
1152// or in a finite field and SW_SYMMETRIC_FF is off, the sign of
1153// CO is zero iff CO is zero, otherwise the sign is one.
1154//
1155// If CO is a polynomial or in an extension of one of the base
1156// domains, the sign of CO is the sign of its leading
1157// coefficient.
1158//
1159// See also: InternalCF::sign(), InternalInteger::sign(),
1160// InternalPrimePower::sign(), InternalRational::sign(),
1161// InternalPoly::sign(), imm_sign(), gf_sign()
1162//
1163//}}}
1164int
1165CanonicalForm::sign () const
1166{
1167    if ( is_imm( value ) )
1168        return imm_sign( value );
1169    else
1170        return value->sign();
1171}
1172//}}}
1173
1174//{{{ CanonicalForm CanonicalForm::sqrt () const
1175//{{{ docu
1176//
1177// sqrt() - calculate integer square root.
1178//
1179// CO has to be an integer greater or equal zero.  Returns the
1180// largest integer less or equal sqrt(CO).
1181//
1182// In the immediate case, we use the newton method to find the
1183// root.  The algorithm is from H. Cohen - 'A Course in
1184// Computational Algebraic Number Theory', ch. 1.7.1.
1185//
1186// See also: InternalCF::sqrt(), InternalInteger::sqrt(), ::sqrt()
1187//
1188//}}}
1189CanonicalForm
1190CanonicalForm::sqrt () const
1191{
1192    if ( is_imm( value ) ) {
1193        ASSERT( is_imm( value ) == INTMARK, "sqrt() not implemented" );
1194        int n = imm2int( value );
1195        ASSERT( n >= 0, "arg to sqrt() less than zero" );
1196        if ( n == 0 || n == 1 )
1197            return CanonicalForm( n );
1198        else {
1199            int x, y = n;
1200            do {
1201                x = y;
1202                // the intermediate result may not fit into an
1203                // integer, but the result does
1204                y = (unsigned int)(x + n/x)/2;
1205            } while ( y < x );
1206            return CanonicalForm( x );
1207        }
1208    }
1209    else
1210        return CanonicalForm( value->sqrt() );
1211}
1212//}}}
1213
1214//{{{ int CanonicalForm::ilog2 () const
1215//{{{ docu
1216//
1217// ilog2() - integer logarithm to base 2.
1218//
1219// Returns the largest integer less or equal logarithm of CO to
1220// base 2.  CO should be a positive integer.
1221//
1222// See also: InternalCF::ilog2(), InternalInteger::ilog2(), ::ilog2()
1223//
1224//}}}
1225int
1226CanonicalForm::ilog2 () const
1227{
1228    if ( is_imm( value ) ) {
1229        ASSERT( is_imm( value ) == INTMARK, "ilog2() not implemented" );
1230        int a = imm2int( value );
1231        ASSERT( a > 0, "arg to ilog2() less or equal zero" );
1232        int n = -1;
1233        while ( a != 0 ) {
1234            n++;
1235            a /= 2;
1236        }
1237        return n;
1238    }
1239    else
1240        return value->ilog2();
1241}
1242//}}}
1243
1244//{{{ CanonicalForm CanonicalForm::gcd( const CanonicalForm & ) const
1245CanonicalForm
1246CanonicalForm::gcd( const CanonicalForm & ) const
1247{
1248//    return ::gcd( *this, f );
1249    return 1;
1250}
1251//}}}
1252
1253//{{{ comparison operators
1254bool
1255operator == ( const CanonicalForm & lhs, const CanonicalForm & rhs )
1256{
1257    int what = is_imm( lhs.value );
1258    if ( what )
1259        if ( what == is_imm( rhs.value ) )
1260            return lhs.value == rhs.value;
1261        else
1262            return false;
1263    else  if ( is_imm( rhs.value ) )
1264        return false;
1265    else  if ( lhs.level() == rhs.level() )
1266        if ( lhs.value->levelcoeff() >= rhs.value->levelcoeff() )
1267            return lhs.value->comparesame( rhs.value ) == 0;
1268        else
1269            return rhs.value->comparesame( lhs.value ) == 0;
1270    else
1271        return false;
1272}
1273
1274bool
1275operator != ( const CanonicalForm & lhs, const CanonicalForm & rhs )
1276{
1277    int what = is_imm( lhs.value );
1278    if ( what )
1279        if ( what == is_imm( rhs.value ) )
1280            return lhs.value != rhs.value;
1281        else
1282            return true;
1283    else  if ( is_imm( rhs.value ) )
1284        return true;
1285    else  if ( lhs.level() == rhs.level() )
1286        if ( lhs.value->levelcoeff() >= rhs.value->levelcoeff() )
1287            return lhs.value->comparesame( rhs.value ) != 0;
1288        else
1289            return rhs.value->comparesame( lhs.value ) != 0;
1290    else
1291        return true;
1292}
1293
1294bool
1295operator > ( const CanonicalForm & lhs, const CanonicalForm & rhs )
1296{
1297    int what = is_imm( lhs.value );
1298    if ( what ) {
1299        ASSERT ( ! is_imm( rhs.value ) || (what==is_imm( rhs.value )), "illegal base coefficients" );
1300        if ( what == INTMARK ) {
1301            if ( what == is_imm( rhs.value ) )
1302                return imm_cmp( lhs.value, rhs.value ) > 0;
1303            else
1304                return rhs.value->comparecoeff( lhs.value ) < 0;
1305        }
1306        else  if ( what == FFMARK ) {
1307            if ( what == is_imm( rhs.value ) )
1308                return imm_cmp_p( lhs.value, rhs.value ) > 0;
1309            else
1310                return rhs.value->comparecoeff( lhs.value ) < 0;
1311        }
1312        else {
1313            if ( what == is_imm( rhs.value ) )
1314                return imm_cmp_gf( lhs.value, rhs.value ) > 0;
1315            else
1316                return rhs.value->comparecoeff( lhs.value ) < 0;
1317        }
1318    }
1319    else  if ( is_imm( rhs.value ) )
1320        return lhs.value->comparecoeff( rhs.value ) > 0;
1321    else  if ( lhs.level() == rhs.level() )
1322        if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
1323            return lhs.value->comparesame( rhs.value ) > 0;
1324        else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
1325            return lhs.value->comparecoeff( lhs.value ) > 0;
1326        else
1327            return rhs.value->comparecoeff( lhs.value ) < 0;
1328    else
1329        return lhs.value->level() > rhs.value->level();
1330}
1331
1332bool
1333operator < ( const CanonicalForm & lhs, const CanonicalForm & rhs )
1334{
1335    int what = is_imm( lhs.value );
1336    if ( what ) {
1337        ASSERT ( ! is_imm( rhs.value ) || (what==is_imm( rhs.value )), "illegal base coefficients" );
1338        if ( what == INTMARK ) {
1339            if ( what == is_imm( rhs.value ) )
1340                return imm_cmp( lhs.value, rhs.value ) < 0;
1341            else
1342                return rhs.value->comparecoeff( lhs.value ) > 0;
1343        }
1344        else  if ( what == FFMARK ) {
1345            if ( what == is_imm( rhs.value ) )
1346                return imm_cmp( lhs.value, rhs.value ) < 0;
1347            else
1348                return rhs.value->comparecoeff( lhs.value ) > 0;
1349        }
1350        else {
1351            if ( what == is_imm( rhs.value ) )
1352                return imm_cmp( lhs.value, rhs.value ) < 0;
1353            else
1354                return rhs.value->comparecoeff( lhs.value ) > 0;
1355        }
1356    }
1357    else  if ( is_imm( rhs.value ) )
1358        return lhs.value->comparecoeff( rhs.value ) < 0;
1359    else  if ( lhs.level() == rhs.level() )
1360        if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
1361            return lhs.value->comparesame( rhs.value ) < 0;
1362        else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
1363            return lhs.value->comparecoeff( lhs.value ) < 0;
1364        else
1365            return rhs.value->comparecoeff( lhs.value ) > 0;
1366    else
1367        return lhs.value->level() < rhs.value->level();
1368}
1369//}}}
1370
1371//{{{ arithmetic operators
1372CanonicalForm
1373operator - ( const CanonicalForm & cf )
1374{
1375    CanonicalForm result( cf );
1376    int what = is_imm( result.value );
1377    if ( what == FFMARK )
1378        result.value = imm_neg_p( result.value );
1379    else  if ( what == GFMARK )
1380        result.value = imm_neg_gf( result.value );
1381    else  if ( what )
1382        result.value = imm_neg( result.value );
1383    else
1384        result.value = result.value->neg();
1385    return result;
1386}
1387
1388CanonicalForm
1389operator + ( const CanonicalForm &c1, const CanonicalForm &c2 )
1390{
1391    CanonicalForm result( c1 );
1392    result += c2;
1393    return result;
1394}
1395
1396CanonicalForm
1397operator - ( const CanonicalForm &c1, const CanonicalForm &c2 )
1398{
1399    CanonicalForm result( c1 );
1400    result -= c2;
1401    return result;
1402}
1403
1404CanonicalForm
1405operator * ( const CanonicalForm &c1, const CanonicalForm &c2 )
1406{
1407    CanonicalForm result( c1 );
1408    result *= c2;
1409    return result;
1410}
1411
1412CanonicalForm
1413operator / ( const CanonicalForm &c1, const CanonicalForm &c2 )
1414{
1415    CanonicalForm result( c1 );
1416    result /= c2;
1417    return result;
1418}
1419
1420CanonicalForm
1421div ( const CanonicalForm &c1, const CanonicalForm &c2 )
1422{
1423    CanonicalForm result( c1 );
1424    result.div( c2 );
1425    return result;
1426}
1427
1428CanonicalForm
1429mod ( const CanonicalForm &c1, const CanonicalForm &c2 )
1430{
1431    CanonicalForm result( c1 );
1432    result.mod( c2 );
1433    return result;
1434}
1435
1436CanonicalForm
1437operator % ( const CanonicalForm &c1, const CanonicalForm &c2 )
1438{
1439    CanonicalForm result( c1 );
1440    result %= c2;
1441    return result;
1442}
1443//}}}
1444
1445//{{{ input/output
1446#ifndef NOSTREAMIO
1447void
1448CanonicalForm::print( ostream & os, char * str ) const
1449{
1450    if ( is_imm( value ) )
1451        imm_print( os, value, str );
1452    else
1453        value->print( os, str );
1454}
1455
1456ostream&
1457operator << ( ostream & os, const CanonicalForm & cf )
1458{
1459    cf.print( os, "" );
1460    return os;
1461}
1462
1463istream&
1464operator >> ( istream & is, CanonicalForm & cf )
1465{
1466#ifndef SINGULAR
1467    cf = readCF( is );
1468    return is;
1469#else /* SINGULAR */
1470    return 0;
1471#endif /* SINGULAR */
1472}
1473#endif /* NOSTREAMIO */
1474//}}}
1475
1476//{{{ genCoeff(), genOne(), genZero()
1477CanonicalForm
1478CanonicalForm::genCoeff( int type, int i )
1479{
1480    return CanonicalForm( CFFactory::basic( type, i ) );
1481}
1482
1483CanonicalForm
1484CanonicalForm::genZero() const
1485{
1486    int what = is_imm( value );
1487    if ( what == FFMARK )
1488        return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 0 ) );
1489    else  if ( what == GFMARK )
1490        return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 0 ) );
1491    else  if ( what )
1492        return CanonicalForm( CFFactory::basic( IntegerDomain, 0 ) );
1493    else
1494        return CanonicalForm( value->genZero() );
1495}
1496
1497CanonicalForm
1498CanonicalForm::genOne() const
1499{
1500    int what = is_imm( value );
1501    if ( what == FFMARK )
1502        return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 1 ) );
1503    else  if ( what == GFMARK )
1504        return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 1 ) );
1505    else  if ( what )
1506        return CanonicalForm( CFFactory::basic( IntegerDomain, 1 ) );
1507    else
1508        return CanonicalForm( value->genOne() );
1509}
1510//}}}
1511
1512//{{{ exponentiation
1513CanonicalForm
1514power ( const CanonicalForm & f, int n )
1515{
1516    ASSERT( n >= 0, "illegal exponent" );
1517    if ( f == 0 )
1518        return 0;
1519    else  if ( f == 1 )
1520        return f;
1521    else  if ( f == -1 ) {
1522        if ( n % 2 == 0 )
1523            return 1;
1524        else
1525            return -1;
1526    }
1527    else  if ( n == 0 )
1528        return 1;
1529    else {
1530        CanonicalForm result = f;
1531        for ( int i = 1; i < n; i++ )
1532            result *= f;
1533        return result;
1534    }
1535}
1536
1537CanonicalForm
1538power ( const Variable & v, int n )
1539{
1540    ASSERT( n >= 0, "illegal exponent" );
1541    if ( n == 0 )
1542        return 1;
1543    else  if ( n == 1 )
1544        return v;
1545    else  if ( v.level() < 0 ) {
1546        CanonicalForm result( v, n-1 );
1547        return result * v;
1548    }
1549    else
1550        return CanonicalForm( v, n );
1551}
1552//}}}
1553
1554//{{{ switches
1555void
1556On( int sw )
1557{
1558    cf_glob_switches.On( sw );
1559}
1560
1561void
1562Off( int sw )
1563{
1564    cf_glob_switches.Off( sw );
1565}
1566
1567bool
1568isOn( int sw )
1569{
1570    return cf_glob_switches.isOn( sw );
1571}
1572//}}}
Note: See TracBrowser for help on using the repository browser.