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/RegularTree.cpp
|
||||||
src/regular/RegularTreeNode.cpp
|
src/regular/RegularTreeNode.cpp
|
||||||
src/NFA/NFAGraph.cpp
|
src/NFA/NFAGraph.cpp
|
||||||
src/NFA/NFATreeVertex.cpp
|
src/NFA/NFAGraphVertex.cpp
|
||||||
src/converters/RegularToNFA.cpp
|
src/converters/RegularToNFA.cpp
|
||||||
src/converters/NFAToDFA.cpp
|
src/converters/NFAToDFA.cpp
|
||||||
src/DFA/DFAGraph.cpp
|
src/DFA/DFAGraph.cpp
|
||||||
|
@ -27,18 +27,20 @@ set(SOURCE_FILES
|
||||||
src/converters/DFAToFDFA.cpp
|
src/converters/DFAToFDFA.cpp
|
||||||
src/converters/DFAToMinDFA.cpp
|
src/converters/DFAToMinDFA.cpp
|
||||||
src/converters/DFAToRegular.cpp
|
src/converters/DFAToRegular.cpp
|
||||||
|
src/converters/InvertFDFA.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(TEST_FILES
|
set(TEST_FILES
|
||||||
tests/regular/parse_regular.cpp
|
tests/regular/ParseRegular.cpp
|
||||||
tests/NFAToDFA/check_equivalence.cpp
|
tests/NFAToDFA/CheckEquivalence.cpp
|
||||||
tests/regularToDFA/regularToDFA.cpp
|
tests/regularToDFA/RegularToDFA.cpp
|
||||||
tests/DFAToRegular/DFAToRegular.cpp
|
tests/DFAToRegular/DFAToRegular.cpp
|
||||||
|
tests/invertFDFA/InvertFDFA.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(Formalang src/main.cpp ${SOURCE_FILES})
|
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(Tests ${GTEST_LIBRARIES} Threads::Threads)
|
||||||
target_link_libraries(Formalang Threads::Threads)
|
target_link_libraries(Formalang Threads::Threads)
|
||||||
|
|
|
@ -38,10 +38,10 @@ class DFAGraph {
|
||||||
|
|
||||||
DFAGraph() = default;
|
DFAGraph() = default;
|
||||||
DFAGraph(const DFAGraph&) = delete;
|
DFAGraph(const DFAGraph&) = delete;
|
||||||
DFAGraph(DFAGraph&&) = default;
|
DFAGraph(DFAGraph&&);
|
||||||
|
|
||||||
DFAGraph& operator=(const DFAGraph&) = delete;
|
DFAGraph& operator=(const DFAGraph&) = delete;
|
||||||
DFAGraph& operator=(DFAGraph&&) = default;
|
DFAGraph& operator=(DFAGraph&&);
|
||||||
|
|
||||||
size_t AddNewVertex();
|
size_t AddNewVertex();
|
||||||
void AddFinalVertex(size_t number);
|
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>
|
#include <iostream>
|
||||||
|
|
||||||
namespace DFA {
|
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() {
|
size_t DFAGraph::AddNewVertex() {
|
||||||
vertexes_[count_vertexes_] = std::make_shared<Vertex>(this);
|
vertexes_[count_vertexes_] = std::make_shared<Vertex>(this);
|
||||||
vertexes_[count_vertexes_]->number_ = count_vertexes_;
|
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/DFAToFDFA.hpp"
|
||||||
#include "converters/DFAToMinDFA.hpp"
|
#include "converters/DFAToMinDFA.hpp"
|
||||||
#include "converters/DFAToRegular.hpp"
|
#include "converters/DFAToRegular.hpp"
|
||||||
|
#include "converters/InvertFDFA.hpp"
|
||||||
|
|
||||||
using namespace regular;
|
using namespace regular;
|
||||||
using namespace regular;
|
using namespace regular;
|
||||||
|
@ -13,161 +14,66 @@ using namespace NFA;
|
||||||
using namespace DFA;
|
using namespace DFA;
|
||||||
using namespace converters;
|
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() {
|
int main() {
|
||||||
{
|
{
|
||||||
RegularTree r("a*");
|
RegularTree r("a*");
|
||||||
NFAGraph NFA_tree = RegularToNFAGraph(std::move(r));
|
NFAGraph NFA_tree = RegularToNFAGraph(std::move(r));
|
||||||
DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree));
|
DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree));
|
||||||
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
|
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
|
||||||
|
|
||||||
|
DFA_graph = DFAGraphToFDFAGraph(std::move(DFA_graph), {'a', 'b', 'c', 'd'});
|
||||||
DFA_graph.Print();
|
DFA_graph.Print();
|
||||||
|
DFA_graph = InvertFDFAGraph(std::move(DFA_graph));
|
||||||
std::string reg = DFAGraphToRegular(std::move(DFA_graph));
|
return 0;
|
||||||
|
|
||||||
r = RegularTree(reg);
|
|
||||||
NFA_tree = RegularToNFAGraph(std::move(r));
|
|
||||||
DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree));
|
|
||||||
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
|
DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph));
|
||||||
DFA_graph.Print();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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|b)+bab(a|b)+");
|
||||||
{
|
// std::cout << DFAGraphToRegular(DFAGraphToMinDFAGraph(InvertFDFAGraph(DFAGraphToFDFAGraph(DFAGraphToMinDFAGraph(NFAGraphToDFAGraph(RegularToNFAGraph(std::move(r)))), {'a', 'b'})))) << std::endl;
|
||||||
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();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
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