00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef _StraightLineProgramWord_H_
00011 #define _StraightLineProgramWord_H_
00012
00013
00014 #include "map"
00015 #include "list"
00016 using namespace std;
00017
00018
00019 #include "gmpxx.h"
00020 typedef mpz_class LongInteger;
00021 #include "Map.h"
00022
00023
00024
00025
00026
00027
00028
00030
00052 class StraightLineProgramWord
00053 {
00054 private:
00055
00057
00062 struct Production {
00063
00064 Production( int t1=0, int t2=0 , LongInteger l=0 , int h=0 ) :
00065 theTerm1(t1),
00066 theTerm2(t2),
00067 theLength(l),
00068 theHeight(h),
00069 reduced(false)
00070 { }
00071
00072 int theTerm1;
00073 int theTerm2;
00074 LongInteger theLength;
00075 int theHeight;
00076 bool reduced;
00077 };
00078
00079
00081
00086 struct Assertion {
00087
00088 Assertion( bool b , int v1 , int v2 , LongInteger l ) : theBase1(b), theVertex1(v1), theVertex2(v2), theLength(l) { }
00089
00090 bool operator < ( const Assertion& A ) const {
00091 if( theBase1<A.theBase1)
00092 return true;
00093 if( theBase1>A.theBase1)
00094 return false;
00095 if( theVertex1<A.theVertex1 )
00096 return true;
00097 if( theVertex1>A.theVertex1 )
00098 return false;
00099 if( theVertex2<A.theVertex2 )
00100 return true;
00101 if( theVertex2>A.theVertex2 )
00102 return false;
00103 if( theLength<A.theLength )
00104 return true;
00105 return false;
00106 }
00107
00108 bool similar( const Assertion& A ) const {
00109 return (theBase1==A.theBase1 && theVertex1==A.theVertex1 && theVertex2==A.theVertex2);
00110 }
00111
00112 friend ostream& operator << ( ostream& os , const Assertion& A ) {
00113 os << "(" << A.theBase1 << "," << A.theVertex1 << "," << A.theVertex2 << "," << A.theLength << ")";
00114 return os;
00115 }
00116
00118 bool theBase1;
00119
00121 int theVertex1;
00122
00124 int theVertex2;
00125
00127 LongInteger theLength;
00128 };
00129
00130
00132
00133
00134
00136
00137 public:
00138
00140 StraightLineProgramWord( ) : theRoot(0) , theTerminals(0) { }
00141
00142
00144 StraightLineProgramWord( int init , int gens );
00145
00146
00148
00153 template< class ConstMapIterator >
00154 StraightLineProgramWord( int init , ConstMapIterator B , ConstMapIterator E ) {
00155 int ai = abs( init );
00156 theRules[ai+1] = Production( init , 0 , 1 , 1 );
00157 theRoot = ai+1;
00158 theTerminals = ai;
00159 for( ; B!=E ; ++B )
00160 *this = applyMapping( *B );
00161 }
00162
00163
00165
00166
00167
00169
00170 public:
00171
00173 StraightLineProgramWord& operator= ( const StraightLineProgramWord& SLP ) {
00174 theRoot = SLP.theRoot;
00175 theRules = SLP.theRules;
00176 theTerminals = SLP.theTerminals;
00177 }
00178
00179
00181 int operator[] ( LongInteger i ) const {
00182 return getGenerator( theRoot , i );
00183 }
00184
00185
00187 StraightLineProgramWord operator- ( ) const;
00188
00189
00191 StraightLineProgramWord operator * ( const StraightLineProgramWord& SLP ) const;
00192
00193
00195
00196
00197
00199
00200 public:
00201
00203 bool equal( int n1 , const StraightLineProgramWord& SLP , int n2 ) const;
00204
00205
00207 int terminalSegment( int n , LongInteger length ) {
00208 return truncateVertexLeft( n , length_rule(n)-length );
00209 }
00210
00211
00213 int initialSegment( int n , LongInteger length ) {
00214 return truncateVertexRight( n , length_rule(n)-length );
00215 }
00216
00217
00219
00223 int truncateVertexLeft( int n , LongInteger length );
00224
00225
00227
00231 int truncateVertexRight( int n , LongInteger length );
00232
00233
00235 LongInteger leftGCDLength( const StraightLineProgramWord& CS ) const {
00236 return leftGCDLength( theRoot , CS , CS.theRoot );
00237 }
00238
00239
00241
00244 Word getWord( ) const { return getWord( theRoot ); }
00245
00246
00248
00252 Word getWord( int N ) const;
00253
00254
00256 LongInteger length( ) const { return length_rule( theRoot ); }
00257
00258
00260 void reduce( ) { if( theRoot!=0 ) reduce_rule( theRoot ); }
00261
00262
00264
00268 void simplify( );
00269
00270
00272
00273
00274
00276
00277 private:
00278
00280
00285 void order_vertices( int n , list< int >& order , set< int >& closure ) const;
00286 void order_vertices( int n , list< int >& order ) const {
00287 set< int > closure;
00288 order_vertices( n , order , closure );
00289 }
00290
00291
00293 LongInteger length_rule( int n ) const {
00294 if( n==0 )
00295 return 0;
00296 if( abs( n )<=theTerminals )
00297 return 1;
00298 return (*theRules.find(abs(n))).second.theLength;
00299 }
00300
00301
00303 int height_rule( int n ) const {
00304 if( n==0 )
00305 return 0;
00306 if( abs( n )<=theTerminals )
00307 return 0;
00308 return (*theRules.find(abs(n))).second.theHeight;
00309 }
00310
00311
00313 static void invertProductionPair( int& A , int& B );
00314
00315
00317
00322 bool assertionType( const Assertion& A , const StraightLineProgramWord& SLP ) const;
00323
00324
00326 void extendTerminals( int nt );
00327
00328
00330 void reduce_rule( int n );
00331
00332
00334 LongInteger leftGCDLength( int n1 , const StraightLineProgramWord& CS , int n2 ) const;
00335
00336
00337
00338 set< Assertion > splitAssertion( const Assertion& A , bool firstTerm , const StraightLineProgramWord& SLP ) const;
00339
00340
00342 void update_lengths( );
00344 void update_length( int n );
00345
00347 void update_heights( );
00349 void update_height( int n );
00350
00351
00353 int getGenerator( int n , LongInteger pos ) const;
00354
00355
00357 LongInteger cancellationLength( int n1 , int n2 ) const;
00358
00359
00361
00366 static pair< map< int , Production > , vector< int > > map_rules( const Map& M );
00367
00368
00370
00378 StraightLineProgramWord applyMapping( const Map& M ) const;
00379
00380
00382 int max_rule_number( ) const;
00383
00384
00386
00387
00388
00390
00391 public:
00392
00393 friend ostream& operator << ( ostream& os , const StraightLineProgramWord& CS );
00394
00396
00397
00398
00400
00401 private:
00402
00404
00407 int theRoot;
00408
00409
00411 int theTerminals;
00412
00413
00415 map< int , Production > theRules;
00416
00417 };
00418
00419
00420 #endif