From 556abfa5695fef09a27c0b8e3993c1ba2fcb5a38 Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Tue, 17 Feb 2015 14:53:32 +0100 Subject: [PATCH] Moves splitting tree to header and adds write to dot function --- lib/splitting_tree.hpp | 50 ++++++++++++++++++++++++++ lib/write_splitting_tree_to_dot.cpp | 52 +++++++++++++++++++++++++++ lib/write_splitting_tree_to_dot.hpp | 8 +++++ src/main.cpp | 55 +++++++---------------------- 4 files changed, 122 insertions(+), 43 deletions(-) create mode 100644 lib/splitting_tree.hpp create mode 100644 lib/write_splitting_tree_to_dot.cpp create mode 100644 lib/write_splitting_tree_to_dot.hpp diff --git a/lib/splitting_tree.hpp b/lib/splitting_tree.hpp new file mode 100644 index 0000000..8dfd0e3 --- /dev/null +++ b/lib/splitting_tree.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "mealy.hpp" + +#include +#include +#include + +struct splijtboom { + splijtboom(size_t N) + : states(N) + { + std::iota(begin(states), end(states), 0); + } + + std::vector states; + std::vector children; + std::vector seperator; + int mark = 0; +}; + +template +void lca_impl1(splijtboom & node, Fun && f){ + node.mark = 0; + if(!node.children.empty()){ + for(auto && c : node.children){ + lca_impl1(c, f); + if(c.mark) node.mark++; + } + } else { + for(auto && s : node.states){ + if(f(s)) node.mark++; + } + } +} + +inline splijtboom & lca_impl2(splijtboom & node){ + if(node.mark > 1) return node; + for(auto && c : node.children){ + if(c.mark > 0) return lca_impl2(c); + } + return node; // this is a leaf +} + +template +splijtboom & lca(splijtboom & root, Fun && f){ + static_assert(std::is_same::value, "f should return a bool"); + lca_impl1(root, f); + return lca_impl2(root); +} diff --git a/lib/write_splitting_tree_to_dot.cpp b/lib/write_splitting_tree_to_dot.cpp new file mode 100644 index 0000000..f817d39 --- /dev/null +++ b/lib/write_splitting_tree_to_dot.cpp @@ -0,0 +1,52 @@ +#include "write_splitting_tree_to_dot.hpp" +#include "splitting_tree.hpp" + +#include +#include +#include +#include +#include + +using namespace std; + +template +ostream & operator<<(ostream& out, vector const & x){ + if(x.empty()) return out; + + auto it = begin(x); + out << *it++; + while(it != end(x)) out << " " << *it++; + return out; +} + +void write_splitting_tree_to_dot(const splijtboom& root, ostream& out){ + out << "digraph splijtboom {\n"; + + // breadth first + int global_id = 0; + queue>> work; + work.push({global_id++, root}); + while(!work.empty()){ + const auto id = work.front().first; + const splijtboom & node = work.front().second; + work.pop(); + + out << "\n\ts" << id << " [label=\"" << node.states; + if(!node.seperator.empty()) out << "\\n" << node.seperator; + out << "\"];\n"; + + for(auto && c : node.children){ + int new_id = global_id++; + out << "\ts" << id << " -> " << "s" << new_id << ";\n"; + work.push({new_id, c}); + } + } + + out << "}" << endl; +} + + +void write_splitting_tree_to_dot(const splijtboom& root, const string& filename){ + ofstream file(filename); + write_splitting_tree_to_dot(root, file); +} diff --git a/lib/write_splitting_tree_to_dot.hpp b/lib/write_splitting_tree_to_dot.hpp new file mode 100644 index 0000000..8c43184 --- /dev/null +++ b/lib/write_splitting_tree_to_dot.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include + +struct splijtboom; + +void write_splitting_tree_to_dot(const splijtboom & root, std::ostream & out); +void write_splitting_tree_to_dot(const splijtboom & root, std::string const & filename); diff --git a/src/main.cpp b/src/main.cpp index 677f4a5..70dc271 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include @@ -12,54 +14,20 @@ using namespace std; int verbose = 0; -struct splijtboom { - splijtboom(size_t N) - : states(N) - { - iota(begin(states), end(states), 0); - } - - vector states; - vector children; - vector seperator; - int mark = 0; -}; - -template -void lca_impl1(splijtboom & node, Fun && f){ - node.mark = 0; - if(!node.children.empty()){ - for(auto && c : node.children){ - lca_impl1(c, f); - if(c.mark) node.mark++; - } - } else { - for(auto && s : node.states){ - if(f(s)) node.mark++; - } - } -} - -splijtboom & lca_impl2(splijtboom & node){ - if(node.mark > 1) return node; - for(auto && c : node.children){ - if(c.mark > 0) return lca_impl2(c); - } - return node; // this is a leaf -} - -template -splijtboom & lca(splijtboom & root, Fun && f){ - static_assert(is_same::value, "f should return a bool"); - lca_impl1(root, f); - return lca_impl2(root); +template +std::vector concat(std::vector const & l, std::vector const & r){ + std::vector ret(l.size() + r.size()); + auto it = copy(begin(l), end(l), begin(ret)); + copy(begin(r), end(r), it); + return ret; } int main(int argc, char *argv[]){ if(argc < 2) return 1; if(argc > 2) verbose = argc - 2; - const auto g = read_mealy_from_dot(argv[1], verbose); + const string filename = argv[1]; + const auto g = read_mealy_from_dot(filename, verbose); assert(is_complete(g)); const auto N = g.graph.size(); @@ -195,6 +163,7 @@ int main(int argc, char *argv[]){ cout << "we have " << part.size() << " blocks / " << N << " states" << endl; cout << "and still " << work.size() << " work" << endl; } - cout << "jippiejeejjo" << endl; + + write_splitting_tree_to_dot(root, filename + ".splitting_tree.dot"); }