1
Fork 0
mirror of https://github.com/Jaxan/hybrid-ads.git synced 2025-04-27 15:07:45 +02:00

Moves splitting tree to header and adds write to dot function

This commit is contained in:
Joshua Moerman 2015-02-17 14:53:32 +01:00
parent f7fb5def0c
commit 556abfa569
4 changed files with 122 additions and 43 deletions

50
lib/splitting_tree.hpp Normal file
View file

@ -0,0 +1,50 @@
#pragma once
#include "mealy.hpp"
#include <numeric>
#include <type_traits>
#include <vector>
struct splijtboom {
splijtboom(size_t N)
: states(N)
{
std::iota(begin(states), end(states), 0);
}
std::vector<state> states;
std::vector<splijtboom> children;
std::vector<input> seperator;
int mark = 0;
};
template <typename Fun>
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 <typename Fun>
splijtboom & lca(splijtboom & root, Fun && f){
static_assert(std::is_same<decltype(f(0)), bool>::value, "f should return a bool");
lca_impl1(root, f);
return lca_impl2(root);
}

View file

@ -0,0 +1,52 @@
#include "write_splitting_tree_to_dot.hpp"
#include "splitting_tree.hpp"
#include <fstream>
#include <functional>
#include <ostream>
#include <queue>
#include <utility>
using namespace std;
template <typename T>
ostream & operator<<(ostream& out, vector<T> 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<pair<int, reference_wrapper<const splijtboom>>> 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);
}

View file

@ -0,0 +1,8 @@
#pragma once
#include <iosfwd>
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);

View file

@ -1,6 +1,8 @@
#include <mealy.hpp>
#include <partition.hpp>
#include <read_mealy_from_dot.hpp>
#include <splitting_tree.hpp>
#include <write_splitting_tree_to_dot.hpp>
#include <cassert>
#include <numeric>
@ -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<state> states;
vector<splijtboom> children;
vector<input> seperator;
int mark = 0;
};
template <typename Fun>
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 <typename Fun>
splijtboom & lca(splijtboom & root, Fun && f){
static_assert(is_same<decltype(f(0)), bool>::value, "f should return a bool");
lca_impl1(root, f);
return lca_impl2(root);
template <typename T>
std::vector<T> concat(std::vector<T> const & l, std::vector<T> const & r){
std::vector<T> 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");
}