libmonaa  0.5.2
timed_automaton.hh
1 #pragma once
2 
3 #include <array>
4 #include <climits>
5 #include <memory>
6 #include <ostream>
7 #include <unordered_map>
8 #include <valarray>
9 #include <vector>
10 
11 #include "common_types.hh"
12 #include "constraint.hh"
13 
14 struct TATransition;
15 
19 struct TAState {
21  bool isMatch;
27  bool zeroDuration = false;
32  std::unordered_map<Alphabet, std::vector<TATransition>> next;
33  TAState(bool isMatch = false) : isMatch(isMatch) { next.clear(); }
34  TAState(bool isMatch,
35  std::unordered_map<Alphabet, std::vector<TATransition>> next)
36  : isMatch(isMatch), next(std::move(next)) {}
37 };
38 
42 struct TATransition {
46  std::vector<ClockVariables> resetVars;
48  std::vector<Constraint> guard;
49 };
50 
54 struct TimedAutomaton : public Automaton<TAState> {
55  using X = ConstraintMaker;
56  using TATransition = TATransition;
57  using State = ::TAState;
58 
60  std::vector<int> maxConstraints;
68  void deepCopy(
69  TimedAutomaton &dest,
70  std::unordered_map<TAState *, std::shared_ptr<TAState>> &old2new) const {
71  // copy states
72  old2new.reserve(stateSize());
73  dest.states.reserve(stateSize());
74  for (auto oldState : states) {
75  dest.states.emplace_back(std::make_shared<TAState>(*oldState));
76  old2new[oldState.get()] = dest.states.back();
77  }
78  // copy initial states
79  dest.initialStates.reserve(initialStates.size());
80  for (auto oldInitialState : initialStates) {
81  dest.initialStates.emplace_back(old2new[oldInitialState.get()]);
82  }
83  // modify dest of transitions
84  for (auto &state : dest.states) {
85  for (auto &edges : state->next) {
86  for (auto &edge : edges.second) {
87  auto oldTarget = edge.target;
88  edge.target = old2new[oldTarget].get();
89  }
90  }
91  }
93  }
95  inline size_t clockSize() const { return maxConstraints.size(); }
96 
102  bool isMember(const std::vector<std::pair<Alphabet, double>> &w) const {
103  std::vector<std::pair<TAState *, std::valarray<double>>> CStates;
104  CStates.reserve(initialStates.size());
105  for (const auto &s : initialStates) {
106  CStates.emplace_back(s.get(), std::valarray<double>(0.0, clockSize()));
107  }
108  for (std::size_t i = 0; i < w.size(); i++) {
109  std::vector<std::pair<TAState *, std::valarray<double>>> NextStates;
110  for (std::pair<TAState *, std::valarray<double>> &config : CStates) {
111  if (i > 0) {
112  config.second += w[i].second - w[i - 1].second;
113  } else {
114  config.second += w[i].second;
115  }
116  auto it = config.first->next.find(w[i].first);
117  if (it == config.first->next.end()) {
118  continue;
119  }
120  for (const auto &edge : it->second) {
121  if (std::all_of(edge.guard.begin(), edge.guard.end(),
122  [&](const Constraint &g) {
123  return g.satisfy(config.second[g.x]);
124  })) {
125  auto tmpConfig = config;
126  tmpConfig.first = edge.target;
127  if (tmpConfig.first) {
128  for (ClockVariables x : edge.resetVars) {
129  tmpConfig.second[x] = 0;
130  }
131  NextStates.emplace_back(std::move(tmpConfig));
132  }
133  }
134  }
135  }
136  CStates = std::move(NextStates);
137  }
138  return std::any_of(CStates.begin(), CStates.end(),
139  [](std::pair<const TAState *, std::valarray<double>> p) {
140  return p.first->isMatch;
141  });
142  }
143 };
144 
146 static inline std::ostream &operator<<(std::ostream &os,
147  const TimedAutomaton &TA) {
148  std::unordered_map<TAState *, bool> isInit;
149  std::unordered_map<TAState *, unsigned int> stateNumber;
150 
151  for (unsigned int i = 0; i < TA.states.size(); ++i) {
152  // Check if the state is initial for each state
153  isInit[TA.states.at(i).get()] =
154  std::find(TA.initialStates.begin(), TA.initialStates.end(),
155  TA.states.at(i)) != TA.initialStates.end();
156  // Assign a number for each state
157  stateNumber[TA.states.at(i).get()] = i + 1;
158  }
159  os << "digraph G {\n";
160 
161  for (std::shared_ptr<TAState> state : TA.states) {
162  os << " loc" << stateNumber.at(state.get())
163  << " [init=" << isInit.at(state.get()) << ", match=" << state->isMatch;
164  if (state->zeroDuration) {
165  os << ", zero_duration=" << state->zeroDuration;
166  }
167  os << "]\n";
168  }
169 
170  for (std::shared_ptr<TAState> source : TA.states) {
171  for (auto edges : source->next) {
172  for (TATransition edge : edges.second) {
173  TAState *target = edge.target;
174  os << " loc" << stateNumber.at(source.get()) << "->loc"
175  << stateNumber.at(target) << " [label=\"" << edges.first << "\"";
176  if (!edge.guard.empty()) {
177  os << ", guard=\"{";
178  bool isFirst = true;
179  for (const Constraint guard : edge.guard) {
180  if (!isFirst) {
181  os << ", ";
182  }
183  os << guard;
184  isFirst = false;
185  }
186  os << "}\"";
187  }
188  if (!edge.resetVars.empty()) {
189  os << ", reset=\"{";
190  bool isFirst = true;
191  for (const ClockVariables var : edge.resetVars) {
192  if (!isFirst) {
193  os << ", ";
194  }
195  os << int(var);
196  isFirst = false;
197  }
198  os << "}\"";
199  }
200  os << "]\n";
201  }
202  }
203  }
204  os << "}\n";
205  return os;
206 }
Definition: constraint.hh:73
An automaton.
Definition: common_types.hh:13
std::size_t stateSize() const
Returns the number of the states.
Definition: common_types.hh:22
std::vector< std::shared_ptr< State > > states
The states of this automaton.
Definition: common_types.hh:14
std::vector< std::shared_ptr< State > > initialStates
The initial states of this automaton.
Definition: common_types.hh:19
A constraint in a guard of transitions.
Definition: constraint.hh:16
A state of timed automata.
Definition: timed_automaton.hh:19
std::unordered_map< Alphabet, std::vector< TATransition > > next
An mapping of a character to the transitions.
Definition: timed_automaton.hh:32
bool zeroDuration
The value is true if the duration to stay this state must be zero.
Definition: timed_automaton.hh:27
bool isMatch
The value is true if and only if the state is an accepting state.
Definition: timed_automaton.hh:21
A state of timed automata.
Definition: timed_automaton.hh:42
std::vector< Constraint > guard
The guard for this transition.
Definition: timed_automaton.hh:48
TAState * target
The pointer to the target state.
Definition: timed_automaton.hh:44
std::vector< ClockVariables > resetVars
The clock variables reset after this transition.
Definition: timed_automaton.hh:46
A timed automaton.
Definition: timed_automaton.hh:54
void deepCopy(TimedAutomaton &dest, std::unordered_map< TAState *, std::shared_ptr< TAState >> &old2new) const
make a deep copy of this timed automaton.
Definition: timed_automaton.hh:68
size_t clockSize() const
Returns the number of clock variables used in the timed automaton.
Definition: timed_automaton.hh:95
bool isMember(const std::vector< std::pair< Alphabet, double >> &w) const
solve membership problem for observable timed automaton
Definition: timed_automaton.hh:102
std::vector< int > maxConstraints
The maximum constraints for each clock variables.
Definition: timed_automaton.hh:60