refactoring & add invertion
This commit is contained in:
parent
1fd4158840
commit
aad17d8c8c
|
@ -19,7 +19,7 @@ set(SOURCE_FILES
|
|||
src/regular/RegularTree.cpp
|
||||
src/regular/RegularTreeNode.cpp
|
||||
src/NFA/NFAGraph.cpp
|
||||
src/NFA/NFATreeVertex.cpp
|
||||
src/NFA/NFAGraphVertex.cpp
|
||||
src/converters/RegularToNFA.cpp
|
||||
src/converters/NFAToDFA.cpp
|
||||
src/DFA/DFAGraph.cpp
|
||||
|
@ -27,18 +27,20 @@ set(SOURCE_FILES
|
|||
src/converters/DFAToFDFA.cpp
|
||||
src/converters/DFAToMinDFA.cpp
|
||||
src/converters/DFAToRegular.cpp
|
||||
src/converters/InvertFDFA.cpp
|
||||
)
|
||||
|
||||
set(TEST_FILES
|
||||
tests/regular/parse_regular.cpp
|
||||
tests/NFAToDFA/check_equivalence.cpp
|
||||
tests/regularToDFA/regularToDFA.cpp
|
||||
tests/regular/ParseRegular.cpp
|
||||
tests/NFAToDFA/CheckEquivalence.cpp
|
||||
tests/regularToDFA/RegularToDFA.cpp
|
||||
tests/DFAToRegular/DFAToRegular.cpp
|
||||
tests/invertFDFA/InvertFDFA.cpp
|
||||
)
|
||||
|
||||
add_executable(Formalang src/main.cpp ${SOURCE_FILES})
|
||||
|
||||
add_executable(Tests tests/test_main.cpp ${TEST_FILES} ${SOURCE_FILES})
|
||||
add_executable(Tests tests/MainTest.cpp ${TEST_FILES} ${SOURCE_FILES})
|
||||
|
||||
target_link_libraries(Tests ${GTEST_LIBRARIES} Threads::Threads)
|
||||
target_link_libraries(Formalang Threads::Threads)
|
||||
|
|
|
@ -38,10 +38,10 @@ class DFAGraph {
|
|||
|
||||
DFAGraph() = default;
|
||||
DFAGraph(const DFAGraph&) = delete;
|
||||
DFAGraph(DFAGraph&&) = default;
|
||||
DFAGraph(DFAGraph&&);
|
||||
|
||||
DFAGraph& operator=(const DFAGraph&) = delete;
|
||||
DFAGraph& operator=(DFAGraph&&) = default;
|
||||
DFAGraph& operator=(DFAGraph&&);
|
||||
|
||||
size_t AddNewVertex();
|
||||
void AddFinalVertex(size_t number);
|
||||
|
|
7
include/converters/InvertFDFA.hpp
Normal file
7
include/converters/InvertFDFA.hpp
Normal file
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
#include "DFA/DFAGraph.hpp"
|
||||
|
||||
namespace converters {
|
||||
using namespace DFA;
|
||||
DFAGraph InvertFDFAGraph(DFAGraph&&);
|
||||
}
|
|
@ -3,6 +3,30 @@
|
|||
#include <iostream>
|
||||
|
||||
namespace DFA {
|
||||
DFAGraph::DFAGraph(DFAGraph&& another) {
|
||||
std::swap(count_vertexes_, another.count_vertexes_);
|
||||
std::swap(vertexes_, another.vertexes_);
|
||||
std::swap(final_vertexes_, another.final_vertexes_);
|
||||
std::swap(start_vertexes_, another.start_vertexes_);
|
||||
|
||||
for (auto& i: vertexes_)
|
||||
i.second->owner_ = this;
|
||||
for (auto& i: another.vertexes_)
|
||||
i.second->owner_ = &another;
|
||||
}
|
||||
|
||||
DFAGraph& DFAGraph::operator=(DFAGraph&& another) {
|
||||
std::swap(count_vertexes_, another.count_vertexes_);
|
||||
std::swap(vertexes_, another.vertexes_);
|
||||
std::swap(final_vertexes_, another.final_vertexes_);
|
||||
std::swap(start_vertexes_, another.start_vertexes_);
|
||||
|
||||
for (auto& i: vertexes_)
|
||||
i.second->owner_ = this;
|
||||
for (auto& i: another.vertexes_)
|
||||
i.second->owner_ = &another;
|
||||
return *this;
|
||||
}
|
||||
size_t DFAGraph::AddNewVertex() {
|
||||
vertexes_[count_vertexes_] = std::make_shared<Vertex>(this);
|
||||
vertexes_[count_vertexes_]->number_ = count_vertexes_;
|
||||
|
|
12
src/converters/InvertFDFA.cpp
Normal file
12
src/converters/InvertFDFA.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "converters/InvertFDFA.hpp"
|
||||
|
||||
namespace converters {
|
||||
DFAGraph InvertFDFAGraph(DFAGraph&& fdfa_graph) {
|
||||
const size_t n = fdfa_graph.GetCountVertexes();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (!fdfa_graph.GetVertex(i)) continue;
|
||||
fdfa_graph.GetVertex(i)->SetFinal(!fdfa_graph.GetVertex(i)->IsFinal());
|
||||
}
|
||||
return std::move(fdfa_graph);
|
||||
}
|
||||
}
|
198
src/main.cpp
198
src/main.cpp
|
@ -6,6 +6,7 @@
|
|||
#include "converters/DFAToFDFA.hpp"
|
||||
#include "converters/DFAToMinDFA.hpp"
|
||||
#include "converters/DFAToRegular.hpp"
|
||||
#include "converters/InvertFDFA.hpp"
|
||||
|
||||
using namespace regular;
|
||||
using namespace regular;
|
||||
|
@ -13,161 +14,66 @@ using namespace NFA;
|
|||
using namespace DFA;
|
||||
using namespace converters;
|
||||
|
||||
void example1() {
|
||||
RegularTree r("a*");
|
||||
NFAGraph NFA_tree = RegularToNFAGraph(std::move(r)); // Regular to FA
|
||||
DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); // to DFA
|
||||
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); // minimize
|
||||
std::string reg = DFAGraphToRegular(std::move(DFA_graph)); // DFA to regular
|
||||
r = RegularTree(reg); // create regular
|
||||
NFA_tree = RegularToNFAGraph(std::move(r)); // to FA
|
||||
DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); // to DFA
|
||||
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); // minimize
|
||||
DFA_graph.Print(); // print
|
||||
}
|
||||
|
||||
void example2() {
|
||||
NFAGraph nfa_graph;
|
||||
const size_t N = 10;
|
||||
|
||||
size_t a[N];
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
a[i] = nfa_graph.AddNewVertex();
|
||||
|
||||
auto AddEdge = [&nfa_graph, &a](char symbol, int u, int v) {
|
||||
nfa_graph.GetVertex(a[u])->AddEdge(symbol, a[v]);
|
||||
};
|
||||
|
||||
AddEdge('a', 0, 1);
|
||||
AddEdge('b', 0, 2);
|
||||
AddEdge('b', 1, 3);
|
||||
AddEdge('b', 2, 4);
|
||||
|
||||
DFAGraph dfa_graph = NFAGraphToDFAGraph(std::move(nfa_graph));
|
||||
dfa_graph = DFAGraphToMinDFAGraph(std::move(dfa_graph));
|
||||
dfa_graph.Print();
|
||||
}
|
||||
|
||||
int main() {
|
||||
{
|
||||
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));
|
||||
|
||||
DFA_graph = DFAGraphToFDFAGraph(std::move(DFA_graph), {'a', 'b', 'c', 'd'});
|
||||
DFA_graph.Print();
|
||||
|
||||
std::string reg = DFAGraphToRegular(std::move(DFA_graph));
|
||||
|
||||
r = RegularTree(reg);
|
||||
NFA_tree = RegularToNFAGraph(std::move(r));
|
||||
DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree));
|
||||
DFA_graph = InvertFDFAGraph(std::move(DFA_graph));
|
||||
return 0;
|
||||
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
|
||||
DFA_graph.Print();
|
||||
}
|
||||
|
||||
return 0;
|
||||
RegularTree r("a*");
|
||||
auto nfa = RegularToNFAGraph(std::move(r));
|
||||
auto dfa = NFAGraphToDFAGraph(std::move(nfa));
|
||||
dfa = DFAGraphToMinDFAGraph(std::move(dfa));
|
||||
auto fdfa = DFAGraphToFDFAGraph(std::move(dfa), {'a', 'b'});
|
||||
fdfa.Print();
|
||||
fdfa = InvertFDFAGraph(std::move(fdfa));
|
||||
fdfa.Print();
|
||||
dfa = DFAGraphToMinDFAGraph(std::move(fdfa));
|
||||
auto s = DFAGraphToRegular(std::move(dfa));
|
||||
|
||||
|
||||
{
|
||||
RegularTree r("a+");
|
||||
r.Print();
|
||||
NFA::NFAGraph NFA_tree = converters::RegularToNFAGraph(std::move(r));
|
||||
NFA_tree.Print();
|
||||
DFA::DFAGraph DFA_graph = converters::NFAGraphToDFAGraph(std::move(NFA_tree));
|
||||
DFA_graph.Print();
|
||||
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
|
||||
DFA_graph.Print();
|
||||
}
|
||||
|
||||
return 0;
|
||||
NFA::NFAGraph tree;
|
||||
|
||||
const int N = 10;
|
||||
int a[N];
|
||||
for (int i = 0; i < N; ++i)
|
||||
a[i] = tree.AddNewVertex();
|
||||
|
||||
/*
|
||||
tree.GetVertex(a[1])->AddEdge('a', a[1]);
|
||||
tree.GetVertex(a[1])->AddEdge('b', a[1]);
|
||||
tree.GetVertex(a[1])->AddEdge('a', a[2]);
|
||||
tree.GetVertex(a[1])->AddEdge('a', a[8]);
|
||||
tree.GetVertex(a[2])->AddEdge('b', a[3]);
|
||||
tree.GetVertex(a[3])->AddEdge('a', a[4]);
|
||||
tree.GetVertex(a[4])->AddEdge('b', a[4]);
|
||||
tree.GetVertex(a[4])->AddEdge('a', a[7]);
|
||||
tree.GetVertex(a[7])->AddEdge('b', a[7]);
|
||||
tree.GetVertex(a[8])->AddEdge('a', a[6]);
|
||||
tree.GetVertex(a[6])->AddEdge('a', a[6]);
|
||||
tree.GetVertex(a[6])->AddEdge('b', a[6]);
|
||||
tree.GetVertex(a[6])->AddEdge('b', a[5]);
|
||||
tree.GetVertex(a[5])->AddEdge('b', a[4]);
|
||||
|
||||
tree.GetVertex(a[1])->SetStart(true);
|
||||
tree.GetVertex(a[7])->SetFinal(true);
|
||||
*/
|
||||
|
||||
/*
|
||||
tree.GetVertex(a[0])->AddEdge('a', a[1]);
|
||||
tree.GetVertex(a[1])->AddEdge('a', a[2]);
|
||||
tree.GetVertex(a[2])->AddEdge('a', a[3]);
|
||||
tree.GetVertex(a[3])->AddEdge('b', a[4]);
|
||||
tree.GetVertex(a[4])->AddEdge('a', a[5]);
|
||||
tree.GetVertex(a[5])->AddEdge('a', a[6]);
|
||||
tree.GetVertex(a[6])->AddEdge('b', a[7]);
|
||||
tree.GetVertex(a[2])->AddEdge(' ', a[4]);
|
||||
tree.GetVertex(a[4])->AddEdge(' ', a[2]);
|
||||
tree.GetVertex(a[5])->AddEdge(' ', a[7]);
|
||||
tree.GetVertex(a[7])->AddEdge(' ', a[5]);
|
||||
tree.GetVertex(a[7])->AddEdge(' ', a[1]);
|
||||
tree.GetVertex(a[1])->AddEdge('b', a[1]);
|
||||
|
||||
tree.GetVertex(a[0])->SetStart(true);
|
||||
tree.GetVertex(a[1])->SetFinal(true);
|
||||
*/
|
||||
/*
|
||||
tree.GetVertex(a[0])->AddEdge('a', a[1]);
|
||||
tree.GetVertex(a[0])->AddEdge('a', a[2]);
|
||||
tree.GetVertex(a[1])->AddEdge('b', a[1]);
|
||||
tree.GetVertex(a[2])->AddEdge('c', a[2]);
|
||||
tree.GetVertex(a[0])->SetStart(true);
|
||||
tree.GetVertex(a[1])->SetFinal(true);
|
||||
tree.GetVertex(a[2])->SetFinal(true);
|
||||
*/
|
||||
|
||||
tree.GetVertex(a[0])->AddEdge('a', a[1]);
|
||||
tree.GetVertex(a[0])->AddEdge('b', a[2]);
|
||||
|
||||
tree.GetVertex(a[1])->AddEdge('b', a[3]);
|
||||
tree.GetVertex(a[2])->AddEdge('b', a[4]);
|
||||
|
||||
tree.GetVertex(a[0])->SetStart(true);
|
||||
tree.GetVertex(a[3])->SetFinal(true);
|
||||
tree.GetVertex(a[4])->SetFinal(true);
|
||||
|
||||
DFA::DFAGraph res = converters::NFAGraphToDFAGraph(std::move(tree));
|
||||
// FDFA::FDFAGraph res2 = converters::DFAGraphToFDFAGraph(std::move(res), {'a', 'b'});
|
||||
|
||||
// res2.Print();
|
||||
|
||||
// std::cout << "\n#####################\n\n";
|
||||
|
||||
// res = converters::DFAGraphToFDFAGraph(std::move(res), {'a', 'b'});
|
||||
|
||||
res = converters::DFAGraphToMinDFAGraph(std::move(res));
|
||||
|
||||
res.Print();
|
||||
|
||||
std::string reg = converters::DFAGraphToRegular(std::move(res));
|
||||
|
||||
std::cout << reg << std::endl;
|
||||
|
||||
|
||||
/*
|
||||
tree = converters::AddAllEpsilonTransitions(std::move(tree));
|
||||
|
||||
tree.Print();
|
||||
|
||||
std::cout << "\n#####################\n\n";
|
||||
|
||||
tree = converters::DeleteEpsilonTransitions(std::move(tree));
|
||||
|
||||
tree.Print();
|
||||
|
||||
std::cout << "\n#####################\n\n";
|
||||
|
||||
tree = converters::DeleteTransitionsByOneLetter(std::move(tree));
|
||||
|
||||
tree.Print();
|
||||
|
||||
std::cout << "\n#####################\n\n";
|
||||
*/
|
||||
|
||||
/*
|
||||
DFA::DFAGraph res = converters::NFATreeToDFAGraph(std::move(tree));
|
||||
|
||||
res.Print();
|
||||
*/
|
||||
std::cout << "END" << std::endl;
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
std::string str;
|
||||
std::cin >> str;
|
||||
RegularTree reg_tree(str);
|
||||
reg_tree.Print();
|
||||
|
||||
auto NFA_tree = converters::RegularToNFAGraph(std::move(reg_tree));
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
NFA_tree.Print();
|
||||
|
||||
|
||||
// RegularTree r("(a|b)+bab(a|b)+");
|
||||
// std::cout << DFAGraphToRegular(DFAGraphToMinDFAGraph(InvertFDFAGraph(DFAGraphToFDFAGraph(DFAGraphToMinDFAGraph(NFAGraphToDFAGraph(RegularToNFAGraph(std::move(r)))), {'a', 'b'})))) << std::endl;
|
||||
}
|
||||
|
|
181
tests/invertFDFA/InvertFDFA.cpp
Normal file
181
tests/invertFDFA/InvertFDFA.cpp
Normal file
|
@ -0,0 +1,181 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <random>
|
||||
#include "regular/RegularTree.hpp"
|
||||
#include "converters/RegularToNFA.hpp"
|
||||
#include "converters/NFAToDFA.hpp"
|
||||
#include "converters/DFAToMinDFA.hpp"
|
||||
#include "converters/DFAToFDFA.hpp"
|
||||
#include "converters/InvertFDFA.hpp"
|
||||
|
||||
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);
|
||||
|
||||
TEST(invert_DFA, 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));
|
||||
|
||||
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));
|
||||
|
||||
std::string s = "";
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
ASSERT_EQ(DFA_graph.Accepted(s), false);
|
||||
s += "a";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(invert_DFA, 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));
|
||||
|
||||
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));
|
||||
|
||||
std::string s = "";
|
||||
ASSERT_EQ(DFA_graph.Accepted(s), true);
|
||||
s += "a";
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
ASSERT_EQ(DFA_graph.Accepted(s), false);
|
||||
s += "a";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(invert_DFA, 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));
|
||||
|
||||
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);
|
||||
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), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(invert_DFA, 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));
|
||||
|
||||
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);
|
||||
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), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(invert_DFA, 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));
|
||||
|
||||
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));
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
ASSERT_EQ(DFA_graph.Accepted(""), false);
|
||||
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(invert_DFA, _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));
|
||||
|
||||
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));
|
||||
|
||||
auto check = [](const std::string str) {
|
||||
std::set<char> s(str.begin(), str.end());
|
||||
return s.find('d') == s.end();
|
||||
};
|
||||
|
||||
ASSERT_EQ(DFA_graph.Accepted(""), false);
|
||||
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(invert_DFA, _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));
|
||||
|
||||
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));
|
||||
|
||||
auto check = [](const std::string str) {
|
||||
std::set<char> s(str.begin(), str.end());
|
||||
return s.find('d') == s.end();
|
||||
};
|
||||
|
||||
ASSERT_EQ(DFA_graph.Accepted(""), false);
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
auto s = GenerateRandomString({'a', 'b', 'c', 'd'}, rnd() % 10);
|
||||
|
||||
ASSERT_EQ(DFA_graph.Accepted(s), !check(s));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue