tp_timeconstraint.cpp

Go to the documentation of this file.
00001 /* tp_timecontraint.cpp -- model of timeconstraints in timed automata */
00002 
00003 
00004 /* Timeplugin for FAU Discrete Event Systems Library (libfaudes)
00005 
00006    Copyright (C) 2006  B Schlein
00007    Copyright (C) 2007  Thomas Moor
00008    Exclusive copyright is granted to Klaus Schmidt
00009 
00010 */
00011 
00012 
00013 
00014 #include "tp_timeconstraint.h"
00015 
00016 namespace faudes {
00017 
00018 
00019 /********************************************************************
00020 
00021  Implementation of ClockSet
00022 
00023 ********************************************************************/
00024 
00025 
00026 // ClockSet::msClockSymbolTable (static)
00027 SymbolTable ClockSet::msSymbolTable;
00028 
00029 // ClockSet::StaticSymbolTablep
00030 SymbolTable* ClockSet::StaticSymbolTablep(void) {
00031   return &msSymbolTable;
00032 }
00033 
00034 
00035 
00036 
00037 /********************************************************************
00038 
00039  Implementation of ElemConstraint
00040 
00041 ********************************************************************/
00042 
00043 
00044 // helper (conversion from operatorname to string
00045 std::string ElemConstraint::OperatorName(Operator op){
00046   switch(op){
00047   case LessThan: return "LT";  
00048   case GreaterThan: return "GT";  
00049   case LessEqual: return "LE";  
00050   case GreaterEqual: return "GE";
00051   }  
00052   return "Inalid";
00053 }                
00054 
00055 
00056 // Constructor
00057 ElemConstraint::ElemConstraint(void) {
00058   Set(0,LessThan,0);
00059 }
00060   
00061 // Constructor
00062 ElemConstraint::ElemConstraint(
00063              Idx clockindex, Operator op, const tpTime::Type timeconst) {
00064   Set(clockindex,op,timeconst);
00065 }
00066   
00067 
00068 // Set(clockindex, op, timeconst)
00069 void  ElemConstraint::Set(Idx clockindex, Operator op, const tpTime::Type timeconst) {
00070   mClockIndex = clockindex;
00071   mCompOperator = op;
00072   mTimeConstant = timeconst;
00073 }
00074 
00075 // Clock(clockindex)
00076 Idx ElemConstraint::Clock(Idx clockindex) {
00077   mClockIndex=clockindex;
00078   return mClockIndex;
00079 }
00080 
00081 // Clock()
00082 Idx ElemConstraint::Clock(void) const {
00083   return mClockIndex;
00084 }
00085 
00086 // CompOperator(newOp)
00087 void ElemConstraint::CompOperator(Operator newOp) {
00088   mCompOperator = newOp;
00089 }
00090 
00091 
00092 // CompOperator()
00093 ElemConstraint::Operator ElemConstraint::CompOperator(void) const {
00094   return mCompOperator;
00095 }
00096 
00097 
00098 // TimeConstant(newTimeConst)
00099 void ElemConstraint::TimeConstant (tpTime::Type newTimeConst) {
00100   mTimeConstant = newTimeConst;
00101 }
00102 
00103 // TimeConstant()
00104 tpTime::Type ElemConstraint::TimeConstant(void) const {
00105   return mTimeConstant;
00106 }
00107 
00108 // Str() const
00109 std::string ElemConstraint::Str(void) const {
00110   std::stringstream resstream;
00111   resstream << "(" << mClockIndex << " "
00112       << OperatorName(mCompOperator) << " " << mTimeConstant << ")";
00113   std::string result = resstream.str();
00114   return result;
00115 }
00116 
00117 // operator ==
00118 bool ElemConstraint::operator == (const ElemConstraint & otherClockConstraint) const {
00119   return ( mClockIndex == otherClockConstraint.mClockIndex
00120      && mCompOperator == otherClockConstraint.mCompOperator
00121      && mTimeConstant == otherClockConstraint.mTimeConstant );
00122 }
00123 
00124 // operator <
00125 bool ElemConstraint::operator < (const ElemConstraint& otherElemConstraint) const {
00126   if (mClockIndex < otherElemConstraint.mClockIndex) return true;
00127   if (mClockIndex > otherElemConstraint.mClockIndex) return false;
00128   if (mCompOperator < otherElemConstraint.mCompOperator) return true;
00129   if (mCompOperator > otherElemConstraint.mCompOperator) return false;
00130   if (mTimeConstant < otherElemConstraint.mTimeConstant) return true;
00131   return false;
00132 }
00133 
00134 
00135 /********************************************************************
00136 
00137  Implementation of TimeConstraint
00138 
00139 ********************************************************************/
00140 
00141 
00142 
00143 // empty constructor
00144 TimeConstraint::TimeConstraint(void) {
00145   FD_DC("TimeConstraint(" << this << ")::TimeConstraint()");
00146   mpClockSymbolTable=ClockSet::StaticSymbolTablep();
00147   mName="TimeConstraint";
00148 }
00149 
00150 // read file constructor
00151 TimeConstraint::TimeConstraint(const std::string& rFilename, const std::string& rLabel) {
00152   FD_DC("TimeConstraint(" << this << ")::TimeConstraint(" << rFilename << ")");
00153   mpClockSymbolTable=ClockSet::StaticSymbolTablep();
00154   Read(rFilename, rLabel);
00155 }
00156 
00157 // constructor
00158 TimeConstraint::TimeConstraint(const TimeConstraint& rOtherTimeConstraint) {
00159   FD_DC("TimeConstraint(" << this << ")::TimeConstraint(other)");
00160   mName=rOtherTimeConstraint.mName;
00161   mpClockSymbolTable= rOtherTimeConstraint.mpClockSymbolTable;
00162   mClockConstraints = rOtherTimeConstraint.ClockConstraints();
00163 }
00164 
00165 
00166 // Destructor
00167 TimeConstraint::~TimeConstraint(void) {
00168 }
00169 
00170 // ClockSymbolTablep()
00171 SymbolTable* TimeConstraint::ClockSymbolTablep(void) const {
00172   return mpClockSymbolTable;
00173 }
00174 
00175 // ClockSymbolTablep(pSymTab)
00176 void TimeConstraint::ClockSymbolTablep(SymbolTable* pSymTab) {
00177   if(mClockConstraints.empty()) {
00178     mpClockSymbolTable=pSymTab;
00179   } else {
00180     // TODO: implement reindex
00181     FD_ERR("TimeConstraint::SymboltTable(pSymTab): "
00182      << "set SymbolTable not implemented!!");
00183     abort();
00184   }   
00185 }
00186 
00187 // Empty()
00188 bool TimeConstraint::Empty(void) const {
00189   return mClockConstraints.empty();
00190 }
00191 
00192 // Size of set of ElemConstraints
00193 Idx TimeConstraint::Size(void) const {
00194   return (Idx)mClockConstraints.size();
00195 }
00196 
00197 // InsClock()
00198 Idx TimeConstraint::InsClock(const std::string& rClockName) const {
00199   return mpClockSymbolTable->InsEntry(rClockName);
00200 }
00201 
00202 // ClockName(clockindex)
00203 std::string TimeConstraint::ClockName(Idx clockindex) const {
00204   return mpClockSymbolTable->Symbol(clockindex);
00205 }
00206 
00207 // ClockIndex(clockname)
00208 Idx TimeConstraint::ClockIndex(const std::string& rClockName) const {
00209   return mpClockSymbolTable->Index(rClockName);
00210 }
00211 
00212 
00213 // EStr(ElemConstraint) const
00214 std::string TimeConstraint::EStr(const ElemConstraint& rElemConstraint) const {
00215   std::stringstream resstream;
00216   resstream << "(" << ClockName(rElemConstraint.Clock()) << "[" <<  rElemConstraint.Clock() 
00217       << "] " << ElemConstraint::OperatorName(rElemConstraint.CompOperator()) << " " 
00218       << rElemConstraint.TimeConstant() << ")";
00219   std::string result = resstream.str();
00220   return result;
00221 }
00222 
00223 // Insert(rNewConstr)
00224 TimeConstraint::Iterator TimeConstraint::Insert(const ElemConstraint& rNewConstr) {
00225   FD_DC("TimeConstraint(" << this << ")::Insert(" << rNewConstr.Str() << ")");
00226   if(rNewConstr.Clock()<=0 || ClockName(rNewConstr.Clock())=="") {
00227     std::stringstream errstr;
00228     errstr << "Invalid ElemConstraint: \"" << rNewConstr.Str();
00229     throw Exception("TimeConstraint::Insert", errstr.str(), 55);
00230   }
00231   return mClockConstraints.insert(rNewConstr).first;
00232 }
00233 
00234 // Insert(clock, op, timeconst)
00235 TimeConstraint::Iterator TimeConstraint::Insert(Idx clockindex, Operator op, const tpTime::Type timeconst) {
00236   FD_DC("TimeConstraint(" << this << ")::Insert(" 
00237   << clockindex << " " << ElemConstraint::OperatorName(op) << " " << timeconst << ")");
00238   ElemConstraint newconstr(clockindex,op,timeconst);
00239   return Insert(newconstr);
00240 }
00241 
00242 
00243 // Insert(clock, op, timeconst)
00244 TimeConstraint::Iterator TimeConstraint::Insert(
00245             const std::string clockname, 
00246             Operator op, 
00247             const tpTime::Type timeconst) 
00248 {
00249   FD_DC("TimeConstraint(" << this << ")::Insert(\"" 
00250   << clockname << "\" " << ElemConstraint::OperatorName(op) << " " << timeconst << ")");
00251   Idx clockindex = InsClock(clockname);
00252   return Insert(clockindex,op,timeconst);
00253 }
00254 
00255 // Insert(rNewConstraints)
00256 void TimeConstraint::Insert(const std::list<ElemConstraint>& rNewConstraints) {
00257   FD_DC("TimeConstraint(" << this << ")::Insert(const std::list<ElemConstraint>&)");
00258   // HELPERS
00259   std::list<ElemConstraint>::const_iterator it;
00260   // ALGORITHM
00261   for(it = rNewConstraints.begin(); it != rNewConstraints.end(); it++)
00262     Insert(*it);
00263 }
00264 
00265 
00266 // Insert(rOtherTimeConstraint)
00267 void TimeConstraint::Insert(const TimeConstraint& rOtherTimeConstraint) {
00268   FD_DC("TimeConstraint(" << this << ")::Insert(" << rOtherTimeConstraint.ToString() << ")");
00269   // HELPERS
00270   Iterator it;    
00271   // ALGORITHM
00272   if(mpClockSymbolTable != rOtherTimeConstraint.mpClockSymbolTable) {
00273     FD_ERR("TimeConstraint::Insert "
00274      << "SymbolTable mismatch aka not implemented!!");
00275     abort();
00276   }
00277   for(it = rOtherTimeConstraint.Begin(); it != rOtherTimeConstraint.End(); it++) {
00278     Insert(*it);
00279   }
00280 }
00281 
00282 // ClockConstraints()
00283 std::set<ElemConstraint> TimeConstraint::ClockConstraints(void) const {
00284   return mClockConstraints;
00285 }
00286 
00287 
00288 // EraseByClock(clock)
00289 bool TimeConstraint::EraseByClock(Idx clock) {
00290   FD_DC("TimeConstraint(" << this << ")::EraseByClock(" << clock << ") const");
00291   // HELPERS
00292   iterator lit,uit;
00293     
00294   // ALGORITHM
00295   lit= mClockConstraints.lower_bound(ElemConstraint(clock,ElemConstraint::GreaterEqual,0));
00296   uit= mClockConstraints.lower_bound(ElemConstraint(clock+1,ElemConstraint::GreaterEqual,0));
00297 
00298   if(lit==mClockConstraints.end()) 
00299     return false;
00300  
00301   mClockConstraints.erase(lit,uit);
00302   return true;
00303 }
00304 
00305 
00306 // Erase(it)
00307 TimeConstraint::Iterator TimeConstraint::Erase(Iterator it) {
00308   FD_DC("TimeConstraint(" << this << ")::Erase(" << it->Str() << ") const");
00309   if(it==End()) return it;
00310   iterator del= it; //cit
00311   it++;
00312   mClockConstraints.erase(del);
00313   return it;
00314 }
00315 
00316 
00317 // Erase(rElemConstr)
00318 bool TimeConstraint::Erase(const ElemConstraint& rElemConstr) {
00319   FD_DC("TimeConstraint(" << this << ")::Erase(" << rElemConstr.Str() << ") const");
00320   // HELPERS
00321   iterator it;
00322   // ALGORITHM
00323   it = mClockConstraints.find(rElemConstr);
00324   if(it == End()) return false;
00325   mClockConstraints.erase(it);
00326   return true;
00327 }
00328 
00329 // Erase(clock, op, timeconst)
00330 bool TimeConstraint::Erase(Idx clockindex, Operator op, const tpTime::Type timeconst) {
00331   FD_DC("TimeConstraint(" << this << ")::Erase(" 
00332   << clockindex << " " << ElemConstraint::OperatorName(op) << " " << timeconst << ")");
00333   ElemConstraint newconstr(clockindex,op,timeconst);
00334   return Erase(newconstr);
00335 }
00336 
00337 
00338 // Erase(clock, op, timeconst)
00339 bool TimeConstraint::Erase(const std::string& clockname,  Operator op, const tpTime::Type timeconst) 
00340 {
00341   FD_DC("TimeConstraint(" << this << ")::Erase(\"" 
00342   << clockname << "\" " << ElemConstraint::OperatorName(op) << " " << timeconst << ")");
00343   Idx clockindex = ClockIndex(clockname);
00344   return Erase(clockindex,op,timeconst);
00345 }
00346 
00347 // Exists(rElemConstr)
00348 bool TimeConstraint::Exists(const ElemConstraint& rElemConstr) const {
00349   FD_DC("TimeConstraint(" << this << ")::ExistsElConstr(" << rElemConstr.Str() << ") const");
00350   // HELPERS
00351   Iterator it;
00352   // ALGORITHM
00353   it = mClockConstraints.find(rElemConstr); 
00354   return (it != End()) ;
00355 }
00356 
00357 
00358 // Deletes all ElemConstraints
00359 void TimeConstraint::Clear(void) {
00360   FD_DC("TimeConstraint(" << this << ")::Clear() const");
00361   mClockConstraints.clear();
00362 }
00363 
00364 
00365 
00366 // Iterator Begin() const
00367 TimeConstraint::Iterator TimeConstraint::Begin(void) const {
00368   return mClockConstraints.begin();
00369 }
00370 
00371 
00372 // iterator End() const
00373 TimeConstraint::Iterator TimeConstraint::End(void) const {
00374   return mClockConstraints.end();
00375 }
00376 
00377 // reverse iterator RBegin()
00378 TimeConstraint::RIterator TimeConstraint::RBegin(void) const {
00379   return mClockConstraints.rbegin();
00380 }
00381 
00382 // reverse iterator REnd() const
00383 TimeConstraint::RIterator TimeConstraint::REnd(void) const {
00384   return mClockConstraints.rend();
00385 }
00386 
00387 // iterator Begin(clock) const
00388 TimeConstraint::Iterator TimeConstraint::Begin(Idx clock) const {
00389   return mClockConstraints.lower_bound(ElemConstraint(clock,ElemConstraint::GreaterEqual,0));
00390 }
00391 
00392 // iterator End(clock) const
00393 TimeConstraint::Iterator TimeConstraint::End(Idx clock) const {
00394   return mClockConstraints.lower_bound(ElemConstraint(clock+1,ElemConstraint::GreaterEqual,0));
00395 }
00396 
00397 // returns ClockSet filled with clocks used by ElemConstraints
00398 ClockSet TimeConstraint::ActiveClocks(void) const {
00399   FD_DC("TimeConstraint(" << this << ")::ActiveClocks() const");
00400   //Helpers
00401   ClockSet result;
00402   result.SymbolTablep(mpClockSymbolTable);
00403   Iterator it;
00404   // Algorithm
00405   for(it = Begin(); it != End(); it++) 
00406     result.Insert(it->Clock());
00407   return result;
00408 }
00409 
00410 // valid timeinterval for given clock 
00411 TimeInterval TimeConstraint::Interval(const std::string& clockname) const{
00412   Idx clockindex = ClockIndex(clockname);
00413   return Interval(clockindex);
00414 }
00415 
00416 // valid timeinterval for given clock 
00417 TimeInterval TimeConstraint::Interval(Idx clockindex) const{
00418   FD_DC("TimeConstraint(" << this << ")::Interval(" << clockindex <<") const");
00419   TimeInterval res;
00420   TimeInterval tint; 
00421   Iterator it;
00422   for(it = Begin(clockindex); it != End(clockindex); it++) {
00423     FD_DC("TimeConstraint(" << this << ")::Interval: elemconstraint: " << it->Str());
00424     tint.SetFull();
00425     if(it->CompOperator() == ElemConstraint::LessThan) {
00426       tint.UB(it->TimeConstant());
00427       tint.UBincl(false);
00428     }
00429     if(it->CompOperator() == ElemConstraint::LessEqual) {
00430       tint.UB(it->TimeConstant());
00431       tint.UBincl(true);
00432     }
00433     if(it->CompOperator() == ElemConstraint::GreaterThan) {
00434       tint.LB(it->TimeConstant());
00435       tint.LBincl(false);
00436     }
00437     if(it->CompOperator() == ElemConstraint::GreaterEqual) {
00438       tint.LB(it->TimeConstant());
00439       tint.LBincl(true);
00440     }
00441     FD_DC("TimeConstraint(" << this << ")::Interval: interval: " << tint.Str());
00442     res.Intersect(tint);
00443   }
00444   return res;
00445 }
00446  
00447 
00448 // set valid timeinterval for given clock 
00449 void TimeConstraint::Interval(const std::string& clockname, const TimeInterval& rInterval) {
00450   Idx clockindex = InsClock(clockname);
00451   Interval(clockindex,rInterval);
00452 }
00453 
00454 // set valid timeinterval for given clock 
00455 void TimeConstraint::Interval(Idx clockindex, const TimeInterval& rInterval) {
00456   FD_DC("TimeConstraint(" << this << ")::Interval(" << clockindex <<", " << rInterval.Str() << ") ");
00457   EraseByClock(clockindex);
00458   if(rInterval.LBinf()==false) {
00459     ElemConstraint newconstraint;
00460     newconstraint.Clock(clockindex);
00461     if(rInterval.LBincl())
00462       newconstraint.CompOperator(ElemConstraint::GreaterEqual);
00463     else
00464       newconstraint.CompOperator(ElemConstraint::GreaterThan);
00465     newconstraint.TimeConstant(rInterval.LB());
00466     Insert(newconstraint);
00467   }
00468   if(rInterval.UBinf()==false) {
00469     ElemConstraint newconstraint;
00470     newconstraint.Clock(clockindex);
00471     if(rInterval.UBincl())
00472       newconstraint.CompOperator(ElemConstraint::LessEqual);
00473     else
00474       newconstraint.CompOperator(ElemConstraint::LessThan);
00475     newconstraint.TimeConstant(rInterval.UB());
00476     Insert(newconstraint);
00477   }
00478 }
00479 
00480 
00481 // Minimize()
00482 void TimeConstraint::Minimize(void) {
00483   ClockSet aclocks=ActiveClocks();
00484   ClockSet::Iterator cit;
00485   for(cit=aclocks.Begin(); cit != aclocks.End(); cit++) {
00486     TimeInterval tint=Interval(*cit);
00487     Interval(*cit, tint);
00488   }
00489 }
00490 
00491 // Write()
00492 void TimeConstraint::Write(void) const {
00493   TokenWriter tw(TokenWriter::Stdout);
00494   Write(tw);
00495 }
00496 
00497 // Write(rFilename, rLabel, openmode)
00498 void TimeConstraint::Write(const std::string& rFilename, const std::string& rLabel,
00499          std::ios::openmode openmode) const {
00500   try {
00501     TokenWriter tw(rFilename, openmode);
00502     Write(tw, rLabel);
00503   }
00504   catch (std::ios::failure&) {
00505     std::stringstream errstr;
00506     errstr << "Exception opening/writing file \"" << rFilename << "\"";
00507     throw Exception("TimeConstraint::Write", errstr.str(), 2);
00508   }
00509 }
00510 
00511 // Write(tw)
00512 void TimeConstraint::Write(TokenWriter& tw) const {
00513   Write(tw, Name());
00514 }
00515 
00516 
00517 // Write(tw, rLabel)
00518 void TimeConstraint::Write(TokenWriter& tw, const std::string& rLabel) const {
00519   Token token;
00520   Iterator it;
00521   int oldcolumns = tw.Columns();
00522   tw.Columns(3);
00523   tw.WriteBegin(rLabel);
00524   for (it = Begin(); it != End(); ++it) {
00525     // 1. clock
00526     if(ClockName(it->Clock()) != "") {
00527       token.SetString(ClockName(it->Clock()));
00528       tw << token;
00529     } else {
00530       token.SetInteger(it->Clock());
00531       tw << token;
00532     }
00533     // 2. operator
00534     token.SetString(ElemConstraint::OperatorName(it->CompOperator()));
00535     tw << token;
00536     // 3. timeconst
00537     token.SetFloat((double) it->TimeConstant());
00538     tw << token;      
00539   }
00540   tw.WriteEnd(rLabel);
00541   tw.Columns(oldcolumns);
00542 }
00543 
00544 
00545 // ToString()
00546 std::string TimeConstraint::ToString(void) const {
00547   TokenWriter tw(TokenWriter::String);
00548   Write(tw);
00549   return tw.Str();
00550 }
00551 
00552 
00553 // DWrite()
00554 void TimeConstraint::DWrite(void) const {
00555   TokenWriter tw(TokenWriter::Stdout);
00556   DWrite(tw);
00557 }
00558 
00559 // DWrite(tw)
00560 void TimeConstraint::DWrite(TokenWriter& tw) const {
00561   Token token;
00562   Iterator it;
00563   tw.WriteBegin(Name());
00564   for (it = Begin(); it != End(); ++it) {
00565     tw << EStr(*it);
00566   }
00567   tw.WriteEnd(Name());
00568 }
00569 
00570 // Read(rFilename, rLabel)
00571 void TimeConstraint::Read(const std::string& rFilename, const std::string& rLabel) {
00572   TokenReader tr(rFilename);
00573   Read(tr,rLabel);
00574 }
00575 
00576 // Read(rTr, rLabel)
00577 void TimeConstraint::Read(TokenReader& rTr, const std::string& rLabel) {
00578   Clear();
00579   Name(rLabel);
00580   rTr.SeekBegin(rLabel);
00581  
00582   std::string clockname;
00583   tpTime::Type  timeconst;
00584   ElemConstraint::Operator compop;
00585   Token token;
00586   while(rTr.Peek(token)) {
00587     // 0. check for end
00588     if (token.Type() == Token::End) {
00589       break;
00590     }
00591     // 1. read clock
00592     rTr >> token;
00593     if (token.Type() != Token::String) {
00594       std::stringstream errstr;
00595       errstr << "Invalid clock" << rTr.FileLine();
00596       throw Exception("TimeConstraint::Read", errstr.str(), 56);
00597     }    
00598     clockname=token.StringValue();
00599     // 2. read operator
00600     rTr >> token;
00601     if (token.Type() != Token::String) {
00602       std::stringstream errstr;
00603       errstr << "Invalid operator" << rTr.FileLine();
00604       throw Exception("TimeConstraint::Read", errstr.str(), 56);
00605     }    
00606     if(token.StringValue() == "LE") {
00607       compop = ElemConstraint::LessEqual;
00608     } else if(token.StringValue() == "GE") {
00609       compop = ElemConstraint::GreaterEqual;
00610     } else if(token.StringValue() == "LT") {
00611       compop = ElemConstraint::LessThan;
00612     } else if(token.StringValue() == "GT") {
00613       compop = ElemConstraint::GreaterThan; 
00614     } else {
00615       std::stringstream errstr;
00616       errstr << "Invalid operator value " << rTr.FileLine();
00617       throw Exception("TimedTransSet::ReadTimeConstraint", errstr.str(), 56);
00618     }
00619     // 3. read timeconst
00620     rTr >> token;
00621     if ((token.Type() != Token::Integer) && (token.Type() != Token::Float)) {
00622       std::stringstream errstr;
00623       errstr << "Invalid timeconstant" << rTr.FileLine();
00624       throw Exception("TimeConstraint::Read", errstr.str(), 56);
00625     }    
00626     timeconst=(tpTime::Type) token.FloatValue();
00627     // 4. set constraint
00628     Insert(clockname,compop,timeconst);
00629   } // while not end
00630   rTr.SeekEnd(rLabel);
00631 }
00632 
00633 
00634 // End Implementation of TimeConstraint
00635 
00636 
00637 
00638 } // namespace faudes

Generated on Mon Nov 10 08:13:15 2008 for libFAUDES 2.11v by  doxygen 1.4.4