diff --git a/aepsilon2/src/aepsilon.cpp b/aepsilon2/src/aepsilon.cpp index 0c2ac5def5cbc57dd03902a53857ee47c0f64aaa..3c8cf8f8c712958a522135bf9a4377c7f1875c3d 100644 --- a/aepsilon2/src/aepsilon.cpp +++ b/aepsilon2/src/aepsilon.cpp @@ -9,7 +9,7 @@ #include <factory/DataFactory.hpp> #include <exception/AlibException.h> -#include "epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h" +#include "epsilon/fsm/FSMEpsilonRemover.h" int main(int argc, char** argv) { int fileParameterIndex = -1; @@ -45,21 +45,9 @@ int main(int argc, char** argv) { if(alib::FromXMLParsers::automatonParser.first(tokens)) { std::string xmlMark = tokens.front( ).getData( ); - if(xmlMark == "EpsilonNFA") { - automaton::EpsilonNFA automaton = alib::DataFactory::fromTokens<automaton::EpsilonNFA>(tokens); - automaton::NFA res = epsilon::EpsilonNFAEpsilonRemover::remove( automaton ); - alib::DataFactory::toStdout(res); - } else if(xmlMark == "NFA") { - automaton::NFA automaton = alib::DataFactory::fromTokens<automaton::NFA>(tokens); - alib::DataFactory::toStdout(automaton); - } else if(xmlMark == "DFA") { - automaton::DFA automaton = alib::DataFactory::fromTokens<automaton::DFA>(tokens); - alib::DataFactory::toStdout(automaton); - } else { - automaton::EpsilonNFA automaton = alib::DataFactory::fromTokens<automaton::EpsilonNFA>(tokens); - automaton::NFA res = epsilon::EpsilonNFAEpsilonRemover::remove( automaton ); - alib::DataFactory::toStdout(res); - } + automaton::Automaton automaton = alib::DataFactory::fromTokens<automaton::Automaton>(tokens); + automaton::Automaton res = epsilon::FSMEpsilonRemover::remove( automaton ); + alib::DataFactory::toStdout(res); } else { throw exception::AlibException("Invalid argument expected Epsilon NFA."); } diff --git a/alib2algo/src/automaton/EpsilonClosure.h b/alib2algo/src/automaton/EpsilonClosure.h index 41030ec815f51d223813c4ad58ceb9c3868319d1..603f85ba9cbb065755197799a1c69264c8ea630f 100644 --- a/alib2algo/src/automaton/EpsilonClosure.h +++ b/alib2algo/src/automaton/EpsilonClosure.h @@ -17,7 +17,7 @@ namespace automaton { -class EpsilonClosure : public VisitableAutomatonBase::const_visitor_type { +class EpsilonClosure : public VisitableAutomatonBase::const_visitor_type { public: static std::set<automaton::State> epsilonClosure( const automaton::Automaton & automaton, const automaton::State & state ); diff --git a/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.cpp b/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.cpp deleted file mode 100644 index 4173dea1290fc588498bc1d32a1e2cdcec09f243..0000000000000000000000000000000000000000 --- a/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * EpsilonNFAEpsilonRemover.cpp - * - * Created on: 16. 1. 2014 - * Author: Tomas Pecka - */ - -#include "EpsilonNFAEpsilonRemover.h" - -#include "../../automaton/EpsilonClosure.h" - -namespace epsilon { - -automaton::NFA EpsilonNFAEpsilonRemover::remove(const automaton::NFA& origFSM) -{ - return origFSM; -} - -automaton::NFA EpsilonNFAEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM ) { - automaton::NFA fsm; - - for( const auto & state : origFSM.getStates() ) - fsm.addState( state ); - - for( const auto & state : origFSM.getInitialStates() ) - fsm.addInitialState( state ); - - for( const auto & symbol : origFSM.getInputAlphabet() ) - fsm.addInputSymbol( symbol ); - - /** - * Step 1 from Melichar 2.41 - */ - for( const auto & from : origFSM.getStates( ) ) - for( const auto & fromClosure : automaton::EpsilonClosure::epsilonClosure( origFSM, from ) ) - for( const auto & transition : origFSM.getSymbolTransitionsFromState( fromClosure ) ) - for( const auto & to : transition.second ) - fsm.addTransition( from, transition.first.second, to ); - - /** - * Step 2 from Melichar 2.41 - */ - std::set<automaton::State> finalStates; - - for( const auto & q : fsm.getStates( ) ) - { - const std::set<automaton::State> & cl = automaton::EpsilonClosure::epsilonClosure( origFSM, q ); - const std::set<automaton::State> & F = origFSM.getFinalStates( ); - std::set<automaton::State> intersect; - - set_intersection( cl.begin(), cl.end(), F.begin(), F.end(), std::inserter( intersect, intersect.begin() ) ); - if( intersect.size( ) != 0 ) - finalStates.insert( q ); - } - - for( const auto & q : finalStates ) - fsm.addFinalState( q ); - - return fsm; -} - -} /* namespace epsilon */ diff --git a/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h b/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h deleted file mode 100644 index c65beebcc4197cbe78ed70ed3e2316aefdb7420d..0000000000000000000000000000000000000000 --- a/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * EpsilonNFAEpsilonRemover.h - * - * Created on: 16. 1. 2014 - * Author: Tomas Pecka - */ - -#ifndef EPSILON_NFA_EPSILON_REMOVER_H_ -#define EPSILON_NFA_EPSILON_REMOVER_H_ - -#include <map> -#include <algorithm> - -#include <automaton/FSM/EpsilonNFA.h> -#include <automaton/FSM/NFA.h> -#include <exception/AlibException.h> - -namespace epsilon { - -class EpsilonNFAEpsilonRemover { -public: - static automaton::NFA remove(const automaton::EpsilonNFA &); - static automaton::NFA remove(const automaton::NFA &); -}; - -} /* namespace epsilon */ - -#endif /* EPSILON_NFA_EPSILON_REMOVER_H_ */ diff --git a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d05c5caafc90f05eb798d8130999e221dd61886f --- /dev/null +++ b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp @@ -0,0 +1,116 @@ +/* + * FSMEpsilonRemover.cpp + * + * Created on: 16. 1. 2014 + * Author: Tomas Pecka + */ + +#include "FSMEpsilonRemover.h" + +#include "../../automaton/EpsilonClosure.h" + +namespace epsilon { + +automaton::DFA FSMEpsilonRemover::remove(const automaton::DFA& origFSM) +{ + return origFSM; +} + +automaton::NFA FSMEpsilonRemover::remove(const automaton::NFA& origFSM) +{ + return origFSM; +} + +automaton::NFA FSMEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM ) { + automaton::NFA fsm; + + for( const auto & state : origFSM.getStates() ) + fsm.addState( state ); + + for( const auto & state : origFSM.getInitialStates() ) + fsm.addInitialState( state ); + + for( const auto & symbol : origFSM.getInputAlphabet() ) + fsm.addInputSymbol( symbol ); + + /** + * Step 1 from Melichar 2.41 + */ + for( const auto & from : origFSM.getStates( ) ) + for( const auto & fromClosure : automaton::EpsilonClosure::epsilonClosure( origFSM, from ) ) + for( const auto & transition : origFSM.getSymbolTransitionsFromState( fromClosure ) ) + for( const auto & to : transition.second ) + fsm.addTransition( from, transition.first.second, to ); + + /** + * Step 2 from Melichar 2.41 + */ + std::set<automaton::State> finalStates; + + for( const auto & q : fsm.getStates( ) ) + { + const std::set<automaton::State> & cl = automaton::EpsilonClosure::epsilonClosure( origFSM, q ); + const std::set<automaton::State> & F = origFSM.getFinalStates( ); + std::set<automaton::State> intersect; + + set_intersection( cl.begin(), cl.end(), F.begin(), F.end(), std::inserter( intersect, intersect.begin() ) ); + if( intersect.size( ) != 0 ) + finalStates.insert( q ); + } + + for( const auto & q : finalStates ) + fsm.addFinalState( q ); + + return fsm; +} + +automaton::Automaton FSMEpsilonRemover::remove(const automaton::Automaton& automaton) { + automaton::Automaton* out = NULL; + automaton.getData().Accept((void*) &out, FSMEpsilonRemover::FSM_EPSILON_REMOVER); + automaton::Automaton res = std::move(*out); + delete out; + return res; +} + +void FSMEpsilonRemover::Visit(void*, const automaton::UnknownAutomaton&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + +void FSMEpsilonRemover::Visit(void* data, const automaton::EpsilonNFA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->remove(automaton)); +} + +void FSMEpsilonRemover::Visit(void* data, const automaton::NFA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->remove(automaton)); +} + +void FSMEpsilonRemover::Visit(void* data, const automaton::DFA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->remove(automaton)); +} + +void FSMEpsilonRemover::Visit(void*, const automaton::ExtendedNFA& ) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + +void FSMEpsilonRemover::Visit(void*, const automaton::CompactNFA& ) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + +void FSMEpsilonRemover::Visit(void*, const automaton::NPDA&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + +void FSMEpsilonRemover::Visit(void*, const automaton::SinglePopNPDA&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + +void FSMEpsilonRemover::Visit(void*, const automaton::OneTapeDTM&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + +const FSMEpsilonRemover FSMEpsilonRemover::FSM_EPSILON_REMOVER; + +} /* namespace epsilon */ diff --git a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h new file mode 100644 index 0000000000000000000000000000000000000000..4b19f9b36cabb462e58728eb64ecdb02b031bbb1 --- /dev/null +++ b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h @@ -0,0 +1,50 @@ +/* + * FSMEpsilonRemover.h + * + * Created on: 16. 1. 2014 + * Author: Tomas Pecka + */ + +#ifndef FMS_EPSILON_REMOVER_H_ +#define FMS_EPSILON_REMOVER_H_ + +#include <map> +#include <algorithm> + +#include <automaton/Automaton.h> + +#include <automaton/FSM/EpsilonNFA.h> +#include <automaton/FSM/NFA.h> +#include <automaton/FSM/DFA.h> +#include <exception/AlibException.h> + +namespace epsilon { + +class FSMEpsilonRemover : public automaton::VisitableAutomatonBase::const_visitor_type { +public: + static automaton::Automaton remove( const automaton::Automaton & automaton ); + + /** + * Computes epsilon closure of a state in epsilon nonfree automaton + */ + static automaton::NFA remove( const automaton::EpsilonNFA & fsm ); + static automaton::NFA remove( const automaton::NFA & fsm ); + static automaton::DFA remove( const automaton::DFA & fsm ); + +private: + void Visit(void*, const automaton::UnknownAutomaton& automaton) const; + void Visit(void*, const automaton::EpsilonNFA& automaton) const; + void Visit(void*, const automaton::NFA& automaton) const; + void Visit(void*, const automaton::DFA& automaton) const; + void Visit(void*, const automaton::ExtendedNFA& automaton) const; + void Visit(void*, const automaton::CompactNFA& automaton) const; + void Visit(void*, const automaton::NPDA& automaton) const; + void Visit(void*, const automaton::SinglePopNPDA& automaton) const; + void Visit(void*, const automaton::OneTapeDTM& automaton) const; + + static const FSMEpsilonRemover FSM_EPSILON_REMOVER; +}; + +} /* namespace epsilon */ + +#endif /* FMS_EPSILON_REMOVER_H_ */ diff --git a/alib2algo/test-src/conversions/playTest.cpp b/alib2algo/test-src/conversions/playTest.cpp index 03a7af3387c5ee02b60d63767a15f99e83ba8932..ee74dc2a748395cc747988e15936c36b49b2267a 100644 --- a/alib2algo/test-src/conversions/playTest.cpp +++ b/alib2algo/test-src/conversions/playTest.cpp @@ -10,7 +10,7 @@ #include "generator/RandomAutomatonFactory.h" #include "normalize/dfa/NormalizeDFA.h" #include "trim/automaton/TrimFSM.h" -#include "epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h" +#include "epsilon/fsm/FSMEpsilonRemover.h" #include "minimize/dfa/MinimizeDFA.h" //#include "conversions/fa2re/StateElimination.h" @@ -57,7 +57,7 @@ automaton::NFA playTest::randomNFA(void) const automaton::DFA playTest::mDFA(const automaton::NFA& automaton) const { - automaton::NFA nfa = epsilon::EpsilonNFAEpsilonRemover::remove(automaton); + automaton::NFA nfa = epsilon::FSMEpsilonRemover::remove(automaton); nfa = trim::TrimFSM::trim(nfa); automaton::DFA dfa = determinize::NFADeterminizer::determinize(nfa); dfa = trim::TrimFSM::trim(dfa); diff --git a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp b/alib2algo/test-src/conversions/re2fa/re2faTest.cpp index 23f3376fe3c24dd5b9f74d1c04e0a1539fa52718..0d0d507550e7fb53051897ccf10760b69bc88d4b 100644 --- a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp +++ b/alib2algo/test-src/conversions/re2fa/re2faTest.cpp @@ -7,7 +7,7 @@ #include "conversions/fa2re/BrzozowskiAlgebraic.h" #include "determinize/nfa/NFADeterminizer.h" #include "minimize/dfa/MinimizeDFA.h" -#include "epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h" +#include "epsilon/fsm/FSMEpsilonRemover.h" #include "regexp/unbounded/UnboundedRegExp.h" #include "regexp/RegExpFromStringParser.h" @@ -37,8 +37,8 @@ void re2faTest::testThompson() { re2fa::Thompson thompson2; automaton::EpsilonNFA enfa2 = thompson2.convert(regexp2); - automaton::NFA nfa1 = epsilon::EpsilonNFAEpsilonRemover::remove(enfa1); - automaton::NFA nfa2 = epsilon::EpsilonNFAEpsilonRemover::remove(enfa2); + automaton::NFA nfa1 = epsilon::FSMEpsilonRemover::remove(enfa1); + automaton::NFA nfa2 = epsilon::FSMEpsilonRemover::remove(enfa2); automaton::DFA dfa1 = determinize::NFADeterminizer::determinize(nfa1); automaton::DFA dfa2 = determinize::NFADeterminizer::determinize(nfa2);