00001 // 00002 // Copyright (c) 2006 by Rafael Ostertag 00003 // 00004 // This program is free software; you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation; either version 2 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 // 00018 // 00019 // $Id: variable.cc,v 1.14 2006/12/31 00:49:39 rafi Exp $ 00020 // 00021 00031 #include <string> 00032 #include <iostream> 00033 00034 #ifdef DEBUG 00035 #include <cassert> 00036 #endif 00037 00038 #include "sum.h" 00039 #include "product.h" 00040 #include "variable.h" 00041 #include "longint.h" 00042 #include "fraction.h" 00043 00050 // Private methods 00051 // ---------------------------------------------------------------------------- 00052 00053 // ---------------------------------------------------------------------------- 00054 00055 // Constructors & Destructor 00056 // ---------------------------------------------------------------------------- 00061 Variable::Variable() : name ( "a" ) { 00062 #ifdef SHOWCONSTRUCTOR 00063 std::cerr << "# Variable::Variable()" << std::endl; 00064 #endif 00065 exponent = new LongInt ( 1L ); 00066 meta.SetSingleValue(); 00067 } 00068 00076 Variable::Variable ( const std::string n, const CASObject* exp ) : name ( n ) { 00077 #ifdef SHOWCONSTRUCTOR 00078 std::cerr << "# Variable::Variable(const std::string n, const CASObject* exponent)" << std::endl; 00079 #endif 00080 checkptr ( exp ); 00081 00082 exponent = exp->Clone(); 00083 meta.SetSingleValue(); 00084 } 00085 00091 Variable::Variable ( const std::string n ) : name ( n ) { 00092 #ifdef SHOWCONSTRUCTOR 00093 std::cerr << "# Variable::Variable(const std::string n)" << std::endl; 00094 #endif 00095 exponent = new LongInt ( 1L ); 00096 meta.SetSingleValue(); 00097 } 00098 00104 Variable::Variable ( const Variable &v ) { 00105 #ifdef SHOWCONSTRUCTOR 00106 std::cerr << "# Variable::Variable(const Variable &v)" << std::endl; 00107 #endif 00108 name = v.name; 00109 exponent = v.exponent->Clone(); 00110 meta = v.meta; 00111 } 00112 00116 Variable::~Variable() { 00117 #ifdef SHOWCONSTRUCTOR 00118 std::cerr << "# Variable::~Variable()" << std::endl; 00119 #endif 00120 #ifdef DEBUG 00121 assert ( exponent != 0 ); 00122 #endif 00123 delete exponent; 00124 } 00125 // ---------------------------------------------------------------------------- 00126 00127 00128 // Public Methods 00129 // ---------------------------------------------------------------------------- 00138 CASObject* 00139 Variable::Clone() const{ 00140 Variable *tmp = new Variable; 00141 00142 *tmp = *this; 00143 00144 return tmp; 00145 } 00146 00155 void 00156 Variable::Get ( std::string &s ) const{ 00157 if ( exponent->IsZero() ) { 00158 s = "1"; 00159 return; 00160 } 00161 00162 if ( exponent->IsOne() ) { 00163 s = name; 00164 } else { 00165 s = name; 00166 if ( exponent->meta.IsSingleValue() ) { 00167 s += "^"; 00168 } else { 00169 s += "^("; 00170 } 00171 00172 std::string tmp; 00173 exponent->Get ( tmp ); 00174 00175 s += tmp; 00176 if ( !exponent->meta.IsSingleValue() ) { 00177 s += ")"; 00178 } 00179 } 00180 } 00181 00196 void 00197 Variable::Get ( char *s, unsigned long size ) const{ 00198 checkptr ( s ); 00199 00200 if ( size < ( Length() + 1 ) ) { 00201 throw EBufTooSmall(); 00202 } 00203 00204 memset ( s, '\0', size ); 00205 00206 std::string tmp; 00207 Get ( tmp ); 00208 00209 strncpy ( s, tmp.c_str(), size ); 00210 } 00211 00217 void 00218 Variable::Print() const{ 00219 std::string tmp; 00220 Get ( tmp ); 00221 std::cout << tmp; 00222 } 00223 00230 unsigned long 00231 Variable::Length() const { 00232 if ( exponent->IsOne() || exponent->IsZero() ) { 00233 return 1; 00234 } 00235 00236 unsigned long len = 0; 00237 len += name.size(); 00238 len += exponent->Length(); 00239 // Add 3 for '^()' 00240 len += 3; 00241 00242 return len; 00243 } 00244 00250 bool 00251 Variable::IsZero() const{ 00252 return false; 00253 } 00254 00260 bool 00261 Variable::IsOne() const{ 00262 return exponent->IsZero(); 00263 } 00264 00276 CASObject* 00277 Variable::Absolute() const{ 00278 return Clone(); 00279 } 00280 00287 void 00288 Variable::AbsoluteIP() { 00289 // Intentionally left blank. 00290 } 00291 00303 CASObject* 00304 Variable::Invert() const{ 00305 Product *res = new Product; 00306 LongInt mo ( -1L ); 00307 mo.meta.SetCoefficient(); 00308 00309 res->Append ( &mo ); 00310 res->Append ( this ); 00311 return res; 00312 } 00313 00321 void 00322 Variable::InvertIP() { 00323 // Intentionally left blank. 00324 } 00325 00339 CASObject* 00340 Variable::Add ( const CASObject* addend ) const { 00341 checkptr ( addend ); 00342 00343 if ( GetType() == addend->GetType() ) { 00344 if ( IsEqual ( addend ) ) { 00345 LongInt coeff ( 2L ); 00346 Product* res = new Product; 00347 res->Append ( &coeff ); 00348 res->Append ( addend ); 00349 return res; 00350 } 00351 } 00352 00353 Sum *result = new Sum; 00354 result->Append ( this ); 00355 result->Append ( addend ); 00356 00357 return result; 00358 } 00359 00373 CASObject* 00374 Variable::Subtract ( const CASObject* subtrahend ) const{ 00375 checkptr ( subtrahend ); 00376 00377 if ( GetType() == subtrahend->GetType() ) { 00378 if ( IsEqual ( subtrahend ) ) { 00379 return new LongInt ( 0L ); 00380 } 00381 00382 Sum *res = new Sum; 00383 CASObject *inv_subtrahend = subtrahend->Invert(); 00384 00385 res->Append ( this ); 00386 res->Append ( inv_subtrahend ); 00387 return res; 00388 } 00389 00390 Sum tmp; 00391 CASObject *result; 00392 00393 tmp.Append ( this ); 00394 result = tmp.Subtract ( subtrahend ); 00395 00396 return result; 00397 } 00398 00411 CASObject* 00412 Variable::Multiply ( const CASObject* factor ) const{ 00413 checkptr ( factor ); 00414 00415 if ( GetType() == factor->GetType() ) { 00416 const Variable *var_ptr = dynamic_cast<const Variable*> ( factor ); 00417 #ifdef DEBUG 00418 assert ( var_ptr != 0 ); 00419 #endif 00420 if ( name == var_ptr->name ) { 00421 Variable *result = new Variable; 00422 CASObject::Garbage->Put ( result->exponent ); 00423 result->name = name; 00424 result->exponent = exponent->Add ( var_ptr->exponent ); 00425 00426 return result; 00427 } 00428 } 00429 00430 Product *result = new Product; 00431 result->Append ( this ); 00432 00433 // Check if the factor is a Coefficient 00434 CASObject *tmp = factor->Clone(); 00435 if ( tmp->IsPureNumerical() ) { 00436 tmp->meta.SetCoefficient(); 00437 } 00438 result->Append ( tmp ); 00439 CASObject::Garbage->Put ( tmp ); 00440 00441 return result; 00442 } 00443 00455 CASObject* 00456 Variable::Divide ( const CASObject* divisor ) const { 00457 checkptr ( divisor ); 00458 00459 if ( GetType() == divisor->GetType() ) { 00460 const Variable *var_ptr = dynamic_cast<const Variable*> ( divisor ); 00461 #ifdef DEBUG 00462 assert ( var_ptr != 0 ); 00463 #endif 00464 if ( name == var_ptr->name ) { 00465 Variable *result = new Variable; 00466 CASObject::Garbage->Put ( result->exponent ); 00467 result->name = name; 00468 result->exponent = exponent->Subtract ( var_ptr->exponent ); 00469 00470 return result; 00471 } 00472 } 00473 00474 Fraction *result = new Fraction ( this, divisor ); 00475 00476 return result; 00477 00478 } 00479 00494 CASObject* 00495 Variable::Modulo ( const CASObject* divisor ) const { 00496 #ifdef WARNINGS 00497 #warning "Not fully implemented: Variable::Modulo(const CASObject* divisor) const" 00498 #endif 00499 checkptr ( divisor ); 00500 return new LongInt ( 0L ); 00501 } 00502 00514 CASObject* 00515 Variable::Power ( const CASObject* exp ) const { 00516 checkptr ( exp ); 00517 00518 Variable* result = dynamic_cast<Variable*> ( Clone() ); 00519 #ifdef DEBUG 00520 assert ( result != 0 ); 00521 #endif 00522 CASObject *new_exp = result->exponent->Multiply ( exp ); 00523 CASObject::Garbage->Put ( result->exponent ); 00524 result->exponent = new_exp; 00525 00526 return result; 00527 } 00528 00543 CASObject* 00544 Variable::GCD ( const CASObject* o ) const { 00545 #ifdef WARNINGS 00546 #warning "Not fully implemented: Variable::GCD(const CASObject* o) const" 00547 #endif 00548 checkptr ( o ); 00549 return new LongInt ( 1L ); 00550 } 00551 00560 bool 00561 Variable::IsEqual ( const CASObject* o ) const { 00562 checkptr ( o ); 00563 if ( GetType() != o->GetType() ) { 00564 return false; 00565 } 00566 const Variable *var_ptr = dynamic_cast<const Variable*> ( o ); 00567 #ifdef DEBUG 00568 assert ( var_ptr != 0 ); 00569 #endif 00570 00571 if ( name == var_ptr->name && 00572 exponent->IsEqual ( var_ptr->exponent ) ) { 00573 return true; 00574 } 00575 00576 return false; 00577 } 00578 00592 bool 00593 Variable::IsLT ( const CASObject* o ) const { 00594 #ifdef WARNINGS 00595 #warning "Not fully implemented: bool Variable::IsLT(const CASObject* o) const" 00596 #endif 00597 00598 checkptr ( o ); 00599 00600 if ( GetType() < o->GetType() ) { 00601 return true; 00602 } 00603 00604 if ( GetType() > o->GetType() ) { 00605 return false; 00606 } 00607 00608 const Variable *v = dynamic_cast<const Variable*> ( o ); 00609 #ifdef DEBUG 00610 assert ( v != 0 ); 00611 #endif 00612 00613 if ( name < v->name ) { 00614 return true; 00615 } 00616 00617 if ( name > v->name ) { 00618 return false; 00619 } 00620 00621 return exponent->IsLT ( v->exponent ); 00622 } 00637 bool 00638 Variable::IsGT ( const CASObject* o ) const { 00639 #ifdef WARNINGS 00640 #warning "Not fully implemented: bool Variable::IsGT(const CASObject* o) const" 00641 #endif 00642 checkptr ( o ); 00643 00644 if ( IsEqual ( o ) ) { 00645 return false; 00646 } 00647 00648 return !IsLT ( o ); 00649 } 00650 00660 bool 00661 Variable::IsSimilar ( const CASObject* o ) const { 00662 checkptr ( o ); 00663 00664 if ( GetType() != o->GetType() ) { 00665 return false; 00666 } 00667 00668 const Variable* var = dynamic_cast<const Variable*> ( o ); 00669 #ifdef DEBUG 00670 assert ( var != 0 ); 00671 #endif 00672 if ( var->name == name ) { 00673 return true; 00674 } 00675 00676 return false; 00677 } 00678 00689 CASObject* 00690 Variable::SortWeight() const { 00691 LongInt weight ( 0L ); 00692 for ( unsigned long i = 0;i < name.length();i++ ) { 00693 weight = weight + name[i]; 00694 } 00695 return weight.Clone(); 00696 } 00697 00703 void 00704 Variable::Sort() { 00705 if ( meta.IsSorted() ) { 00706 return; 00707 } 00708 exponent->Sort(); 00709 meta.SetSorted(); 00710 } 00711 00719 CASObject* 00720 Variable::Evaluate() const { 00721 if ( meta.IsEvaluated() ) { 00722 return Clone(); 00723 } 00724 Variable *ret_val = dynamic_cast<Variable*> ( Clone() ); 00725 #ifdef DEBUG 00726 assert ( ret_val != 0 ); 00727 #endif 00728 00729 CASObject *exp = ret_val->exponent; 00730 ret_val->exponent = ret_val->exponent->Evaluate(); 00731 00732 CASObject::Garbage->Put ( exp ); 00733 00734 ret_val->Sort(); 00735 ret_val->meta.SetEvaluated(); 00736 00737 return ret_val; 00738 } 00739 00740 // ---------------------------------------------------------------------------- 00741 00742 // Operators 00743 // ---------------------------------------------------------------------------- 00751 const Variable& 00752 Variable::operator= ( const Variable &v ) { 00753 #ifdef SHOWCONSTRUCTOR 00754 std::cerr << "# Variable::operator=(const Variable &v)" << std::endl; 00755 #endif 00756 if ( &v == this ) { 00757 return *this; 00758 } 00759 00760 #ifdef DEBUG 00761 assert ( exponent != 0 ); 00762 #endif 00763 name = v.name; 00764 00765 CASObject::Garbage->Put ( exponent ); 00766 exponent = v.exponent->Clone(); 00767 00768 meta = v.meta; 00769 00770 return *this; 00771 } 00772 00773 // ---------------------------------------------------------------------------- 00774
1.4.7