00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #ifndef FUNCTION_H_JUN_26_2005
00067 #define FUNCTION_H_JUN_26_2005
00068
00069 #include <ext/hash_set>
00070 using namespace __gnu_cxx;
00071 #include "functiontemplate.h"
00072 #include "hash.h"
00073 #include "term.h"
00074
00075
00076
00077 class Function
00078 {
00079 public:
00080
00081 Function(const FunctionTemplate* const & ft)
00082 : template_(ft), terms_(new Array<Term*>), retConstId_(-1),
00083 intArrRep_(NULL), hashCode_(0), dirty_(true), parent_(NULL) {}
00084
00085
00086 Function(const FunctionTemplate* const & ft, Term* const & parent)
00087 : template_(ft), terms_(new Array<Term*>), retConstId_(-1),
00088 intArrRep_(NULL), hashCode_(0), dirty_(true), parent_(NULL) {}
00089
00090
00091 Function(const Function& f) { parent_ = NULL; copy(f); }
00092 Function(const Function& f, Term* const & parent) { parent_=parent; copy(f); }
00093
00094
00095 ~Function()
00096 {
00097 for (int i = 0; i < terms_->size(); i++)
00098 delete (*terms_)[i];
00099 delete terms_;
00100 if (intArrRep_) delete intArrRep_;
00101 }
00102
00103
00104
00105 void appendTerm(Term* const & term)
00106 {
00107 if (template_->getNumTerms() == terms_->size())
00108 {
00109 cout << "Error: In Function::appendTerm. Tried to add more terms than "
00110 << "the declared num of " << template_->getNumTerms() << endl;
00111 exit(-1);
00112 }
00113 terms_->append(term);
00114 setDirty();
00115 }
00116
00122 Term* removeLastTerm()
00123 {
00124 Term* term = terms_->removeLastItem();
00125 terms_->compress();
00126 setDirty();
00127 return term;
00128 }
00129
00130 int getNumTerms() const { return terms_->size(); }
00131
00132 const Term* getTerm(const int& idx) const { return (*terms_)[idx]; }
00133
00134 void setTemplate(FunctionTemplate* const & t) { template_ = t; }
00135
00136 const FunctionTemplate* getTemplate() const { return template_; }
00137
00138
00139 const char* getName() const { return template_->getName(); }
00140
00141 int getId() const { return template_->getId(); }
00142
00143
00144
00145 void setRetConstId(const int& constId) { retConstId_ = constId; setDirty();}
00146 int getRetConstId() const { return retConstId_; }
00147
00148 void setDirty();
00149 bool isDirty() const { return dirty_; }
00150
00151 void setParent(Term* const parent) { parent_ = parent; setDirty(); }
00152 Term* getParent() const { return parent_; }
00153
00154
00155
00156
00157
00158 const char* getTermTypeAsStr(const int& idx) const
00159 {
00160 if (idx >= template_->getNumTerms()) return NULL;
00161 return template_->getTermTypeAsStr(idx);
00162 }
00163
00164
00165 int getTermTypeAsInt(const int& idx) const
00166 {
00167 if (idx >= template_->getNumTerms()) return -1;
00168 return template_->getTermTypeAsInt(idx);
00169 }
00170
00171
00172 int getRetTypeId() const { return template_->getRetTypeId(); }
00173
00174
00175 const char* getRetTypeName() const { return template_->getRetTypeName(); }
00176
00177 bool same(const Function* const & f) const
00178 {
00179 if (this == f) return true;
00180
00181
00182 if (template_->getId() != f->getId()) return false;
00183 int numTerms = terms_->size();
00184 if (numTerms != f->getNumTerms()) return false;
00185 for (int i = 0; i < numTerms; i++)
00186 if ((*terms_)[i]->getId() != f->getTerm(i)->getId()) return false;
00187 return true;
00188 }
00189
00190
00191
00192 void appendIntArrRep(Array<int>& rep)
00193 {
00194 if (dirty_) computeAndStoreIntArrRep();
00195 rep.append(*intArrRep_);
00196 }
00197
00198
00199 size_t hashCode()
00200 {
00201 if (dirty_) computeAndStoreIntArrRep();
00202 return hashCode_;
00203 }
00204
00205
00206 bool same(Function* const & f)
00207 {
00208 if (this==f) return true;
00209 const Array<int>* fArr = f->getIntArrRep();
00210 const Array<int>* myArr = getIntArrRep();
00211 if (myArr->size() != fArr->size()) return false;
00212 const int* fItems = f->getIntArrRep()->getItems();
00213 const int* myItems = getIntArrRep()->getItems();
00214 return (memcmp(myItems, fItems, myArr->size()*sizeof(int))==0);
00215 }
00216
00217
00218 ostream& printAsInt(ostream& out) const
00219 {
00220 out << template_->getId() << "(";
00221 for (int i = 0; i < terms_->size(); i++)
00222 {
00223 (*terms_)[i]->printAsInt(out);
00224 out << ((i!=terms_->size()-1)?",":")");
00225 }
00226 return out;
00227 }
00228
00229
00230 ostream& printAsIntWithRetConstId(ostream& out) const
00231 {
00232 printAsInt(out);
00233 out << "=" << retConstId_ << endl;
00234 return out;
00235 }
00236
00237
00238 ostream& print(ostream& out, const Domain* const & domain) const
00239 {
00240 out << template_->getName() << "(";
00241 for (int i = 0; i < terms_->size(); i++)
00242 {
00243 (*terms_)[i]->print(out, domain);
00244 out << ((i!=terms_->size()-1)?",":")");
00245 }
00246 return out;
00247 }
00248
00249
00250 ostream&
00251 printWithRetConstName(ostream& out, const Domain* const & domain) const;
00252
00253
00254 private:
00255 void copy(const Function& f)
00256 {
00257 template_ = f.template_;
00258
00259 terms_ = new Array<Term*>;
00260 Array<Term*>* fterms = f.terms_;
00261 for (int i = 0; i < fterms->size(); i++)
00262 {
00263 Term* t = (*fterms)[i];
00264 terms_->append(new Term(*t, (void*)this, false));
00265 }
00266 dirty_ = f.dirty_;
00267
00268 if (!dirty_) { assert(noDirtyTerms()); }
00269
00270 retConstId_ = f.retConstId_;
00271
00272 if (f.intArrRep_) intArrRep_ = new Array<int>(*(f.intArrRep_));
00273 else intArrRep_ = NULL;
00274
00275 hashCode_ = f.hashCode_;
00276
00277 if (parent_) parent_->setDirty();
00278 }
00279
00280
00281 bool noDirtyTerms()
00282 {
00283 for (int i = 0; i < terms_->size(); i++)
00284 if ((*terms_)[i]->isDirty()) return false;
00285 return true;
00286 }
00287
00288
00289 const Array<int>* getIntArrRep()
00290 { if (dirty_) computeAndStoreIntArrRep(); return intArrRep_; }
00291
00292
00293 void computeAndStoreIntArrRep()
00294 {
00295
00296 dirty_ = false;
00297 if (intArrRep_ == NULL) intArrRep_ = new Array<int>;
00298 else intArrRep_->clear();
00299 intArrRep_->append(template_->getId());
00300
00301 int numTerms = terms_->size();
00302 for (int i = 0; i < numTerms; i++)
00303 (*terms_)[i]->appendIntArrRep(*intArrRep_);
00304
00305 intArrRep_->compress();
00306 hashCode_ = Hash::hash(*intArrRep_);
00307 }
00308
00309
00310 private:
00311 const FunctionTemplate* template_;
00312 Array<Term*>* terms_;
00313 int retConstId_;
00314 Array<int>* intArrRep_;
00315 size_t hashCode_;
00316 bool dirty_;
00317 Term* parent_;
00318 };
00319
00320 inline
00321 ostream& operator<<(ostream& out, const Function& f) {return f.printAsInt(out);}
00322
00323
00325
00326 class HashFunction
00327 {
00328 public:
00329 size_t operator()(Function* const & f) const { return f->hashCode(); }
00330 };
00331
00332
00333 class EqualFunction
00334 {
00335 public:
00336 bool operator()(const Function* const & f1, const Function* const & f2) const
00337 { return f1->same(f2); }
00338 };
00339
00340
00342
00343 typedef hash_set<Function*, HashFunction, EqualFunction> FunctionSet;
00344
00345
00346 #endif