tp_timeconstraint.cpp
Go to the documentation of this file.
1 /* tp_timecontraint.cpp -- model of timeconstraints in timed automata */
2 
3 
4 /* Timeplugin for FAU Discrete Event Systems Library (libfaudes)
5 
6  Copyright (C) 2006 B Schlein
7  Copyright (C) 2007 Thomas Moor
8  Exclusive copyright is granted to Klaus Schmidt
9 
10 */
11 
12 
13 
14 #include "tp_timeconstraint.h"
15 
16 namespace faudes {
17 
18 
19 /********************************************************************
20 
21  Implementation of ClockSet
22 
23 ********************************************************************/
24 
25 
26 // std faudes type (cannot do New() with macro)
27 FAUDES_TYPE_IMPLEMENTATION_COPY(Void,ClockSet,NameSet)
28 FAUDES_TYPE_IMPLEMENTATION_CAST(Void,ClockSet,NameSet)
29 FAUDES_TYPE_IMPLEMENTATION_ASSIGN(Void,ClockSet,NameSet)
30 FAUDES_TYPE_IMPLEMENTATION_EQUAL(Void,ClockSet,NameSet)
31 
32 // ClockSet::msClockSymbolTable (static)
33 SymbolTable ClockSet::msSymbolTable;
34 
35 // ClockSet(void);
36 ClockSet::ClockSet(void) : NameSet() {
37  // overwrite default static symboltable
38  mpSymbolTable= &msSymbolTable;
39  NameSet::Name("Clocks");
40  FD_DC("ClockSet("<<this<<")::ClockSet() with csymtab "<< SymbolTablep());
41 }
42 
43 // ClockSet(clockset)
44 ClockSet::ClockSet(const ClockSet& rOtherSet) : NameSet(rOtherSet) {
45  FD_DC("ClockSet(" << this << ")::ClockSet(rOtherSet " << &rOtherSet << ")");
46 }
47 
48 // ClockSet(file);
49 ClockSet::ClockSet(const std::string& rFilename, const std::string& rLabel) : NameSet() {
50  // overwrite default static symboltable
52  // read file
53  NameSet::Read(rFilename,rLabel);
54 }
55 
56 // Clockset::New()
57 ClockSet* ClockSet::New(void) const {
58  ClockSet* res = new ClockSet();
60  return res;
61 }
62 
63 // DoAssign()
64 void ClockSet::DoAssign(const ClockSet& rSourceSet) {
65  // call base
66  NameSet::DoAssign(rSourceSet);
67 }
68 
69 // DoEqual()
70 bool ClockSet::DoEqual(const ClockSet& rOtherSet) const {
71  // call base
72  return NameSet::DoEqual(rOtherSet);
73 }
74 
75 // ClockSet::StaticSymbolTablep
77  return &msSymbolTable;
78 }
79 
80 
81 
82 
83 
84 /********************************************************************
85 
86  Implementation of ElemConstraint
87 
88 ********************************************************************/
89 
90 
91 // helper (conversion from operatorname to string
93  switch(op){
94  case LessThan: return "LT";
95  case GreaterThan: return "GT";
96  case LessEqual: return "LE";
97  case GreaterEqual: return "GE";
98  }
99  return "Inalid";
100 }
101 
102 
103 // Constructor
105  Set(0,LessThan,0);
106 }
107 
108 // Constructor
110  Idx clockindex, Operator op, const tpTime::Type timeconst) {
111  Set(clockindex,op,timeconst);
112 }
113 
114 
115 // Set(clockindex, op, timeconst)
116 void ElemConstraint::Set(Idx clockindex, Operator op, const tpTime::Type timeconst) {
117  mClockIndex = clockindex;
118  mCompOperator = op;
119  mTimeConstant = timeconst;
120 }
121 
122 // Clock(clockindex)
124  mClockIndex=clockindex;
125  return mClockIndex;
126 }
127 
128 // Clock()
130  return mClockIndex;
131 }
132 
133 // CompOperator(newOp)
135  mCompOperator = newOp;
136 }
137 
138 
139 // CompOperator()
141  return mCompOperator;
142 }
143 
144 
145 // TimeConstant(newTimeConst)
147  mTimeConstant = newTimeConst;
148 }
149 
150 // TimeConstant()
152  return mTimeConstant;
153 }
154 
155 // Str() const
156 std::string ElemConstraint::Str(void) const {
157  std::stringstream resstream;
158  resstream << "(" << mClockIndex << " "
159  << OperatorName(mCompOperator) << " " << mTimeConstant << ")";
160  std::string result = resstream.str();
161  return result;
162 }
163 
164 // operator==
165 bool ElemConstraint::operator== (const ElemConstraint & otherClockConstraint) const {
166  return ( mClockIndex == otherClockConstraint.mClockIndex
167  && mCompOperator == otherClockConstraint.mCompOperator
168  && mTimeConstant == otherClockConstraint.mTimeConstant );
169 }
170 
171 // operator!=
172 bool ElemConstraint::operator!= (const ElemConstraint & otherClockConstraint) const {
173  return !(operator==(otherClockConstraint));
174 }
175 
176 // operator <
177 bool ElemConstraint::operator < (const ElemConstraint& otherElemConstraint) const {
178  if (mClockIndex < otherElemConstraint.mClockIndex) return true;
179  if (mClockIndex > otherElemConstraint.mClockIndex) return false;
180  if (mCompOperator < otherElemConstraint.mCompOperator) return true;
181  if (mCompOperator > otherElemConstraint.mCompOperator) return false;
182  if (mTimeConstant < otherElemConstraint.mTimeConstant) return true;
183  return false;
184 }
185 
186 
187 /********************************************************************
188 
189  Implementation of TimeConstraint
190 
191 ********************************************************************/
192 
193 
194 
195 // empty constructor
197  FD_DC("TimeConstraint(" << this << ")::TimeConstraint()");
199  mName="TimeConstraint";
200 }
201 
202 // read file constructor
203 TimeConstraint::TimeConstraint(const std::string& rFilename, const std::string& rLabel) {
204  FD_DC("TimeConstraint(" << this << ")::TimeConstraint(" << rFilename << ")");
206  Read(rFilename, rLabel);
207 }
208 
209 // constructor
210 TimeConstraint::TimeConstraint(const TimeConstraint& rOtherTimeConstraint) {
211  FD_DC("TimeConstraint(" << this << ")::TimeConstraint(other)");
212  mName=rOtherTimeConstraint.mName;
213  mpClockSymbolTable= rOtherTimeConstraint.mpClockSymbolTable;
214  mClockConstraints = rOtherTimeConstraint.ClockConstraints();
215 }
216 
217 
218 // Destructor
220 }
221 
222 // ClockSymbolTablep()
224  return mpClockSymbolTable;
225 }
226 
227 // ClockSymbolTablep(pSymTab)
229  if(mClockConstraints.empty()) {
230  mpClockSymbolTable=pSymTab;
231  } else {
232  // TODO: implement reindex
233  FD_ERR("TimeConstraint::SymboltTable(pSymTab): "
234  << "set SymbolTable not implemented!!");
235  abort();
236  }
237 }
238 
239 // Empty()
240 bool TimeConstraint::Empty(void) const {
241  return mClockConstraints.empty();
242 }
243 
244 // Size of set of ElemConstraints
246  return (Idx)mClockConstraints.size();
247 }
248 
249 // InsClock()
250 Idx TimeConstraint::InsClock(const std::string& rClockName) const {
251  return mpClockSymbolTable->InsEntry(rClockName);
252 }
253 
254 // ClockName(clockindex)
255 std::string TimeConstraint::ClockName(Idx clockindex) const {
256  return mpClockSymbolTable->Symbol(clockindex);
257 }
258 
259 // ClockIndex(clockname)
260 Idx TimeConstraint::ClockIndex(const std::string& rClockName) const {
261  return mpClockSymbolTable->Index(rClockName);
262 }
263 
264 
265 // EStr(ElemConstraint) const
266 std::string TimeConstraint::EStr(const ElemConstraint& rElemConstraint) const {
267  std::stringstream resstream;
268  resstream << "(" << ClockName(rElemConstraint.Clock()) << "[" << rElemConstraint.Clock()
269  << "] " << ElemConstraint::OperatorName(rElemConstraint.CompOperator()) << " "
270  << rElemConstraint.TimeConstant() << ")";
271  std::string result = resstream.str();
272  return result;
273 }
274 
275 // Insert(rNewConstr)
277  FD_DC("TimeConstraint(" << this << ")::Insert(" << rNewConstr.Str() << ")");
278  if(rNewConstr.Clock()<=0 || ClockName(rNewConstr.Clock())=="") {
279  std::stringstream errstr;
280  errstr << "Invalid ElemConstraint: \"" << rNewConstr.Str();
281  throw Exception("TimeConstraint::Insert", errstr.str(), 55);
282  }
283  return mClockConstraints.insert(rNewConstr).first;
284 }
285 
286 // Insert(clock, op, timeconst)
288  FD_DC("TimeConstraint(" << this << ")::Insert("
289  << clockindex << " " << ElemConstraint::OperatorName(op) << " " << timeconst << ")");
290  ElemConstraint newconstr(clockindex,op,timeconst);
291  return Insert(newconstr);
292 }
293 
294 
295 // Insert(clock, op, timeconst)
297  const std::string clockname,
298  Operator op,
299  const tpTime::Type timeconst)
300 {
301  FD_DC("TimeConstraint(" << this << ")::Insert(\""
302  << clockname << "\" " << ElemConstraint::OperatorName(op) << " " << timeconst << ")");
303  Idx clockindex = InsClock(clockname);
304  return Insert(clockindex,op,timeconst);
305 }
306 
307 // Insert(rNewConstraints)
308 void TimeConstraint::Insert(const std::list<ElemConstraint>& rNewConstraints) {
309  FD_DC("TimeConstraint(" << this << ")::Insert(const std::list<ElemConstraint>&)");
310  // HELPERS
311  std::list<ElemConstraint>::const_iterator it;
312  // ALGORITHM
313  for(it = rNewConstraints.begin(); it != rNewConstraints.end(); it++)
314  Insert(*it);
315 }
316 
317 
318 // Insert(rOtherTimeConstraint)
319 void TimeConstraint::Insert(const TimeConstraint& rOtherTimeConstraint) {
320  FD_DC("TimeConstraint(" << this << ")::Insert(" << rOtherTimeConstraint.ToString() << ")");
321  // HELPERS
322  Iterator it;
323  // ALGORITHM
324  if(mpClockSymbolTable != rOtherTimeConstraint.mpClockSymbolTable) {
325  FD_ERR("TimeConstraint::Insert "
326  << "SymbolTable mismatch aka not implemented!!");
327  abort();
328  }
329  for(it = rOtherTimeConstraint.Begin(); it != rOtherTimeConstraint.End(); it++) {
330  Insert(*it);
331  }
332 }
333 
334 // ClockConstraints()
335 std::set<ElemConstraint> TimeConstraint::ClockConstraints(void) const {
336  return mClockConstraints;
337 }
338 
339 
340 // EraseByClock(clock)
342  FD_DC("TimeConstraint(" << this << ")::EraseByClock(" << clock << ") const");
343  // HELPERS
344  iterator lit,uit;
345 
346  // ALGORITHM
349 
350  if(lit==mClockConstraints.end())
351  return false;
352 
353  mClockConstraints.erase(lit,uit);
354  return true;
355 }
356 
357 
358 // Erase(it)
360  FD_DC("TimeConstraint(" << this << ")::Erase(" << it->Str() << ") const");
361  if(it==End()) return it;
362  iterator del= it; //cit
363  it++;
364  mClockConstraints.erase(del);
365  return it;
366 }
367 
368 
369 // Erase(rElemConstr)
370 bool TimeConstraint::Erase(const ElemConstraint& rElemConstr) {
371  FD_DC("TimeConstraint(" << this << ")::Erase(" << rElemConstr.Str() << ") const");
372  // HELPERS
373  iterator it;
374  // ALGORITHM
375  it = mClockConstraints.find(rElemConstr);
376  if(it == End()) return false;
377  mClockConstraints.erase(it);
378  return true;
379 }
380 
381 // Erase(clock, op, timeconst)
382 bool TimeConstraint::Erase(Idx clockindex, Operator op, const tpTime::Type timeconst) {
383  FD_DC("TimeConstraint(" << this << ")::Erase("
384  << clockindex << " " << ElemConstraint::OperatorName(op) << " " << timeconst << ")");
385  ElemConstraint newconstr(clockindex,op,timeconst);
386  return Erase(newconstr);
387 }
388 
389 
390 // Erase(clock, op, timeconst)
391 bool TimeConstraint::Erase(const std::string& clockname, Operator op, const tpTime::Type timeconst)
392 {
393  FD_DC("TimeConstraint(" << this << ")::Erase(\""
394  << clockname << "\" " << ElemConstraint::OperatorName(op) << " " << timeconst << ")");
395  Idx clockindex = ClockIndex(clockname);
396  return Erase(clockindex,op,timeconst);
397 }
398 
399 // Exists(rElemConstr)
400 bool TimeConstraint::Exists(const ElemConstraint& rElemConstr) const {
401  FD_DC("TimeConstraint(" << this << ")::ExistsElConstr(" << rElemConstr.Str() << ") const");
402  // HELPERS
403  Iterator it;
404  // ALGORITHM
405  it = mClockConstraints.find(rElemConstr);
406  return (it != End()) ;
407 }
408 
409 
410 // Deletes all ElemConstraints
412  FD_DC("TimeConstraint(" << this << ")::Clear() const");
413  mClockConstraints.clear();
414 }
415 
416 
417 
418 // Iterator Begin() const
420  return mClockConstraints.begin();
421 }
422 
423 
424 // iterator End() const
426  return mClockConstraints.end();
427 }
428 
429 // reverse iterator RBegin()
431  return mClockConstraints.rbegin();
432 }
433 
434 // reverse iterator REnd() const
436  return mClockConstraints.rend();
437 }
438 
439 // iterator Begin(clock) const
442 }
443 
444 // iterator End(clock) const
446  return mClockConstraints.lower_bound(ElemConstraint(clock+1,ElemConstraint::GreaterEqual,0));
447 }
448 
449 // returns ClockSet filled with clocks used by ElemConstraints
451  FD_DC("TimeConstraint(" << this << ")::ActiveClocks() const");
452  //Helpers
453  ClockSet result;
455  Iterator it;
456  // Algorithm
457  for(it = Begin(); it != End(); it++)
458  result.Insert(it->Clock());
459  return result;
460 }
461 
462 // valid timeinterval for given clock
463 TimeInterval TimeConstraint::Interval(const std::string& clockname) const{
464  Idx clockindex = ClockIndex(clockname);
465  return Interval(clockindex);
466 }
467 
468 // valid timeinterval for given clock
470  FD_DC("TimeConstraint(" << this << ")::Interval(" << clockindex <<") const");
471  TimeInterval res;
472  TimeInterval tint;
473  Iterator it;
474  for(it = Begin(clockindex); it != End(clockindex); it++) {
475  FD_DC("TimeConstraint(" << this << ")::Interval: elemconstraint: " << it->Str());
476  tint.SetFull();
477  if(it->CompOperator() == ElemConstraint::LessThan) {
478  tint.UB(it->TimeConstant());
479  tint.UBincl(false);
480  }
481  if(it->CompOperator() == ElemConstraint::LessEqual) {
482  tint.UB(it->TimeConstant());
483  tint.UBincl(true);
484  }
485  if(it->CompOperator() == ElemConstraint::GreaterThan) {
486  tint.LB(it->TimeConstant());
487  tint.LBincl(false);
488  }
489  if(it->CompOperator() == ElemConstraint::GreaterEqual) {
490  tint.LB(it->TimeConstant());
491  tint.LBincl(true);
492  }
493  FD_DC("TimeConstraint(" << this << ")::Interval: interval: " << tint.Str());
494  res.Intersect(tint);
495  }
496  return res;
497 }
498 
499 
500 // set valid timeinterval for given clock
501 void TimeConstraint::Interval(const std::string& clockname, const TimeInterval& rInterval) {
502  Idx clockindex = InsClock(clockname);
503  Interval(clockindex,rInterval);
504 }
505 
506 // set valid timeinterval for given clock
507 void TimeConstraint::Interval(Idx clockindex, const TimeInterval& rInterval) {
508  FD_DC("TimeConstraint(" << this << ")::Interval(" << clockindex <<", " << rInterval.Str() << ") ");
509  EraseByClock(clockindex);
510  if(rInterval.LBinf()==false) {
511  ElemConstraint newconstraint;
512  newconstraint.Clock(clockindex);
513  if(rInterval.LBincl())
515  else
517  newconstraint.TimeConstant(rInterval.LB());
518  Insert(newconstraint);
519  }
520  if(rInterval.UBinf()==false) {
521  ElemConstraint newconstraint;
522  newconstraint.Clock(clockindex);
523  if(rInterval.UBincl())
525  else
526  newconstraint.CompOperator(ElemConstraint::LessThan);
527  newconstraint.TimeConstant(rInterval.UB());
528  Insert(newconstraint);
529  }
530 }
531 
532 
533 // Minimize()
535  ClockSet aclocks=ActiveClocks();
536  ClockSet::Iterator cit;
537  for(cit=aclocks.Begin(); cit != aclocks.End(); cit++) {
538  TimeInterval tint=Interval(*cit);
539  Interval(*cit, tint);
540  }
541 }
542 
543 // operator==
544 bool TimeConstraint::operator== (const TimeConstraint & rOther) const {
545  ClockSet aclocks=ActiveClocks();
546  aclocks.InsertSet(rOther.ActiveClocks());
547  ClockSet::Iterator cit;
548  for(cit=aclocks.Begin(); cit != aclocks.End(); cit++) {
549  TimeInterval tint=Interval(*cit);
550  if(rOther.Interval(*cit)!=tint) return false;
551  }
552  return true;
553 }
554 
555 // operator!=
556 bool TimeConstraint::operator!= (const TimeConstraint & rOther) const {
557  return !(operator==(rOther));
558 }
559 
560 
561 // Write()
562 void TimeConstraint::Write(void) const {
564  Write(tw);
565 }
566 
567 // Write(rFilename, rLabel, openmode)
568 void TimeConstraint::Write(const std::string& rFilename, const std::string& rLabel,
569  std::ios::openmode openmode) const {
570  try {
571  TokenWriter tw(rFilename, openmode);
572  Write(tw, rLabel);
573  }
574  catch (std::ios::failure&) {
575  std::stringstream errstr;
576  errstr << "Exception opening/writing file \"" << rFilename << "\"";
577  throw Exception("TimeConstraint::Write", errstr.str(), 2);
578  }
579 }
580 
581 // Write(tw)
583  Write(tw, Name());
584 }
585 
586 
587 // Write(tw, rLabel)
588 void TimeConstraint::Write(TokenWriter& tw, const std::string& rLabel) const {
589  Token token;
590  Iterator it;
591  int oldcolumns = tw.Columns();
592  tw.Columns(3);
593  tw.WriteBegin(rLabel);
594  for (it = Begin(); it != End(); ++it) {
595  // 1. clock
596  if(ClockName(it->Clock()) != "") {
597  token.SetString(ClockName(it->Clock()));
598  tw << token;
599  } else {
600  token.SetInteger(it->Clock());
601  tw << token;
602  }
603  // 2. operator
604  token.SetString(ElemConstraint::OperatorName(it->CompOperator()));
605  tw << token;
606  // 3. timeconst
607  token.SetFloat((Float) it->TimeConstant());
608  tw << token;
609  }
610  tw.WriteEnd(rLabel);
611  tw.Columns(oldcolumns);
612 }
613 
614 
615 // ToString()
616 std::string TimeConstraint::ToString(void) const {
618  Write(tw);
619  return tw.Str();
620 }
621 
622 
623 // DWrite()
624 void TimeConstraint::DWrite(void) const {
626  DWrite(tw);
627 }
628 
629 // DWrite(tw)
631  Token token;
632  Iterator it;
633  tw.WriteBegin(Name());
634  for (it = Begin(); it != End(); ++it) {
635  tw << EStr(*it);
636  }
637  tw.WriteEnd(Name());
638 }
639 
640 // Read(rFilename, rLabel)
641 void TimeConstraint::Read(const std::string& rFilename, const std::string& rLabel) {
642  TokenReader tr(rFilename);
643  Read(tr,rLabel);
644 }
645 
646 // Read(rTr, rLabel)
647 void TimeConstraint::Read(TokenReader& rTr, const std::string& rLabel) {
648  Clear();
649  Name(rLabel);
650  rTr.ReadBegin(rLabel);
651 
652  std::string clockname;
653  tpTime::Type timeconst;
655  Token token;
656  while(rTr.Peek(token)) {
657  // 0. check for end
658  if (token.Type() == Token::End) {
659  break;
660  }
661  // 1. read clock
662  rTr >> token;
663  if (token.Type() != Token::String) {
664  std::stringstream errstr;
665  errstr << "Invalid clock" << rTr.FileLine();
666  throw Exception("TimeConstraint::Read", errstr.str(), 56);
667  }
668  clockname=token.StringValue();
669  // 2. read operator
670  rTr >> token;
671  if (token.Type() != Token::String) {
672  std::stringstream errstr;
673  errstr << "Invalid operator" << rTr.FileLine();
674  throw Exception("TimeConstraint::Read", errstr.str(), 56);
675  }
676  if(token.StringValue() == "LE") {
677  compop = ElemConstraint::LessEqual;
678  } else if(token.StringValue() == "GE") {
680  } else if(token.StringValue() == "LT") {
681  compop = ElemConstraint::LessThan;
682  } else if(token.StringValue() == "GT") {
683  compop = ElemConstraint::GreaterThan;
684  } else {
685  std::stringstream errstr;
686  errstr << "Invalid operator value " << rTr.FileLine();
687  throw Exception("TimedTransSet::ReadTimeConstraint", errstr.str(), 56);
688  }
689  // 3. read timeconst
690  rTr >> token;
691  if (!token.IsFloat()) {
692  std::stringstream errstr;
693  errstr << "Invalid timeconstant" << rTr.FileLine();
694  throw Exception("TimeConstraint::Read", errstr.str(), 56);
695  }
696  timeconst=(tpTime::Type) token.FloatValue();
697  // 4. set constraint
698  Insert(clockname,compop,timeconst);
699  } // while not end
700  rTr.ReadEnd(rLabel);
701 }
702 
703 
704 // End Implementation of TimeConstraint
705 
706 
707 
708 } // namespace faudes

libFAUDES 2.26g --- 2015.08.17 --- c++ api documentaion by doxygen