mirror of
https://github.com/Jaxan/hybrid-ads.git
synced 2025-04-27 23:17:44 +02:00
Moves splitting tree to header and adds write to dot function
This commit is contained in:
parent
f7fb5def0c
commit
556abfa569
4 changed files with 122 additions and 43 deletions
50
lib/splitting_tree.hpp
Normal file
50
lib/splitting_tree.hpp
Normal 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);
|
||||||
|
}
|
52
lib/write_splitting_tree_to_dot.cpp
Normal file
52
lib/write_splitting_tree_to_dot.cpp
Normal 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);
|
||||||
|
}
|
8
lib/write_splitting_tree_to_dot.hpp
Normal file
8
lib/write_splitting_tree_to_dot.hpp
Normal 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);
|
55
src/main.cpp
55
src/main.cpp
|
@ -1,6 +1,8 @@
|
||||||
#include <mealy.hpp>
|
#include <mealy.hpp>
|
||||||
#include <partition.hpp>
|
#include <partition.hpp>
|
||||||
#include <read_mealy_from_dot.hpp>
|
#include <read_mealy_from_dot.hpp>
|
||||||
|
#include <splitting_tree.hpp>
|
||||||
|
#include <write_splitting_tree_to_dot.hpp>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
@ -12,54 +14,20 @@ using namespace std;
|
||||||
|
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
|
|
||||||
struct splijtboom {
|
template <typename T>
|
||||||
splijtboom(size_t N)
|
std::vector<T> concat(std::vector<T> const & l, std::vector<T> const & r){
|
||||||
: states(N)
|
std::vector<T> ret(l.size() + r.size());
|
||||||
{
|
auto it = copy(begin(l), end(l), begin(ret));
|
||||||
iota(begin(states), end(states), 0);
|
copy(begin(r), end(r), it);
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]){
|
int main(int argc, char *argv[]){
|
||||||
if(argc < 2) return 1;
|
if(argc < 2) return 1;
|
||||||
if(argc > 2) verbose = argc - 2;
|
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));
|
assert(is_complete(g));
|
||||||
|
|
||||||
const auto N = g.graph.size();
|
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 << "we have " << part.size() << " blocks / " << N << " states" << endl;
|
||||||
cout << "and still " << work.size() << " work" << endl;
|
cout << "and still " << work.size() << " work" << endl;
|
||||||
}
|
}
|
||||||
cout << "jippiejeejjo" << endl;
|
|
||||||
|
write_splitting_tree_to_dot(root, filename + ".splitting_tree.dot");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue