diff --git a/CMakeLists.txt b/CMakeLists.txt index 703bedc..db8dc50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,6 @@ cmake_minimum_required(VERSION 3.10) project("Formalang") # set(CMAKE_CXX_FLAGS "-O3") -# set(CMAKE_CXX_FLAGS "-O0 --coverage -ftest-coverage -fprofile-arcs") find_package(GTest REQUIRED) find_package(Threads REQUIRED) @@ -16,33 +15,14 @@ include_directories( set(CMAKE_CXX_STANDARD 17) -set(SOURCE_FILES - src/regular/RegularTree.cpp - src/regular/RegularTreeNode.cpp - src/NFA/NFAGraph.cpp - src/NFA/NFAGraphVertex.cpp - src/converters/RegularToNFA.cpp - src/converters/NFAToDFA.cpp - src/DFA/DFAGraph.cpp - src/DFA/DFAGraphVertex.cpp - src/converters/DFAToFDFA.cpp - src/converters/DFAToMinDFA.cpp - src/converters/DFAToRegular.cpp - src/converters/InvertFDFA.cpp - ) +set(SOURCE_FILES) -set(TEST_FILES - tests/regular/ParseRegular.cpp - tests/NFAToDFA/CheckEquivalence.cpp - tests/regularToDFA/RegularToDFA.cpp - tests/DFAToRegular/DFAToRegular.cpp - tests/invertFDFA/InvertFDFA.cpp - tests/DFAToRegular/DFAToRegular2.cpp - tests/DFAToMinDFA/CountSizesMinDFA.cpp - ) +set(TEST_FILES) add_executable(Formalang src/main.cpp ${SOURCE_FILES}) -add_executable(Tests tests/MainTest.cpp ${TEST_FILES} ${SOURCE_FILES}) +add_executable(Tests tests/test_main.cpp ${TEST_FILES} ${SOURCE_FILES}) target_link_libraries(Tests ${GTEST_LIBRARIES} Threads::Threads) +target_link_libraries(Formalang Threads::Threads) + diff --git a/README.md b/README.md deleted file mode 100644 index c18d217..0000000 --- a/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# Formalang -```c++ -#include "regular/RegularTree.hpp" -#include "NFA/NFAGraph.hpp" -#include "DFA/DFAGraph.hpp" -#include "converters/RegularToNFA.hpp" -#include "converters/NFAToDFA.hpp" -#include "converters/DFAToFDFA.hpp" -#include "converters/DFAToMinDFA.hpp" -#include "converters/DFAToRegular.hpp" -#include "converters/InvertFDFA.hpp" - -using namespace regular; -using namespace NFA; -using namespace DFA; -using namespace converters; -``` -так можно подключить все что есть в моей программе. -```c++ -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.Print(); // Мой вывод -DFA_graph.CreateDotFile("2.dot"); // Вывод в dot файл -std::string reg = DFAGraphToRegular(std::move(DFA_graph)); // В регулярку -``` -Такой вывод в регулярку как показано в прошлом примере сделает много лишних скобок, если мы хотим привести к более нормальному виду, то можно сделать так -```c++ -RegularTree(reg).ToString() // Получится более красивая регулярка -``` -Про сами регулярки + * - это плюс и звезда Клини. Их можно писать после слов, или после скобок. -abacaba* ~ (abacaba)\*. a(b)a\* ~ a(b)(a)\*. Для сложения языков используется |. Символом пустого слова является пробел. - -Примеры регулярок - -a* - -a(b)+a - -(a|b)* diff --git a/include/DFA/DFAGraph.hpp b/include/DFA/DFAGraph.hpp deleted file mode 100644 index f1cb616..0000000 --- a/include/DFA/DFAGraph.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace DFA { -class DFAGraph { - public: - class Vertex { - public: - Vertex(DFAGraph* owner); - - bool IsFinal() const; - bool IsStart() const; - size_t GetNumber() const; - - const std::map& GetTransitions() const; - const std::map& GetBackTransitions() const; - - void AddEdge(char, size_t); - void RemoveEdge(char); - void SetOwner(DFAGraph* owner); - void SetFinal(bool status); - void SetStart(bool status); - private: - DFAGraph* owner_; - std::map transitions_; - std::map back_transitions_; - - size_t number_; - bool is_final_ = false; - bool is_start_ = false; - - friend class DFAGraph; - }; - - DFAGraph() = default; - DFAGraph(const DFAGraph&) = delete; - DFAGraph(DFAGraph&&); - - DFAGraph& operator=(const DFAGraph&) = delete; - DFAGraph& operator=(DFAGraph&&); - - size_t AddNewVertex(); - void AddFinalVertex(size_t number); - void SetStartVertex(size_t number); - - void RemoveVertex(size_t number); - void RemoveFinalVertex(size_t number); - void RemoveStartVertex(size_t number); - - Vertex& GetVertex(size_t number); - bool NotExistVertex(size_t number); - - size_t GetCountVertexes() const; - size_t GetReallyCountVertexes() const; - const std::vector& GetFinalVertexes() const; - size_t GetStartVertex() const; - - void Print() const; - bool Accepted(const std::string&) const; - void CreateDotFile(const std::string& filename) const; - private: - size_t count_vertexes_ = 0; - std::map vertexes_; - std::vector final_vertexes_; - size_t start_vertex_ = -1; -}; -} diff --git a/include/NFA/NFAGraph.hpp b/include/NFA/NFAGraph.hpp deleted file mode 100644 index db389af..0000000 --- a/include/NFA/NFAGraph.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace NFA { -class NFAGraph { - public: - class Vertex { - public: - Vertex(NFAGraph* owner); - - bool IsFinal() const; - bool IsStart() const; - size_t GetNumber() const; - - const std::map>& GetTransitions() const; - const std::map>& GetBackTransitions() const; - - void AddEdge(char, size_t); - void RemoveEdge(char, size_t); - void SetOwner(NFAGraph* owner); - void SetFinal(bool status); - void SetStart(bool status); - private: - NFAGraph* owner_; - std::map> transitions_; - std::map> back_transitions_; - - size_t number_; - bool is_final_ = false; - bool is_start_ = false; - - friend class NFAGraph; - }; - - NFAGraph() = default; - NFAGraph(const NFAGraph&) = delete; - NFAGraph(NFAGraph&&); - - NFAGraph& operator=(const NFAGraph&) = delete; - NFAGraph& operator=(NFAGraph&&); - - size_t AddNewVertex(); - void AddFinalVertex(size_t number); - void AddStartVertex(size_t number); - - void RemoveVertex(size_t number); - void RemoveFinalVertex(size_t number); - void RemoveStartVertex(size_t number); - - void Composition(NFAGraph&&, - std::vector start_vertexes, - std::vector final_vertexes); - - Vertex& GetVertex(size_t number); - bool NotExistVertex(size_t number); - - size_t GetCountVertexes() const; - size_t GetReallyCountVertexes() const; - const std::vector& GetFinalVertexes() const; - const std::vector& GetStartVertexes() const; - - void Print() const; - void CreateDotFile(const std::string& filename) const; - private: - size_t count_vertexes_ = 0; - std::map vertexes_; - std::vector final_vertexes_; - std::vector start_vertexes_; -}; -} diff --git a/include/converters/DFAToFDFA.hpp b/include/converters/DFAToFDFA.hpp deleted file mode 100644 index 915d51c..0000000 --- a/include/converters/DFAToFDFA.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "DFA/DFAGraph.hpp" - -namespace converters { -using namespace DFA; -DFAGraph DFAGraphToFDFAGraph(DFAGraph&&, const std::vector& alphabet); -} diff --git a/include/converters/DFAToMinDFA.hpp b/include/converters/DFAToMinDFA.hpp deleted file mode 100644 index 9791c83..0000000 --- a/include/converters/DFAToMinDFA.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "DFA/DFAGraph.hpp" - -namespace converters { -using namespace DFA; -DFAGraph DFAGraphToMinDFAGraph(DFAGraph&&); -} diff --git a/include/converters/DFAToRegular.hpp b/include/converters/DFAToRegular.hpp deleted file mode 100644 index 4c825da..0000000 --- a/include/converters/DFAToRegular.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include "DFA/DFAGraph.hpp" -#include - -namespace converters { -using namespace DFA; -std::string DFAGraphToRegular(DFAGraph&&); -} diff --git a/include/converters/InvertFDFA.hpp b/include/converters/InvertFDFA.hpp deleted file mode 100644 index e5dce0e..0000000 --- a/include/converters/InvertFDFA.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "DFA/DFAGraph.hpp" - -namespace converters { -using namespace DFA; -DFAGraph InvertFDFAGraph(DFAGraph&&); -} diff --git a/include/converters/NFAToDFA.hpp b/include/converters/NFAToDFA.hpp deleted file mode 100644 index 66eb908..0000000 --- a/include/converters/NFAToDFA.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "NFA/NFAGraph.hpp" -#include "DFA/DFAGraph.hpp" - -namespace converters { -using namespace NFA; -using namespace DFA; -NFAGraph AddAllEpsilonTransitions(NFAGraph&&); -NFAGraph AddAllPossibleFinalVertexes(NFAGraph&&); -NFAGraph DeleteEpsilonTransitions(NFAGraph&&); -NFAGraph DeleteTransitionsByOneLetter(NFAGraph&&); -DFAGraph NFAGraphToDFAGraph(NFAGraph&&); -} diff --git a/include/converters/RegularToNFA.hpp b/include/converters/RegularToNFA.hpp deleted file mode 100644 index dce3ef0..0000000 --- a/include/converters/RegularToNFA.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "regular/RegularTree.hpp" -#include "NFA/NFAGraph.hpp" - -namespace converters { -using namespace NFA; -using namespace regular; - -NFAGraph RegularToNFAGraph(RegularTree&&); -} diff --git a/include/regular/RegularTree.hpp b/include/regular/RegularTree.hpp deleted file mode 100644 index 3863b3d..0000000 --- a/include/regular/RegularTree.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once -#include -#include -#include -#include - -namespace regular { -class RegularTree { - public: - class Node { - public: - enum class Type { - Addition, Concatenation, Word - }; - enum class Modifier { - Plus, Star, None - }; - - Node(); - Node(Type); - - void Parse(const std::string&); - void Print() const; - std::vector> children; - std::string word; - Type type; - Modifier modifier = Modifier::None; - std::string ToString() const; - private: - void ParseCurrentType(const std::string_view); - void Compression(); - void Compression2(); - void Print(int nesting_level) const; - }; - - RegularTree(const std::string&); - const Node& GetNode() const; - void Print() const; - std::string ToString() const; - - private: - Node node_; -}; -} diff --git a/src/DFA/DFAGraph.cpp b/src/DFA/DFAGraph.cpp deleted file mode 100644 index 011df6e..0000000 --- a/src/DFA/DFAGraph.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#include "DFA/DFAGraph.hpp" -#include -#include -#include - -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_); - // TODO - // 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_); - // TODO - // 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_.emplace(count_vertexes_, this); - GetVertex(count_vertexes_).number_ = count_vertexes_; - return count_vertexes_++; -} - -void DFAGraph::AddFinalVertex(size_t number) { - if (!GetVertex(number).is_final_) { - GetVertex(number).is_final_ = true; - final_vertexes_.push_back(number); - } -} - -void DFAGraph::SetStartVertex(size_t number) { - if (!GetVertex(number).is_start_) { - GetVertex(number).is_start_ = true; - start_vertex_ = number; - } -} - -void DFAGraph::RemoveVertex(size_t number) { - RemoveFinalVertex(number); - RemoveStartVertex(number); - vertexes_.erase(number); - if (number == count_vertexes_ - 1) count_vertexes_--; -} - -void DFAGraph::RemoveFinalVertex(size_t number) { - for (size_t i = 0; i < final_vertexes_.size(); ++i) { - if (final_vertexes_[i] == number) { - GetVertex(number).is_final_ = false; - std::swap(final_vertexes_[i], final_vertexes_.back()); - final_vertexes_.pop_back(); - break; - } - } -} - -void DFAGraph::RemoveStartVertex(size_t number) { - if (start_vertex_ == number) { - start_vertex_ = -1; - } -} - -DFAGraph::Vertex& DFAGraph::GetVertex(size_t number) { - if (!NotExistVertex(number)) - return vertexes_.at(number); - throw std::out_of_range("This vertex don't exist"); -} - -bool DFAGraph::NotExistVertex(size_t number) { - return !vertexes_.count(number); -} - -size_t DFAGraph::GetCountVertexes() const { - return count_vertexes_; -} - -size_t DFAGraph::GetReallyCountVertexes() const { - return vertexes_.size(); -} - -const std::vector& DFAGraph::GetFinalVertexes() const { - return final_vertexes_; -} - -size_t DFAGraph::GetStartVertex() const { - return start_vertex_; -} - -void DFAGraph::Print() const { - for (auto i: vertexes_) { - std::cout << i.second.number_ << " " << "f-" << i.second.is_final_ << " s-" << - i.second.is_start_ << std::endl; - } - for (auto& i: vertexes_) { - for (auto& j: i.second.transitions_) { - std::cout << i.second.number_ << "->" << j.second << " <" << j.first << ">" << - std::endl; - } - } - std::cout << std::endl; -} - -bool DFAGraph::Accepted(const std::string& str) const { - size_t current = start_vertex_; - for (auto i: str) { - if (vertexes_.at(current).GetTransitions().count(i)) { - current = vertexes_.at(vertexes_.at(current).GetTransitions().at(i)).GetNumber(); - } else { - return false; - } - } - return vertexes_.at(current).IsFinal(); -} - -void DFAGraph::CreateDotFile(const std::string& filename) const { - std::ofstream out(filename); - out << "digraph G {\n"; - - for (auto& i: vertexes_) { - for (auto& j: i.second.transitions_) { - out << i.first << "->" << j.second << "[label=" << j.first << "]\n"; - } - if (i.second.IsStart() && i.second.IsFinal()) { - out << " " << i.first << " [shape=star];\n"; - } else if (i.second.IsStart()) { - out << " " << i.first << " [shape=rarrow];\n"; - } else if (i.second.IsFinal()) { - out << " " << i.first << " [shape=Msquare];\n"; - } - } - - out << "}\n"; -} -} - diff --git a/src/DFA/DFAGraphVertex.cpp b/src/DFA/DFAGraphVertex.cpp deleted file mode 100644 index ddad254..0000000 --- a/src/DFA/DFAGraphVertex.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "DFA/DFAGraph.hpp" - -using Vertex = DFA::DFAGraph::Vertex; - -Vertex::Vertex(DFAGraph* owner) : owner_(owner) {} - -bool Vertex::IsFinal() const { - return is_final_; -} - -bool Vertex::IsStart() const { - return is_start_; -} - -size_t Vertex::GetNumber() const { - return number_; -} - -const std::map& Vertex::GetTransitions() const { - return transitions_; -} - -const std::map& Vertex::GetBackTransitions() const { - return back_transitions_; -} - -void Vertex::AddEdge(char symbol, size_t number) { - transitions_[symbol] = number; - owner_->GetVertex(number).back_transitions_[symbol] = number_; -} - -void Vertex::RemoveEdge(char symbol) { - owner_->GetVertex(transitions_[symbol]).back_transitions_.erase(symbol); - transitions_.erase(symbol); -} - -void Vertex::SetOwner(DFAGraph* owner) { - owner_ = owner; -} - -void Vertex::SetFinal(bool status) { - if (status != is_final_) { - if (status) - owner_->AddFinalVertex(number_); - else - owner_->RemoveFinalVertex(number_); - } -} - -void Vertex::SetStart(bool status) { - if (status != is_start_) { - if (status) - owner_->SetStartVertex(number_); - else - owner_->RemoveStartVertex(number_); - } -} diff --git a/src/NFA/NFAGraph.cpp b/src/NFA/NFAGraph.cpp deleted file mode 100644 index 2d31831..0000000 --- a/src/NFA/NFAGraph.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include "NFA/NFAGraph.hpp" -#include -#include -#include - -namespace NFA { -NFAGraph::NFAGraph(NFAGraph&& 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; -} - -NFAGraph& NFAGraph::operator=(NFAGraph&& 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 NFAGraph::AddNewVertex() { - vertexes_.emplace(count_vertexes_, this); - GetVertex(count_vertexes_).number_ = count_vertexes_; - return count_vertexes_++; -} - -void NFAGraph::AddFinalVertex(size_t number) { - if (!GetVertex(number).is_final_) { - GetVertex(number).is_final_ = true; - final_vertexes_.push_back(number); - } -} - -void NFAGraph::AddStartVertex(size_t number) { - if (!GetVertex(number).is_start_) { - GetVertex(number).is_start_ = true; - start_vertexes_.push_back(number); - } -} - -void NFAGraph::RemoveVertex(size_t number) { - RemoveFinalVertex(number); - RemoveStartVertex(number); - vertexes_.erase(number); -} - -void NFAGraph::RemoveFinalVertex(size_t number) { - for (size_t i = 0; i < final_vertexes_.size(); ++i) { - if (final_vertexes_[i] == number) { - GetVertex(number).is_final_ = false; - std::swap(final_vertexes_[i], final_vertexes_.back()); - final_vertexes_.pop_back(); - break; - } - } -} - -void NFAGraph::RemoveStartVertex(size_t number) { - for (size_t i = 0; i < start_vertexes_.size(); ++i) { - if (start_vertexes_[i] == number) { - GetVertex(number).is_start_ = false; - std::swap(start_vertexes_[i], start_vertexes_.back()); - start_vertexes_.pop_back(); - break; - } - } -} - -void NFAGraph::Composition(NFAGraph&& nfa_graph, - std::vector start_vertexes, - std::vector final_vertexes) { - auto add_final_vertexes = nfa_graph.final_vertexes_; - auto add_start_vertexes = nfa_graph.start_vertexes_; - - size_t new_count_vertexes = count_vertexes_; - - for (auto& i: nfa_graph.vertexes_) { - new_count_vertexes = std::max(new_count_vertexes, i.first + count_vertexes_ + 1); - i.second.number_ += count_vertexes_; - std::map> new_transitions; - for (auto& j: i.second.transitions_) { - for (auto& k: j.second) { - new_transitions[j.first].insert(k + count_vertexes_); - } - } - std::map> new_back_transitions; - for (auto& j: i.second.back_transitions_) { - for (auto& k: j.second) { - new_back_transitions[j.first].insert(k + count_vertexes_); - } - } - i.second.transitions_ = std::move(new_transitions); - i.second.back_transitions_ = std::move(new_back_transitions); - - i.second.SetOwner(this); - vertexes_.emplace(i.second.number_, std::move(i.second)); - } - - for (auto& i: add_start_vertexes) { - i += count_vertexes_; - } - for (auto& i: add_final_vertexes) { - i += count_vertexes_; - } - - count_vertexes_ = new_count_vertexes; - - for (auto& i: start_vertexes) { - for (auto& j: add_start_vertexes) { - GetVertex(i).transitions_[' '].insert(j); - GetVertex(j).back_transitions_[' '].insert(i); - } - } - for (auto& i: add_final_vertexes) { - for (auto& j: final_vertexes) { - GetVertex(i).transitions_[' '].insert(j); - GetVertex(j).back_transitions_[' '].insert(i); - } - } - for (auto& i: add_final_vertexes) { - GetVertex(i).is_final_ = false; - } - for (auto& i: add_start_vertexes) { - GetVertex(i).is_start_ = false; - } -} - -NFAGraph::Vertex& NFAGraph::GetVertex(size_t number) { - if (!NotExistVertex(number)) - return vertexes_.at(number); - throw std::out_of_range("This vertex don't exist"); -} - -bool NFAGraph::NotExistVertex(size_t number) { - return !vertexes_.count(number); -} - -size_t NFAGraph::GetCountVertexes() const { - return count_vertexes_; -} - -size_t NFAGraph::GetReallyCountVertexes() const { - return vertexes_.size(); -} - -const std::vector& NFAGraph::GetFinalVertexes() const { - return final_vertexes_; -} - -const std::vector& NFAGraph::GetStartVertexes() const { - return start_vertexes_; -} - -void NFAGraph::Print() const { - for (auto i: vertexes_) { - std::cout << i.second.number_ << " " << "f-" << i.second.is_final_ << " s-" << - i.second.is_start_ << std::endl; - } - for (auto& i: vertexes_) { - for (auto& j: i.second.transitions_) { - for (auto k: j.second) { - std::cout << i.second.number_ << "." << k << " <" << j.first << ">" << - std::endl; - } - } - } - std::cout << std::endl; -} - -void NFAGraph::CreateDotFile(const std::string& filename) const { - std::ofstream out(filename); - out << "digraph G {\n"; - - for (auto& i: vertexes_) { - for (auto& j: i.second.transitions_) { - for (auto& k: j.second) { - out << i.first << "." << k << "[label=" << j.first << "]\n"; - } - } - if (i.second.IsStart() && i.second.IsFinal()) { - out << " " << i.first << " [shape=Mstar];\n"; - } else if (i.second.IsStart()) { - out << " " << i.first << " [shape=Mdiamond];\n"; - } else if (i.second.IsFinal()) { - out << " " << i.first << " [shape=Msquare];\n"; - } - } - - out << "}\n"; -} -} diff --git a/src/NFA/NFAGraphVertex.cpp b/src/NFA/NFAGraphVertex.cpp deleted file mode 100644 index 32610a9..0000000 --- a/src/NFA/NFAGraphVertex.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "NFA/NFAGraph.hpp" - -using Vertex = NFA::NFAGraph::Vertex; - -Vertex::Vertex(NFAGraph* owner) : owner_(owner) {} - -bool Vertex::IsFinal() const { - return is_final_; -} - -bool Vertex::IsStart() const { - return is_start_; -} - -size_t Vertex::GetNumber() const { - return number_; -} - -const std::map>& Vertex::GetTransitions() const { - return transitions_; -} - -const std::map>& Vertex::GetBackTransitions() const { - return back_transitions_; -} - -void Vertex::AddEdge(char symbol, size_t number) { - transitions_[symbol].insert(number); - owner_->GetVertex(number).back_transitions_[symbol]; - owner_->GetVertex(number).back_transitions_[symbol].insert(number_); -} - -void Vertex::RemoveEdge(char symbol, size_t number) { - transitions_[symbol].erase(number); - if (transitions_[symbol].size() == 0) - transitions_.erase(symbol); - owner_->GetVertex(number).back_transitions_[symbol].erase(number_); - if (owner_->GetVertex(number).back_transitions_[symbol].size() == 0) - owner_->GetVertex(number).back_transitions_.erase(symbol); -} - -void Vertex::SetOwner(NFAGraph* owner) { - owner_ = owner; -} - -void Vertex::SetFinal(bool status) { - if (status != is_final_) { - if (status) - owner_->AddFinalVertex(number_); - else - owner_->RemoveFinalVertex(number_); - } -} - -void Vertex::SetStart(bool status) { - if (status != is_start_) { - if (status) - owner_->AddStartVertex(number_); - else - owner_->RemoveStartVertex(number_); - } -} diff --git a/src/converters/DFAToFDFA.cpp b/src/converters/DFAToFDFA.cpp deleted file mode 100644 index 6b7245d..0000000 --- a/src/converters/DFAToFDFA.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "converters/DFAToFDFA.hpp" - -namespace converters { -DFAGraph DFAGraphToFDFAGraph(DFAGraph&& graph, const std::vector& alphabet) { - DFAGraph result; - const int n = graph.GetCountVertexes(); - std::map number_vertex_in_DFA; - for (int i = 0; i < n; ++i) { - if (graph.NotExistVertex(i)) continue; - number_vertex_in_DFA[i] = result.AddNewVertex(); - } - for (int i = 0; i < n; ++i) { - if (graph.NotExistVertex(i)) continue; - if (graph.GetVertex(i).IsFinal()) - result.GetVertex(number_vertex_in_DFA[i]).SetFinal(true); - if (graph.GetVertex(i).IsStart()) - result.GetVertex(number_vertex_in_DFA[i]).SetStart(true); - - const auto& transitions = graph.GetVertex(i).GetTransitions(); - for (const auto& t: transitions) { - result.GetVertex(number_vertex_in_DFA[i]).AddEdge(t.first, t.second); - } - } - - size_t drain = result.AddNewVertex(); - - for (int i = 0; i < n; ++i) { - const auto& transitions = graph.GetVertex(i).GetTransitions(); - for (char j: alphabet) { - if (!transitions.count(j)) { - result.GetVertex(i).AddEdge(j, drain); - } - } - } - - if (result.GetVertex(drain).GetBackTransitions().size() == 0) { - result.RemoveVertex(drain); - } else { - for (char j: alphabet) { - result.GetVertex(drain).AddEdge(j, drain); - } - } - - return result; -} -} diff --git a/src/converters/DFAToMinDFA.cpp b/src/converters/DFAToMinDFA.cpp deleted file mode 100644 index af52be9..0000000 --- a/src/converters/DFAToMinDFA.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "converters/DFAToMinDFA.hpp" -#include - -namespace converters { -DFAGraph DFAGraphToMinDFAGraph(DFAGraph&& graph) { - const int n = graph.GetCountVertexes(); - DFAGraph result; - - std::vector alphabet; - - { - std::set set_alphabet; - for (int i = 0; i < n; ++i) { - if (graph.NotExistVertex(i)) continue; - for (auto i: graph.GetVertex(i).GetTransitions()) { - set_alphabet.insert(i.first); - } - } - alphabet = std::vector(set_alphabet.begin(), set_alphabet.end()); - } - - std::vector>> table(n, - std::vector>(n, std::vector(alphabet.size() + 1))); - - { - std::vector>& layer(table[0]); - for (int i = 0; i < n; ++i) { - layer[i][0] = graph.GetVertex(i).IsFinal(); - } - for (int i = 0; i < n; ++i) { - for (int j = 0; j < alphabet.size(); ++j) { - const auto& transitions = graph.GetVertex(i).GetTransitions(); - if (transitions.count(alphabet[j])) - layer[i][j + 1] = layer[transitions.at(alphabet[j])][0]; - else - layer[i][j + 1] = -1; - } - } - } - - for (int number_layer = 1; number_layer < n; ++number_layer) { - size_t count_types = 0; - std::vector>& prev_layer(table[number_layer - 1]); - std::vector>& layer(table[number_layer]); - for (int i = 0; i < n; ++i) { - bool is_find = false; - for (int j = 0; j < i; ++j) { - if (prev_layer[j] == prev_layer[i]) { - layer[i][0] = layer[j][0]; - is_find = true; - break; - } - } - if (!is_find) { - layer[i][0] = count_types++; - } - } - for (int i = 0; i < n; ++i) { - for (int j = 0; j < alphabet.size(); ++j) { - const auto& transitions = graph.GetVertex(i).GetTransitions(); - if (transitions.count(alphabet[j])) - layer[i][j + 1] = layer[transitions.at(alphabet[j])][0]; - else - layer[i][j + 1] = -1LL; - } - } - } - - /* - for (int i = 0; i < n; ++i) { - for (int k = 0; k < n; ++k) { - for (int j = 0; j < alphabet.size() + 1; ++j) { - std::cout << table[k][i][j] << " "; - } - std::cout << "| "; - } - std::cout << std::endl; - } - */ - - std::vector>& last_layer(table.back()); - size_t count_vertex = 0; - - for (int i = 0; i < n; ++i) { - count_vertex = std::max(count_vertex, last_layer[i][0]); - } - count_vertex++; - - std::map number_vertex_in_DFA; - for (int i = 0; i < count_vertex; ++i) { - number_vertex_in_DFA[i] = result.AddNewVertex(); - } - - for (int i = 0; i < n; ++i) { - size_t v = number_vertex_in_DFA[last_layer[i][0]]; - - const auto& transitions = graph.GetVertex(i).GetTransitions(); - for (const auto& t: transitions) { - if (last_layer[t.second][0] != -1LL) { - size_t u = number_vertex_in_DFA[last_layer[t.second][0]]; - result.GetVertex(v).AddEdge(t.first, u); - } - } - - if (graph.GetVertex(i).IsStart()) result.GetVertex(v).SetStart(true); - if (graph.GetVertex(i).IsFinal()) result.GetVertex(v).SetFinal(true); - } - - return result; -} -} diff --git a/src/converters/DFAToRegular.cpp b/src/converters/DFAToRegular.cpp deleted file mode 100644 index ffd6f0c..0000000 --- a/src/converters/DFAToRegular.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "converters/DFAToRegular.hpp" - -namespace converters { -std::string DFAGraphToRegular(DFAGraph&& graph) { - const size_t n = graph.GetCountVertexes() + 1; - std::string result = ""; - - std::vector>> transitions(n, - std::vector>(n)); - - std::map rename; - size_t start = -1; - - for (int i = 0; i < n - 1; ++i) { - if (graph.NotExistVertex(i)) continue; - if (graph.GetVertex(i).IsStart()) start = i; - } - - rename[start] = 1; - int cnt = 2; - - for (int i = 0; i < n - 1; ++i) { - if (i == start) continue; - rename[i] = cnt++; - } - - - for (int i = 0; i < n - 1; ++i) { - if (graph.NotExistVertex(i)) continue; - const auto& vertex_transitions = graph.GetVertex(i).GetTransitions(); - - for (auto j: vertex_transitions) { - transitions[rename[i]][rename[j.second]].insert(std::string(1, j.first)); - } - if (graph.GetVertex(i).IsFinal()) { - transitions[rename[i]][0].insert("( )"); - } - } - - for (int i = n - 1; i > 1; --i) { - std::vector>> new_transitions(n, - std::vector>(n)); - std::string loop = ""; - if (transitions[i][i].size() != 0) { - for (const std::string s: transitions[i][i]) { - loop += "("; - loop += s; - loop += ")"; - loop += "|"; - } - if (loop.size()) - loop.pop_back(); - if (transitions[i][i].size() > 1) - loop = "(" + loop + ")*"; - else - loop += "*"; - } - - for (int j = 0; j < i; ++j) { - if (transitions[j][i].size() == 0) continue; - std::string j_to_i = ""; - for (const std::string s: transitions[j][i]) { - j_to_i += "("; - j_to_i += s; - j_to_i += ")"; - j_to_i += "|"; - } - if (j_to_i.size()) - j_to_i.pop_back(); - if (transitions[j][i].size() > 1) - j_to_i = "(" + j_to_i + ")"; - - for (int k = 0; k < i; ++k) { - if (transitions[i][k].size() == 0) continue; - std::string i_to_k = ""; - for (const std::string s: transitions[i][k]) { - i_to_k += "("; - i_to_k += s; - i_to_k += ")"; - i_to_k += "|"; - } - if (i_to_k.size()) - i_to_k.pop_back(); - if (transitions[i][k].size() > 1) - i_to_k = "(" + j_to_i + ")"; - - new_transitions[j][k].insert(j_to_i + loop + i_to_k); - } - } - - for (int j = 0; j < i; ++j) { - for (int k = 0; k < i; ++k) { - transitions[j][k].insert(new_transitions[j][k].begin(), new_transitions[j][k].end()); - } - } - } - - std::string loop; - std::string begin_to_end; - - if (transitions[1][1].size() != 0) { - for (const std::string& s: transitions[1][1]) { - loop += "("; - loop += s; - loop += ")"; - loop += "|"; - } - if (loop.size()) - loop.pop_back(); - loop = "(" + loop + ")*"; - } - for (const std::string& s: transitions[1][0]) { - begin_to_end += "("; - begin_to_end += s; - begin_to_end += ")"; - begin_to_end += "|"; - } - if (begin_to_end.size()) - begin_to_end.pop_back(); - - std::string res(loop + "(" + begin_to_end + ")"); - return res; -} -} diff --git a/src/converters/InvertFDFA.cpp b/src/converters/InvertFDFA.cpp deleted file mode 100644 index 429060b..0000000 --- a/src/converters/InvertFDFA.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#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.NotExistVertex(i)) continue; - fdfa_graph.GetVertex(i).SetFinal(!fdfa_graph.GetVertex(i).IsFinal()); - } - return std::move(fdfa_graph); -} -} diff --git a/src/converters/NFAToDFA.cpp b/src/converters/NFAToDFA.cpp deleted file mode 100644 index 843fc06..0000000 --- a/src/converters/NFAToDFA.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include "converters/NFAToDFA.hpp" -#include -#include -#include - -namespace converters { -NFAGraph AddAllEpsilonTransitions(NFAGraph&& nfa_graph) { - const int n = nfa_graph.GetCountVertexes(); - std::vector used(n, false); - - std::function dfs = [&nfa_graph, &used, &dfs](int u, int v) -> void { - used[v] = true; - const auto& transitions = nfa_graph.GetVertex(v).GetTransitions(); - if (transitions.count(' ')) { - const auto& s = transitions.at(' '); - for (auto i: s) { - if (!used[i]) { - if (u != i) - nfa_graph.GetVertex(u).AddEdge(' ', i); - dfs(u, i); - } - } - } - }; - - for (int i = 0; i < n; ++i) { - if (nfa_graph.NotExistVertex(i)) continue; - - used.assign(n, false); - dfs(i, i); - } - return std::move(nfa_graph); -} - -NFAGraph AddAllPossibleFinalVertexes(NFAGraph&& nfa_graph) { - if (nfa_graph.GetStartVertexes().size() != 1) { - size_t start_vertex = nfa_graph.AddNewVertex(); - for (auto v: nfa_graph.GetStartVertexes()) { - nfa_graph.GetVertex(start_vertex).AddEdge(' ', v); - } - } - for (const auto& v: nfa_graph.GetFinalVertexes()) { - const auto& transitions = nfa_graph.GetVertex(v).GetBackTransitions(); - if (transitions.count(' ')) { - const auto& s = transitions.at(' '); - for (auto i: s) { - nfa_graph.GetVertex(i).SetFinal(true); - } - } - } - return std::move(nfa_graph); -} - -NFAGraph DeleteEpsilonTransitions(NFAGraph&& nfa_graph) { - const int n = nfa_graph.GetCountVertexes(); - - for (int v = 0; v < n; ++v) { - if (nfa_graph.NotExistVertex(v)) continue; - - const auto& transitions = nfa_graph.GetVertex(v).GetTransitions(); - if (transitions.count(' ')) { - auto s = transitions.at(' '); - for (auto u: s) { - for (auto& i: nfa_graph.GetVertex(u).GetTransitions()) { - if (i.first == ' ') continue; - for (auto t: i.second) { - nfa_graph.GetVertex(v).AddEdge(i.first, t); - } - } - } - for (auto u: s) { - nfa_graph.GetVertex(v).RemoveEdge(' ', u); - } - } - } - return std::move(nfa_graph); -} - -NFAGraph DeleteTransitionsByOneLetter(NFAGraph&& nfa_graph) { - const int n = nfa_graph.GetCountVertexes(); - - NFAGraph result_tree; - - std::map, char>, std::set> transitions; - std::map, size_t> number_vertex_in_result_tree; - std::queue> queue; - - std::set alphabet; - for (int i = 0; i < n; ++i) { - if (nfa_graph.NotExistVertex(i)) continue; - for (const auto& j: nfa_graph.GetVertex(i).GetTransitions()) { - if (j.second.size() > 0) - alphabet.insert(j.first); - } - } - - for (auto i: nfa_graph.GetStartVertexes()) { - queue.push({i}); - number_vertex_in_result_tree[{i}] = result_tree.AddNewVertex(); - } - - while (!queue.empty()) { - auto current = queue.front(); - queue.pop(); - - for (auto symbol: alphabet) { - std::set result; - for (auto v: current) { - const auto& transitions = nfa_graph.GetVertex(v).GetTransitions(); - if (transitions.count(symbol)) { - const auto& s = transitions.at(symbol); - result.insert(s.begin(), s.end()); - } - } - - if (result.size() == 0) continue; - - transitions[std::make_pair(current, symbol)] = result; - if (!number_vertex_in_result_tree.count(result)) { - queue.push(result); - number_vertex_in_result_tree[result] = result_tree.AddNewVertex(); - } - } - } - - for (auto i: transitions) { - int v = number_vertex_in_result_tree[i.first.first]; - int u = number_vertex_in_result_tree[i.second]; - char symbol = i.first.second; - result_tree.GetVertex(v).AddEdge(symbol, u); - } - - for (auto i: number_vertex_in_result_tree) { - auto s = i.first; - auto v = i.second; - - for (auto i: s) { - if (nfa_graph.GetVertex(i).IsFinal()) - result_tree.GetVertex(v).SetFinal(true); - if (nfa_graph.GetVertex(i).IsStart()) - result_tree.GetVertex(v).SetStart(true); - } - } - - return result_tree; -} - -DFAGraph NFAGraphToDFAGraph(NFAGraph&& nfa_graph) { - nfa_graph = DeleteTransitionsByOneLetter(DeleteEpsilonTransitions(AddAllPossibleFinalVertexes( - AddAllEpsilonTransitions(std::move(nfa_graph))))); - - const int n = nfa_graph.GetCountVertexes(); - DFAGraph result; - std::map number_vertex_in_DFA; - for (int i = 0; i < n; ++i) { - if (nfa_graph.NotExistVertex(i)) continue; - number_vertex_in_DFA[i] = result.AddNewVertex(); - } - bool exists_start_vertex = false; - for (int i = 0; i < n; ++i) { - if (nfa_graph.NotExistVertex(i)) continue; - if (nfa_graph.GetVertex(i).IsFinal()) - result.GetVertex(number_vertex_in_DFA[i]).SetFinal(true); - if (nfa_graph.GetVertex(i).IsStart()) { - if (exists_start_vertex) { - throw std::runtime_error("I can't delete starts vertex"); - } - result.GetVertex(number_vertex_in_DFA[i]).SetStart(true); - exists_start_vertex = true; - } - - const auto& transitions = nfa_graph.GetVertex(i).GetTransitions(); - for (const auto& t: transitions) { - if (t.second.size() != 1) throw std::logic_error(""); - result.GetVertex(number_vertex_in_DFA[i]).AddEdge(t.first, *t.second.begin()); - } - } - if (!exists_start_vertex) { - throw std::runtime_error("I can't find start vertex"); - } - return result; -} -} diff --git a/src/converters/RegularToNFA.cpp b/src/converters/RegularToNFA.cpp deleted file mode 100644 index acae0a6..0000000 --- a/src/converters/RegularToNFA.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "converters/RegularToNFA.hpp" -#include "regular/RegularTree.hpp" -#include "NFA/NFAGraph.hpp" - -using namespace NFA; -using namespace regular; -using Node = RegularTree::Node; - -struct do_nothing_deleter{ - template - void operator()(T*) const {} -}; - -template -NFAGraph RegularToNFA(std::unique_ptr node) { - NFAGraph result; - if (node->type == Node::Type::Word) { - auto end = result.AddNewVertex(); - auto start = end; - result.AddStartVertex(end); - for (char i: node->word) { - auto tmp = result.AddNewVertex(); - result.GetVertex(end).AddEdge(i, tmp); - end = tmp; - } - if (node->modifier == Node::Modifier::Plus) { - result.GetVertex(end).AddEdge(' ', start); - } else if (node->modifier == Node::Modifier::Star) { - result.GetVertex(end).AddEdge(' ', start); - result.GetVertex(start).AddEdge(' ', end); - } - result.AddFinalVertex(end); - } else if (node->type == Node::Type::Concatenation) { - result = RegularToNFA(std::move(node->children[0])); - for (auto it = node->children.begin() + 1; it != node->children.end(); ++it) { - auto tmp = RegularToNFA(std::move(*it)); - auto v = result.AddNewVertex(); - result.Composition(std::move(tmp), result.GetFinalVertexes(), {v}); - while (!result.GetFinalVertexes().empty()) { - result.RemoveFinalVertex(result.GetFinalVertexes()[0]); - } - result.AddFinalVertex(v); - } - const auto& start_vertexes = result.GetStartVertexes(); - const auto& end_vertexes = result.GetFinalVertexes(); - - if (node->modifier == Node::Modifier::Plus) { - for (auto start: start_vertexes) { - for (auto end: end_vertexes) { - result.GetVertex(end).AddEdge(' ', start); - } - } - } else if (node->modifier == Node::Modifier::Star) { - for (auto start: start_vertexes) { - for (auto end: end_vertexes) { - result.GetVertex(end).AddEdge(' ', start); - result.GetVertex(start).AddEdge(' ', end); - } - } - } - - } else if (node->type == Node::Type::Addition) { - auto start = result.AddNewVertex(); - result.AddStartVertex(start); - auto end = result.AddNewVertex(); - result.AddFinalVertex(end); - for (auto& i: node->children) { - auto tmp = RegularToNFA(std::move(i)); - result.Composition(std::move(tmp), {start}, {end}); - } - if (node->modifier == Node::Modifier::Plus) { - result.GetVertex(end).AddEdge(' ', start); - } else if (node->modifier == Node::Modifier::Star) { - result.GetVertex(end).AddEdge(' ', start); - result.GetVertex(start).AddEdge(' ', end); - } - } - return result; -} - -namespace converters { -NFAGraph RegularToNFAGraph(RegularTree&& tree) { - const Node& root = tree.GetNode(); - return RegularToNFA(std::unique_ptr(&const_cast(tree.GetNode()))); -} -} diff --git a/src/main.cpp b/src/main.cpp index 9187628..a03be09 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,108 +1,5 @@ #include -#include "regular/RegularTree.hpp" -#include "NFA/NFAGraph.hpp" -#include "DFA/DFAGraph.hpp" -#include "converters/RegularToNFA.hpp" -#include "converters/NFAToDFA.hpp" -#include "converters/DFAToFDFA.hpp" -#include "converters/DFAToMinDFA.hpp" -#include "converters/DFAToRegular.hpp" -#include "converters/InvertFDFA.hpp" - -using namespace regular; -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_graph = RegularToNFAGraph(std::move(r)); - DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_graph)); - DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); - DFA_graph = DFAGraphToFDFAGraph(std::move(DFA_graph), {'a', 'b'}); - DFA_graph.Print(); - DFA_graph.CreateDotFile("1.dot"); - DFA_graph = InvertFDFAGraph(std::move(DFA_graph)); - DFA_graph.CreateDotFile("2.dot"); - DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); - } - - return 0; - { - RegularTree r("((ab|ba)*( |a|ba))"); - NFAGraph NFA_tree = RegularToNFAGraph(std::move(r)); - DFAGraph DFA_graph = NFAGraphToDFAGraph(std::move(NFA_tree)); - // DFA_graph.CreateDotFile("1.dot"); - // DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); - DFA_graph = DFAGraphToFDFAGraph(std::move(DFA_graph), {'a', 'b'}); - DFA_graph = InvertFDFAGraph(std::move(DFA_graph)); - // DFA_graph.CreateDotFile("2.dot"); - auto ss = DFAGraphToRegular(std::move(DFA_graph)); - std::cout << ss << std::endl; - r = RegularTree(ss); - // r.Print(); - std::cout << r.ToString() << std::endl; - // DFA_graph.Print(); - return 0; - - DFA_graph = DFAGraphToMinDFAGraph(std::move(DFA_graph)); - DFA_graph.Print(); - auto s = DFAGraphToRegular(std::move(DFA_graph)); - std::cout << s << std::endl; - r = RegularTree(s); - // r.Print(); - std::cout << r.ToString() << std::endl; - } - 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; - */ + std::cout << "hello world"; } diff --git a/src/regular/RegularTree.cpp b/src/regular/RegularTree.cpp deleted file mode 100644 index 70285b7..0000000 --- a/src/regular/RegularTree.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "regular/RegularTree.hpp" - -namespace regular { -RegularTree::RegularTree(const std::string& regular) { - node_.Parse(regular); -} - -const RegularTree::Node& RegularTree::GetNode() const { - return node_; -} - -void RegularTree::Print() const { - node_.Print(); -} - -std::string RegularTree::ToString() const { - return node_.ToString(); -} -} diff --git a/src/regular/RegularTreeNode.cpp b/src/regular/RegularTreeNode.cpp deleted file mode 100644 index ac297ae..0000000 --- a/src/regular/RegularTreeNode.cpp +++ /dev/null @@ -1,254 +0,0 @@ -#include "regular/RegularTree.hpp" -#include - -using Node = regular::RegularTree::Node; -Node::Node() {} -Node::Node(Type type) : type(type) {} - -void Node::Parse(const std::string& regular) { - type = Type::Addition; - ParseCurrentType(std::string_view(regular.c_str(), regular.size())); - for (int i = 0; i < 10; ++i) { - Compression(); - Compression2(); - } -} - -void Node::Print() const { - Print(0); -} - -void Node::ParseCurrentType(const std::string_view regular) { - const size_t n = regular.size(); - children.clear(); - word.clear(); - - auto AddChild = [this](const std::string_view regular) { - this->children.push_back(std::make_unique(Type::Addition)); - this->children.back()->ParseCurrentType(regular); - }; - - if (n == 1) { - type = Type::Word; - } - - if (type == Type::Addition) { - int balance = 0; - int begin_child = 0; - bool wrapped_brackets = (regular[0] == '('); - - for (size_t i = 0; i < n; ++i) { - if (regular[i] == '(') { - ++balance; - } else if (regular[i] == ')') { - --balance; - } - - if (regular[i] == '|') { - if (balance == 0) { - AddChild(regular.substr(begin_child + wrapped_brackets, i - - begin_child - 2 * - wrapped_brackets)); - begin_child = i + 1; - - if (i + 1 < n) - wrapped_brackets = (regular[i + 1] == '('); - } - } else { - if (i + 1 == n) { - if (children.size() == 0) { - type = Type::Concatenation; - break; - } else { - AddChild(regular.substr(begin_child + wrapped_brackets, i - - begin_child + 1 - 2 * - wrapped_brackets)); - begin_child = i + 1; - if (i + 1 < n) - wrapped_brackets = (regular[i + 1] == '('); - } - } else if (balance == 0) { - wrapped_brackets = false; - } - } - } - } - - if (type == Type::Concatenation) { - int balance = 0; - int begin_child = 0; - - for (size_t i = 0; i < n; ++i) { - if (regular[i] == '(') { - ++balance; - if (balance == 1) { - if (begin_child < i) { - AddChild(regular.substr(begin_child, i - begin_child)); - } - begin_child = i + 1; - } - } else if (regular[i] == ')') { - --balance; - if (balance == 0) { - AddChild(regular.substr(begin_child, i - begin_child)); - begin_child = i + 1; - } - } else if (i + 1 == n) { - if (balance != 0) { - throw std::logic_error("invalid regular"); - } - - if (children.size() == 0) { - type = Type::Word; - break; - } else { - if (regular[i] == '+') { - if (begin_child < i) { - AddChild(regular.substr(begin_child, i - begin_child)); - } - children.back()->modifier = Modifier::Plus; - begin_child = i + 1; - } else if (regular[i] == '*') { - if (begin_child < i) { - AddChild(regular.substr(begin_child, i - begin_child)); - } - children.back()->modifier = Modifier::Star; - begin_child = i + 1; - } else { - AddChild(regular.substr(begin_child, i - begin_child + 1)); - begin_child = i + 1; - } - } - } else if (balance == 0) { - if (regular[i] == '+') { - if (begin_child < i) { - AddChild(regular.substr(begin_child, i - begin_child)); - } - children.back()->modifier = Modifier::Plus; - begin_child = i + 1; - } else if (regular[i] == '*') { - if (begin_child < i) { - AddChild(regular.substr(begin_child, i - begin_child)); - } - children.back()->modifier = Modifier::Star; - begin_child = i + 1; - } - } - } - } - - if (type == Type::Word) { - bool exist_modifire = regular.back() == '+' || regular.back() == '*'; - if (regular.back() == '+') { - modifier = Modifier::Plus; - } else if (regular.back() == '*') { - modifier = Modifier::Star; - } - for (size_t i = 0; i < n - exist_modifire; ++i) { - if (regular[i] == '|' || regular[i] == '(' || regular[i] == ')') { - throw std::logic_error("invalid regular"); - } - word += regular[i]; - } - } -} - -void Node::Compression() { - for (auto& i: children) { - i->Compression(); - } - if (children.size() == 1 && modifier == Modifier::None) { - auto tmp = std::move(*children[0]); - *this = std::move(tmp); - } -} - -void Node::Compression2() { - for (auto& i: children) { - i->Compression2(); - } - bool f = type == Type::Concatenation; - for (auto& i: children) { - f &= i->modifier == Modifier::None; - f &= i->type == Type::Word; - } - if (f) { - auto tmp = std::move(*children[0]); - tmp.modifier = modifier; - for (int i = 1; i < children.size(); ++i) { - tmp.word += children[i]->word; - } - *this = std::move(tmp); - } -} - -void Node::Print(int nesting_level) const { - auto PrintNesingLevel = [](int nesting_level) { - for (int i = 0; i < nesting_level; ++i) { - std::cout << " "; - } - }; - - PrintNesingLevel(nesting_level); - if (type == Type::Addition) { - std::cout << "Addition"; - if (modifier == Modifier::Plus) { - std::cout << "+"; - } else if (modifier == Modifier::Star) { - std::cout << "*"; - } - std::cout << " " << std::to_string(children.size()) << ":" << std::endl; - } else if (type == Type::Concatenation) { - std::cout << "Concatenation"; - if (modifier == Modifier::Plus) { - std::cout << "+"; - } else if (modifier == Modifier::Star) { - std::cout << "*"; - } - std::cout << " " << children.size() << ":" << std::endl; - } else if (type == Type::Word) { - std::cout << "Word"; - if (modifier == Modifier::Plus) { - std::cout << "+"; - } else if (modifier == Modifier::Star) { - std::cout << "*"; - } - std::cout << ": " << word << std::endl; - } - - for (const auto& i: children) { - i->Print(nesting_level + 1); - } -} - -std::string regular::RegularTree::Node::ToString() const { - std::string res; - if (type == Type::Word) { - res = word; - if (modifier == Modifier::Plus) - res = "(" + res + ")+"; - else if (modifier == Modifier::Star) - res = "(" + res + ")*"; - } else if (type == Type::Concatenation) { - for (auto& i: children) { - res += i->ToString(); - } - if (modifier == Modifier::Plus) - res = "(" + res + ")+"; - else if (modifier == Modifier::Star) - res = "(" + res + ")*"; - } else if (type == Type::Addition) { - for (auto& i: children) { - res += i->ToString(); - res += "|"; - } - if (res.size()) - res.pop_back(); - res = "(" + res + ")"; - if (modifier == Modifier::Plus) - res += "+"; - else if (modifier == Modifier::Star) - res += "*"; - } - return res; -} diff --git a/tests/DFAToMinDFA/CountSizesMinDFA.cpp b/tests/DFAToMinDFA/CountSizesMinDFA.cpp deleted file mode 100644 index 66a1cf5..0000000 --- a/tests/DFAToMinDFA/CountSizesMinDFA.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#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; - -size_t GetCountVertexes(const std::string& regular) { - 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)); - - return DFA_graph.GetReallyCountVertexes(); -} - -TEST(DFA_to_min_DFA, a_start) { - EXPECT_EQ(GetCountVertexes("a*"), GetCountVertexes("( a | )*| | | aaa a a")); -} - -TEST(DFA_to_min_DFA, a_plus) { - EXPECT_EQ(GetCountVertexes("a+"), GetCountVertexes("( a | a a )+|a | a |a ")); -} - -TEST(DFA_to_min_DFA, a_star_or_b_star) { - EXPECT_EQ(GetCountVertexes("a*|b*"), GetCountVertexes("a|b|a*|a+|b*|b+|bbb b b b| a a aa a aa | a+")); -} - -TEST(DFA_to_min_DFA, epsilon) { - EXPECT_EQ(GetCountVertexes(" "), GetCountVertexes(" | | | ")); -} - -TEST(DFA_to_min_DFA, a_or_b_star) { - EXPECT_EQ(GetCountVertexes("(a|b)*"), GetCountVertexes("a+|b+|a*|b*|a*b*a*|a|b(a|b)*|b| |(a|b)*")); -} diff --git a/tests/DFAToRegular/DFAToRegular.cpp b/tests/DFAToRegular/DFAToRegular.cpp deleted file mode 100644 index e46e99f..0000000 --- a/tests/DFAToRegular/DFAToRegular.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#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_regular, 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)); - - 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_regular, 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)); - - 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_regular, 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)); - - 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_regular, 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)); - - 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_regular, 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)); - - 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_regular, _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)); - - 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_regular, _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)); - - 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)); - } -} diff --git a/tests/DFAToRegular/DFAToRegular2.cpp b/tests/DFAToRegular/DFAToRegular2.cpp deleted file mode 100644 index 17603ab..0000000 --- a/tests/DFAToRegular/DFAToRegular2.cpp +++ /dev/null @@ -1,209 +0,0 @@ -#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)); - } -} diff --git a/tests/NFAToDFA/CheckEquivalence.cpp b/tests/NFAToDFA/CheckEquivalence.cpp deleted file mode 100644 index 2b84cfa..0000000 --- a/tests/NFAToDFA/CheckEquivalence.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include -#include -#include "DFA/DFAGraph.hpp" -#include "NFA/NFAGraph.hpp" -#include "converters/NFAToDFA.hpp" - -using namespace NFA; -using namespace DFA; -using namespace converters; - -std::mt19937 rnd(1337); - -std::string GenerateRandomString(std::vector alphabet, size_t len) { - std::string res(len, ' '); - for (auto& i: res) { - i = alphabet[rnd() % alphabet.size()]; - } - return res; -} - -TEST(check_equivalence_NFA_to_DFA, 1) { - NFA::NFAGraph tree; - - const int N = 10; - int a[N]; - for (int i = 0; i < N; ++i) - a[i] = tree.AddNewVertex(); - - tree.GetVertex(a[0]).AddEdge('a', a[1]); - tree.GetVertex(a[1]).AddEdge('a', a[2]); - tree.GetVertex(a[0]).AddEdge('a', a[3]); - - tree.GetVertex(a[0]).SetStart(true); - tree.GetVertex(a[2]).SetFinal(true); - tree.GetVertex(a[3]).SetFinal(true); - - DFA::DFAGraph res = converters::NFAGraphToDFAGraph(std::move(tree)); - - EXPECT_FALSE(res.Accepted("")); - EXPECT_TRUE(res.Accepted("a")); - EXPECT_TRUE(res.Accepted("aa")); - EXPECT_FALSE(res.Accepted("aaa")); - EXPECT_FALSE(res.Accepted("aaaa")); - EXPECT_FALSE(res.Accepted("aaaaa")); - EXPECT_FALSE(res.Accepted("b")); -} - -TEST(check_equivalence_NFA_to_DFA, 2) { - NFA::NFAGraph tree; - - const int N = 10; - int a[N]; - for (int i = 0; i < N; ++i) - a[i] = tree.AddNewVertex(); - - 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); - - DFA::DFAGraph res = converters::NFAGraphToDFAGraph(std::move(tree)); - - auto check = [](const std::string& str) { - if (str.size() > 0) { - if (str[0] == 'a') { - if (str.size() == 1) { - return true; - } - if (str[1] == 'b') { - for (int i = 1; i < str.size(); ++i) { - if (str[i] != 'b') { - return false; - } - } - return true; - } - if (str[1] == 'c') { - for (int i = 1; i < str.size(); ++i) { - if (str[i] != 'c') { - return false; - } - } - return true; - } - } - } - - return false; - }; - - EXPECT_FALSE(res.Accepted("")); - EXPECT_TRUE(res.Accepted("a")); - EXPECT_FALSE(res.Accepted("aa")); - EXPECT_FALSE(res.Accepted("aaa")); - EXPECT_FALSE(res.Accepted("aaaa")); - EXPECT_FALSE(res.Accepted("aaaaa")); - EXPECT_FALSE(res.Accepted("b")); - EXPECT_TRUE(res.Accepted("ab")); - EXPECT_TRUE(res.Accepted("abb")); - EXPECT_TRUE(res.Accepted("ac")); - EXPECT_TRUE(res.Accepted("acc")); - - for (int i = 0; i < 5000; ++i) { - auto str = GenerateRandomString({'a', 'b', 'c', 'd'}, 20); - ASSERT_EQ(res.Accepted(str), check(str)); - } -} diff --git a/tests/invertFDFA/InvertFDFA.cpp b/tests/invertFDFA/InvertFDFA.cpp deleted file mode 100644 index cc1efb2..0000000 --- a/tests/invertFDFA/InvertFDFA.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include -#include -#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 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 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 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 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)); - } -} diff --git a/tests/regular/ParseRegular.cpp b/tests/regular/ParseRegular.cpp deleted file mode 100644 index 25bf34a..0000000 --- a/tests/regular/ParseRegular.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include "regular/RegularTree.hpp" - -using namespace regular; - -TEST(parse_regular, only_addition) { - RegularTree("a"); - RegularTree("aa"); - RegularTree("aaa"); - RegularTree("aaaa"); - RegularTree("aaaaa"); - RegularTree("a|aaaa"); - RegularTree("a|a|a|a|a"); - RegularTree("hello|world"); - RegularTree("qe|wr|lkj|alk"); -} - -TEST(parse_regular, only_folding) { - RegularTree("(kajfkasf(aksdjf)jka(((aksjdf)K)))jakd"); - RegularTree("(kajsdfk(aksdjf)kajsdf)kjasdkfja(skdjf(((aksjdkadf)ksjf(kdja))))"); - RegularTree("((((kdjf))))"); - RegularTree("kasjf(akjsfkjasdg)kajsdg"); - RegularTree("akjsdf(akjdf(kdjfak(jkasdf)))"); - RegularTree("123k4j1k351kk21jkj21k6j2k36j1(((((ajkfajsdfkafdalkdjflk)))))"); -} - -TEST(parse_regular, only_modifiers) { - RegularTree("jlakjdf*aksdjflaf8*laksfj*lakjsf*alksjdf"); - RegularTree("jlakjdf*aksdjflaf8+laksfj*lakjsf*alksjdf*"); - RegularTree("jlakjdf*aksdjflaf8*laksfj*lakjsf+alksjdf"); - RegularTree("jlakjd+aksdjflaf8*laksfj*lakjsf*alksjdf+"); -} - -TEST(parse_regular, all_operations) { - RegularTree("(alkjdfaksdf*|lkasdj*|(kasjdf|kajdf*|kjd)*|laksjf*)+"); - RegularTree("(alkjdfaksdf|lkasdj*|(kas+jdf|kajdf*|kjd)*|laksjf*)+"); - RegularTree("a|(a|(a|(a|)*))*"); - RegularTree("kj*|kjadf*|(kajsdf|(kajsd|kjadf|(kasjdf)|kajs)*)*"); -} - diff --git a/tests/regularToDFA/RegularToDFA.cpp b/tests/regularToDFA/RegularToDFA.cpp deleted file mode 100644 index 6087923..0000000 --- a/tests/regularToDFA/RegularToDFA.cpp +++ /dev/null @@ -1,151 +0,0 @@ -#include -#include -#include "regular/RegularTree.hpp" -#include "converters/RegularToNFA.hpp" -#include "converters/NFAToDFA.hpp" -#include "converters/DFAToMinDFA.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(regular_to_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)); - - std::string s = ""; - for (int i = 0; i < 100; ++i) { - ASSERT_EQ(DFA_graph.Accepted(s), true); - s += "a"; - } -} - -TEST(regular_to_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)); - - 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(regular_to_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)); - - 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(regular_to_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)); - - 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(regular_to_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)); - - 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(regular_to_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)); - - 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(regular_to_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)); - - 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)); - } -} diff --git a/tests/MainTest.cpp b/tests/test_main.cpp similarity index 100% rename from tests/MainTest.cpp rename to tests/test_main.cpp