Skip to content
Snippets Groups Projects
Commit 8efa194a authored by Tomáš Pecka's avatar Tomáš Pecka
Browse files

algo: fa2re: Algebraic API

parent 5000b64f
No related branches found
No related tags found
No related merge requests found
...@@ -6,16 +6,28 @@ ...@@ -6,16 +6,28 @@
*/ */
   
#include "Algebraic.h" #include "Algebraic.h"
#include "alphabet/Symbol.h"
#include "automaton/FSM/DFA.h" #include <alphabet/Symbol.h>
#include "automaton/FSM/NFA.h" #include <automaton/FSM/DFA.h>
#include "automaton/FSM/EpsilonNFA.h" #include <automaton/FSM/NFA.h>
#include <automaton/FSM/EpsilonNFA.h>
#include <exception/AlibException.h>
#include "../../equations/RightRegularEquationSolver.h"
   
namespace conversions namespace conversions
{ {
   
namespace fa2re { namespace fa2re {
   
regexp::RegExp Algebraic::convert(const automaton::Automaton& automaton) {
regexp::RegExp* out = NULL;
automaton.getData().Accept((void*) &out, Algebraic::ALGEBRAIC);
regexp::RegExp res = std::move(*out);
delete out;
return res;
}
template<> template<>
regexp::UnboundedRegExp Algebraic::convert( const automaton::EpsilonNFA & automaton ) { regexp::UnboundedRegExp Algebraic::convert( const automaton::EpsilonNFA & automaton ) {
equations::RightRegularEquationSolver solver; equations::RightRegularEquationSolver solver;
...@@ -25,7 +37,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::EpsilonNFA & automa ...@@ -25,7 +37,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::EpsilonNFA & automa
solver.addSymbol( alphabet::Symbol( alphabet::LabeledSymbol( q.getName( ) ) ) ); solver.addSymbol( alphabet::Symbol( alphabet::LabeledSymbol( q.getName( ) ) ) );
   
for( const auto & q : automaton.getStates( ) ) { for( const auto & q : automaton.getStates( ) ) {
if( isInSet( q, automaton.getFinalStates( ) ) ) if( automaton.getFinalStates( ).count( q ) > 0 )
solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q.getName( ) ) ), regexp::UnboundedRegExpEpsilon { } ); solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q.getName( ) ) ), regexp::UnboundedRegExpEpsilon { } );
} }
   
...@@ -61,7 +73,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::NFA & automaton ) { ...@@ -61,7 +73,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::NFA & automaton ) {
solver.addSymbol( alphabet::Symbol( alphabet::LabeledSymbol( q.getName( ) ) ) ); solver.addSymbol( alphabet::Symbol( alphabet::LabeledSymbol( q.getName( ) ) ) );
   
for( const auto & q : automaton.getStates( ) ) { for( const auto & q : automaton.getStates( ) ) {
if( isInSet( q, automaton.getFinalStates( ) ) ) if( automaton.getFinalStates( ).count( q ) > 0 )
solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q.getName( ) ) ), regexp::UnboundedRegExpEpsilon { } ); solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q.getName( ) ) ), regexp::UnboundedRegExpEpsilon { } );
} }
   
...@@ -91,7 +103,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::DFA & automaton ) { ...@@ -91,7 +103,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::DFA & automaton ) {
solver.addSymbol( alphabet::Symbol( alphabet::LabeledSymbol( q.getName( ) ) ) ); solver.addSymbol( alphabet::Symbol( alphabet::LabeledSymbol( q.getName( ) ) ) );
   
for( const auto & q : automaton.getStates( ) ) { for( const auto & q : automaton.getStates( ) ) {
if( isInSet( q, automaton.getFinalStates( ) ) ) if( automaton.getFinalStates( ).count( q ) > 0 )
solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q.getName( ) ) ), regexp::UnboundedRegExpEpsilon { } ); solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q.getName( ) ) ), regexp::UnboundedRegExpEpsilon { } );
} }
   
...@@ -102,6 +114,64 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::DFA & automaton ) { ...@@ -102,6 +114,64 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::DFA & automaton ) {
return solver.solve( alphabet::Symbol( alphabet::LabeledSymbol (automaton.getInitialState().getName() ) ) ); return solver.solve( alphabet::Symbol( alphabet::LabeledSymbol (automaton.getInitialState().getName() ) ) );
} }
   
