Limi
dot_printer.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_DOT_PRINTER_H
21 #define LIMI_DOT_PRINTER_H
22 #include "automaton.h"
23 
24 #include <iostream>
25 #include <fstream>
26 #include <string>
27 #include <unordered_set>
28 #include <deque>
29 #include <unordered_map>
30 #include <cassert>
31 #include "internal/helpers.h"
32 #include "generics.h"
33 
34 namespace Limi {
35 
46 template <class State, class Symbol,class Implementation>
47 class dot_printer {
48  typedef std::unordered_set<State> State_set;
49  typedef std::unordered_set<Symbol> Symbol_set;
51 
52  struct frontier_item {
53  State s;
54  Symbol_set sleep_set;
55  explicit frontier_item(State s) : s(s) {}
56  frontier_item(State s, const Symbol_set& sleep_set) : frontier_item(s)
57  { this->sleep_set = sleep_set; }
58  };
59 
60 
61  public:
62 
69  void print_dot(const Automaton& automaton, std::ostream& out) {
70  unsigned state_counter = 0; // give every state a unique number
71  std::unordered_map<State, unsigned> state_id;
72 
73  out << "digraph automaton {" << std::endl;
74  std::unordered_set<State> seen;
75  std::deque<State> frontier;
76  for (const auto& s : automaton.initial_states()) {
77  frontier.push_back(s);
78  state_id[s] = ++state_counter;
79  out << "begin" << state_counter << " [shape=none,label=\"\"]" << std::endl;
80  out << "begin" << state_counter << " -> " << state_counter << std::endl;
81  }
82 
83  while (!frontier.empty()) {
84  State next = frontier.front();
85  frontier.pop_front();
86  if (seen.find(next) == seen.end()) {
87  seen.insert(next);
88  auto next_it = state_id.find(next);
89  assert(next_it != state_id.end());
90 
91  out << std::to_string(next_it->second) << " [label=\"" << automaton.state_printer()(next) << "\"";
92  if (automaton.is_final_state(next))
93  out << ",shape=doublecircle";
94  out << "]" << std::endl;
95  for (const Symbol& symbol : automaton.next_symbols(next)) {
96  for (const State& succ : automaton.successors(next, symbol)) {
97  // put id
98  auto succ_it = state_id.find(succ);
99  if (succ_it == state_id.end()) succ_it = state_id.insert(std::make_pair(succ, ++state_counter)).first;
100 
101  frontier.push_back(succ);
102  out << std::to_string(next_it->second) << " -> " << std::to_string(succ_it->second) << " [label=\"" << automaton.symbol_printer()(symbol) << "\"]" << std::endl;
103  }
104  }
105  }
106  }
107 
108  out << "}" << std::endl;
109  }
110 
117  void print_dot(const automaton<State,Symbol,Implementation>& automaton, const std::string& filename) {
118  std::ofstream myfile;
119  myfile.open(filename);
120  print_dot(automaton, myfile);
121  myfile.close();
122  }
123  };
124 
125 }
126 
127 #endif // LIMI_DOT_PRINTER_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
Prints automata in dot format.
Definition: dot_printer.h:47
void print_dot(const automaton< State, Symbol, Implementation > &automaton, const std::string &filename)
Writes the automaton to a file.
Definition: dot_printer.h:117
void print_dot(const Automaton &automaton, std::ostream &out)
Prints the automaton to the ostream out.
Definition: dot_printer.h:69
const printer_base< State > & state_printer() const
Returns a printer for states.
Definition: automaton.h:292
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
const printer_base< Symbol > & symbol_printer() const
Returns a printer for symbols.
Definition: automaton.h:304
void initial_states(State_vector &states) const
Returns the initial states.
Definition: automaton.h:167
Automata need to inherit from this class and implement certain methods.
Definition: automaton.h:49