00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00031 #include <iostream>
00032 #include <algorithm>
00033
00034 #ifdef DEBUG
00035 #include <cassert>
00036 #endif
00037
00038 #include "casfuncobj.h"
00039 #include "casexception.h"
00040 #include "product.h"
00041 #include "sum.h"
00042 #include "longint.h"
00043 #include "fraction.h"
00044 #include "casconvert.h"
00045
00053
00054
00055
00066 void
00067 Product::GetOperandsWithoutCoefficient ( std::vector<const CASObject*>& lst ) const {
00068 std::transform ( operands.begin(),
00069 operands.end(),
00070 std::back_inserter ( lst ),
00071 CASExtractNonCoefficients() );
00072
00073 std::vector<const CASObject*>::iterator last =
00074 std::remove ( lst.begin(), lst.end(), ( ( CASObject* ) 0 ) );
00075 lst.erase ( last, lst.end() );
00076
00077
00078 std::sort ( lst.begin(), lst.end(), CASSortObject() );
00079 }
00080
00081 const CASObject* Product::GetCoefficient() const {
00082 CASGetCoefficient coe;
00083 coe = std::for_each ( operands.begin(), operands.end(), coe );
00084 return coe.Result();
00085 }
00086
00102 CASObject*
00103 Product::CollectEqualOperands() const {
00104 Product *working_obj = dynamic_cast<Product*> ( Clone() );
00105 #ifdef DEBUG2
00106 std::cout << "Product::CollectEqualOperands()" << std::endl;
00107 Print();
00108 std::cout << std::endl;
00109 #endif
00110 bool exprmodified;
00111 do {
00112 exprmodified = false;
00113 resolve_parentheses<Product> ( working_obj );
00114 working_obj->Sort();
00115 #ifdef DEBUG
00116 assert ( working_obj != 0 );
00117 #endif
00118
00119 std::vector<CASObject*>::const_iterator op_it = working_obj->operands.begin();
00120 std::vector<CASObject*>::const_iterator op_begin = op_it;
00121 std::vector<CASObject*>::const_iterator op_it_next = op_it;
00122 std::vector<CASObject*>::const_iterator op_end = working_obj->operands.end();
00123
00124
00125 op_it_next++;
00126
00127
00128 std::vector<CASObject*> equal_objs;
00129
00130
00131
00132 std::vector<CASObject*> new_operands;
00133 while ( op_it != op_end && op_it_next != op_end ) {
00134 while ( op_it != op_end &&
00135 op_it_next != op_end &&
00136 ( *op_it )->IsEqual ( *op_it_next ) ) {
00137 equal_objs.push_back ( *op_it );
00138 equal_objs.push_back ( *op_it_next );
00139
00140 op_it++;
00141 op_it_next++;
00142 }
00143
00144
00145 if ( equal_objs.size() > 0 ) {
00146 exprmodified = true;
00147
00148
00149
00150
00151
00152 std::sort ( equal_objs.begin(), equal_objs.end(), CASGarbageSort_Cmp() );
00153
00154 std::vector<CASObject*>::iterator ip =
00155 std::unique ( equal_objs.begin(), equal_objs.end() );
00156
00157 equal_objs.erase ( ip, equal_objs.end() );
00158
00159 LongInt li_exponent ( equal_objs.size() );
00160 CASObject *res =
00161 ( equal_objs.front() )->Power ( &li_exponent );
00162
00163 new_operands.push_back ( res );
00164
00165
00166 std::vector<CASObject*>::const_iterator eqo_it = equal_objs.begin();
00167 while ( eqo_it != equal_objs.end() ) {
00168
00169
00170 CASObjectFindByAddr needle ( *eqo_it );
00171 std::vector<CASObject*>::iterator pos =
00172 std::find_if ( working_obj->operands.begin(),
00173 working_obj->operands.end(),
00174 needle );
00175 #ifdef DEBUG
00176 assert ( pos != op_end );
00177 assert ( *pos != 0 );
00178 #endif
00179
00180 *pos = 0;
00181 CASObject::Garbage->Put ( *eqo_it );
00182 eqo_it++;
00183 }
00184
00185 equal_objs.clear();
00186 } else {
00187 exprmodified = false;
00188 }
00189
00190 op_it++;
00191 op_it_next++;
00192 }
00193
00194 if ( new_operands.size() > 0 ) {
00195
00196
00197 std::vector<CASObject*>::iterator last =
00198 std::remove ( working_obj->operands.begin(),
00199 working_obj->operands.end(),
00200 ( ( CASObject* ) 0 ) )
00201 ;
00202 working_obj->operands.erase ( last, working_obj->operands.end() );
00203
00204 std::copy ( new_operands.begin(),
00205 new_operands.end(),
00206 std::back_inserter ( working_obj->operands ) );
00207
00208 new_operands.clear();
00209
00210 working_obj->meta.UnsetSorted();
00211 working_obj->Sort();
00212 }
00213 } while ( exprmodified );
00214
00215 return working_obj;
00216 }
00217
00230 CASObject*
00231 Product::CollectOther() const {
00232 #ifdef DEBUG2
00233 std::cout << "Product::CollectOther()" << std::endl;
00234 Print();
00235 std::cout << std::endl;
00236 #endif
00237 std::vector<CASObject*> newoperands;
00238 std::transform ( operands.begin(),
00239 operands.end(),
00240 back_inserter ( newoperands ),
00241 CASCloneObject() );
00242
00243 std::vector<CASObject*>::iterator it = newoperands.begin();
00244 std::vector<CASObject*>::iterator secondary_it;
00245
00246 while ( it != newoperands.end() ) {
00247 secondary_it = it;
00248 secondary_it++;
00249 while ( secondary_it != newoperands.end() ) {
00250 bool similar = ( *it )->IsSimilar ( ( *secondary_it ) );
00251 if ( similar ) {
00252 CASObject *tmp = *secondary_it;
00253 *secondary_it = ( *it )->Multiply ( ( *secondary_it ) );
00254 CASObject::Garbage->Put ( tmp );
00255 CASObject::Garbage->Put ( ( *it ) );
00256 *it = 0;
00257 break;
00258 }
00259
00260 secondary_it++;
00261 }
00262
00263 it++;
00264 }
00265
00266 it = std::remove ( newoperands.begin(),
00267 newoperands.end(),
00268 ( CASObject* ) 0 );
00269 newoperands.erase ( it, newoperands.end() );
00270 Product* result = new Product();
00271 #ifdef DEBUG
00272 assert ( result->exponent != 0 );
00273 #endif
00274 CASObject::Garbage->Put ( result->exponent );
00275 result->exponent = exponent->Clone();
00276 result->operands = newoperands;
00277 result->Sort();
00278
00279 return result;
00280
00281 }
00282
00295 void
00296 Product::ExplodeSumsIP() {
00297 std::vector<CASObject*>::iterator it = operands.begin();
00298 std::vector<CASObject*> exploded_sums;
00299
00300 while ( it != operands.end() ) {
00301 if ( ( *it )->GetType() == CT_SUM &&
00302 ( *it )->exponent->GetType() == CT_LONGINT &&
00303 ! ( *it )->exponent->IsOne() ) {
00304 Sum *sum = dynamic_cast<Sum*> ( *it );
00305 LongInt *li_exp = dynamic_cast<LongInt*> ( sum->exponent );
00306 #ifdef DEBUG
00307 assert ( li_exp != 0 );
00308 assert ( sum != 0 );
00309 #endif
00310 Sum *sum_exp_one = dynamic_cast<Sum*> ( sum->Clone() );
00311 #ifdef DEBUG
00312 assert ( sum_exp_one != 0 );
00313 #endif
00314 CASObject::Garbage->Put ( sum_exp_one->exponent );
00315 LongInt li ( 1L );
00316 sum_exp_one->exponent = li.Clone();
00317 for ( li = 0; li < * ( li_exp ); li++ ) {
00318 exploded_sums.push_back ( sum_exp_one->Clone() );
00319 }
00320 ( *it ) = 0;
00321
00322 CASObject::Garbage->Put ( sum );
00323 CASObject::Garbage->Put ( sum_exp_one );
00324 }
00325 it++;
00326 }
00327 std::vector<CASObject*>::iterator remove_it =
00328 std::remove ( operands.begin(),
00329 operands.end(),
00330 ( ( CASObject* ) 0 ) );
00331 operands.erase ( remove_it, operands.end() );
00332 std::copy ( exploded_sums.begin(),
00333 exploded_sums.end(),
00334 std::back_inserter ( operands )
00335 );
00336 return;
00337 }
00338
00357 void
00358 Product::GetSums ( const std::vector<const CASObject*> &in,
00359 std::vector<const CASObject*> &out ) {
00360 for ( unsigned long i = 0; i < in.size(); i++ ) {
00361 if ( in[i]->GetType() == CT_SUM )
00362 out.push_back ( in[i] );
00363 }
00364 }
00365
00384 void
00385 Product::GetNonSums ( const std::vector<const CASObject*> &in,
00386 std::vector<const CASObject*> &out ) {
00387 for ( unsigned long i = 0; i < in.size(); i++ ) {
00388 if ( in[i]->GetType() != CT_SUM )
00389 out.push_back ( in[i] );
00390 }
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00407 Product::Product() : CASTerm() {
00408 #ifdef SHOWCONSTRUCTOR
00409 std::cout << "# Product::Product()" << std::endl;
00410 #endif
00411 LongInt one ( 1L );
00412 exponent = one.Clone();
00413 }
00414
00419 Product::~Product() {
00420 #ifdef SHOWCONSTRUCTOR
00421 std::cout << "# Product::~Product()" << std::endl;
00422 #endif
00423 #ifdef DEBUG
00424 assert ( exponent != 0 );
00425 #endif
00426 delete exponent;
00427 }
00428
00434 Product::Product ( const Product &p ) {
00435 #ifdef SHOWCONSTRUCTOR
00436 std::cout << "# Product::Product(const Product &f)" << std::endl;
00437 #endif
00438
00439 std::transform ( p.operands.begin(),
00440 p.operands.end(),
00441 std::back_inserter ( operands ),
00442 CASCloneObject() );
00443 meta = p.meta;
00444 exponent = p.exponent->Clone();
00445 }
00446
00447
00448
00449
00450
00451
00460 CASObject*
00461 Product::Clone() const {
00462 Product *ret_val = new Product;
00463
00464 *ret_val = *this;
00465
00466 return ret_val;
00467 }
00468
00479 void
00480 Product::Get ( std::string &s ) const {
00481 s.erase();
00482 std::string tmp;
00483
00484 #ifdef DEBUG
00485 s = "[";
00486 #endif
00487
00488 if ( !exponent->IsOne() ) {
00489 #ifdef DEBUG
00490 s += "(";
00491 #else
00492 s = "(";
00493 #endif
00494 }
00495
00496 for ( unsigned long i = 0; i < operands.size(); i++ ) {
00497 #ifdef DEBUG
00498 assert ( operands[i] != 0 );
00499 #endif
00500 if ( i > 0 ) {
00501 s += "*";
00502 }
00503
00504 if ( operands[i]->GetType() == CT_SUM ) {
00505 s += "(";
00506 }
00507
00508 operands[i]->Get ( tmp );
00509
00510 s += tmp;
00511
00512 if ( operands[i]->GetType() == CT_SUM ) {
00513 s += ")";
00514 }
00515 }
00516
00517 if ( !exponent->IsOne() ) {
00518 s += ")^";
00519 exponent->Get ( tmp );
00520 if ( !exponent->meta.IsSingleValue() ) {
00521 s += "(" + tmp + ")";
00522 } else {
00523 s += tmp;
00524 }
00525 }
00526 #ifdef DEBUG
00527 s += "]";
00528 #endif
00529 }
00530
00545 void
00546 Product::Get ( char *s, unsigned long size ) const {
00547 checkptr ( s );
00548
00549 if ( size < ( Length() + 1 ) ) {
00550 throw EBufTooSmall();
00551 }
00552
00553 memset ( s, '\0', size );
00554
00555 std::string tmp;
00556 Get ( tmp );
00557
00558 strncpy ( s, tmp.c_str(), size );
00559 }
00560
00566 void
00567 Product::Print() const {
00568 std::string tmp;
00569 Get ( tmp );
00570 std::cout << tmp;
00571 }
00572
00579 unsigned long
00580 Product::Length() const {
00581 unsigned long len = 0;
00582
00583 for ( unsigned long i = 0; i < operands.size(); i++ ) {
00584 #ifdef DEBUG
00585 assert ( operands[i] != 0 );
00586 #endif
00587
00588 len += operands[i]->Length();
00589 }
00590
00591
00592 len += operands.size() - 1;
00593
00594 return len;
00595 }
00596
00603 bool
00604 Product::IsZero() const {
00605 if ( operands.size() == 0 )
00606 return true;
00607
00608 for ( unsigned long i = 0; i < operands.size(); i++ ) {
00609 #ifdef DEBUG
00610 assert ( operands[i] != 0 );
00611 #endif
00612
00613 if ( operands[i]->IsZero() ) {
00614 return true;
00615 }
00616 }
00617
00618 return false;
00619 }
00620
00627 bool
00628 Product::IsOne() const {
00629 for ( unsigned long i = 0; i < operands.size(); i++ ) {
00630 #ifdef DEBUG
00631 assert ( operands[i] != 0 );
00632 #endif
00633
00634 if ( !operands[i]->IsOne() ) {
00635 return false;
00636 }
00637 }
00638
00639 return true;
00640
00641 }
00642
00654 bool
00655 Product::IsSimilar ( const CASObject *o ) const {
00656 checkptr ( o );
00657 #ifdef DEBUG2
00658 std::cout << "Object to search for similarity: ";
00659 o->Print();
00660 std::cout << std::endl;
00661 #endif
00662
00663 if ( !o->meta.IsSingleValue() && ( GetType() != o->GetType() ) ) {
00664 return false;
00665 }
00666 if ( IsEqual ( o ) ) {
00667 return true;
00668 }
00669
00670 std::vector<const CASObject*> ops_without_coeff;
00671 GetOperandsWithoutCoefficient ( ops_without_coeff );
00672 #ifdef DEBUG
00673 assert ( ops_without_coeff.size() > 0 );
00674 #endif
00675
00676 CASConvert convert ( ops_without_coeff );
00677
00678 Product *tmp_prod;
00679 try {
00680 tmp_prod = convert.ToProduct();
00681 } catch ( EDoesNotApply &e ) {
00682 #ifdef DEBUG2
00683 std::cout << "Catched exception EDoesNotApply()";
00684 #endif
00685 return false;
00686 }
00687
00688 CASConvert convert_o ( o );
00689 Product* converted_o;
00690 try {
00691 converted_o = convert_o.ToProduct();
00692 } catch ( EDoesNotApply &e ) {
00693 #ifdef DEBUG2
00694 std::cout << "Catched exception EDoesNotApply()";
00695 #endif
00696 CASObject::Garbage->Put ( tmp_prod );
00697 return false;
00698 }
00699
00700
00701 std::vector<const CASObject*> o_ops_without_coeff;
00702 converted_o->GetOperandsWithoutCoefficient ( o_ops_without_coeff );
00703
00704 CASConvert non_coeff_conv ( o_ops_without_coeff );
00705 Product* final_o_conversion;
00706 try {
00707 final_o_conversion = non_coeff_conv.ToProduct();
00708 } catch ( EDoesNotApply &e ) {
00709 #ifdef DEBUG2
00710 std::cout << "Catched exception EDoesNotApply()";
00711 #endif
00712 CASObject::Garbage->Put ( tmp_prod );
00713 CASObject::Garbage->Put ( converted_o );
00714 return false;
00715 }
00716
00717
00718
00719 bool ret_val = tmp_prod->IsEqual ( final_o_conversion );
00720 CASObject::Garbage->Put ( final_o_conversion );
00721 CASObject::Garbage->Put ( converted_o );
00722 CASObject::Garbage->Put ( tmp_prod );
00723
00724 return ret_val;
00725 }
00726
00737 CASObject*
00738 Product::Absolute() const {
00739 Product *tmp = new Product;
00740 *tmp = *this;
00741
00742 std::for_each ( tmp->operands.begin(),
00743 tmp->operands.end(),
00744 CASAbsoluteObjectIP() );
00745
00746 return tmp;
00747 }
00748
00749
00756 void
00757 Product::AbsoluteIP() {
00758 std::for_each ( operands.begin(), operands.end(), CASAbsoluteObjectIP() );
00759 }
00760
00770 CASObject*
00771 Product::Invert() const {
00772 Product *tmp = new Product;
00773 *tmp = *this;
00774
00775 std::for_each ( tmp->operands.begin(),
00776 tmp->operands.end(),
00777 CASInvertObjectIP() );
00778
00779 return tmp;
00780 }
00781
00788 void
00789 Product::InvertIP() {
00790 std::for_each ( operands.begin(), operands.end(), CASInvertObjectIP() );
00791 }
00792
00820 CASObject*
00821 Product::Add ( const CASObject* addend ) const {
00822 checkptr ( addend );
00823
00824
00825 std::vector<const CASObject*> this_noncoe;
00826 GetOperandsWithoutCoefficient ( this_noncoe );
00827 #if defined(DEBUG)
00828 assert ( this_noncoe.size() > 0 );
00829 #endif
00830 const CASObject *this_coeff = GetCoefficient();
00831
00832 if ( GetType() == addend->GetType() ) {
00833 const Product *arg_obj = dynamic_cast<const Product*> ( addend );
00834 #if defined(DEBUG)
00835 assert ( arg_obj != 0 );
00836 #endif
00837
00838
00839
00840 std::vector<const CASObject*> arg_noncoe;
00841 arg_obj->GetOperandsWithoutCoefficient ( arg_noncoe );
00842 #if defined(DEBUG)
00843 assert ( arg_noncoe.size() > 0 );
00844 #endif
00845
00846 bool equal = false;
00847 if ( this_noncoe.size() == arg_noncoe.size() ) {
00848 equal = std::equal ( this_noncoe.begin(),
00849 this_noncoe.end(),
00850 arg_noncoe.begin(),
00851 CASObjectEqual() );
00852 }
00853
00854
00855
00856 if ( equal ) {
00857
00858
00859
00860
00861 Product *result = new Product;
00862
00863 const CASObject *arg_coeff = arg_obj->GetCoefficient();
00864 #if defined(DEBUG)
00865
00866
00867 if ( this_coeff != 0 ) {
00868 assert ( this_coeff->IsPureNumerical() );
00869 }
00870 if ( arg_coeff != 0 ) {
00871 assert ( arg_coeff->IsPureNumerical() );
00872 }
00873 #endif
00874
00875
00876
00877 if ( this_coeff != 0 && arg_coeff != 0 ) {
00878 CASObject *new_coeff = this_coeff->Add ( arg_coeff );
00879 result->Append ( new_coeff );
00880
00881 CASObject::Garbage->Put ( new_coeff );
00882 } else {
00883
00884
00885
00886
00887 if ( this_coeff == 0 && arg_coeff == 0 ) {
00888 LongInt new_coeff ( 2L );
00889 result->Append ( &new_coeff );
00890 }
00891
00892 LongInt one ( 1L );
00893 CASObject *new_coeff;
00894 if ( this_coeff != 0 ) {
00895 new_coeff = this_coeff->Add ( &one );
00896 result->Append ( new_coeff );
00897 CASObject::Garbage->Put ( new_coeff );
00898 }
00899
00900 if ( arg_coeff != 0 ) {
00901 new_coeff = arg_coeff->Add ( &one );
00902 result->Append ( new_coeff );
00903 CASObject::Garbage->Put ( new_coeff );
00904 }
00905 }
00906
00907
00908
00909 std::transform ( this_noncoe.begin(), this_noncoe.end(),
00910 back_inserter ( result->operands ), CASCloneObject() );
00911 return result;
00912 }
00913 } else {
00914
00915 if ( this_noncoe.size() == 1 ) {
00916 if ( addend->IsEqual ( this_noncoe[0] ) ) {
00917 Product *result = new Product;
00918 result->Append ( addend );
00919 if ( this_coeff != 0 ) {
00920 LongInt one ( 1L );
00921 CASObject *new_coeff = this_coeff->Add ( &one );
00922 new_coeff->meta.SetCoefficient();
00923 result->Append ( new_coeff );
00924 CASObject::Garbage->Put ( new_coeff );
00925 } else {
00926 LongInt two ( 2L );
00927 two.meta.SetCoefficient();
00928 result->Append ( &two );
00929 }
00930 return result;
00931 }
00932 }
00933
00934 }
00935 Sum *result = new Sum;
00936 result->Append ( this );
00937 result->Append ( addend );
00938
00939 return result;
00940 }
00941
00958 CASObject*
00959 Product::Subtract ( const CASObject* subtrahend ) const {
00960 checkptr ( subtrahend );
00961
00962 Sum *result = new Sum;
00963 result->Append ( this );
00964 CASObject* inv_subtrahend = subtrahend->Invert();
00965 result->Append ( inv_subtrahend );
00966
00967 CASObject::Garbage->Put ( inv_subtrahend );
00968 return result;
00969 }
00970
00988 CASObject*
00989 Product::Multiply ( const CASObject* factor ) const {
00990 checkptr ( factor );
00991
00992 Product *NewProd = new Product;
00993 *NewProd = *this;
00994 NewProd->meta.UnsetSorted();
00995
00996 if ( GetType() == factor->GetType() ) {
00997
00998 const Product *pr_ptr = dynamic_cast<const Product *> ( factor );
00999 #ifdef DEBUG
01000 assert ( pr_ptr != 0 );
01001 #endif
01002
01003 std::transform ( pr_ptr->operands.begin(),
01004 pr_ptr->operands.end(),
01005 back_inserter ( NewProd->operands ),
01006 CASCloneObject() );
01007 } else {
01008 std::vector<CASObject*>::iterator pi = find_if ( NewProd->operands.begin(),
01009 NewProd->operands.end(),
01010 CASTypeFinder_EQ ( factor ) );
01011
01012 if ( pi != NewProd->operands.end() ) {
01013
01014 CASObject *result = ( *pi )->Multiply ( factor );
01015
01016 CASObject::Garbage->Put ( *pi );
01017
01018 NewProd->operands.erase ( pi );
01019
01020 if ( result->IsPureNumerical() ) {
01021 result->meta.SetCoefficient();
01022 NewProd->operands.push_back ( result );
01023 } else {
01024
01025
01026 if ( GetType() == result->GetType() ) {
01027 Product *result_prod = dynamic_cast<Product*> ( result );
01028 #ifdef DEBUG
01029 assert ( result_prod != 0 );
01030 #endif
01031 std::copy ( result_prod->operands.begin(),
01032 result_prod->operands.end(),
01033 back_inserter ( NewProd->operands ) );
01034 } else {
01035 NewProd->operands.push_back ( result );
01036 }
01037 }
01038
01039 } else {
01040 CASObject *tmp = factor->Clone();
01041 if ( tmp->IsPureNumerical() ) {
01042 tmp->meta.SetCoefficient();
01043 }
01044 NewProd->operands.push_back ( tmp );
01045 }
01046 }
01047
01048 return NewProd;
01049 }
01050
01062 CASObject*
01063 Product::Divide ( const CASObject* divisor ) const {
01064 checkptr ( divisor );
01065
01066 Fraction *result = new Fraction ( this, divisor );
01067
01068 return result;
01069 }
01070
01085 CASObject*
01086 Product::Modulo ( const CASObject* divisor ) const {
01087 #ifdef WARNINGS
01088 #warning "Not fully implemented: Product::Modulo(const CASObject*)"
01089 #endif
01090 checkptr ( divisor );
01091 return new LongInt ( 0L );
01092 }
01093
01108 CASObject*
01109 Product::GCD ( const CASObject* o ) const {
01110 #ifdef WARNINGS
01111 #warning "Not fully implemented: Product::GCD(const CASObject*) const"
01112 #endif
01113
01114 checkptr ( o );
01115 return new LongInt ( 1L );
01116 }
01117
01136 CASObject*
01137 Product::Evaluate() const {
01138 if ( meta.IsEvaluated() ) {
01139 return Clone();
01140 }
01141
01142 #ifdef DEBUG2
01143 std::cout << ">>> Begin evaluation of ";
01144 Print();
01145 std::cout << std::endl;
01146 #endif
01147
01148 Product *tmp = dynamic_cast<Product*> ( Clone() );
01149 #ifdef DEBUG
01150 assert ( tmp != 0 );
01151 #endif
01152 tmp->UnsetAllEvaluated();
01153 resolve_parentheses<Product> ( tmp );
01154 evaluate_operands<Product> ( tmp );
01155
01156 CASObject* result = tmp->Collect();
01157 CASObject::Garbage->Put ( tmp );
01158
01159 result->meta.SetEvaluated();
01160 CASTerm *term = dynamic_cast<CASTerm*> ( result );
01161 if ( term != 0 ) {
01162 term->RemoveNoOpElements();
01163 if ( term->IsOne() ) {
01164 CASObject::Garbage->Put ( result );
01165 LongInt r ( 1L );
01166 return r.Clone();
01167 }
01168 term->SetAllEvaluated();
01169 }
01170
01171 if ( result->IsOne() ) {
01172 CASObject::Garbage->Put ( result );
01173 LongInt r ( 1L );
01174 return r.Clone();
01175 }
01176
01177 if ( result->IsZero() ) {
01178 CASObject::Garbage->Put ( result );
01179 LongInt r ( 0L );
01180 return r.Clone();
01181 }
01182
01183 #ifdef DEBUG2
01184 std::cout << ">>> End evaluation of ";
01185 Print();
01186 std::cout << std::endl;
01187 #endif
01188
01189 return result;
01190 }
01191
01203 CASObject*
01204 Product::Collect() const {
01205 Product *product = dynamic_cast<Product*> ( Clone() );
01206
01207 CASObject* tmp = product->CollectEqualOperands();
01208 #ifdef DEBUG
01209 checkptr ( tmp );
01210 #endif
01211 CASObject::Garbage->Put ( product );
01212
01213 product = dynamic_cast<Product*> ( tmp );
01214 if ( product == 0 ) {
01215 return tmp;
01216 }
01217
01218 tmp = product->CollectOther();
01219 CASObject::Garbage->Put ( product );
01220
01221 return tmp;
01222
01223 }
01224
01255 CASObject*
01256 Product::Expand() const {
01257 if ( !meta.IsEvaluated() ) {
01258 throw EEvaluateFirst();
01259 }
01260 CASObject *clone = Clone();
01261
01262 Product *wrking = dynamic_cast<Product*> ( clone );
01263 #ifdef DEBUG
01264 assert ( wrking != 0 );
01265 #endif
01266 wrking->ExplodeSumsIP();
01267
01268
01269 resolve_parentheses<Product> ( wrking );
01270
01271 std::vector<const CASObject*> non_singleval;
01272 wrking->GetNonSingleValues ( non_singleval );
01273
01274 std::vector<const CASObject*> sums_only;
01275 std::vector<const CASObject*>::const_iterator sums_only_it;
01276 wrking->GetSums ( non_singleval, sums_only );
01277 if ( sums_only.size() == 0 ) {
01278 CASObject::Garbage->Put ( wrking );
01279 return Clone();
01280 }
01281
01282 std::vector<const CASObject*> nonsums_only;
01283 std::vector<const CASObject*>::const_iterator nonsums_only_it;
01284 wrking->GetNonSums ( non_singleval, nonsums_only );
01285 #ifdef DEBUG
01286 assert ( nonsums_only.size() + sums_only.size() == non_singleval.size() );
01287 #endif
01288
01289 std::vector<const CASObject*>::const_iterator singleval_it;
01290 std::vector<const CASObject*> singleval;
01291 wrking->GetSingleValues ( singleval );
01292
01293 std::vector<CASObject*> result_vector;
01294 std::vector<CASObject*>::iterator result_it;
01295
01296 std::vector<const CASObject*> temp_operands;
01297 std::vector<const CASObject*>::const_iterator temp_operands_it;
01298
01299
01300
01301 sums_only_it = sums_only.begin();
01302 const Sum* temp_sum = dynamic_cast<const Sum*> ( *sums_only_it );
01303 #ifdef DEBUG
01304 assert ( temp_sum != 0 );
01305 #endif
01306
01307 GetOperands ( temp_sum, temp_operands );
01308
01309
01310 std::transform ( temp_operands.begin(),
01311 temp_operands.end(),
01312 std::back_inserter ( result_vector ),
01313 CASCloneObject()
01314 );
01315
01316 std::vector<CASObject*> intermediate_results;
01317
01318 sums_only_it++;
01319
01320 while ( sums_only_it != sums_only.end() ) {
01321 temp_sum = dynamic_cast<const Sum*> ( *sums_only_it );
01322 #ifdef DEBUG
01323 assert ( temp_sum != 0 );
01324 #endif
01325 temp_operands.clear();
01326 GetOperands ( temp_sum, temp_operands );
01327
01328 result_it = result_vector.begin();
01329 while ( result_it != result_vector.end() ) {
01330 temp_operands_it = temp_operands.begin();
01331 while ( temp_operands_it != temp_operands.end() ) {
01332 intermediate_results.push_back ( ( *result_it )->Multiply ( *temp_operands_it ) );
01333 temp_operands_it++;
01334 }
01335 result_it++;
01336 }
01337 CASObject::Garbage->Put ( result_vector );
01338 result_vector.clear();
01339 std::copy ( intermediate_results.begin(),
01340 intermediate_results.end(),
01341 std::back_inserter ( result_vector )
01342 );
01343 intermediate_results.clear();
01344 sums_only_it++;
01345 }
01346 #ifdef DEBUG
01347 assert ( intermediate_results.size() == 0 );
01348 #endif
01349
01350
01351 singleval_it = singleval.begin();
01352 while ( singleval_it != singleval.end() ) {
01353 result_it = result_vector.begin();
01354 while ( result_it != result_vector.end() ) {
01355 intermediate_results.push_back ( ( *result_it )->Multiply ( *singleval_it ) );
01356 result_it++;
01357 }
01358 CASObject::Garbage->Put ( result_vector );
01359 result_vector.clear();
01360 std::copy ( intermediate_results.begin(),
01361 intermediate_results.end(),
01362 std::back_inserter ( result_vector )
01363 );
01364 intermediate_results.clear();
01365 singleval_it++;
01366 }
01367 #ifdef DEBUG
01368 assert ( intermediate_results.size() == 0 );
01369 #endif
01370
01371
01372 nonsums_only_it = nonsums_only.begin();
01373 while ( nonsums_only_it != nonsums_only.end() ) {
01374 result_it = result_vector.begin();
01375 while ( result_it != result_vector.end() ) {
01376 intermediate_results.push_back ( ( *result_it )->Multiply ( *nonsums_only_it ) );
01377 result_it++;
01378 }
01379 CASObject::Garbage->Put ( result_vector );
01380 result_vector.clear();
01381 std::copy ( intermediate_results.begin(),
01382 intermediate_results.end(),
01383 std::back_inserter ( result_vector )
01384 );
01385 intermediate_results.clear();
01386 nonsums_only_it++;
01387 }
01388 #ifdef DEBUG
01389 assert ( intermediate_results.size() == 0 );
01390 #endif
01391 CASObject::Garbage->Put ( wrking );
01392
01393 Sum *s = new Sum;
01394 SetOperands ( s, result_vector );
01395 CASObject::Garbage->Put ( result_vector );
01396
01397 s->UnsetAllEvaluated();
01398 CASObject *result = s->Evaluate();
01399 CASObject::Garbage->Put ( s );
01400
01401 return result;
01402 }
01403
01411 void
01412 Product::RemoveNoOpElements() {
01413 std::vector<CASObject*>::iterator it = operands.begin();
01414 while ( it != operands.end() ) {
01415 if ( ( *it )->IsOne() ) {
01416 CASObject::Garbage->Put ( *it );
01417 it = operands.erase ( it );
01418 } else {
01419 CASTerm *term = dynamic_cast<CASTerm*> ( *it );
01420 if ( term != 0 ) {
01421 term->RemoveNoOpElements();
01422 }
01423 it++;
01424 }
01425
01426 }
01427 }
01428
01429
01430
01431
01432
01433
01441 const Product&
01442 Product::operator= ( const Product &p ) {
01443 #ifdef SHOWCONSTRUCTOR
01444 std::cout << "# Product::operator=(const Product &p)" << std::endl;
01445 #endif
01446
01447 if ( &p == this ) {
01448 return *this;
01449 }
01450
01451 CASObject::Garbage->Put ( operands );
01452
01453 operands.clear();
01454
01455 std::transform ( p.operands.begin(),
01456 p.operands.end(),
01457 std::back_inserter ( operands ),
01458 CASCloneObject() );
01459
01460 meta = p.meta;
01461
01462 CASObject::Garbage->Put ( exponent );
01463 exponent = p.exponent->Clone();
01464
01465 return *this;
01466 }
01467
01468