libmonaa 0.5.2
Loading...
Searching...
No Matches
zone_automaton.hh
1#pragma once
2
3#include "timed_automaton.hh"
4#include "zone.hh"
5#include <stack>
6#include <unordered_set>
7#include <utility>
8
9struct ZAState {
10 bool isMatch;
11 // An epsilon transition is denoted by the null character (\0)
12 std::array<std::vector<std::weak_ptr<ZAState>>, CHAR_MAX> next;
13 TAState *taState;
14 Zone zone;
15 ZAState() : isMatch(false), next({}) {}
16 ZAState(TAState *taState, Zone zone)
17 : isMatch(taState->isMatch), next({}), taState(taState),
18 zone(std::move(zone)) {}
19 ZAState(bool isMatch) : isMatch(isMatch), next({}) {}
20 ZAState(bool isMatch,
21 std::array<std::vector<std::weak_ptr<ZAState>>, CHAR_MAX> next)
22 : isMatch(isMatch), next(next) {}
23 bool operator==(std::pair<TAState *, Zone> pair) {
24 return pair.first == taState && pair.second == zone;
25 }
26};
27
29 bool isMatch;
30 std::array<std::vector<std::weak_ptr<NoEpsilonZAState>>, CHAR_MAX> next;
31 std::unordered_set<std::shared_ptr<ZAState>> zaStates;
32 bool operator==(const std::unordered_set<std::shared_ptr<ZAState>> &zas) {
33 return zas == zaStates;
34 }
35};
36
39static inline void
40epsilonClosure(std::unordered_set<std::shared_ptr<ZAState>> &closure) {
41 auto waiting =
42 std::deque<std::shared_ptr<ZAState>>(closure.begin(), closure.end());
43 while (!waiting.empty()) {
44 for (auto wstate : waiting.front()->next[0]) {
45 auto state = wstate.lock();
46 if (state && closure.find(state) == closure.end()) {
47 closure.insert(state);
48 waiting.push_back(state);
49 }
50 }
51 waiting.pop_front();
52 }
53}
54
55struct ZoneAutomaton : public Automaton<ZAState> {
56 using State = ::ZAState;
57
60 // Find states unreachable to any accepting states
61 using Config = std::pair<std::shared_ptr<ZAState>,
62 std::unordered_set<std::shared_ptr<ZAState>>>;
63 std::stack<Config> States;
64 for (auto state : initialStates) {
65 States.push(Config(state, {}));
66 }
67 std::unordered_set<std::shared_ptr<ZAState>> reachable;
68 while (!States.empty()) {
69 Config conf = States.top();
70 States.pop();
71 if (conf.first->isMatch) {
72 reachable.insert(conf.first);
73 reachable.insert(conf.second.begin(), conf.second.end());
74 }
75 for (const auto &edges : conf.first->next) {
76 for (const auto &edge : edges) {
77 if (conf.second.find(conf.first) != conf.second.end()) {
78 // We are in a loop
79 continue;
80 }
81 if (reachable.find(edge.lock()) != reachable.end()) {
82 // The next state is reachable
83 reachable.insert(conf.first);
84 reachable.insert(conf.second.begin(), conf.second.end());
85 } else {
86 // The next state may be unreachable
87 auto parents = conf.second;
88 parents.insert(conf.first);
89 States.push(Config(edge.lock(), parents));
90 }
91 }
92 }
93 }
94
95 // Remove unreachable states
96 for (auto it = states.begin(); it != states.end();) {
97 if (reachable.find(*it) == reachable.end()) {
98 it = states.erase(it);
99 } else {
100 it++;
101 }
102 }
103 for (auto it = initialStates.begin(); it != initialStates.end();) {
104 if (reachable.find(*it) == reachable.end()) {
105 it = initialStates.erase(it);
106 } else {
107 it++;
108 }
109 }
110 }
111
117 const std::vector<std::shared_ptr<TAState>> taInitialStates) {
118 // update initial states
119 initialStates.clear();
120 for (std::shared_ptr<ZAState> s : states) {
121 if (std::find_if(taInitialStates.begin(), taInitialStates.end(),
122 [&](std::shared_ptr<TAState> taS) {
123 return taS.get() == s->taState;
124 }) != taInitialStates.end()) {
125 initialStates.push_back(s);
126 }
127 }
128
129 // update accepting states
130 for (auto &state : states) {
131 state->isMatch = state->taState->isMatch;
132 }
133 }
134
136 bool empty() const {
137 std::vector<std::shared_ptr<ZAState>> currentStates = initialStates;
138 std::unordered_set<std::shared_ptr<ZAState>> visited = {
139 initialStates.begin(), initialStates.end()};
140 while (!currentStates.empty()) {
141 std::vector<std::shared_ptr<ZAState>> nextStates;
142 for (auto state : currentStates) {
143 if (state->isMatch) {
144 return false;
145 }
146 for (const auto &edges : state->next) {
147 for (const auto &edge : edges) {
148 auto target = edge.lock();
149 if (target && visited.find(target) == visited.end()) {
150 // We have not visited the state
151 nextStates.push_back(target);
152 visited.insert(target);
153 }
154 }
155 }
156 }
157 currentStates = std::move(nextStates);
158 }
159 return true;
160 }
161};
An automaton.
Definition common_types.hh:13
std::vector< std::shared_ptr< ZAState > > states
The states of this automaton.
Definition common_types.hh:17
std::vector< std::shared_ptr< ZAState > > initialStates
The initial states of this automaton.
Definition common_types.hh:19
Definition zone_automaton.hh:28
A state of timed automata.
Definition timed_automaton.hh:19
bool isMatch
The value is true if and only if the state is an accepting state.
Definition timed_automaton.hh:21
Definition zone_automaton.hh:9
Definition zone_automaton.hh:55
void removeDeadStates()
remove states unreachable to any accepting states
Definition zone_automaton.hh:59
void updateInitAccepting(const std::vector< std::shared_ptr< TAState > > taInitialStates)
Propagate accepting states from the original timed automaton.
Definition zone_automaton.hh:116
bool empty() const
emptiness check of the language
Definition zone_automaton.hh:136
Implementation of a zone with DBM.
Definition zone.hh:43