mirror of
https://github.com/Jaxan/hybrid-ads.git
synced 2025-04-28 07:27:45 +02:00
Refactors the dist_seq to distinguishing_sequence
This commit is contained in:
parent
4a2bc674cc
commit
a7a7f815da
8 changed files with 112 additions and 112 deletions
|
@ -1,23 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "mealy.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
struct dist_seq {
|
|
||||||
dist_seq(size_t N, size_t depth)
|
|
||||||
: CI(N)
|
|
||||||
, depth(depth)
|
|
||||||
{
|
|
||||||
for(size_t i = 0; i < N; ++i)
|
|
||||||
CI[i] = {i, i};
|
|
||||||
}
|
|
||||||
|
|
||||||
// current, initial
|
|
||||||
std::vector<std::pair<state, state>> CI;
|
|
||||||
std::vector<input> word;
|
|
||||||
std::vector<dist_seq> children;
|
|
||||||
size_t depth;
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,29 +1,26 @@
|
||||||
#include "create_adaptive_distinguishing_sequence.hpp"
|
#include "create_adaptive_distinguishing_sequence.hpp"
|
||||||
#include "splitting_tree.hpp"
|
#include "create_splitting_tree.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
result2 create_adaptive_distinguishing_sequence(const result & splitting_tree){
|
distinguishing_sequence create_adaptive_distinguishing_sequence(const result & splitting_tree){
|
||||||
const auto & root = splitting_tree.root;
|
const auto & root = splitting_tree.root;
|
||||||
const auto & succession = splitting_tree.successor_cache;
|
const auto & succession = splitting_tree.successor_cache;
|
||||||
const auto N = root.states.size();
|
const auto N = root.states.size();
|
||||||
|
|
||||||
result2 r(N);
|
distinguishing_sequence sequence(N, 0);
|
||||||
auto & root_seq = r.sequence;
|
|
||||||
|
|
||||||
{
|
queue<reference_wrapper<distinguishing_sequence>> work;
|
||||||
queue<reference_wrapper<dist_seq>> work2;
|
work.push(sequence);
|
||||||
work2.push(root_seq);
|
|
||||||
|
|
||||||
while(!work2.empty()){
|
while(!work.empty()){
|
||||||
dist_seq & node = work2.front();
|
distinguishing_sequence & node = work.front();
|
||||||
work2.pop();
|
work.pop();
|
||||||
|
|
||||||
if(node.CI.size() < 2) continue;
|
if(node.CI.size() < 2) continue;
|
||||||
|
|
||||||
|
@ -40,7 +37,7 @@ result2 create_adaptive_distinguishing_sequence(const result & splitting_tree){
|
||||||
|
|
||||||
node.word = oboom.seperator;
|
node.word = oboom.seperator;
|
||||||
for(auto && c : oboom.children){
|
for(auto && c : oboom.children){
|
||||||
dist_seq new_c(0, node.depth + 1);
|
distinguishing_sequence new_c(0, node.depth + 1);
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
|
@ -70,10 +67,9 @@ result2 create_adaptive_distinguishing_sequence(const result & splitting_tree){
|
||||||
assert(node.children.size() > 1);
|
assert(node.children.size() > 1);
|
||||||
|
|
||||||
for(auto & c : node.children) {
|
for(auto & c : node.children) {
|
||||||
work2.push(c);
|
work.push(c);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return sequence;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,32 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "adaptive_distinguishing_sequence.hpp"
|
#include "mealy.hpp"
|
||||||
#include "create_splitting_tree.hpp"
|
|
||||||
|
|
||||||
struct result2 {
|
#include <vector>
|
||||||
result2(size_t N)
|
#include <utility>
|
||||||
: sequence(N, 0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// The adaptive distinguishing sequence as described in Lee & Yannakakis
|
struct result;
|
||||||
// This is really a tree!
|
struct distinguishing_sequence;
|
||||||
dist_seq sequence;
|
|
||||||
|
|
||||||
|
// Creates a distinguishing sequence based on the output of the first algorithm
|
||||||
|
distinguishing_sequence create_adaptive_distinguishing_sequence(result const & splitting_tree);
|
||||||
|
|
||||||
|
|
||||||
|
// The adaptive distinguishing sequence as described in Lee & Yannakakis
|
||||||
|
// This is really a tree!
|
||||||
|
struct distinguishing_sequence {
|
||||||
|
distinguishing_sequence(size_t N, size_t depth)
|
||||||
|
: CI(N)
|
||||||
|
, depth(depth)
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < N; ++i)
|
||||||
|
CI[i] = {i, i};
|
||||||
|
}
|
||||||
|
|
||||||
|
// current, initial
|
||||||
|
std::vector<std::pair<state, state>> CI;
|
||||||
|
std::vector<input> word;
|
||||||
|
std::vector<distinguishing_sequence> children;
|
||||||
|
size_t depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
result2 create_adaptive_distinguishing_sequence(result const & splitting_tree);
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "create_splitting_tree.hpp"
|
#include "create_splitting_tree.hpp"
|
||||||
|
#include "partition.hpp"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
|
@ -1,11 +1,31 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mealy.hpp"
|
#include "mealy.hpp"
|
||||||
#include "partition.hpp"
|
|
||||||
#include "splitting_tree.hpp"
|
#include "splitting_tree.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
struct options;
|
||||||
|
struct result;
|
||||||
|
|
||||||
|
|
||||||
|
// Creates a Lee & Yannakakis style splitting tree
|
||||||
|
// Depending on the options it can also create the classical Hopcroft splitting tree
|
||||||
|
result create_splitting_tree(Mealy const & m, options opt);
|
||||||
|
|
||||||
|
|
||||||
|
// The algorithm can be altered in some ways. This struct provides options
|
||||||
|
// to the algorithm
|
||||||
|
struct options {
|
||||||
|
bool check_validity = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr options with_validity_check{true};
|
||||||
|
constexpr options without_validity_check{false};
|
||||||
|
|
||||||
|
|
||||||
|
// The algorithm constructs more than the splitting tree
|
||||||
|
// We capture the other information as well
|
||||||
struct result {
|
struct result {
|
||||||
result(size_t N)
|
result(size_t N)
|
||||||
: root(N, 0)
|
: root(N, 0)
|
||||||
|
@ -22,12 +42,3 @@ struct result {
|
||||||
// false <-> no adaptive distinguishing sequence
|
// false <-> no adaptive distinguishing sequence
|
||||||
bool is_complete;
|
bool is_complete;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct options {
|
|
||||||
bool check_validity = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr options with_validity_check{true};
|
|
||||||
constexpr options without_validity_check{false};
|
|
||||||
|
|
||||||
result create_splitting_tree(Mealy const & m, options opt);
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "write_tree_to_dot.hpp"
|
#include "write_tree_to_dot.hpp"
|
||||||
#include "adaptive_distinguishing_sequence.hpp"
|
#include "create_adaptive_distinguishing_sequence.hpp"
|
||||||
#include "splitting_tree.hpp"
|
#include "splitting_tree.hpp"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -31,8 +31,8 @@ void write_splitting_tree_to_dot(const splijtboom& root, const string& filename)
|
||||||
write_splitting_tree_to_dot(root, file);
|
write_splitting_tree_to_dot(root, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_adaptive_distinguishing_sequence_to_dot(const dist_seq & root, ostream & out){
|
void write_adaptive_distinguishing_sequence_to_dot(const distinguishing_sequence & root, ostream & out){
|
||||||
write_tree_to_dot(root, [](const dist_seq & node, ostream& out){
|
write_tree_to_dot(root, [](const distinguishing_sequence & node, ostream& out){
|
||||||
if(!node.word.empty()){
|
if(!node.word.empty()){
|
||||||
out << node.word;
|
out << node.word;
|
||||||
} else {
|
} else {
|
||||||
|
@ -43,7 +43,7 @@ void write_adaptive_distinguishing_sequence_to_dot(const dist_seq & root, ostrea
|
||||||
}, out);
|
}, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_adaptive_distinguishing_sequence_to_dot(const dist_seq & root, string const & filename){
|
void write_adaptive_distinguishing_sequence_to_dot(const distinguishing_sequence & root, string const & filename){
|
||||||
ofstream file(filename);
|
ofstream file(filename);
|
||||||
write_adaptive_distinguishing_sequence_to_dot(root, file);
|
write_adaptive_distinguishing_sequence_to_dot(root, file);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,6 @@ struct splijtboom;
|
||||||
void write_splitting_tree_to_dot(const splijtboom & root, std::ostream & out);
|
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);
|
void write_splitting_tree_to_dot(const splijtboom & root, std::string const & filename);
|
||||||
|
|
||||||
struct dist_seq;
|
struct distinguishing_sequence;
|
||||||
void write_adaptive_distinguishing_sequence_to_dot(const dist_seq & root, std::ostream & out);
|
void write_adaptive_distinguishing_sequence_to_dot(const distinguishing_sequence & root, std::ostream & out);
|
||||||
void write_adaptive_distinguishing_sequence_to_dot(const dist_seq & root, std::string const & filename);
|
void write_adaptive_distinguishing_sequence_to_dot(const distinguishing_sequence & root, std::string const & filename);
|
||||||
|
|
25
src/main.cpp
25
src/main.cpp
|
@ -1,21 +1,20 @@
|
||||||
#include <create_adaptive_distinguishing_sequence.hpp>
|
#include <create_adaptive_distinguishing_sequence.hpp>
|
||||||
#include <create_splitting_tree.hpp>
|
#include <create_splitting_tree.hpp>
|
||||||
|
#include <logging.hpp>
|
||||||
#include <read_mealy_from_dot.hpp>
|
#include <read_mealy_from_dot.hpp>
|
||||||
#include <write_tree_to_dot.hpp>
|
#include <write_tree_to_dot.hpp>
|
||||||
#include <logging.hpp>
|
|
||||||
|
|
||||||
#include <boost/iostreams/device/file_descriptor.hpp>
|
#include <boost/iostreams/device/file_descriptor.hpp>
|
||||||
#include <boost/iostreams/filtering_stream.hpp>
|
|
||||||
#include <boost/iostreams/filter/gzip.hpp>
|
#include <boost/iostreams/filter/gzip.hpp>
|
||||||
|
#include <boost/iostreams/filtering_stream.hpp>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <stack>
|
|
||||||
#include <functional>
|
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stack>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -127,7 +126,7 @@ int main(int argc, char *argv[]){
|
||||||
write_splitting_tree_to_dot(splitting_tree.root, tree_filename);
|
write_splitting_tree_to_dot(splitting_tree.root, tree_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto distinguishing_sequence = [&]{
|
const auto sequence = [&]{
|
||||||
timer t("Lee & Yannakakis II");
|
timer t("Lee & Yannakakis II");
|
||||||
return create_adaptive_distinguishing_sequence(splitting_tree);
|
return create_adaptive_distinguishing_sequence(splitting_tree);
|
||||||
}();
|
}();
|
||||||
|
@ -135,7 +134,7 @@ int main(int argc, char *argv[]){
|
||||||
if(false){
|
if(false){
|
||||||
timer t("writing dist sequence");
|
timer t("writing dist sequence");
|
||||||
const string dseq_filename = splitting_tree.is_complete ? (filename + ".dist_seq") : (filename + ".incomplete_dist_seq");
|
const string dseq_filename = splitting_tree.is_complete ? (filename + ".dist_seq") : (filename + ".incomplete_dist_seq");
|
||||||
write_adaptive_distinguishing_sequence_to_dot(distinguishing_sequence.sequence, dseq_filename);
|
write_adaptive_distinguishing_sequence_to_dot(sequence, dseq_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto seperating_family = [&]{
|
const auto seperating_family = [&]{
|
||||||
|
@ -144,12 +143,12 @@ int main(int argc, char *argv[]){
|
||||||
using SepSet = vector<Word>;
|
using SepSet = vector<Word>;
|
||||||
vector<SepSet> seperating_family(machine.graph_size);
|
vector<SepSet> seperating_family(machine.graph_size);
|
||||||
|
|
||||||
stack<pair<vector<input>, reference_wrapper<const dist_seq>>> work;
|
stack<pair<vector<input>, reference_wrapper<const distinguishing_sequence>>> work;
|
||||||
work.push({{}, distinguishing_sequence.sequence});
|
work.push({{}, sequence});
|
||||||
|
|
||||||
while(!work.empty()){
|
while(!work.empty()){
|
||||||
auto word = work.top().first;
|
auto word = work.top().first;
|
||||||
const dist_seq & node = work.top().second;
|
const distinguishing_sequence & node = work.top().second;
|
||||||
work.pop();
|
work.pop();
|
||||||
|
|
||||||
if(node.children.empty()){
|
if(node.children.empty()){
|
||||||
|
|
Loading…
Add table
Reference in a new issue