LearnTA  0.0.1
forward_regional_elementary_language.hh
1 
6 #pragma once
7 
8 #include <string>
9 #include <utility>
10 
11 #include "elementary_language.hh"
12 #include "fractional_order.hh"
13 #include "backward_regional_elementary_language.hh"
14 
15 namespace learnta {
24  protected:
25  FractionalOrder fractionalOrder;
26  public:
29 
31  ElementaryLanguage(std::move(elementary)), fractionalOrder(std::move(fractionalOrder)) {
32  assert(this->fractionalOrder.getSize() == this->wordSize() + 1);
33  }
34 
36 
38 
39  ForwardRegionalElementaryLanguage &operator=(const ForwardRegionalElementaryLanguage &language) = default;
40 
42 
47  std::vector<double> fractionalPart, accumulatedDuration;
48  fractionalPart.resize(timedWord.wordSize() + 1);
49  accumulatedDuration.resize(timedWord.wordSize() + 1);
50  accumulatedDuration.back() = timedWord.getDurations().back();
51  fractionalPart.back() = timedWord.getDurations().back() - std::floor(timedWord.getDurations().back());
52  for (int i = static_cast<int>(fractionalPart.size()) - 2; i >= 0; --i) {
53  accumulatedDuration.at(i) = accumulatedDuration.at(i + 1) + timedWord.getDurations().at(i);
54  fractionalPart.at(i) = accumulatedDuration.at(i);
55  fractionalPart.at(i) -= std::floor(fractionalPart.at(i));
56  }
57 
58  return {ElementaryLanguage{timedWord.getWord(), TimedCondition{accumulatedDuration}},
59  FractionalOrder{fractionalPart}};
60  }
61 
65  [[nodiscard]] ForwardRegionalElementaryLanguage successor(char action) const {
66  return {{this->word + action, this->timedCondition.extendN()}, fractionalOrder.extendN()};
67  }
68 
73  return {{this->word, this->timedCondition.successor(fractionalOrder.successorVariables())},
74  fractionalOrder.successor()};
75  }
76 
80  void successorAssign() {
81  this->timedCondition.successorAssign(fractionalOrder.successorVariables());
82  this->fractionalOrder.successorAssign();
83  }
84 
90  [[nodiscard]] bool hasEqualityN() const {
91  // By simplicity of the timed condition, we can check only the one side
92  return this->timedCondition.hasEqualityN();
93  }
94 
98  [[nodiscard]] std::optional<ForwardRegionalElementaryLanguage> immediatePrefix() const {
99  if (this->getWord().empty() && !this->getTimedCondition().hasPrefix()) {
100  // When no prefix exists
101  return std::nullopt;
102  } else if (this->getTimedCondition().hasPrefix()) {
103  // return the continuous prefix
104  return std::make_optional(ForwardRegionalElementaryLanguage{
105  {this->getWord(), this->getTimedCondition().prefix(this->fractionalOrder.predecessorVariables())},
106  this->fractionalOrder.predecessor()});
107  } else {
108  // return the discrete prefix
109  auto word = this->getWord();
110  word.pop_back();
111  return std::make_optional(ForwardRegionalElementaryLanguage{
112  {word, this->timedCondition.removeN()}, this->fractionalOrder.removeN()});
113  }
114  }
115 
119  [[nodiscard]] std::vector<ForwardRegionalElementaryLanguage> prefixes() const {
120  std::list<ForwardRegionalElementaryLanguage> resultList;
121  auto language = *this;
122  resultList.push_front(language);
123  auto next = language.immediatePrefix();
124 
125  while (next.has_value()) {
126  language = *next;
127  resultList.push_front(language);
128  next = language.immediatePrefix();
129  }
130 
131  std::vector<ForwardRegionalElementaryLanguage> result;
132  result.resize(resultList.size());
133  std::move(resultList.begin(), resultList.end(), result.begin());
134 
135  return result;
136  }
137 
146  // Check the preconditions
147  assert(prefix.isSimple());
148  assert(this->isSimple());
149  assert(this->word.compare(0, prefix.wordSize(), prefix.getWord()) == 0);
150  const auto prefixWord = prefix.sample();
151  ElementaryLanguage tmpLanguage = this->constrain(prefixWord);
152  const auto fullWord = tmpLanguage.sample();
153 
154  const std::size_t suffixWordSize = this->wordSize() - prefix.wordSize();
155  // Generate the word of the suffix
156  const std::string suffixWord = this->word.substr(prefix.wordSize(), suffixWordSize);
157  auto suffixDurations = fullWord.getDurations();
158  suffixDurations.erase(suffixDurations.begin(), suffixDurations.begin() + prefix.wordSize());
159  suffixDurations.front() -= prefixWord.getDurations().back();
160  // Generate the elementary language containing the suffix
161  const auto forward = fromTimedWord(TimedWord{suffixWord, suffixDurations});
162  // Construct the fractional order
163  std::vector<double> suffixDurationsFractional;
164  suffixDurationsFractional.resize(suffixDurations.size());
165  suffixDurationsFractional.front() = suffixDurations.front() - std::floor(suffixDurations.front());
166  for (std::size_t i = 1; i < suffixDurationsFractional.size(); ++i) {
167  suffixDurationsFractional.at(i) = suffixDurationsFractional.at(i - 1) + suffixDurations.at(i);
168  suffixDurationsFractional.at(i) -= std::floor(suffixDurationsFractional.at(i));
169  }
170  assert(std::all_of(suffixDurationsFractional.begin(), suffixDurationsFractional.end(),
171  [](const double fractional) {
172  return 0 <= fractional && fractional < 1;
173  }));
174 
175  return BackwardRegionalElementaryLanguage{ElementaryLanguage{forward.getWord(), forward.getTimedCondition()},
176  FractionalOrder(suffixDurationsFractional)};
177  }
178 
179  [[nodiscard]] ForwardRegionalElementaryLanguage applyResets(const TATransition::Resets &resets) const {
180  return fromTimedWord(ElementaryLanguage{this->word, this->timedCondition.applyResets(resets)}.sample());
181  }
182 
193  [[nodiscard]] ForwardRegionalElementaryLanguage applyResets(const std::string &newWord,
194  const TATransition::Resets &resets,
195  const std::size_t targetClockSize) const {
196  assert(newWord.size() + 1 == targetClockSize);
197  return fromTimedWord(ElementaryLanguage{newWord,
198  this->timedCondition.applyResets(resets, targetClockSize)}.sample());
199  }
200 
201  bool operator==(const ForwardRegionalElementaryLanguage &another) const {
202  return this->getWord() == another.getWord() && this->getTimedCondition() == another.getTimedCondition() &&
203  this->fractionalOrder == another.fractionalOrder;
204  }
205 
206  std::ostream &print(std::ostream &os) const {
207  os << "(" << this->getWord() << ", " << this->getTimedCondition() << ", " << this->fractionalOrder << ")";
208 
209  return os;
210  }
211 
212  [[nodiscard]] std::size_t hash_value() const {
213  return boost::hash_value(std::make_tuple(this->getWord(), this->getTimedCondition(),
214  this->fractionalOrder.hash_value()));
215  }
216  };
217 
218  static inline std::ostream &operator<<(std::ostream &os, const learnta::ForwardRegionalElementaryLanguage &lang) {
219  return lang.print(os);
220  }
221 
222  inline std::size_t hash_value(learnta::ForwardRegionalElementaryLanguage const &lang) {
223  return lang.hash_value();
224  }
225 }
A back regional elementary language.
Definition: backward_regional_elementary_language.hh:22
An elementary language.
Definition: elementary_language.hh:23
bool isSimple() const
Returns if this elementary language is simple.
Definition: elementary_language.hh:66
ElementaryLanguage constrain(const TimedWord &prefix) const
Constrain the valuation using a timed word.
Definition: elementary_language.hh:167
static ElementaryLanguage empty()
Construct the empty elementary language containing only 0.
Definition: elementary_language.hh:38
std::size_t wordSize() const
Returns the number of the events in this elementary language.
Definition: elementary_language.hh:73
TimedWord sample() const
Return a timed word in this elementary language.
Definition: elementary_language.hh:114
A forward regional elementary language.
Definition: forward_regional_elementary_language.hh:23
ForwardRegionalElementaryLanguage successor() const
Construct the continuous successor.
Definition: forward_regional_elementary_language.hh:72
BackwardRegionalElementaryLanguage suffix(const ForwardRegionalElementaryLanguage &prefix) const
Return the suffix s such that this \subseteq p \cdot s.
Definition: forward_regional_elementary_language.hh:145
ForwardRegionalElementaryLanguage successor(char action) const
Construct the discrete successor.
Definition: forward_regional_elementary_language.hh:65
ForwardRegionalElementaryLanguage applyResets(const std::string &newWord, const TATransition::Resets &resets, const std::size_t targetClockSize) const
Return the language after applying the given reset.
Definition: forward_regional_elementary_language.hh:193
ForwardRegionalElementaryLanguage()=default
Construct the empty language.
void successorAssign()
Construct the continuous successor.
Definition: forward_regional_elementary_language.hh:80
std::vector< ForwardRegionalElementaryLanguage > prefixes() const
Return the prefixes in the shorter to the longer order.
Definition: forward_regional_elementary_language.hh:119
static ForwardRegionalElementaryLanguage fromTimedWord(const TimedWord &timedWord)
Construct the fractional elementary language containing the given timed word.
Definition: forward_regional_elementary_language.hh:46
std::optional< ForwardRegionalElementaryLanguage > immediatePrefix() const
Return the immediate prefix if exists.
Definition: forward_regional_elementary_language.hh:98
bool hasEqualityN() const
Return if there is .
Definition: forward_regional_elementary_language.hh:90
Order on the fractional part of the variables.
Definition: fractional_order.hh:24
FractionalOrder extendN() const
Add another variable such that .
Definition: fractional_order.hh:142
FractionalOrder predecessor() const
Make it to be the predecessor.
Definition: fractional_order.hh:125
void successorAssign()
Make it to be the successor.
Definition: fractional_order.hh:94
size_t getSize() const
Returns the number of the variables.
Definition: fractional_order.hh:179
const std::deque< ClockVariables > & successorVariables() const
Return the variable to elapse.
Definition: fractional_order.hh:66
FractionalOrder removeN() const
Remove .
Definition: fractional_order.hh:153
std::deque< ClockVariables > predecessorVariables() const
Return the variable to backward-elapse.
Definition: fractional_order.hh:108
FractionalOrder successor() const
Make it to be the successor.
Definition: fractional_order.hh:77
A timed condition, a finite conjunction of inequalities of the form , where and .
Definition: timed_condition.hh:19
TimedCondition removeN() const
Remove .
Definition: timed_condition.hh:523
bool hasEqualityN() const
Return if there is .
Definition: timed_condition.hh:548
void successorAssign(const std::deque< ClockVariables > &variables)
Make a continuous successor by elapsing variables.
Definition: timed_condition.hh:391
TimedCondition successor(const std::deque< ClockVariables > &variables) const
Make a continuous successor by elapsing variables.
Definition: timed_condition.hh:367
TimedCondition prefix(const std::deque< ClockVariables > &variables) const
Make a continuous prefix.
Definition: timed_condition.hh:459
TimedCondition extendN() const
Add another variable such that .
Definition: timed_condition.hh:507
A timed word.
Definition: timed_word.hh:25
std::size_t wordSize() const
Return the number of the actions in this timed word.
Definition: timed_word.hh:150
Definition: experiment_runner.hh:23
Definition: external_transition_maker.hh:149