libmonaa 0.5.2
Loading...
Searching...
No Matches
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
14struct TATransition;
15
19struct 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
46 std::vector<ClockVariables> resetVars;
48 std::vector<Constraint> guard;
49};
50
54struct TimedAutomaton : public Automaton<TAState> {
55 using X = ConstraintMaker;
57 using State = ::TAState;
58
60 std::vector<int> maxConstraints;
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
146static 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:17
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
size_t clockSize() const
Returns the number of clock variables used in the timed automaton.
Definition timed_automaton.hh:95
std::vector< int > maxConstraints
The maximum constraints for each clock variables.
Definition timed_automaton.hh:60
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
bool isMember(const std::vector< std::pair< Alphabet, double > > &w) const
solve membership problem for observable timed automaton
Definition timed_automaton.hh:102