Limi
automaton.h
1 /*
2  * Copyright 2016, IST Austria
3  *
4  * This file is part of Limi.
5  *
6  * Limi is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Limi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with Limi. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef LIMI_AUTOMATON_H
21 #define LIMI_AUTOMATON_H
22 
23 #include <unordered_set>
24 #include <unordered_map>
25 #include <vector>
26 #include <ostream>
27 #include <algorithm>
28 #include <deque>
29 #include <iostream>
30 #include "generics.h"
31 #include "internal/hash.h"
32 
33 namespace Limi {
34 
35 
48 template <class State, class Symbol, class Implementation>
49 class automaton
50 {
51 public:
52  using Symbol_ = Symbol;
53  using State_ = State;
66 
67  ~automaton() {
68  delete state_printer_;
69  delete symbol_printer_;
70  }
71 
72  using State_set = std::unordered_set<State>;
73  using Symbol_set = std::unordered_set<Symbol>;
74  using State_vector = std::vector<State>;
75  using Symbol_vector = std::vector<Symbol>;
76 
77  /***********************************************
78  * Internal functions that need to be overriden by the deriving class
79  **********************************************/
80 
90  inline printer_base<State>* int_state_printer() const { return new printer<State>(); }
91 
101  inline printer_base<Symbol>* int_symbol_printer() const { return new printer<Symbol>(); }
102 
109  bool int_is_final_state(const State& state) const;
110 
116  void int_initial_states(State_vector& states) const;
117 
125  void int_successors(const State& state, const Symbol& sigma, State_vector& successors) const;
126 
136  void int_next_symbols(const State& state, Symbol_vector& symbols) const;
137 
148  bool int_is_epsilon(const Symbol& symbol) const;
149 
150  /***********************************************
151  * Public functions
152  **********************************************/
153 
160  inline bool is_final_state(const State& state) const { return impl().int_is_final_state(state); }
161 
167  inline void initial_states(State_vector& states) const {
168  impl().int_initial_states(states);
169  explore_epsilon(states);
170  }
171 
177  inline void initial_states(State_set& states) const {
178  State_vector initial;
179  initial_states(initial);
180  states.insert(initial.begin(), initial.end());
181  }
182 
188  inline State_vector initial_states() const {
189  State_vector result;
190  initial_states(result);
191  return result;
192  }
193 
201  void successors(const State& state, const Symbol& sigma, State_vector& successors1) const {
202  impl().int_successors(state, sigma, successors1);
203  explore_epsilon(successors1);
204  }
205 
213  inline State_set successors(const State_set& states, const Symbol& sigma) const
214  {
215  State_set result;
216  successors(states, sigma, result);
217  return result;
218  }
219 
227  inline void successors(const State_set& states, const Symbol& sigma, State_set& successors1) const
228  {
229  State_vector successors2;
230  for (const State& state : states) {
231  successors(state, sigma, successors2);
232  }
233  successors1.insert(successors2.begin(), successors2.end());
234  }
235 
236 
244  inline State_vector successors(const State& state, const Symbol& sigma) const {
245  State_vector result;
246  successors(state, sigma, result);
247  return result;
248  }
249 
256  inline void next_symbols(const State& state, Symbol_vector& symbols) const {
257  impl().int_next_symbols(state, symbols);
258  filter_epsilon(symbols);
259  }
260 
267  inline Symbol_vector next_symbols(const State& state) const {
268  Symbol_vector result;
269  next_symbols(state, result);
270  return result;
271  }
272 
279  inline void next_symbols(const State& state, Symbol_set& symbols) const {
280  Symbol_vector result;
281  next_symbols(state, result);
282  symbols.insert(result.begin(), result.end());
283  }
284 
292  inline const printer_base<State>& state_printer() const {
293  if (!state_printer_) state_printer_ = impl().int_state_printer();
294  return *state_printer_;
295  }
296 
304  inline const printer_base<Symbol>& symbol_printer() const {
305  if (!symbol_printer_) symbol_printer_ = impl().int_symbol_printer();
306  return *symbol_printer_;
307 
308  }
309 
320  inline bool is_epsilon(const Symbol& symbol) const { return impl().int_is_epsilon(symbol); }
321 
328  inline bool is_final_state(const State_set& states) const {
329  for (State s:states) {
330  if (is_final_state(s))
331  return true;
332  }
333  return false;
334  }
335 
336 
337 
338 
345 
351 private:
352  mutable const printer_base<State>* state_printer_ = nullptr;
353  mutable const printer_base<Symbol>* symbol_printer_ = nullptr;
354 
355  inline Implementation& impl() {
356  return *static_cast<Implementation*>(this);
357  }
358  inline const Implementation& impl() const {
359  return *static_cast<const Implementation*>(this);
360  }
361 
362  void filter_epsilon(Symbol_vector& symbols) const {
363  if (collapse_epsilon) {
364  for (auto it = symbols.begin(); it!=symbols.end(); ) {
365  if (impl().int_is_epsilon(*it))
366  it = symbols.erase(it);
367  else
368  ++it;
369  }
370  }
371  }
372 
373  void explore_epsilon(State_vector& states) const {
374  if (!collapse_epsilon) return;
375  State_set seen;
376  std::deque<State> frontier;
377  frontier.insert(frontier.begin(), states.begin(), states.end());
378  states.clear();
379  while(!frontier.empty()) {
380  const State& s = frontier.front();
381  //state_printer()(s, std::cout); std::cout << std::endl;
382 
383  Symbol_vector next_symbols;
384  impl().int_next_symbols(s, next_symbols);
385  State_vector succs;
386  bool first = true;
387  if (impl().int_is_final_state(s)) {
388  first = false;
389  states.push_back(s);
390  }
391  for (const Symbol& sy : next_symbols) {
392  if (impl().int_is_epsilon(sy)) {
393  impl().int_successors(s, sy, succs);
394  } else if (first) { // if there is at least one non-epsilon transition we add this state
395  first = false;
396  states.push_back(s);
397  }
398  }
399  for (const State& st : succs) {
400  if (seen.insert(st).second) {
401  frontier.push_back(st);
402  }
403  }
404  frontier.pop_front();
405  }
406  //std::cout << std::endl;
407  }
408 };
409 }
410 
411 #endif // LIMI_AUTOMATON_H
void next_symbols(const State &state, Symbol_vector &symbols) const
Returns possible successor symbols for a state.
Definition: automaton.h:256
The main namespace of the library.
Definition: antichain_algo.h:40
bool int_is_epsilon(const Symbol &symbol) const
Implement Determines if a symbol should be considered an epsilon transition.
State_vector successors(const State &state, const Symbol &sigma) const
Returns successors for a state.
Definition: automaton.h:244
State_vector initial_states() const
Returns a set of initial states.
Definition: automaton.h:188
void initial_states(State_set &states) const
Returns the initial states.
Definition: automaton.h:177
void int_next_symbols(const State &state, Symbol_vector &symbols) const
Implement Returns possible successor symbols for a state.
printer_base< Symbol > * int_symbol_printer() const
Optionally Implement Returns a printer for symbols.
Definition: automaton.h:101
const printer_base< State > & state_printer() const
Returns a printer for states.
Definition: automaton.h:292
bool is_epsilon(const Symbol &symbol) const
Determines if a symbol should be considered an epsilon transition.
Definition: automaton.h:320
bool is_final_state(const State &state) const
This function determines if a specific state is final.
Definition: automaton.h:160
void successors(const State &state, const Symbol &sigma, State_vector &successors1) const
Returns the successor for a specific state.
Definition: automaton.h:201
bool no_epsilon_produced
Indicates that the implementation of next_symbols(const State&,Symbol_set&) const will never produce ...
Definition: automaton.h:350
automaton(bool collapse_epsilon=false, bool no_epsilon_produced=false)
Constructor.
Definition: automaton.h:65
const printer_base< Symbol > & symbol_printer() const
Returns a printer for symbols.
Definition: automaton.h:304
void int_successors(const State &state, const Symbol &sigma, State_vector &successors) const
Implement Returns the successor for a specific state.
The default implementation of Limi::printer_base.
Definition: generics.h:104
void int_initial_states(State_vector &states) const
Implement Returns the initial states.
bool is_final_state(const State_set &states) const
Determines if one of the states is final.
Definition: automaton.h:328
void initial_states(State_vector &states) const
Returns the initial states.
Definition: automaton.h:167
bool collapse_epsilon
If true during exploration of the next state the epsilons will be fully explored. If false then epsil...
Definition: automaton.h:344
bool int_is_final_state(const State &state) const
Implement This function determines if a specific state is final.
Automata need to inherit from this class and implement certain methods.
Definition: automaton.h:49
printer_base< State > * int_state_printer() const
Optionally Implement Returns a printer for states.
Definition: automaton.h:90
void next_symbols(const State &state, Symbol_set &symbols) const
Returns possible successor symbols of a state.
Definition: automaton.h:279
void successors(const State_set &states, const Symbol &sigma, State_set &successors1) const
Returns successors for a set of states.
Definition: automaton.h:227
State_set successors(const State_set &states, const Symbol &sigma) const
Finds successors for a set of states.
Definition: automaton.h:213
Symbol_vector next_symbols(const State &state) const
Returns possible successor symbols of a state.
Definition: automaton.h:267