#pragma once #include "phantom.hpp" #include #include #include /* We use size_t's for easy indexing. But we do not want to mix states and * inputs. We use phantom typing to "generate" distinguished types :). */ using state = phantom; using input = phantom; using output = phantom; /* * Structure used for reading mealy files from dot files. * Everything is indexed by size_t's, so that we can index vectors * in constant time. The maps contain the original values corresponding * to these size_t's. Can only represent deterministic machines, * but partiality still can occur. */ struct Mealy { struct edge { state to = -1; output output = -1; }; std::map nodes_indices; std::map input_indices; std::map output_indices; // state -> input -> (output, state) std::vector> graph; // these are actually redundant! size_t graph_size = 0; size_t input_size = 0; size_t output_size = 0; }; inline auto is_complete(const Mealy & m){ for(state n = 0; n < m.graph_size; ++n){ if(m.graph[n.base()].size() != m.input_size) return false; for(auto && e : m.graph[n.base()]) if(e.to == -1 || e.output == -1) return false; } return true; } inline auto apply(Mealy const & m, state state, input input){ return m.graph[state.base()][input.base()]; } template auto apply(Mealy const & m, state state, Iterator b, Iterator e){ Mealy::edge ret; while(b != e){ ret = apply(m, state, *b++); state = ret.to; } return ret; }