variable.cc

Go to the documentation of this file.
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 

Generated on Sun Dec 31 01:57:27 2006 for ECAS by  doxygen 1.4.7