From 8efa194ae8d573d9ed9e16febb54e0c3e4763815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <peckato1@fit.cvut.cz> Date: Mon, 22 Sep 2014 13:22:40 +0200 Subject: [PATCH] algo: fa2re: Algebraic API --- alib2algo/src/conversions/fa2re/Algebraic.cpp | 84 +++++++++++++++++-- alib2algo/src/conversions/fa2re/Algebraic.h | 28 +++++-- 2 files changed, 100 insertions(+), 12 deletions(-) diff --git a/alib2algo/src/conversions/fa2re/Algebraic.cpp b/alib2algo/src/conversions/fa2re/Algebraic.cpp index 16f1492fb3..44d14dc7c6 100644 --- a/alib2algo/src/conversions/fa2re/Algebraic.cpp +++ b/alib2algo/src/conversions/fa2re/Algebraic.cpp @@ -6,16 +6,28 @@ */ #include "Algebraic.h" -#include "alphabet/Symbol.h" -#include "automaton/FSM/DFA.h" -#include "automaton/FSM/NFA.h" -#include "automaton/FSM/EpsilonNFA.h" + +#include <alphabet/Symbol.h> +#include <automaton/FSM/DFA.h> +#include <automaton/FSM/NFA.h> +#include <automaton/FSM/EpsilonNFA.h> +#include <exception/AlibException.h> + +#include "../../equations/RightRegularEquationSolver.h" namespace conversions { 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<> regexp::UnboundedRegExp Algebraic::convert( const automaton::EpsilonNFA & automaton ) { equations::RightRegularEquationSolver solver; @@ -25,7 +37,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::EpsilonNFA & automa solver.addSymbol( alphabet::Symbol( alphabet::LabeledSymbol( q.getName( ) ) ) ); 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 { } ); } @@ -61,7 +73,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::NFA & automaton ) { solver.addSymbol( alphabet::Symbol( alphabet::LabeledSymbol( q.getName( ) ) ) ); 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 { } ); } @@ -91,7 +103,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::DFA & automaton ) { solver.addSymbol( alphabet::Symbol( alphabet::LabeledSymbol( q.getName( ) ) ) ); 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 { } ); } @@ -102,6 +114,64 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::DFA & automaton ) { 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 conversions */ diff --git a/alib2algo/src/conversions/fa2re/Algebraic.h b/alib2algo/src/conversions/fa2re/Algebraic.h index 55dbaca7de..a6fbc2471e 100644 --- a/alib2algo/src/conversions/fa2re/Algebraic.h +++ b/alib2algo/src/conversions/fa2re/Algebraic.h @@ -12,10 +12,9 @@ #include <map> #include <queue> +#include <regexp/RegExp.h> #include <regexp/unbounded/UnboundedRegExpElements.h> - -#include "common/macros.h" -#include "../../equations/RightRegularEquationSolver.h" +#include <automaton/Automaton.h> namespace conversions { @@ -30,15 +29,34 @@ namespace fa2re * Converts FA to RE using Brzozowski's algebraic method using right regular equations. * Source : Melichar 2.122 */ -class Algebraic +class Algebraic : public automaton::VisitableAutomatonBase::const_visitor_type { public: /** * Performs conversion. * @return regular expression equivalent to input automaton. */ + static regexp::RegExp convert(const automaton::Automaton& automaton); + 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 */ -- GitLab