mirror of
https://github.com/Jaxan/hybrid-ads.git
synced 2025-04-27 23:17:44 +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);
|
vector<bool> states(N, false);
|
||||||
for(auto && state : node.CI){
|
for(auto && state : node.CI){
|
||||||
states[state.first.base()] = true;
|
states[state.first] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto & oboom = lca(root, [&states](state state) -> bool{
|
const auto & oboom = lca(root, [&states](state state) -> bool{
|
||||||
return states[state.base()];
|
return states[state];
|
||||||
});
|
});
|
||||||
|
|
||||||
if(oboom.children.empty()) continue;
|
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]) {
|
} else if(node.CI[i].first > c.states[j]) {
|
||||||
j++;
|
j++;
|
||||||
} else {
|
} 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;
|
const auto init = node.CI[i].second;
|
||||||
new_c.CI.push_back({curr, init});
|
new_c.CI.push_back({curr, init});
|
||||||
i++;
|
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){
|
inline auto is_complete(const mealy & m){
|
||||||
for(state n = 0; n < m.graph_size; ++n){
|
for(state n = 0; n < m.graph_size; ++n){
|
||||||
if(m.graph[n.base()].size() != m.input_size) return false;
|
if(m.graph[n].size() != m.input_size) return false;
|
||||||
for(auto && e : m.graph[n.base()]) if(e.to == -1 || e.output == -1) return false;
|
for(auto && e : m.graph[n]) if(e.to == -1 || e.output == -1) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto apply(mealy const & m, state state, input input){
|
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>
|
template <typename Iterator>
|
||||||
auto apply(mealy const & m, state state, Iterator b, Iterator e){
|
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){
|
while(b != e){
|
||||||
ret = apply(m, state, *b++);
|
ret = apply(m, ret.to, *b++);
|
||||||
state = ret.to;
|
|
||||||
}
|
}
|
||||||
return ret;
|
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++;
|
if(t.output_indices.count(output) < 1) t.output_indices[output] = t.max_output++;
|
||||||
|
|
||||||
// add edge
|
// add edge
|
||||||
m.graph.resize(max_state.base());
|
m.graph.resize(max_state);
|
||||||
auto & v = m.graph[state_indices[lh].base()];
|
auto & v = m.graph[state_indices[lh]];
|
||||||
v.resize(t.max_input.base());
|
v.resize(t.max_input);
|
||||||
v[t.input_indices[input].base()] = {state_indices[rh], t.output_indices[output]};
|
v[t.input_indices[input]] = {state_indices[rh], t.output_indices[output]};
|
||||||
}
|
}
|
||||||
|
|
||||||
m.graph_size = max_state.base();
|
m.graph_size = max_state;
|
||||||
m.input_size = t.max_input.base();
|
m.input_size = t.max_input;
|
||||||
m.output_size = t.max_output.base();
|
m.output_size = t.max_output;
|
||||||
|
|
||||||
if(m.graph_size == 0) throw runtime_error("Empty state set");
|
if(m.graph_size == 0) throw runtime_error("Empty state set");
|
||||||
if(m.input_size == 0) throw runtime_error("Empty input 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> create_reverse_map(std::map<std::string, T> const & indices){
|
||||||
std::vector<std::string> ret(indices.size());
|
std::vector<std::string> ret(indices.size());
|
||||||
for(auto&& p : indices){
|
for(auto&& p : indices){
|
||||||
ret[p.second.base()] = p.first;
|
ret[p.second] = p.first;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ seperating_family create_seperating_family(const adaptive_distinguishing_sequenc
|
||||||
// add sequence to this leave
|
// add sequence to this leave
|
||||||
for(auto && p : node.CI){
|
for(auto && p : node.CI){
|
||||||
const auto state = p.second;
|
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
|
// 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 s = p.second;
|
||||||
const auto t = q.second;
|
const auto t = q.second;
|
||||||
if(s == t) continue;
|
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){
|
while(jt != ed){
|
||||||
for(auto && s : it->states){
|
for(auto && s : it->states){
|
||||||
for(auto && t : jt->states){
|
for(auto && t : jt->states){
|
||||||
assert(all_pair_seperating_sequences[t.base()][s.base()].empty());
|
assert(all_pair_seperating_sequences[t][s].empty());
|
||||||
assert(all_pair_seperating_sequences[s.base()][t.base()].empty());
|
assert(all_pair_seperating_sequences[s][t].empty());
|
||||||
all_pair_seperating_sequences[t.base()][s.base()] = node.seperator;
|
all_pair_seperating_sequences[t][s] = node.seperator;
|
||||||
all_pair_seperating_sequences[s.base()][t.base()] = node.seperator;
|
all_pair_seperating_sequences[s][t] = node.seperator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jt++;
|
jt++;
|
||||||
|
|
|
@ -68,7 +68,7 @@ result create_splitting_tree(const mealy& g, options opt){
|
||||||
|
|
||||||
for(auto && block : blocks) {
|
for(auto && block : blocks) {
|
||||||
const auto new_blocks = partition_(begin(block), end(block), [symbol, &g](state state){
|
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);
|
}, N);
|
||||||
for(auto && new_block : new_blocks){
|
for(auto && new_block : new_blocks){
|
||||||
if(new_block.size() != 1) return false;
|
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){
|
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));
|
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
|
// 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 new_blocks = partition_(begin(boom.states), end(boom.states), [symbol, depth, &g, &update_succession](state state){
|
||||||
const auto ret = apply(g, state, symbol);
|
const auto ret = apply(g, state, symbol);
|
||||||
update_succession(state, ret.to, depth);
|
update_succession(state, ret.to, depth);
|
||||||
return ret.output.base();
|
return ret.output;
|
||||||
}, Q);
|
}, Q);
|
||||||
|
|
||||||
// no split -> continue with other input symbols
|
// 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){
|
for(input symbol : all_inputs){
|
||||||
vector<bool> successor_states(N, false);
|
vector<bool> successor_states(N, false);
|
||||||
for(auto && state : boom.states){
|
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{
|
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
|
// 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 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));
|
const auto ret = apply(g, state, begin(word), end(word));
|
||||||
update_succession(state, ret.to, depth);
|
update_succession(state, ret.to, depth);
|
||||||
return ret.output.base();
|
return ret.output;
|
||||||
}, Q);
|
}, Q);
|
||||||
|
|
||||||
// not a valid split -> continue
|
// 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;
|
const auto d = p.first - 1;
|
||||||
work.pop();
|
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){
|
for(input i = 0; i < machine.input_size; ++i){
|
||||||
const auto v = apply(machine, u, i).to;
|
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] = words[u];
|
||||||
words[v.base()].push_back(i);
|
words[v].push_back(i);
|
||||||
work.push({d, v});
|
work.push({d, v});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,17 +55,17 @@ transfer_sequences create_randomized_transfer_sequences(const mealy & machine, s
|
||||||
const auto d = p.first - 1;
|
const auto d = p.first - 1;
|
||||||
work.pop();
|
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);
|
shuffle(begin(all_inputs), end(all_inputs), generator);
|
||||||
for(input i : all_inputs){
|
for(input i : all_inputs){
|
||||||
const auto v = apply(machine, u, i).to;
|
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] = words[u];
|
||||||
words[v.base()].push_back(i);
|
words[v].push_back(i);
|
||||||
work.push({d, v});
|
work.push({d, v});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "phantom.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/* We use size_t's for easy indexing. But we do not want to mix states and
|
// We use size_ts for fast indexing. Note that there is little type safety here
|
||||||
* inputs. We use phantom typing to "generate" distinguished types :).
|
using state = size_t;
|
||||||
*/
|
using input = size_t;
|
||||||
using state = phantom<size_t, struct state_tag>;
|
using output = size_t;
|
||||||
using input = phantom<size_t, struct input_tag>;
|
|
||||||
using output = phantom<size_t, struct output_tag>;
|
|
||||||
|
|
||||||
using word = std::vector<input>;
|
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
|
// 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){
|
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);
|
auto it = begin(ret);
|
||||||
for(auto const & x : seqs){
|
for(auto const & x : seqs){
|
||||||
for(input i = min; i < max; ++i){
|
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){
|
for(input i = 0; i < machine.input_size; ++i){
|
||||||
//const auto test1 = apply(machine, s, i).output != machine.output_indices.at("quiescence");
|
//const auto test1 = apply(machine, s, i).output != machine.output_indices.at("quiescence");
|
||||||
const auto test2 = apply(machine, s, i).to != s;
|
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;
|
return distributions;
|
||||||
});
|
});
|
||||||
|
@ -122,7 +122,7 @@ int main(int argc, char *argv[]) try {
|
||||||
const auto inputs = inputs_fut.get();
|
const auto inputs = inputs_fut.get();
|
||||||
|
|
||||||
const auto print_word = [&](auto w){
|
const auto print_word = [&](auto w){
|
||||||
for(auto && x : w) cout << inputs[x.base()] << ' ';
|
for(auto && x : w) cout << inputs[x] << ' ';
|
||||||
};
|
};
|
||||||
|
|
||||||
if(statistics){
|
if(statistics){
|
||||||
|
@ -176,9 +176,9 @@ int main(int argc, char *argv[]) try {
|
||||||
for(int k = 0; k <= k_max; ++k){
|
for(int k = 0; k <= k_max; ++k){
|
||||||
cerr << "*** K = " << k << endl;
|
cerr << "*** K = " << k << endl;
|
||||||
for(state s = 0; s < machine.graph_size; ++s){
|
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){
|
for(auto && r : all_sequences){
|
||||||
print_word(prefix);
|
print_word(prefix);
|
||||||
print_word(r);
|
print_word(r);
|
||||||
|
@ -214,14 +214,14 @@ int main(int argc, char *argv[]) try {
|
||||||
m.reserve(k_max + 2);
|
m.reserve(k_max + 2);
|
||||||
size_t minimal_size = k_max + 1;
|
size_t minimal_size = k_max + 1;
|
||||||
while(minimal_size || unfair_coin(generator)){
|
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);
|
m.push_back(i);
|
||||||
current_state = apply(machine, current_state, i).to;
|
current_state = apply(machine, current_state, i).to;
|
||||||
if(minimal_size) minimal_size--;
|
if(minimal_size) minimal_size--;
|
||||||
}
|
}
|
||||||
|
|
||||||
using params = uniform_int_distribution<size_t>::param_type;
|
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})];
|
const auto & s = suffixes[suffix_selection(generator, params{0, suffixes.size()-1})];
|
||||||
|
|
||||||
print_word(p);
|
print_word(p);
|
||||||
|
|
|
@ -16,13 +16,13 @@ auto create_transfer_sequences(const mealy& machine, const state s, const input
|
||||||
const auto u = work.front();
|
const auto u = work.front();
|
||||||
work.pop();
|
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){
|
for(input i = 0; i < machine.input_size; ++i){
|
||||||
if(i == ignore) continue;
|
if(i == ignore) continue;
|
||||||
const auto v = apply(machine, u, i).to;
|
const auto v = apply(machine, u, i).to;
|
||||||
if(visited[v.base()]) continue;
|
if(visited[v]) continue;
|
||||||
work.push(v);
|
work.push(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ int main(int argc, char *argv[]){
|
||||||
|
|
||||||
// vector<vector<bool>> table(machine.input_size);
|
// vector<vector<bool>> table(machine.input_size);
|
||||||
// for(input i = 0; i < machine.input_size; ++i){
|
// 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
|
// 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){
|
for(auto && p : state_cover){
|
||||||
state s = 0;
|
state s = 0;
|
||||||
for(auto && inp : p){
|
for(auto && inp : p){
|
||||||
if(!visited[s.base()]) visited[s.base()] = i;
|
if(!visited[s]) visited[s] = i;
|
||||||
s = apply(machine, s, inp).to;
|
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";
|
out << "digraph {\n";
|
||||||
|
|
||||||
for(state s = 0; s < machine.graph_size; ++s){
|
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 << "\t" << "s" << s << " [";
|
||||||
out << "color=\"" << (is_visited ? "green" : "red") << "\"" << ", ";
|
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";
|
out << "]\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for(state s = 0; s < machine.graph_size; ++s){
|
for(state s = 0; s < machine.graph_size; ++s){
|
||||||
vector<bool> visited(machine.graph_size, false);
|
vector<bool> visited(machine.graph_size, false);
|
||||||
visited[s.base()] = true;
|
visited[s] = true;
|
||||||
for(input i = 0; i < machine.input_size; ++i){
|
for(input i = 0; i < machine.input_size; ++i){
|
||||||
const auto t = apply(machine, s, i).to;
|
const auto t = apply(machine, s, i).to;
|
||||||
if(visited[t.base()]) continue;
|
if(visited[t]) continue;
|
||||||
out << "\t" << "s" << s << " -> " << "s" << t << "\n";
|
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();
|
const state s = work.front();
|
||||||
work.pop();
|
work.pop();
|
||||||
|
|
||||||
if(visited[s.base()]) continue;
|
if(visited[s]) continue;
|
||||||
visited[s.base()] = true;
|
visited[s] = true;
|
||||||
|
|
||||||
for(auto x : subalphabet){
|
for(auto x : subalphabet){
|
||||||
const state t = apply(machine, s, x).to;
|
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";
|
out << "digraph {\n";
|
||||||
|
|
||||||
for(state s = 0; s < machine.graph_size; ++s){
|
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 << "\t" << "s" << s << " [";
|
||||||
out << "color=\"" << (is_visited ? "green" : "red") << "\"" << ", ";
|
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";
|
out << "]\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for(state s = 0; s < machine.graph_size; ++s){
|
for(state s = 0; s < machine.graph_size; ++s){
|
||||||
vector<bool> visited(machine.graph_size, false);
|
vector<bool> visited(machine.graph_size, false);
|
||||||
visited[s.base()] = true;
|
visited[s] = true;
|
||||||
for(input i = 0; i < machine.input_size; ++i){
|
for(input i = 0; i < machine.input_size; ++i){
|
||||||
const auto t = apply(machine, s, i).to;
|
const auto t = apply(machine, s, i).to;
|
||||||
if(visited[t.base()]) continue;
|
if(visited[t]) continue;
|
||||||
out << "\t" << "s" << s << " -> " << "s" << t << "\n";
|
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 <mealy.hpp>
|
||||||
#include <read_mealy_from_dot.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";
|
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[]){
|
int main(int argc, char *argv[]){
|
||||||
if(argc != 2) return 37;
|
if(argc != 2) return 37;
|
||||||
|
|
||||||
const string filename = argv[1];
|
const string filename = argv[1];
|
||||||
if(filename.find("test_suite") == string::npos){
|
print_stats_for_machine(filename);
|
||||||
print_stats_for_machine(filename);
|
|
||||||
} else {
|
|
||||||
print_stats_for_suite(filename);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue