formalang/tests/invertFDFA/InvertFDFA.cpp

182 lines
5.9 KiB
C++
Raw Permalink Normal View History

2021-10-05 12:01:30 +00:00
#include <gtest/gtest.h>
#include <random>
#include "regular/RegularTree.hpp"
#include "converters/RegularToNFA.hpp"
#include "converters/NFAToDFA.hpp"
#include "converters/DFAToMinDFA.hpp"
2021-10-05 14:03:03 +00:00
#include "converters/DFAToFDFA.hpp"
#include "converters/InvertFDFA.hpp"
2021-10-05 12:01:30 +00:00
using namespace regular;
using namespace NFA;
using namespace DFA;
using namespace converters;
extern std::mt19937 rnd;
extern std::string GenerateRandomString(std::vector<char> alphabet, size_t len);
2021-10-05 14:03:03 +00:00
TEST(invert_DFA, a_star) {
2021-10-05 12:01:30 +00:00
RegularTree r("a*");
2021-10-05 13:11:24 +00:00
NFAGraph NFA_tree = RegularToNFAGraph(std::move(r));
DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
2021-10-05 12:01:30 +00:00
2021-10-05 14:03:03 +00:00
DFA_graph = DFAGraphToFDFAGraph(std::move(DFA_graph), {'a', 'b', 'c', 'd'});
DFA_graph = InvertFDFAGraph(std::move(DFA_graph));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
2021-10-05 12:01:30 +00:00
std::string s = "";
for (int i = 0; i < 100; ++i) {
2021-10-05 14:03:03 +00:00
ASSERT_EQ(DFA_graph.Accepted(s), false);
2021-10-05 12:01:30 +00:00
s += "a";
}
}
2021-10-05 14:03:03 +00:00
TEST(invert_DFA, a_plus) {
2021-10-05 12:01:30 +00:00
std::string regulars[] = {"a+", "(a)+", "(a+)"};
for (const auto& regular: regulars) {
RegularTree r(regular);
2021-10-05 13:11:24 +00:00
NFAGraph NFA_tree = RegularToNFAGraph(std::move(r));
DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
2021-10-05 12:01:30 +00:00
2021-10-05 14:03:03 +00:00
DFA_graph = DFAGraphToFDFAGraph(std::move(DFA_graph), {'a', 'b', 'c', 'd'});
DFA_graph = InvertFDFAGraph(std::move(DFA_graph));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
2021-10-05 12:01:30 +00:00
std::string s = "";
2021-10-05 14:03:03 +00:00
ASSERT_EQ(DFA_graph.Accepted(s), true);
2021-10-05 12:01:30 +00:00
s += "a";
for (int i = 0; i < 100; ++i) {
2021-10-05 14:03:03 +00:00
ASSERT_EQ(DFA_graph.Accepted(s), false);
2021-10-05 12:01:30 +00:00
s += "a";
}
}
}
2021-10-05 14:03:03 +00:00
TEST(invert_DFA, abc) {
2021-10-05 12:01:30 +00:00
std::string regulars[] = {"abc"};
for (const auto& regular: regulars) {
RegularTree r(regular);
2021-10-05 13:11:24 +00:00
NFAGraph NFA_tree = RegularToNFAGraph(std::move(r));
DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
2021-10-05 12:01:30 +00:00
2021-10-05 14:03:03 +00:00
DFA_graph = DFAGraphToFDFAGraph(std::move(DFA_graph), {'a', 'b', 'c', 'd'});
DFA_graph = InvertFDFAGraph(std::move(DFA_graph));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
ASSERT_EQ(DFA_graph.Accepted("abc"), false);
2021-10-05 12:01:30 +00:00
for (int i = 0; i < 1000; ++i) {
auto s = GenerateRandomString({'a', 'b', 'c', 'd'}, rnd() % 10);
if (s == "abc") continue;
2021-10-05 14:03:03 +00:00
ASSERT_EQ(DFA_graph.Accepted(s), true);
2021-10-05 12:01:30 +00:00
}
}
}
2021-10-05 14:03:03 +00:00
TEST(invert_DFA, a_or_b_or_c) {
2021-10-05 12:01:30 +00:00
std::string regulars[] = {};
for (const auto& regular: regulars) {
RegularTree r("a|b|c");
2021-10-05 13:11:24 +00:00
NFAGraph NFA_tree = RegularToNFAGraph(std::move(r));
DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
2021-10-05 12:01:30 +00:00
2021-10-05 14:03:03 +00:00
DFA_graph = DFAGraphToFDFAGraph(std::move(DFA_graph), {'a', 'b', 'c', 'd'});
DFA_graph = InvertFDFAGraph(std::move(DFA_graph));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
ASSERT_EQ(DFA_graph.Accepted("a"), false);
ASSERT_EQ(DFA_graph.Accepted("b"), false);
ASSERT_EQ(DFA_graph.Accepted("c"), false);
2021-10-05 12:01:30 +00:00
for (int i = 0; i < 1000; ++i) {
auto s = GenerateRandomString({'a', 'b', 'c', 'd'}, rnd() % 10);
if (s == "a") continue;
if (s == "b") continue;
if (s == "c") continue;
2021-10-05 14:03:03 +00:00
ASSERT_EQ(DFA_graph.Accepted(s), true);
2021-10-05 12:01:30 +00:00
}
2021-10-05 14:03:03 +00:00
}
2021-10-05 12:01:30 +00:00
}
2021-10-05 14:03:03 +00:00
TEST(invert_DFA, a_star_or_b_star_or_c_star) {
2021-10-05 12:01:30 +00:00
std::string regulars[] = {"a*|b*|c*", "(a*)|(b*|c*)", "(a*|b*|c*)", "((a*)|(b*)|(c*))"};
for (const auto& regular: regulars) {
RegularTree r(regular);
2021-10-05 13:11:24 +00:00
NFAGraph NFA_tree = RegularToNFAGraph(std::move(r));
DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
2021-10-05 12:01:30 +00:00
2021-10-05 14:03:03 +00:00
DFA_graph = DFAGraphToFDFAGraph(std::move(DFA_graph), {'a', 'b', 'c', 'd'});
DFA_graph = InvertFDFAGraph(std::move(DFA_graph));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
2021-10-05 12:01:30 +00:00
auto check = [](const std::string str) {
std::set<char> s(str.begin(), str.end());
if (s.size() == 0)
return true;
else {
if (s.size() == 1)
return *s.begin() != 'd';
else
return false;
}
};
2021-10-05 14:03:03 +00:00
ASSERT_EQ(DFA_graph.Accepted(""), false);
2021-10-05 12:01:30 +00:00
for (int i = 0; i < 1000; ++i) {
auto s = GenerateRandomString({'a', 'b', 'c', 'd'}, rnd() % 10);
2021-10-05 14:03:03 +00:00
ASSERT_EQ(DFA_graph.Accepted(s), !check(s));
2021-10-05 12:01:30 +00:00
}
2021-10-05 14:03:03 +00:00
}
2021-10-05 12:01:30 +00:00
}
2021-10-05 14:03:03 +00:00
TEST(invert_DFA, _a_star_or_b_star_or_c_star_plus) {
2021-10-05 12:01:30 +00:00
RegularTree r("(a*|b*|c*)+");
2021-10-05 13:11:24 +00:00
NFAGraph NFA_tree = RegularToNFAGraph(std::move(r));
DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
2021-10-05 12:01:30 +00:00
2021-10-05 14:03:03 +00:00
DFA_graph = DFAGraphToFDFAGraph(std::move(DFA_graph), {'a', 'b', 'c', 'd'});
DFA_graph = InvertFDFAGraph(std::move(DFA_graph));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
2021-10-05 12:01:30 +00:00
auto check = [](const std::string str) {
std::set<char> s(str.begin(), str.end());
return s.find('d') == s.end();
};
2021-10-05 14:03:03 +00:00
ASSERT_EQ(DFA_graph.Accepted(""), false);
2021-10-05 12:01:30 +00:00
for (int i = 0; i < 1000; ++i) {
auto s = GenerateRandomString({'a', 'b', 'c', 'd'}, rnd() % 10);
2021-10-05 14:03:03 +00:00
ASSERT_EQ(DFA_graph.Accepted(s), !check(s));
2021-10-05 12:01:30 +00:00
}
}
2021-10-05 14:03:03 +00:00
TEST(invert_DFA, _a_or_b_or_c_star_plus) {
2021-10-05 12:01:30 +00:00
RegularTree r("(a|b|c*)+");
2021-10-05 13:11:24 +00:00
NFAGraph NFA_tree = RegularToNFAGraph(std::move(r));
DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
2021-10-05 12:01:30 +00:00
2021-10-05 14:03:03 +00:00
DFA_graph = DFAGraphToFDFAGraph(std::move(DFA_graph), {'a', 'b', 'c', 'd'});
DFA_graph = InvertFDFAGraph(std::move(DFA_graph));
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
2021-10-05 12:01:30 +00:00
auto check = [](const std::string str) {
std::set<char> s(str.begin(), str.end());
return s.find('d') == s.end();
};
2021-10-05 14:03:03 +00:00
ASSERT_EQ(DFA_graph.Accepted(""), false);
2021-10-05 12:01:30 +00:00
for (int i = 0; i < 1000; ++i) {
auto s = GenerateRandomString({'a', 'b', 'c', 'd'}, rnd() % 10);
2021-10-05 14:03:03 +00:00
ASSERT_EQ(DFA_graph.Accepted(s), !check(s));
2021-10-05 12:01:30 +00:00
}
}