/* emacs edit mode for this file is -*- C++ -*- */ #include "config.h" #include "cf_assert.h" #include "cf_defs.h" #include "cf_generator.h" #include "imm.h" #include "gfops.h" #include "ffops.h" bool IntGenerator::hasItems() const { return 1; } CanonicalForm IntGenerator::item() const { return mapinto (CanonicalForm (current)); } void IntGenerator::next() { current++; } CFGenerator * IntGenerator::clone () const { return new IntGenerator(); } bool FFGenerator::hasItems() const { return current < ff_prime; } CanonicalForm FFGenerator::item() const { ASSERT( current < ff_prime, "no more items" ); return CanonicalForm( int2imm_p( current ) ); } void FFGenerator::next() { ASSERT( current < ff_prime, "no more items" ); current++; } CFGenerator * FFGenerator::clone () const { return new FFGenerator(); } GFGenerator::GFGenerator() { current = gf_zero(); } bool GFGenerator::hasItems() const { return ( current != gf_q + 1 ); } void GFGenerator::reset() { current = gf_zero(); } CanonicalForm GFGenerator::item() const { ASSERT( current != gf_q + 1, "no more items" ); return CanonicalForm( int2imm_gf( current ) ); } void GFGenerator::next() { ASSERT( current != gf_q + 1, "no more items" ); if ( gf_iszero( current ) ) current = 0; else if ( current == gf_q1 - 1 ) current = gf_q + 1; else current++; } CFGenerator * GFGenerator::clone () const { return new GFGenerator(); } AlgExtGenerator::AlgExtGenerator() { ASSERT( 0, "not a valid generator" ); } AlgExtGenerator::AlgExtGenerator( const AlgExtGenerator & ) { ASSERT( 0, "not a valid generator" ); } AlgExtGenerator& AlgExtGenerator::operator= ( const AlgExtGenerator & ) { ASSERT( 0, "not a valid generator" ); return *this; } AlgExtGenerator::AlgExtGenerator( const Variable & a ) { ASSERT( a.level() < 0, "not an algebraic extension" ); ASSERT( getCharacteristic() > 0, "not a finite field" ); algext = a; n = degree( getMipo( a ) ); if ( getGFDegree() > 1 ) { gensg = new GFGenerator * [n]; for ( int i = 0; i < n; i++ ) gensg[i] = new GFGenerator(); } else { gensf = new FFGenerator * [n]; for ( int i = 0; i < n; i++ ) gensf[i] = new FFGenerator(); } nomoreitems = false; } AlgExtGenerator::~AlgExtGenerator() { if ( getGFDegree() > 1 ) { for ( int i = 0; i < n; i++ ) delete gensg[i]; delete [] gensg; } else { for ( int i = 0; i < n; i++ ) delete gensf[i]; delete [] gensf; } } void AlgExtGenerator::reset() { if ( getGFDegree() > 1 ) { for ( int i = 0; i < n; i++ ) gensg[i]->reset(); } else { for ( int i = 0; i < n; i++ ) gensf[i]->reset(); } nomoreitems = false; } CanonicalForm AlgExtGenerator::item() const { ASSERT( ! nomoreitems, "no more items" ); CanonicalForm result = 0; if ( getGFDegree() > 1 ) { for ( int i = 0; i < n; i++ ) result += power( algext, i ) * gensg[i]->item(); } else { for ( int i = 0; i < n; i++ ) result += power( algext, i ) * gensf[i]->item(); } return result; } void AlgExtGenerator::next() { ASSERT( ! nomoreitems, "no more items" ); int i = 0; bool stop = false; if ( getGFDegree() > 1 ) { while ( ! stop && i < n ) { gensg[i]->next(); if ( ! gensg[i]->hasItems() ) { gensg[i]->reset(); i++; } else stop = true; } } else { while ( ! stop && i < n ) { gensf[i]->next(); if ( ! gensf[i]->hasItems() ) { gensf[i]->reset(); i++; } else stop = true; } } if ( ! stop ) nomoreitems = true; } CFGenerator * AlgExtGenerator::clone () const { return new AlgExtGenerator(algext); } CFGenerator * CFGenFactory::generate() { if (getCharacteristic() == 0) return new IntGenerator(); else if ( getGFDegree() > 1 ) return new GFGenerator(); else return new FFGenerator(); }