void Algebraic::Visit(void*, const automaton::UnknownAutomaton&) const {
throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
}
void Algebraic::Visit(void* data, const automaton::EpsilonNFA& automaton) const {
regexp::RegExp* & out = *((regexp::RegExp**) data);
out = new regexp::RegExp(this->convert(automaton));
}
void Algebraic::Visit(void* data, const automaton::NFA& automaton) const {
regexp::RegExp* & out = *((regexp::RegExp**) data);
out = new regexp::RegExp(this->convert(automaton));
}
void Algebraic::Visit(void* data, const automaton::DFA& automaton) const {
regexp::RegExp* & out = *((regexp::RegExp**) data);
out = new regexp::RegExp(this->convert(automaton));
}
void Algebraic::Visit(void*, const automaton::ExtendedNFA& ) const {
throw exception::AlibException("Unsupported automaton type ExtendedNFA");
}
void Algebraic::Visit(void*, const automaton::CompactNFA& ) const {
throw exception::AlibException("Unsupported automaton type CompactNFA");
}
void Algebraic::Visit(void*, const automaton::DPDA&) const {
throw exception::AlibException("Unsupported automaton type DPDA");
}
void Algebraic::Visit(void*, const automaton::SinglePopDPDA&) const {
throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
}
void Algebraic::Visit(void*, const automaton::InputDrivenNPDA&) const {
throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
}
void Algebraic::Visit(void*, const automaton::VisiblyPushdownNPDA&) const {
throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
}
void Algebraic::Visit(void*, const automaton::NPDA&) const {
throw exception::AlibException("Unsupported automaton type NPDA");
}
void Algebraic::Visit(void*, const automaton::SinglePopNPDA&) const {
throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
}
void Algebraic::Visit(void*, const automaton::OneTapeDTM&) const {
throw exception::AlibException("Unsupported automaton type OneTapeDTM");
}
const Algebraic Algebraic::ALGEBRAIC;
} /* namespace fa2re */ } /* namespace fa2re */
   
} /* namespace conversions */ } /* namespace conversions */
...@@ -12,10 +12,9 @@ ...@@ -12,10 +12,9 @@
#include <map> #include <map>
#include <queue> #include <queue>
   
#include <regexp/RegExp.h>
#include <regexp/unbounded/UnboundedRegExpElements.h> #include <regexp/unbounded/UnboundedRegExpElements.h>
#include <automaton/Automaton.h>
#include "common/macros.h"
#include "../../equations/RightRegularEquationSolver.h"
   
namespace conversions namespace conversions
{ {
...@@ -30,15 +29,34 @@ namespace fa2re ...@@ -30,15 +29,34 @@ namespace fa2re
* Converts FA to RE using Brzozowski's algebraic method using right regular equations. * Converts FA to RE using Brzozowski's algebraic method using right regular equations.
* Source : Melichar 2.122 * Source : Melichar 2.122
*/ */
class Algebraic class Algebraic : public automaton::VisitableAutomatonBase::const_visitor_type
{ {
public: public:
/** /**
* Performs conversion. * Performs conversion.
* @return regular expression equivalent to input automaton. * @return regular expression equivalent to input automaton.
*/ */
static regexp::RegExp convert(const automaton::Automaton& automaton);
template <class T> template <class T>
static regexp::UnboundedRegExp convert( const T & automaton ); static regexp::UnboundedRegExp convert(const T& automaton);
private:
void Visit(void*, const automaton::UnknownAutomaton&) const;
void Visit(void*, const automaton::EpsilonNFA&) const;
void Visit(void*, const automaton::NFA&) const;
void Visit(void*, const automaton::DFA&) const;
void Visit(void*, const automaton::ExtendedNFA&) const;
void Visit(void*, const automaton::CompactNFA&) const;
void Visit(void*, const automaton::InputDrivenNPDA&) const;
void Visit(void*, const automaton::VisiblyPushdownNPDA&) const;
void Visit(void*, const automaton::NPDA&) const;
void Visit(void*, const automaton::SinglePopNPDA&) const;
void Visit(void*, const automaton::DPDA&) const;
void Visit(void*, const automaton::SinglePopDPDA&) const;
void Visit(void*, const automaton::OneTapeDTM&) const;
static const Algebraic ALGEBRAIC;
}; };
   
} /* namespace fa2re */ } /* namespace fa2re */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment