diff --git a/lib/mealy.hpp b/lib/mealy.hpp index 9f6d51f..5f61617 100644 --- a/lib/mealy.hpp +++ b/lib/mealy.hpp @@ -39,6 +39,13 @@ inline bool is_complete(const mealy & m){ return true; } +inline bool defined(mealy const & m, state s, input i) { + if (s >= m.graph.size()) return false; + if (i >= m.graph[s].size()) return false; + if (m.graph[s][i].to == state(-1) || m.graph[s][i].output == output(-1)) return false; + return true; +} + inline mealy::edge apply(mealy const & m, state state, input input){ return m.graph[state][input]; } diff --git a/lib/read_mealy_from_dot.cpp b/lib/read_mealy_from_dot.cpp index 116ba54..c94fccc 100644 --- a/lib/read_mealy_from_dot.cpp +++ b/lib/read_mealy_from_dot.cpp @@ -49,6 +49,9 @@ mealy read_mealy_from_dot(std::istream & in, translation & t){ if(t.input_indices.count(input) < 1) t.input_indices[input] = t.max_input++; if(t.output_indices.count(output) < 1) t.output_indices[output] = t.max_output++; + if(defined(m, state_indices[lh], t.input_indices[input])) + throw runtime_error("Nondeterministic machine"); + // add edge m.graph.resize(max_state); auto & v = m.graph[state_indices[lh]]; diff --git a/lib/read_mealy_from_txt.cpp b/lib/read_mealy_from_txt.cpp new file mode 100644 index 0000000..6a1d75a --- /dev/null +++ b/lib/read_mealy_from_txt.cpp @@ -0,0 +1,76 @@ +#include "read_mealy_from_txt.hpp" +#include "mealy.hpp" + +#include +#include +#include +#include + +#include + +using namespace std; + +mealy read_mealy_from_txt(std::istream & in) { + mealy m; + + state max_state = 0; + input max_input = 0; + output max_output = 0; + + string line; + while (getline(in, line)) { + state from, to; + input i; + output o; + string seperator; + + stringstream ss(line); + ss >> from >> seperator >> i >> seperator >> o >> seperator >> to; + + if (from >= max_state) max_state = from + 1; + if (to >= max_state) max_state = to + 1; + if (i >= max_input) max_input = i + 1; + if (o >= max_output) max_output = o + 1; + + if (defined(m, from, i)) throw runtime_error("Nondeterministic machine"); + + m.graph.resize(max_state); + auto & v = m.graph[from]; + v.resize(max_input); + v[i] = mealy::edge(to, o); + + assert(defined(m, to, i)); + } + + m.graph_size = max_state; + m.input_size = max_input; + m.output_size = max_output; + + if (m.graph_size == 0) throw runtime_error("Empty state set"); + if (m.input_size == 0) throw runtime_error("Empty input set"); + if (m.output_size == 0) throw runtime_error("Empty output set"); + if (!is_complete(m)) throw runtime_error("Partial machine"); + return m; +} + +mealy read_mealy_from_txt(const std::string & filename) { + std::ifstream file(filename); + return read_mealy_from_txt(file); +} + + +translation create_translation_for_mealy(const mealy & m) { + translation t; + t.max_input = m.input_size; + t.max_output = m.output_size; + + for (input i = 0; i < t.max_input; ++i) { + t.input_indices[to_string(i)] = i; + } + + for (output o = 0; o < t.max_output; ++o) { + t.output_indices[to_string(o)] = o; + } + + return t; +} diff --git a/lib/read_mealy_from_txt.hpp b/lib/read_mealy_from_txt.hpp new file mode 100644 index 0000000..cb8e3d0 --- /dev/null +++ b/lib/read_mealy_from_txt.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "types.hpp" +#include "read_mealy_from_dot.hpp" + +#include + +struct mealy; + +/// \brief reads a mealy machine from plain txt file (as provided by A. T. Endo) +/// States, inputs and outputs in these files are already integral (and contiguous) +mealy read_mealy_from_txt(std::istream & in); +mealy read_mealy_from_txt(std::string const & filename); + +translation create_translation_for_mealy(mealy const & m);