mirror of
https://github.com/Jaxan/hybrid-ads.git
synced 2025-06-07 17:07:46 +02:00
Adds code to calculate distance between automata relative to log
This commit is contained in:
parent
b2edef0574
commit
8752cebcfa
1 changed files with 109 additions and 0 deletions
109
src/distance.cpp
Normal file
109
src/distance.cpp
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
#include <mealy.hpp>
|
||||||
|
#include <read_mealy_from_dot.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <queue>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(int argc, char * argv[]) {
|
||||||
|
if (argc != 4) {
|
||||||
|
cerr << "usage: distance <file1> <file2> <log>" << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
translation t;
|
||||||
|
const auto m1 = read_mealy_from_dot(argv[1], t);
|
||||||
|
const auto m2 = read_mealy_from_dot(argv[2], t);
|
||||||
|
|
||||||
|
if (m1.input_size != m2.input_size) throw runtime_error("different alphabets!");
|
||||||
|
|
||||||
|
const auto log = [&] {
|
||||||
|
vector<word> log_;
|
||||||
|
string line;
|
||||||
|
ifstream log_file(argv[3]);
|
||||||
|
while (std::getline(log_file, line)) {
|
||||||
|
log_.emplace_back();
|
||||||
|
word & w = log_.back();
|
||||||
|
stringstream ss(line);
|
||||||
|
string symbol;
|
||||||
|
while (ss >> symbol) {
|
||||||
|
w.push_back(t.input_indices.at(symbol));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return log_;
|
||||||
|
}();
|
||||||
|
|
||||||
|
// can be vector of bool, but meh
|
||||||
|
set<pair<state, state>> visited;
|
||||||
|
queue<pair<state, state>> work;
|
||||||
|
|
||||||
|
size_t current_length_work = 0;
|
||||||
|
size_t next_length_work = 0;
|
||||||
|
size_t current_length = 0;
|
||||||
|
size_t current_counterexamples = 0;
|
||||||
|
|
||||||
|
const auto push = [&](auto s1, auto s2) {
|
||||||
|
next_length_work++;
|
||||||
|
work.push({s1, s2});
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto pop = [&]() {
|
||||||
|
const auto p = work.front();
|
||||||
|
work.pop();
|
||||||
|
current_length_work--;
|
||||||
|
return p;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto check_length = [&]() {
|
||||||
|
if (current_length_work == 0) {
|
||||||
|
if (current_counterexamples != 0) {
|
||||||
|
cout << "(-" << current_length << ", " << current_counterexamples << ")" << endl;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
current_length_work = next_length_work;
|
||||||
|
current_length++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
push(0, 0);
|
||||||
|
for(auto const & l : log){
|
||||||
|
state s1 = 0;
|
||||||
|
state s2 = 0;
|
||||||
|
for(auto const & i : l){
|
||||||
|
s1 = apply(m1, s1, i).to;
|
||||||
|
s2 = apply(m2, s2, i).to;
|
||||||
|
push(s1, s2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!work.empty()) {
|
||||||
|
check_length();
|
||||||
|
|
||||||
|
const auto p = pop();
|
||||||
|
const auto s1 = p.first;
|
||||||
|
const auto s2 = p.second;
|
||||||
|
|
||||||
|
if (visited.count(p)) continue;
|
||||||
|
visited.insert(p);
|
||||||
|
|
||||||
|
for (input i = 0; i < m1.input_size; ++i) {
|
||||||
|
auto q1 = apply(m1, s1, i);
|
||||||
|
auto q2 = apply(m2, s2, i);
|
||||||
|
|
||||||
|
if (q1.output != q2.output) {
|
||||||
|
current_counterexamples++;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto new_p = make_pair(q1.to, q2.to);
|
||||||
|
if (visited.count(new_p)) continue;
|
||||||
|
push(q1.to, q2.to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "distance = 0" << endl;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue