diff --git a/lib/adaptive_distinguishing_sequence.cpp b/lib/adaptive_distinguishing_sequence.cpp index 7d281b4..bc57865 100644 --- a/lib/adaptive_distinguishing_sequence.cpp +++ b/lib/adaptive_distinguishing_sequence.cpp @@ -33,11 +33,11 @@ adaptive_distinguishing_sequence create_adaptive_distinguishing_sequence(const r vector states(N, false); for(auto && state : node.CI){ - states[state.first.base()] = true; + states[state.first] = true; } const auto & oboom = lca(root, [&states](state state) -> bool{ - return states[state.base()]; + return states[state]; }); if(oboom.children.empty()) continue; @@ -55,7 +55,7 @@ adaptive_distinguishing_sequence create_adaptive_distinguishing_sequence(const r } else if(node.CI[i].first > c.states[j]) { j++; } else { - const auto curr = succession[oboom.depth][node.CI[i].first.base()]; + const auto curr = succession[oboom.depth][node.CI[i].first]; const auto init = node.CI[i].second; new_c.CI.push_back({curr, init}); i++; diff --git a/lib/io.hpp b/lib/io.hpp deleted file mode 100644 index c25f3c7..0000000 --- a/lib/io.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "phantom.hpp" -#include "mealy.hpp" - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -namespace boost { -namespace serialization { - -template -void serialize(Archive & ar, phantom & value, const unsigned int /*version*/){ - ar & value.x; -} - -} // namespace serialization -} // namespace boost diff --git a/lib/mealy.hpp b/lib/mealy.hpp index 7c01efd..83791a7 100644 --- a/lib/mealy.hpp +++ b/lib/mealy.hpp @@ -31,22 +31,22 @@ struct mealy { 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; + if(m.graph[n].size() != m.input_size) return false; + for(auto && e : m.graph[n]) 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()]; + return m.graph[state][input]; } template auto apply(mealy const & m, state state, Iterator b, Iterator e){ - mealy::edge ret{state, -1}; + mealy::edge ret; + ret.to = state; while(b != e){ - ret = apply(m, state, *b++); - state = ret.to; + ret = apply(m, ret.to, *b++); } return ret; } diff --git a/lib/phantom.hpp b/lib/phantom.hpp deleted file mode 100644 index 39e53ce..0000000 --- a/lib/phantom.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include - -#include - -template -struct phantom : boost::operators>, boost::shiftable> { - phantom() = default; - phantom(Base y) : x(y) {} - phantom(phantom const &) = default; - phantom& operator=(phantom const &) = default; - phantom(phantom &&) = default; - phantom& operator=(phantom &&) = default; - - explicit operator Base() const { return x; } - Base base() const { return x; } - - Base x; - -#define IMPL(op) \ - phantom & operator op (phantom rh) { \ - x op rh.x; \ - return *this; \ - } - - IMPL(+=) - IMPL(-=) - IMPL(*=) - IMPL(/=) - IMPL(%=) - IMPL(|=) - IMPL(&=) - IMPL(^=) - IMPL(<<=) - IMPL(>>=) -#undef IMPL - - phantom & operator++() { ++x; return *this; } - phantom & operator--() { --x; return *this; } - - bool operator<(phantom rh) const { return x < rh.x; } - bool operator==(phantom rh) const { return x == rh.x; } -}; - -template -std::ostream & operator<<(std::ostream & out, phantom p){ return out << p.x; } - -template -std::istream & operator>>(std::istream & in, phantom & p){ return in >> p.x; } diff --git a/lib/read_mealy_from_dot.cpp b/lib/read_mealy_from_dot.cpp index 8ea318f..fbc5999 100644 --- a/lib/read_mealy_from_dot.cpp +++ b/lib/read_mealy_from_dot.cpp @@ -54,15 +54,15 @@ mealy read_mealy_from_dot(std::istream & in, translation & t){ if(t.output_indices.count(output) < 1) t.output_indices[output] = t.max_output++; // add edge - m.graph.resize(max_state.base()); - auto & v = m.graph[state_indices[lh].base()]; - v.resize(t.max_input.base()); - v[t.input_indices[input].base()] = {state_indices[rh], t.output_indices[output]}; + m.graph.resize(max_state); + auto & v = m.graph[state_indices[lh]]; + v.resize(t.max_input); + v[t.input_indices[input]] = {state_indices[rh], t.output_indices[output]}; } - m.graph_size = max_state.base(); - m.input_size = t.max_input.base(); - m.output_size = t.max_output.base(); + m.graph_size = max_state; + m.input_size = t.max_input; + m.output_size = t.max_output; if(m.graph_size == 0) throw runtime_error("Empty state set"); if(m.input_size == 0) throw runtime_error("Empty input set"); diff --git a/lib/read_mealy_from_dot.hpp b/lib/read_mealy_from_dot.hpp index 8836d9f..653d7cb 100644 --- a/lib/read_mealy_from_dot.hpp +++ b/lib/read_mealy_from_dot.hpp @@ -32,7 +32,7 @@ template std::vector create_reverse_map(std::map const & indices){ std::vector ret(indices.size()); for(auto&& p : indices){ - ret[p.second.base()] = p.first; + ret[p.second] = p.first; } return ret; } diff --git a/lib/seperating_family.cpp b/lib/seperating_family.cpp index ecbdfce..8c50651 100644 --- a/lib/seperating_family.cpp +++ b/lib/seperating_family.cpp @@ -24,7 +24,7 @@ seperating_family create_seperating_family(const adaptive_distinguishing_sequenc // add sequence to this leave for(auto && p : node.CI){ const auto state = p.second; - seperating_family[state.base()].push_back(word); + seperating_family[state].push_back(word); } // if the leaf is not a singleton, we need the all_pair seperating seqs @@ -33,7 +33,7 @@ seperating_family create_seperating_family(const adaptive_distinguishing_sequenc const auto s = p.second; const auto t = q.second; if(s == t) continue; - seperating_family[s.base()].push_back(all_pair_seperating_sequences[s.base()][t.base()]); + seperating_family[s].push_back(all_pair_seperating_sequences[s][t]); } } diff --git a/lib/seperating_matrix.cpp b/lib/seperating_matrix.cpp index 8a21e2a..0f80ef9 100644 --- a/lib/seperating_matrix.cpp +++ b/lib/seperating_matrix.cpp @@ -26,10 +26,10 @@ seperating_matrix create_all_pair_seperating_sequences(const splitting_tree & ro while(jt != ed){ for(auto && s : it->states){ for(auto && t : jt->states){ - assert(all_pair_seperating_sequences[t.base()][s.base()].empty()); - assert(all_pair_seperating_sequences[s.base()][t.base()].empty()); - all_pair_seperating_sequences[t.base()][s.base()] = node.seperator; - all_pair_seperating_sequences[s.base()][t.base()] = node.seperator; + assert(all_pair_seperating_sequences[t][s].empty()); + assert(all_pair_seperating_sequences[s][t].empty()); + all_pair_seperating_sequences[t][s] = node.seperator; + all_pair_seperating_sequences[s][t] = node.seperator; } } jt++; diff --git a/lib/splitting_tree.cpp b/lib/splitting_tree.cpp index adfe3ac..a29c5ea 100644 --- a/lib/splitting_tree.cpp +++ b/lib/splitting_tree.cpp @@ -68,7 +68,7 @@ result create_splitting_tree(const mealy& g, options opt){ for(auto && block : blocks) { const auto new_blocks = partition_(begin(block), end(block), [symbol, &g](state state){ - return apply(g, state, symbol).to.base(); + return apply(g, state, symbol).to; }, N); for(auto && new_block : new_blocks){ if(new_block.size() != 1) return false; @@ -78,7 +78,7 @@ result create_splitting_tree(const mealy& g, options opt){ }; const auto update_succession = [N, &succession](state s, state t, size_t depth){ if(succession.size() < depth+1) succession.resize(depth+1, vector(N, -1)); - succession[depth][s.base()] = t; + succession[depth][s] = t; }; // We'll start with the root, obviously @@ -99,7 +99,7 @@ result create_splitting_tree(const mealy& g, options opt){ const auto new_blocks = partition_(begin(boom.states), end(boom.states), [symbol, depth, &g, &update_succession](state state){ const auto ret = apply(g, state, symbol); update_succession(state, ret.to, depth); - return ret.output.base(); + return ret.output; }, Q); // no split -> continue with other input symbols @@ -119,11 +119,11 @@ result create_splitting_tree(const mealy& g, options opt){ for(input symbol : all_inputs){ vector successor_states(N, false); for(auto && state : boom.states){ - successor_states[apply(g, state, symbol).to.base()] = true; + successor_states[apply(g, state, symbol).to] = true; } const auto & oboom = lca(root, [&successor_states](state state) -> bool{ - return successor_states[state.base()]; + return successor_states[state]; }); // a leaf, hence not a split -> try other symbols @@ -134,7 +134,7 @@ result create_splitting_tree(const mealy& g, options opt){ const auto new_blocks = partition_(begin(boom.states), end(boom.states), [word, depth, &g, &update_succession](state state){ const auto ret = apply(g, state, begin(word), end(word)); update_succession(state, ret.to, depth); - return ret.output.base(); + return ret.output; }, Q); // not a valid split -> continue diff --git a/lib/transfer_sequences.cpp b/lib/transfer_sequences.cpp index aae7deb..766fec6 100644 --- a/lib/transfer_sequences.cpp +++ b/lib/transfer_sequences.cpp @@ -21,16 +21,16 @@ transfer_sequences create_transfer_sequences(const mealy& machine, state s){ const auto d = p.first - 1; work.pop(); - if(visited[u.base()]) continue; + if(visited[u]) continue; - visited[u.base()] = true; + visited[u] = true; for(input i = 0; i < machine.input_size; ++i){ const auto v = apply(machine, u, i).to; - if(visited[v.base()]) continue; + if(visited[v]) continue; - words[v.base()] = words[u.base()]; - words[v.base()].push_back(i); + words[v] = words[u]; + words[v].push_back(i); work.push({d, v}); } } @@ -55,17 +55,17 @@ transfer_sequences create_randomized_transfer_sequences(const mealy & machine, s const auto d = p.first - 1; work.pop(); - if(visited[u.base()]) continue; + if(visited[u]) continue; - visited[u.base()] = true; + visited[u] = true; shuffle(begin(all_inputs), end(all_inputs), generator); for(input i : all_inputs){ const auto v = apply(machine, u, i).to; - if(visited[v.base()]) continue; + if(visited[v]) continue; - words[v.base()] = words[u.base()]; - words[v.base()].push_back(i); + words[v] = words[u]; + words[v].push_back(i); work.push({d, v}); } } diff --git a/lib/types.hpp b/lib/types.hpp index 202043d..7871280 100644 --- a/lib/types.hpp +++ b/lib/types.hpp @@ -1,15 +1,11 @@ #pragma once -#include "phantom.hpp" - #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; +// We use size_ts for fast indexing. Note that there is little type safety here +using state = size_t; +using input = size_t; +using output = size_t; using word = std::vector; @@ -24,7 +20,7 @@ std::vector concat(std::vector const & l, std::vector const & r){ // extends all words in seqs by all input symbols. Used to generate *all* strings inline std::vector all_seqs(input min, input max, std::vector const & seqs){ - std::vector ret((max.base() - min.base()) * seqs.size()); + std::vector ret((max - min) * seqs.size()); auto it = begin(ret); for(auto const & x : seqs){ for(input i = min; i < max; ++i){ diff --git a/src/conf.cpp b/src/conf.cpp deleted file mode 100644 index 894b1e5..0000000 --- a/src/conf.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include - -#include - -#include -#include -#include -#include - -using namespace std; - -template -vector resize_new(vector const & in, size_t N){ - vector ret(N); - copy_n(in.begin(), N, ret.begin()); - return ret; -} - -struct mealy_with_maps { - mealy machine; - map inputs; - vector outputs; -}; - -vector conform(mealy_with_maps const & spec, mealy_with_maps const & impl, vector> const & suite){ - for(auto && test : suite){ - state s = 0; - state t = 0; - - size_t count = 0; - for(auto && i : test){ - const auto i1 = spec.inputs.at(i); - const auto r1 = apply(spec.machine, s, i1); - const auto o1 = spec.outputs[r1.output.base()]; - s = r1.to; - - const auto i2 = impl.inputs.at(i); - const auto r2 = apply(impl.machine, t, i2); - const auto o2 = impl.outputs[r2.output.base()]; - t = r2.to; - - if(o1 != o2){ - return resize_new(test, count+1); - } - count++; - } - } - - return {}; -} - -vector> open_suite(string suite_filename){ - boost::iostreams::filtering_istream suite_file; - suite_file.push(boost::iostreams::gzip_decompressor()); - suite_file.push(boost::iostreams::file_descriptor_source(suite_filename)); - boost::archive::text_iarchive archive(suite_file); - - vector> suite; - archive >> suite; - return suite; -} - -int main(int argc, char *argv[]){ - if(argc != 3) return 1; - - const auto spec = read_mealy_from_dot(argv[1]); - const auto spec_o_map = create_reverse_map(spec.second.output_indices); - - const auto impl = read_mealy_from_dot(argv[2]); - const auto impl_o_map = create_reverse_map(impl.second.output_indices); - - const auto suite = open_suite(argv[1] + string("test_suite")); - - const auto counter_example = conform({spec.first, spec.second.input_indices, spec_o_map}, {impl.first, impl.second.input_indices, impl_o_map}, suite); - if(counter_example.empty()){ - cerr << "No counter example found" << endl; - } - for(auto && i : counter_example) cout << i << ' '; - cout << endl; -} - diff --git a/src/main.cpp b/src/main.cpp index f2a5b57..e1d0e44 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -101,11 +101,11 @@ int main(int argc, char *argv[]) try { for(input i = 0; i < machine.input_size; ++i){ //const auto test1 = apply(machine, s, i).output != machine.output_indices.at("quiescence"); const auto test2 = apply(machine, s, i).to != s; - r_cache[i.base()] = 0.1 + test2; + r_cache[i] = 0.1 + test2; } } - distributions[s.base()] = discrete_distribution(begin(r_cache), end(r_cache)); + distributions[s] = discrete_distribution(begin(r_cache), end(r_cache)); } return distributions; }); @@ -122,7 +122,7 @@ int main(int argc, char *argv[]) try { const auto inputs = inputs_fut.get(); const auto print_word = [&](auto w){ - for(auto && x : w) cout << inputs[x.base()] << ' '; + for(auto && x : w) cout << inputs[x] << ' '; }; if(statistics){ @@ -176,9 +176,9 @@ int main(int argc, char *argv[]) try { for(int k = 0; k <= k_max; ++k){ cerr << "*** K = " << k << endl; for(state s = 0; s < machine.graph_size; ++s){ - const auto prefix = transfer_sequences[s.base()]; + const auto prefix = transfer_sequences[s]; - for(auto && suffix : seperating_family[s.base()]){ + for(auto && suffix : seperating_family[s]){ for(auto && r : all_sequences){ print_word(prefix); print_word(r); @@ -214,14 +214,14 @@ int main(int argc, char *argv[]) try { m.reserve(k_max + 2); size_t minimal_size = k_max + 1; while(minimal_size || unfair_coin(generator)){ - input i = relevant_inputs[current_state.base()](generator); + input i = relevant_inputs[current_state](generator); m.push_back(i); current_state = apply(machine, current_state, i).to; if(minimal_size) minimal_size--; } using params = uniform_int_distribution::param_type; - const auto & suffixes = seperating_family[current_state.base()]; + const auto & suffixes = seperating_family[current_state]; const auto & s = suffixes[suffix_selection(generator, params{0, suffixes.size()-1})]; print_word(p); diff --git a/src/metrics.cpp b/src/metrics.cpp index 91f1414..0b4034e 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -16,13 +16,13 @@ auto create_transfer_sequences(const mealy& machine, const state s, const input const auto u = work.front(); work.pop(); - if(visited[u.base()]) continue; - visited[u.base()] = true; + if(visited[u]) continue; + visited[u] = true; for(input i = 0; i < machine.input_size; ++i){ if(i == ignore) continue; const auto v = apply(machine, u, i).to; - if(visited[v.base()]) continue; + if(visited[v]) continue; work.push(v); } } @@ -40,7 +40,7 @@ int main(int argc, char *argv[]){ // vector> table(machine.input_size); // for(input i = 0; i < machine.input_size; ++i){ -// table[i.base()] = create_transfer_sequences(machine, 0, i); +// table[i] = create_transfer_sequences(machine, 0, i); // } // note the wrong iteration ;D diff --git a/src/phantom_test.cpp b/src/phantom_test.cpp deleted file mode 100644 index ea3e7aa..0000000 --- a/src/phantom_test.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include - -template -using phantom_int = phantom; - -struct state_tag; -using state = phantom_int; - -struct input_tag; -using input = phantom_int; - -int main(int argc, char *argv[]){ - state x = 5; - x += 5; - - input y = 9; - y -= 9; - y++; - - std::cout << (x - 1) << std::endl; - std::cout << (y << 1) << std::endl; - // std::cout << x+y << std::endl; // does not compile - - for(input i = 0; i < 10; ++i){ - std::cout << i << ", "; - } - std::cout << std::endl; -} - diff --git a/src/pre_gephi_tool.cpp b/src/pre_gephi_tool.cpp index 9485c09..f47042d 100644 --- a/src/pre_gephi_tool.cpp +++ b/src/pre_gephi_tool.cpp @@ -54,10 +54,10 @@ int main(int argc, char *argv[]){ for(auto && p : state_cover){ state s = 0; for(auto && inp : p){ - if(!visited[s.base()]) visited[s.base()] = i; + if(!visited[s]) visited[s] = i; s = apply(machine, s, inp).to; } - if(!visited[s.base()]) visited[s.base()] = i; + if(!visited[s]) visited[s] = i; } } @@ -72,21 +72,21 @@ int main(int argc, char *argv[]){ out << "digraph {\n"; for(state s = 0; s < machine.graph_size; ++s){ - bool is_visited = visited[s.base()] ? (visited[s.base()].value() <= i) : false; + bool is_visited = visited[s] ? (visited[s].value() <= i) : false; out << "\t" << "s" << s << " ["; out << "color=\"" << (is_visited ? "green" : "red") << "\"" << ", "; - out << "pos=\"" << positions[s.base()].first << "," << positions[s.base()].second << "\""; + out << "pos=\"" << positions[s].first << "," << positions[s].second << "\""; out << "]\n"; } for(state s = 0; s < machine.graph_size; ++s){ vector visited(machine.graph_size, false); - visited[s.base()] = true; + visited[s] = true; for(input i = 0; i < machine.input_size; ++i){ const auto t = apply(machine, s, i).to; - if(visited[t.base()]) continue; + if(visited[t]) continue; out << "\t" << "s" << s << " -> " << "s" << t << "\n"; - visited[t.base()] = true; + visited[t] = true; } } diff --git a/src/reachability.cpp b/src/reachability.cpp index 27088c6..d3a73b4 100644 --- a/src/reachability.cpp +++ b/src/reachability.cpp @@ -42,12 +42,12 @@ int main(int argc, char *argv[]){ const state s = work.front(); work.pop(); - if(visited[s.base()]) continue; - visited[s.base()] = true; + if(visited[s]) continue; + visited[s] = true; for(auto x : subalphabet){ const state t = apply(machine, s, x).to; - if(!visited[t.base()]) work.push(t); + if(!visited[t]) work.push(t); } } @@ -56,21 +56,21 @@ int main(int argc, char *argv[]){ out << "digraph {\n"; for(state s = 0; s < machine.graph_size; ++s){ - bool is_visited = visited[s.base()]; + bool is_visited = visited[s]; out << "\t" << "s" << s << " ["; out << "color=\"" << (is_visited ? "green" : "red") << "\"" << ", "; - out << "pos=\"" << positions[s.base()].first << "," << positions[s.base()].second << "\""; + out << "pos=\"" << positions[s].first << "," << positions[s].second << "\""; out << "]\n"; } for(state s = 0; s < machine.graph_size; ++s){ vector visited(machine.graph_size, false); - visited[s.base()] = true; + visited[s] = true; for(input i = 0; i < machine.input_size; ++i){ const auto t = apply(machine, s, i).to; - if(visited[t.base()]) continue; + if(visited[t]) continue; out << "\t" << "s" << s << " -> " << "s" << t << "\n"; - visited[t.base()] = true; + visited[t] = true; } } diff --git a/src/stats.cpp b/src/stats.cpp index 23e1a4d..4ec6497 100644 --- a/src/stats.cpp +++ b/src/stats.cpp @@ -1,4 +1,3 @@ -#include #include #include @@ -18,33 +17,9 @@ void print_stats_for_machine(string filename){ cout << '\t' << machine.output_size << " outputs\n"; } -void print_stats_for_suite(string filename){ - boost::iostreams::filtering_istream suite_file; - suite_file.push(boost::iostreams::gzip_decompressor()); - suite_file.push(boost::iostreams::file_descriptor_source(filename)); - boost::archive::text_iarchive archive(suite_file); - - vector> suite; - archive >> suite; - - const auto & longest = *max_element(suite.begin(), suite.end(), [](const auto & x, const auto & y){ return x.size() < y.size(); }); - const auto total_length = accumulate(suite.begin(), suite.end(), 0, [](const auto & x, const auto & y){ return x + y.size(); }); - - cout << "suite " << filename << " has\n"; - cout << '\t' << suite.size() << " sequences\n"; - cout << '\t' << total_length << " input symbols in total\n"; - cout << '\t' << double(total_length) / suite.size() << " input symbols on average per test\n"; - cout << '\t' << longest.size() << " inputs symbols in the longest test\n"; -} - int main(int argc, char *argv[]){ if(argc != 2) return 37; const string filename = argv[1]; - if(filename.find("test_suite") == string::npos){ - print_stats_for_machine(filename); - } else { - print_stats_for_suite(filename); - } + print_stats_for_machine(filename); } -