Commit b82573db authored by Gijs van Cuyck's avatar Gijs van Cuyck

finalized debugging of splitting_tree code. splitting tree generation tested on small benchmarks.

parent 3481e128
......@@ -145,6 +145,9 @@ void add_push_new_block(deque<work_set> &work_list, list<list<state>> const &new
}
}
assert(boom.children.size()==boom.separators.size());
if(boom.children.size()>1)
assert(boom.valid_map.size()>0);
assert(boom.states.size() == accumulate(begin(boom.children.back()), end(boom.children.back()), 0ul,
[](size_t l, const splitting_tree &r)
{
......@@ -217,16 +220,18 @@ splitting_tree create_splitting_tree(const mealy &g)
while (!work_list.empty())
{
splitting_tree &boom = work_list.front().work;
unordered_set<state> &valid_set = work_list.front().valid_states;
unordered_set<state> valid_set = move(work_list.front().valid_states);
bool split_on_output = work_list.front().split_on_output;
work_list.pop_front();
//the state for which the current tree prioritizes validity.
//if there is no preference then the first one in the list is chosen.
//used when selecting a separator from multiple options.
//The preference is the one which is valid for valid_target, if it exists.
state valid_target = 0;
state valid_target;
if (valid_set.size() > 0)
valid_target = *valid_set.begin();
else
valid_target = boom.states.front();
const size_t depth = boom.depth;
......@@ -275,12 +280,29 @@ splitting_tree create_splitting_tree(const mealy &g)
//the forced progress might open new options, for which we check first before we force progress again.
force_progress = false;
//copy the valid set so we can delete things from it without affecting the tree.
unordered_set targets(valid_set);
assert(valid_set.size() == 0 || [&valid_set](splitting_tree & boom)
{
for (state s : valid_set)
{
if (std::find(boom.states.begin(), boom.states.end(), s) != boom.states.end())
{
continue;
} else
{
return false;
}
}
return true;
}(boom));
//the set of all states for which we want to be valid: the intersection between valid_set and boom.states.
unordered_set<state> targets;
//an empty set actually means its valid for everything, but you cant delete states from an empty set.
//So we explicitly fill it here.
if (targets.size() < 1)
fill_set(targets, N);
if (valid_set.size() < 1)
targets = unordered_set<state>(boom.states.begin(),boom.states.end());
else
targets = unordered_set<state>(valid_set);
//a list of all the splits that were made.
//they are saved in a list so that they can be modified if required before they are pushed onto the work_list.
......@@ -379,7 +401,7 @@ splitting_tree create_splitting_tree(const mealy &g)
unordered_set<state> new_valid_set = is_valid_for(N,g,new_blocks, symbol);
bool updated_separator =false;
if(new_valid_set.size()>best_separator_value)
if(best_separator_value ==-1 ||new_valid_set.size()>best_separator_value)
{
best_separator=word;
best_separator_value = new_valid_set.size();
......@@ -455,8 +477,7 @@ splitting_tree create_splitting_tree(const mealy &g)
successor_states[apply(g, state, symbol).to] = true;
}
//the state to which the valid target moves when given the selected symbol as input.
state
valid_target_image = apply(g, valid_target, symbol).to;
state valid_target_image = apply(g, valid_target, symbol).to;
const auto &oboom = lca(root, [&successor_states](state state) -> bool
{
......
......@@ -19,8 +19,22 @@ struct splitting_tree {
const std::vector<splitting_tree> & get_children(state s) const {
if(children.size()<1)
throw std::runtime_error("get_children called when there were no children");
else if(children.size()==1)
return children.front();
else if(valid_map.size()<1 ||valid_map.count(s)<1)
return children[0];
throw std::runtime_error("valid map does not contain required information");
else
return children[valid_map.at(s)];
}
//returns the first set of children if the target is not found in valid list.
//otherwise behaves exactly the same as get_children.
//this behaviour is required for the lca_impl, but might mask errors if used elsewere.
const std::vector<splitting_tree> & get_children_reliably(state s) const {
if(children.size()<1)
throw std::runtime_error("get_children called when there were no children");
else if(valid_map.count(s)<1)
return children.front();
else
return children[valid_map.at(s)];
}
......@@ -28,8 +42,10 @@ struct splitting_tree {
const word & get_separator(state s) const {
if (children.size() < 1)
throw std::runtime_error("get_separator called when there were no separators");
else if(children.size()==1)
return separators.front();
else if (valid_map.size() < 1 || valid_map.count(s) < 1)
return separators[0];
throw std::runtime_error("valid map does not contain required information");
else
return separators[valid_map.at(s)];
}
......@@ -60,7 +76,7 @@ size_t lca_impl(splitting_tree const & node, Fun && f, Store && store, state val
// we return this (it's the lca), if more children return a non-nil
// node, then we are the lca
size_t count = 0;
for (const splitting_tree & c : node.get_children(valid_target)) {
for (const splitting_tree & c : node.get_children_reliably(valid_target)) {
auto inner_count = lca_impl(c, f, store,valid_target);
if (inner_count > 0) count++;
}
......
......@@ -7,6 +7,7 @@
#include <string>
#include <sstream>
#include <vector>
/// \brief turns a vector of printable objects into a string, putting a sepperator between every two elements and
/// a concluder after the last one.
......@@ -34,4 +35,14 @@ std::string join(InputIt begin,
return ss.str();
}
template <typename T>
std::ostream & operator<<(std::ostream & s,std::vector<T> v)
{
for(int i = 0; i<v.size(); i++)
{
s<<i << " = " << v[i] << "\n";
}
return s;
}
#endif //COMPLETE_ADS_PRINTING_H
......@@ -4,6 +4,7 @@
#include <read_mealy.hpp>
#include <splitting_tree.hpp>
#include "readable_splitting_tree.hpp"
#include "vector_printing.hpp"
#include <algorithm>
......@@ -58,6 +59,9 @@ struct main_options {
unsigned long k_max = 1; // 3 means 2 extra states. currently not supported
unsigned long seed = 0; // 0 for unset/noise. currently not supported
//"../examples/coffe_machine.dot";
//"../examples/lee_yannakakis_difficult.dot";
//"../examples/lee_yannakakis_distinguishable.dot";
string input_filename = "../examples/coffe_machine.dot";
string output_filename = "";
};
......@@ -166,6 +170,14 @@ int main(int argc, char * argv[]){
splitting_tree complete_splitting_tree = create_splitting_tree(machine);
vector<string> input_translation = create_reverse_map(translation.input_indices);
vector<string> state_translation = create_reverse_map(translation.state_indices);
ofstream translation_file(output_directory+"translations.txt");
translation_file << "input translation\n";
translation_file << input_translation;
translation_file <<"\nstate translation\n";
translation_file << state_translation;
translation_file.close();
readable_splitting_tree translated_tree = translate_splitting_tree(complete_splitting_tree,input_translation,state_translation);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment