mirror of
https://github.com/Jaxan/hybrid-ads.git
synced 2025-04-27 15:07:45 +02:00
Simplifies code by removing phantom typing.
Also removes other unused tools.
This commit is contained in:
parent
3de4f29a87
commit
598e72b880
18 changed files with 71 additions and 293 deletions
|
@ -33,11 +33,11 @@ adaptive_distinguishing_sequence create_adaptive_distinguishing_sequence(const r
|
|||
|
||||
vector<bool> 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++;
|
||||
|
|
31
lib/io.hpp
31
lib/io.hpp
|
@ -1,31 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "phantom.hpp"
|
||||
#include "mealy.hpp"
|
||||
|
||||
#include <boost/iostreams/device/file_descriptor.hpp>
|
||||
#include <boost/iostreams/filter/gzip.hpp>
|
||||
#include <boost/iostreams/filtering_stream.hpp>
|
||||
|
||||
#include <boost/serialization/serialization.hpp>
|
||||
#include <boost/serialization/string.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/binary_oarchive.hpp>
|
||||
#include <boost/archive/binary_iarchive.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
template<class Archive, typename B, typename T>
|
||||
void serialize(Archive & ar, phantom<B, T> & value, const unsigned int /*version*/){
|
||||
ar & value.x;
|
||||
}
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
|
@ -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 <typename Iterator>
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
template <typename Base, typename T>
|
||||
struct phantom : boost::operators<phantom<Base, T>>, boost::shiftable<phantom<Base, T>> {
|
||||
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 <typename B, typename T>
|
||||
std::ostream & operator<<(std::ostream & out, phantom<B, T> p){ return out << p.x; }
|
||||
|
||||
template <typename B, typename T>
|
||||
std::istream & operator>>(std::istream & in, phantom<B, T> & p){ return in >> p.x; }
|
|
@ -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");
|
||||
|
|
|
@ -32,7 +32,7 @@ template <typename T>
|
|||
std::vector<std::string> create_reverse_map(std::map<std::string, T> const & indices){
|
||||
std::vector<std::string> ret(indices.size());
|
||||
for(auto&& p : indices){
|
||||
ret[p.second.base()] = p.first;
|
||||
ret[p.second] = p.first;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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<state>(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<bool> 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
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "phantom.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
/* 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<size_t, struct state_tag>;
|
||||
using input = phantom<size_t, struct input_tag>;
|
||||
using output = phantom<size_t, struct output_tag>;
|
||||
// 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<input>;
|
||||
|
||||
|
@ -24,7 +20,7 @@ std::vector<T> concat(std::vector<T> const & l, std::vector<T> const & r){
|
|||
|
||||
// extends all words in seqs by all input symbols. Used to generate *all* strings
|
||||
inline std::vector<word> all_seqs(input min, input max, std::vector<word> const & seqs){
|
||||
std::vector<word> ret((max.base() - min.base()) * seqs.size());
|
||||
std::vector<word> ret((max - min) * seqs.size());
|
||||
auto it = begin(ret);
|
||||
for(auto const & x : seqs){
|
||||
for(input i = min; i < max; ++i){
|
||||
|
|
82
src/conf.cpp
82
src/conf.cpp
|
@ -1,82 +0,0 @@
|
|||
#include <mealy.hpp>
|
||||
#include <read_mealy_from_dot.hpp>
|
||||
|
||||
#include <io.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
vector<T> resize_new(vector<T> const & in, size_t N){
|
||||
vector<T> ret(N);
|
||||
copy_n(in.begin(), N, ret.begin());
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct mealy_with_maps {
|
||||
mealy machine;
|
||||
map<string, input> inputs;
|
||||
vector<string> outputs;
|
||||
};
|
||||
|
||||
vector<string> conform(mealy_with_maps const & spec, mealy_with_maps const & impl, vector<vector<string>> 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<vector<string>> 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<vector<string>> 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;
|
||||
}
|
||||
|
14
src/main.cpp
14
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<input>(begin(r_cache), end(r_cache));
|
||||
distributions[s] = discrete_distribution<input>(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<size_t>::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);
|
||||
|
|
|
@ -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<vector<bool>> 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
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
#include <phantom.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <typename T>
|
||||
using phantom_int = phantom<int, T>;
|
||||
|
||||
struct state_tag;
|
||||
using state = phantom_int<state_tag>;
|
||||
|
||||
struct input_tag;
|
||||
using input = phantom_int<input_tag>;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -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<bool> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<bool> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include <io.hpp>
|
||||
#include <mealy.hpp>
|
||||
#include <read_mealy_from_dot.hpp>
|
||||
|
||||
|
@ -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<vector<string>> 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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue