Skip to content

Commit

Permalink
Refactorización de conversión + se resolvieron los bugs de salida de …
Browse files Browse the repository at this point in the history
…dfa a string
  • Loading branch information
ignacioDias committed Apr 12, 2024
1 parent 4ac04cc commit d4841eb
Show file tree
Hide file tree
Showing 35 changed files with 1,564 additions and 1,077 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ add_executable(tpOb1
TP/auxiliarmethods/CollectionsOperators.cpp
TP/Main.cpp
TP/parser/Parser.h
TP/parser/Parser.cpp)
TP/parser/Parser.cpp
TP/automata/convertion/ConvertionOfAutomatas.h
TP/automata/convertion/ConvertionOfAutomatas.cpp)
9 changes: 6 additions & 3 deletions TP/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "automata/dfa/DeterministicFiniteAutomata.h"
#include "automata/ndfa/NotDeterministicFiniteAutomata.h"
#include "parser/Parser.h"
#include "automata/convertion/ConvertionOfAutomatas.h"
using namespace std;

int main() {
Expand Down Expand Up @@ -45,7 +46,9 @@ int main() {
ndfa.addPath(13,2,13);
ndfa.addFinalState(12);
// cout << Parser::ndfaToString(ndfa);
DeterministicFiniteAutomata dfa = ndfa.nfaToDfa();
cout << Parser::dfaToString(dfa);
return 0;
ConvertionOfAutomatas convertor;
convertor.setNDFA(ndfa);
convertor.convertFromNDFA();
cout << Parser::dfaToString(convertor.getDFA());
return 0;
}
90 changes: 90 additions & 0 deletions TP/automata/convertion/ConvertionOfAutomatas.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//
// Created by ignaciodias on 12/04/24.
//
#define LAMBDA -1
#include "ConvertionOfAutomatas.h"
ConvertionOfAutomatas :: ConvertionOfAutomatas() : ndfa(), dfa(){
}
void ConvertionOfAutomatas :: setNDFA(NotDeterministicFiniteAutomata ndfa) {
this->ndfa = ndfa;
}
void ConvertionOfAutomatas :: setDFA(DeterministicFiniteAutomata dfa) {
this->dfa = std::move(dfa);
}
DeterministicFiniteAutomata ConvertionOfAutomatas :: getDFA() {
return dfa;
}
void ConvertionOfAutomatas :: convertFromNDFA() {
set<int> q0AsSet;
q0AsSet.insert(ndfa.getInitialState());
set<int> Q0 = getSymbolClosure(q0AsSet);
dfa.setInitialState(Q0);
set<set<int>> newK;
newK.insert(Q0);

dfa.setAlphabet(ndfa.getAlphabet());

dfa.setStates(newK);
calculateNewK();
dfa.setFinalStates(calculateFinal(dfa.getStates()));
}
void ConvertionOfAutomatas::calculateNewK() {
set<set<int>> unvisitedNodes = dfa.getStates();
while(!unvisitedNodes.empty()) {
auto currentNode = *unvisitedNodes.begin();
for (auto currentNumber : ndfa.getAlphabet()) {
set<int> currentSet = move(currentNode, currentNumber);
currentSet = getSymbolClosure(currentSet);
if (dfa.getStates().count(currentSet) <= 0) {
dfa.insertSate(currentSet);
unvisitedNodes.insert(currentSet);
dfa.addPath(currentNode, currentNumber, currentSet);
}
}
unvisitedNodes.erase(currentNode);
}
}
set<int> ConvertionOfAutomatas::getSymbolClosure(const set<int>& Q) {
set<int> result;
set<int> visited_states;
set<int> unvisited_states = Q;
while (!unvisited_states.empty()) {
int curr_state = *unvisited_states.begin();
unvisited_states.erase(curr_state);
visited_states.insert(curr_state);
set<int> reachable_states = ndfa.calculateDelta({curr_state, LAMBDA});
if(reachable_states.empty())
result.insert(curr_state);
for (int reachable_state : reachable_states) {
result.insert(reachable_state);
if (visited_states.find(reachable_state) == visited_states.end())
unvisited_states.insert(reachable_state);
}
}
return result;
}
set<int> ConvertionOfAutomatas :: move(const set<int>& Q, int a) {
set<int> ret;
for(auto elem : Q) {
pair<int,int> actualPair;
actualPair.first = elem;
actualPair.second = a;
set<int> actualSet = ndfa.calculateDelta(actualPair);
if(!actualSet.empty())
CollectionsOperators::insertAll(ret, actualSet);
}
return ret;
}

set<set<int>> ConvertionOfAutomatas :: calculateFinal(const set<set<int>>& k) {
set<set<int>> newF;
for(const auto& currentSet : k) {
for(auto currentNumber : currentSet) {
if(ndfa.getFinalSates().count(currentNumber) > 0) {
newF.insert(currentSet);
break;
}
}
}
return newF;
}
28 changes: 28 additions & 0 deletions TP/automata/convertion/ConvertionOfAutomatas.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// Created by ignaciodias on 12/04/24.
//

#ifndef TPOB1_CONVERTIONOFAUTOMATAS_H
#define TPOB1_CONVERTIONOFAUTOMATAS_H
#include "../dfa/DeterministicFiniteAutomata.h"
#include "../ndfa/NotDeterministicFiniteAutomata.h"

class ConvertionOfAutomatas {
private:
DeterministicFiniteAutomata dfa;
NotDeterministicFiniteAutomata ndfa;
public:
ConvertionOfAutomatas();
void setNDFA(NotDeterministicFiniteAutomata ndfa);
void setDFA(DeterministicFiniteAutomata dfa);
void convertFromNDFA();
DeterministicFiniteAutomata getDFA();
private:
set<int> getSymbolClosure(const set<int>& Q);
set<int> move(const set<int>& Q, int a);
set<set<int>> calculateFinal(const set<set<int>>& k);
void calculateNewK();
};


#endif //TPOB1_CONVERTIONOFAUTOMATAS_H
78 changes: 1 addition & 77 deletions TP/automata/ndfa/NotDeterministicFiniteAutomata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,80 +66,4 @@ set<int> NotDeterministicFiniteAutomata :: calculateWaysToGo(int from, int desti
ret.insert(letter);
}
return ret;
}
DeterministicFiniteAutomata NotDeterministicFiniteAutomata :: nfaToDfa() {
DeterministicFiniteAutomata convertedAutomata = *new DeterministicFiniteAutomata();
set<int> q0AsSet;
q0AsSet.insert(getInitialState());
set<int> Q0 = getSymbolClosure(q0AsSet);
convertedAutomata.setInitialState(Q0);
set<set<int>> newK;
newK.insert(Q0);

convertedAutomata.setAlphabet(getAlphabet());

convertedAutomata.setStates(newK);
calculateNewK(convertedAutomata);
convertedAutomata.setFinalStates(calculateFinal(newK));
return convertedAutomata;
}
void NotDeterministicFiniteAutomata :: calculateNewK(DeterministicFiniteAutomata& dfa) {
set<set<int>> unvisitedNodes = dfa.getStates();
while(!unvisitedNodes.empty()) {
auto currentNode = *unvisitedNodes.begin();
for (auto currentNumber: getAlphabet()) {
set<int> currentSet = move(currentNode, currentNumber);
currentSet = getSymbolClosure(currentSet);
if (dfa.getStates().count(currentSet) <= 0) {
dfa.insertSate(currentSet);
unvisitedNodes.insert(currentSet);
dfa.addPath(currentNode, currentNumber, currentSet);
}
}
unvisitedNodes.erase(currentNode);
}
}
set<int> NotDeterministicFiniteAutomata ::getSymbolClosure(const set<int>& Q) {
set<int> result;
set<int> visited_states;
set<int> unvisited_states = Q;
while (!unvisited_states.empty()) {
int curr_state = *unvisited_states.begin();
unvisited_states.erase(curr_state);
visited_states.insert(curr_state);
set<int> reachable_states = calculateDelta({curr_state, LAMBDA});
if(reachable_states.empty())
result.insert(curr_state);
for (int reachable_state : reachable_states) {
result.insert(reachable_state);
if (visited_states.find(reachable_state) == visited_states.end())
unvisited_states.insert(reachable_state);
}
}
return result;
}
set<int> NotDeterministicFiniteAutomata :: move(const set<int>& Q, int a) {
set<int> ret;
for(auto elem : Q) {
pair<int,int> actualPair;
actualPair.first = elem;
actualPair.second = a;
set<int> actualSet = calculateDelta(actualPair);
if(!actualSet.empty())
CollectionsOperators::insertAll(ret, actualSet);
}
return ret;
}

set<set<int>> NotDeterministicFiniteAutomata :: calculateFinal(const set<set<int>>& k) {
set<set<int>> newF;
for(const auto& currentSet : k) {
for(auto currentNumber : currentSet) {
if(getFinalSates().count(currentNumber) > 0) {
newF.insert(currentSet);
break;
}
}
}
return newF;
}
}
6 changes: 0 additions & 6 deletions TP/automata/ndfa/NotDeterministicFiniteAutomata.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,7 @@ class NotDeterministicFiniteAutomata : public AutomataInterface {
void addFinalState(int state);
void addPath(int node, int arc, int destination);
set<int> calculateDelta(pair<int,int> key);
DeterministicFiniteAutomata nfaToDfa();
set<int> calculateWaysToGo(int from, int destination);

private:
set<int> getSymbolClosure(const set<int>& Q);
set<int> move(const set<int>& Q, int a);
set<set<int>> calculateFinal(const set<set<int>>& k);
void calculateNewK(DeterministicFiniteAutomata& dfa);
};
#endif //TPOB1_NOTDETERMINISTICFINITEAUTOMATA_H
20 changes: 12 additions & 8 deletions TP/auxiliarmethods/CollectionsOperators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,18 @@ void CollectionsOperators :: insertAll(set<int>& setToBeModify, const set<int>&
}

string CollectionsOperators::to_string_set(const set<int>& set) {
string ret;
for(auto elem : set)
ret += std::to_string(elem) +", ";
return ret + "\n";
stringstream ss;
for (auto it = set.begin(); it != set.end(); ++it) {
if (it != set.begin())
ss << ",";
ss << *it;
}
return ss.str();
}
string CollectionsOperators::to_string_set_of_sets(const set<set<int>>& setOfSets) {
string ret;
for(const auto& elem : setOfSets)
ret += to_string_set(elem);
return ret;
stringstream ret;
for (const auto & setOfSet : setOfSets) {
ret << to_string_set(setOfSet);
}
return ret.str();
}
23 changes: 9 additions & 14 deletions TP/parser/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,25 +101,22 @@ void Parser::fileManagement(const string& line) {
}
string Parser::dfaToString(DeterministicFiniteAutomata dfa) {
string ret = "digraph{\ninic[shape=point];\ninic->";
ret += "{\"" + toStringSet(dfa.getInitialState()) + "\"};\n";
ret += "{\"" + CollectionsOperators::to_string_set(dfa.getInitialState()) + "\"};\n";
toStringStatesDFA(dfa, ret);
toStringFinalStateDFA(dfa, ret);
ret += "\n}";
return ret;
}
string Parser::toStringSet(const set<int>& set) {
string ret;
for(auto elem : set)
ret += to_string(elem) + ",";
ret.pop_back();
return ret;
}
void Parser::toStringStatesDFA(DeterministicFiniteAutomata dfa, std::string &ret) {
void Parser::toStringStatesDFA(DeterministicFiniteAutomata dfa, string &ret) {
for(const auto& set1 : dfa.getStates()) {
if(set1.empty())
continue;
for(const auto& set2 : dfa.getStates()) {
if(set2.empty())
continue;
set<int> label = dfa.calculateWaysToGo(set1, set2);
if(!label.empty()) {
ret += toStringSet(set1) + " -> " + toStringSet(set2) + " [label = \"";
ret += "\"" + CollectionsOperators::to_string_set(set1) + "\" -> \"" + CollectionsOperators::to_string_set(set2) + "\" [label = \"";
for(auto elem : label)
ret += to_string(elem) + ",";
ret.pop_back();
Expand All @@ -129,11 +126,9 @@ void Parser::toStringStatesDFA(DeterministicFiniteAutomata dfa, std::string &ret
}
}
void Parser :: toStringFinalStateDFA(DeterministicFiniteAutomata dfa, string& ret) {
for(set<int> finalState : dfa.getFinalStates())
ret += toStringSet(finalState) + "[shape=doublecircle];\n";
ret.pop_back();
ret += "\"" + CollectionsOperators::to_string_set_of_sets(dfa.getFinalStates()) + "\" [shape=doublecircle];\n";
ret.pop_back();
}

string Parser::ndfaToString(NotDeterministicFiniteAutomata ndfa) {
string ret = "digraph{\ninic[shape=point];\ninic -> ";
ret += to_string(ndfa.getInitialState()) + ";\n";
Expand Down
Loading

0 comments on commit d4841eb

Please sign in to comment.