#include #include #include "regular/RegularTree.hpp" #include "converters/RegularToNFA.hpp" #include "converters/NFAToDFA.hpp" #include "converters/DFAToMinDFA.hpp" #include "converters/DFAToRegular.hpp" using namespace regular; using namespace NFA; using namespace DFA; using namespace converters; extern std::mt19937 rnd; extern std::string GenerateRandomString(std::vector alphabet, size_t len); TEST(DFA_to_regular2, a_star) { RegularTree r("a*"); NFAGraph NFA_tree = RegularToNFAGraph(std::move(r)); DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); std::string reg = DFAGraphToRegular(std::move(DFA_graph)); reg = RegularTree(reg).ToString(); r = RegularTree(reg); NFA_tree = RegularToNFAGraph(std::move(r)); DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); std::string s = ""; for (int i = 0; i < 100; ++i) { ASSERT_EQ(DFA_graph.Accepted(s), true); s += "a"; } } TEST(DFA_to_regular2, a_plus) { std::string regulars[] = {"a+", "(a)+", "(a+)"}; for (const auto& regular: regulars) { RegularTree r(regular); NFAGraph NFA_tree = RegularToNFAGraph(std::move(r)); DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); std::string reg = DFAGraphToRegular(std::move(DFA_graph)); reg = RegularTree(reg).ToString(); r = RegularTree(reg); NFA_tree = RegularToNFAGraph(std::move(r)); DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); std::string s = ""; ASSERT_EQ(DFA_graph.Accepted(s), false); s += "a"; for (int i = 0; i < 100; ++i) { ASSERT_EQ(DFA_graph.Accepted(s), true); s += "a"; } } } TEST(DFA_to_regular2, abc) { std::string regulars[] = {"abc"}; for (const auto& regular: regulars) { RegularTree r(regular); NFAGraph NFA_tree = RegularToNFAGraph(std::move(r)); DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); std::string reg = DFAGraphToRegular(std::move(DFA_graph)); reg = RegularTree(reg).ToString(); r = RegularTree(reg); NFA_tree = RegularToNFAGraph(std::move(r)); DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); ASSERT_EQ(DFA_graph.Accepted("abc"), true); for (int i = 0; i < 1000; ++i) { auto s = GenerateRandomString({'a', 'b', 'c', 'd'}, rnd() % 10); if (s == "abc") continue; ASSERT_EQ(DFA_graph.Accepted(s), false); } } } TEST(DFA_to_regular2, a_or_b_or_c) { std::string regulars[] = {}; for (const auto& regular: regulars) { RegularTree r("a|b|c"); NFAGraph NFA_tree = RegularToNFAGraph(std::move(r)); DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); std::string reg = DFAGraphToRegular(std::move(DFA_graph)); reg = RegularTree(reg).ToString(); r = RegularTree(reg); NFA_tree = RegularToNFAGraph(std::move(r)); DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); ASSERT_EQ(DFA_graph.Accepted("a"), true); ASSERT_EQ(DFA_graph.Accepted("b"), true); ASSERT_EQ(DFA_graph.Accepted("c"), true); 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; ASSERT_EQ(DFA_graph.Accepted(s), false); } } } TEST(DFA_to_regular2, a_star_or_b_star_or_c_star) { std::string regulars[] = {"a*|b*|c*", "(a*)|(b*|c*)", "(a*|b*|c*)", "((a*)|(b*)|(c*))"}; for (const auto& regular: regulars) { RegularTree r(regular); NFAGraph NFA_tree = RegularToNFAGraph(std::move(r)); DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); std::string reg = DFAGraphToRegular(std::move(DFA_graph)); reg = RegularTree(reg).ToString(); r = RegularTree(reg); NFA_tree = RegularToNFAGraph(std::move(r)); DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); auto check = [](const std::string str) { std::set s(str.begin(), str.end()); if (s.size() == 0) return true; else { if (s.size() == 1) return *s.begin() != 'd'; else return false; } }; ASSERT_EQ(DFA_graph.Accepted(""), true); for (int i = 0; i < 1000; ++i) { auto s = GenerateRandomString({'a', 'b', 'c', 'd'}, rnd() % 10); ASSERT_EQ(DFA_graph.Accepted(s), check(s)); } } } TEST(DFA_to_regular2, _a_star_or_b_star_or_c_star_plus) { RegularTree r("(a*|b*|c*)+"); NFAGraph NFA_tree = RegularToNFAGraph(std::move(r)); DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); std::string reg = DFAGraphToRegular(std::move(DFA_graph)); reg = RegularTree(reg).ToString(); r = RegularTree(reg); NFA_tree = RegularToNFAGraph(std::move(r)); DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); auto check = [](const std::string str) { std::set s(str.begin(), str.end()); return s.find('d') == s.end(); }; ASSERT_EQ(DFA_graph.Accepted(""), true); for (int i = 0; i < 1000; ++i) { auto s = GenerateRandomString({'a', 'b', 'c', 'd'}, rnd() % 10); ASSERT_EQ(DFA_graph.Accepted(s), check(s)); } } TEST(DFA_to_regular2, _a_or_b_or_c_star_plus) { RegularTree r("(a|b|c*)+"); NFAGraph NFA_tree = RegularToNFAGraph(std::move(r)); DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); std::string reg = DFAGraphToRegular(std::move(DFA_graph)); reg = RegularTree(reg).ToString(); r = RegularTree(reg); NFA_tree = RegularToNFAGraph(std::move(r)); DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); auto check = [](const std::string str) { std::set s(str.begin(), str.end()); return s.find('d') == s.end(); }; ASSERT_EQ(DFA_graph.Accepted(""), true); for (int i = 0; i < 1000; ++i) { auto s = GenerateRandomString({'a', 'b', 'c', 'd'}, rnd() % 10); ASSERT_EQ(DFA_graph.Accepted(s), check(s)); } }