diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp index 943586ed62cafd8d9993300c5fe16462f24812f5..18673ede362941b3eee0173b2843b82107d29c3f 100644 --- a/aconversions2/src/ConversionHandler.cpp +++ b/aconversions2/src/ConversionHandler.cpp @@ -338,9 +338,8 @@ void ConversionHandler::convertLRGtoRRG( void ) switch( m_algorithm ) { default: - rg2rg::LeftToRightRegularGrammar conv( lrg ); - grammar::RightRG rrg = conv.convert(); - alib::DataFactory::toStdout(rrg); + rg2rg::LeftToRightRegularGrammar conv; + alib::DataFactory::toStdout(conv.convert(lrg)); break; } } @@ -352,9 +351,8 @@ void ConversionHandler::convertRRGtoLRG( void ) switch( m_algorithm ) { default: - rg2rg::RightToLeftRegularGrammar conv( rrg ); - grammar::LeftRG lrg = conv.convert(); - alib::DataFactory::toStdout(lrg); + rg2rg::RightToLeftRegularGrammar conv; + alib::DataFactory::toStdout(conv.convert(rrg)); break; } } diff --git a/alib2algo/src/conversions/rg2rg/lrg2rrg/LeftToRightRegularGrammar.cpp b/alib2algo/src/conversions/rg2rg/lrg2rrg/LeftToRightRegularGrammar.cpp index e6c8b8ff74df5b12dd77a73d390e75b9fe2bfcb4..c9b1a00677a959458bd6ebfde85e2c6a677a7c79 100644 --- a/alib2algo/src/conversions/rg2rg/lrg2rrg/LeftToRightRegularGrammar.cpp +++ b/alib2algo/src/conversions/rg2rg/lrg2rrg/LeftToRightRegularGrammar.cpp @@ -9,31 +9,22 @@ namespace rg2rg { -LeftToRightRegularGrammar::LeftToRightRegularGrammar( const grammar::LeftRG & lrg ) : m_lrg( lrg ) { - -} - -LeftToRightRegularGrammar::~LeftToRightRegularGrammar( void ) -{ - -} - -grammar::RightRG LeftToRightRegularGrammar::convert( void ) +grammar::RightRG LeftToRightRegularGrammar::convert(const grammar::LeftRG& lrg) { // 1. - alphabet::Symbol s = alphabet::createUniqueSymbol( m_lrg.getInitialSymbol( ), m_lrg.getNonterminalAlphabet(), m_lrg.getTerminalAlphabet() ); + alphabet::Symbol s = alphabet::createUniqueSymbol( lrg.getInitialSymbol( ), lrg.getNonterminalAlphabet(), lrg.getTerminalAlphabet() ); grammar::RightRG rrg( s ); - for(const auto & nonterminalSymbol : m_lrg.getNonterminalAlphabet() ) { + for(const auto & nonterminalSymbol : lrg.getNonterminalAlphabet() ) { rrg.addNonterminalSymbol( nonterminalSymbol ); } - rrg.setTerminalAlphabet( m_lrg.getTerminalAlphabet( ) ); - rrg.setGeneratesEpsilon( m_lrg.getGeneratesEpsilon( ) ); + rrg.setTerminalAlphabet( lrg.getTerminalAlphabet( ) ); + rrg.setGeneratesEpsilon( lrg.getGeneratesEpsilon( ) ); // 2 - for( const auto & rule : m_lrg.getRules( ) ) { + for( const auto & rule : lrg.getRules( ) ) { const alphabet::Symbol& lhs = rule.first; for(const auto & ruleRHS : rule.second ) { @@ -44,7 +35,7 @@ grammar::RightRG LeftToRightRegularGrammar::convert( void ) std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair( rhs.second, lhs ); rrg.addRule( leftSide, rightSide ); - if( lhs == m_lrg.getInitialSymbol( ) ) { + if( lhs == lrg.getInitialSymbol( ) ) { alphabet::Symbol leftSide = rhs.first; alphabet::Symbol rightSide = rhs.second; rrg.addRule( leftSide, rightSide ); @@ -56,7 +47,7 @@ grammar::RightRG LeftToRightRegularGrammar::convert( void ) std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair( rhs, lhs ); rrg.addRule( leftSide, rightSide ); - if( lhs == m_lrg.getInitialSymbol( ) ) { + if( lhs == lrg.getInitialSymbol( ) ) { alphabet::Symbol leftSide = rrg.getInitialSymbol( ); alphabet::Symbol rightSide = rhs; rrg.addRule( leftSide, rightSide ); diff --git a/alib2algo/src/conversions/rg2rg/lrg2rrg/LeftToRightRegularGrammar.h b/alib2algo/src/conversions/rg2rg/lrg2rrg/LeftToRightRegularGrammar.h index e0089201702c70a012e6faab27f0f5d0938737fb..f01665d3b330b32ffc2d551da90d4fc4e3ad8937 100644 --- a/alib2algo/src/conversions/rg2rg/lrg2rrg/LeftToRightRegularGrammar.h +++ b/alib2algo/src/conversions/rg2rg/lrg2rrg/LeftToRightRegularGrammar.h @@ -17,24 +17,11 @@ namespace rg2rg class LeftToRightRegularGrammar { public: - /** - * @param lrg Original left regular grammar. - */ - LeftToRightRegularGrammar( const grammar::LeftRG & lrg ); - - ~LeftToRightRegularGrammar( void ); - - /** + /** * Performs conversion. * @return right regular grammar which is equivalent to source left regular grammar. */ - grammar::RightRG convert( void ); - -protected: - /** - * input grammar - */ - const grammar::LeftRG & m_lrg; + grammar::RightRG convert(const grammar::LeftRG& lrg); }; } /* namespace rg2rg */ diff --git a/alib2algo/src/conversions/rg2rg/rrg2lrg/RightToLeftRegularGrammar.cpp b/alib2algo/src/conversions/rg2rg/rrg2lrg/RightToLeftRegularGrammar.cpp index 420b9365a8a83070e8a7b7fcca9810f922432ff5..f51ab73248d30e1d3ba9ed3dc815cc27a8bb7f7f 100644 --- a/alib2algo/src/conversions/rg2rg/rrg2lrg/RightToLeftRegularGrammar.cpp +++ b/alib2algo/src/conversions/rg2rg/rrg2lrg/RightToLeftRegularGrammar.cpp @@ -10,32 +10,22 @@ namespace rg2rg { -RightToLeftRegularGrammar::RightToLeftRegularGrammar( const grammar::RightRG & rrg ) : m_rrg( rrg ) -{ - -} - -RightToLeftRegularGrammar::~RightToLeftRegularGrammar( void ) -{ - -} - -grammar::LeftRG RightToLeftRegularGrammar::convert( void ) +grammar::LeftRG RightToLeftRegularGrammar::convert(const grammar::RightRG& rrg) { // 1. - alphabet::Symbol s = alphabet::createUniqueSymbol( m_rrg.getInitialSymbol( ), m_rrg.getNonterminalAlphabet(), m_rrg.getTerminalAlphabet() ); + alphabet::Symbol s = alphabet::createUniqueSymbol( rrg.getInitialSymbol( ), rrg.getNonterminalAlphabet(), rrg.getTerminalAlphabet() ); grammar::LeftRG lrg(s); - for(const auto & nonterminalSymbol : m_rrg.getNonterminalAlphabet()) { + for(const auto & nonterminalSymbol : rrg.getNonterminalAlphabet()) { lrg.addNonterminalSymbol( nonterminalSymbol ); } - lrg.setTerminalAlphabet( m_rrg.getTerminalAlphabet( ) ); - lrg.setGeneratesEpsilon( m_rrg.getGeneratesEpsilon( ) ); + lrg.setTerminalAlphabet( rrg.getTerminalAlphabet( ) ); + lrg.setGeneratesEpsilon( rrg.getGeneratesEpsilon( ) ); // 2. - for( const auto & rule : m_rrg.getRules( ) ) { + for( const auto & rule : rrg.getRules( ) ) { const alphabet::Symbol& lhs = rule.first; for(const auto & ruleRHS : rule.second ) { @@ -46,7 +36,7 @@ grammar::LeftRG RightToLeftRegularGrammar::convert( void ) std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair( lhs, rhs.first ); lrg.addRule( leftSide, rightSide ); - if( lhs == m_rrg.getInitialSymbol( ) ) { + if( lhs == rrg.getInitialSymbol( ) ) { alphabet::Symbol leftSide = rhs.second; alphabet::Symbol rightSide = rhs.first; lrg.addRule( leftSide, rightSide ); @@ -58,7 +48,7 @@ grammar::LeftRG RightToLeftRegularGrammar::convert( void ) std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair ( lhs, rhs ); lrg.addRule( leftSide, rightSide ); - if( lhs == m_rrg.getInitialSymbol( ) ) { + if( lhs == rrg.getInitialSymbol( ) ) { alphabet::Symbol leftSide = lrg.getInitialSymbol( ); alphabet::Symbol rightSide = rhs; lrg.addRule( leftSide, rightSide ); diff --git a/alib2algo/src/conversions/rg2rg/rrg2lrg/RightToLeftRegularGrammar.h b/alib2algo/src/conversions/rg2rg/rrg2lrg/RightToLeftRegularGrammar.h index 73dcdc3968ce2fa2806fa3410c013275d605326a..8b7e3dc7207a4551b36fce2d48683e310d4bc48a 100644 --- a/alib2algo/src/conversions/rg2rg/rrg2lrg/RightToLeftRegularGrammar.h +++ b/alib2algo/src/conversions/rg2rg/rrg2lrg/RightToLeftRegularGrammar.h @@ -20,24 +20,11 @@ namespace rg2rg class RightToLeftRegularGrammar { public: - /** - * @param rrg Original right regular grammar. - */ - RightToLeftRegularGrammar( const grammar::RightRG & rrg ); - - ~RightToLeftRegularGrammar( void ); - /** * Performs conversion. * @return left regular grammar which is equivalent to source right regular grammar. */ - grammar::LeftRG convert( void ); - -private: - /** - * - */ - const grammar::RightRG & m_rrg; + grammar::LeftRG convert(const grammar::RightRG& rrg); }; } /* namespace rg2rg */ diff --git a/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.cpp b/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.cpp index 8a9d97c1808876203666fdbd45ddae65ef19a4d2..584bd8809981fe686fb89a3313e3db1a1b64a92b 100644 --- a/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.cpp +++ b/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.cpp @@ -11,6 +11,11 @@ namespace epsilon { +automaton::NFA EpsilonNFAEpsilonRemover::remove(const automaton::NFA& origFSM) +{ + return origFSM; +} + automaton::NFA EpsilonNFAEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM ) { automaton::NFA fsm; diff --git a/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h b/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h index d02438e7d8fa42e5be0137281f643bafab0597d5..c65beebcc4197cbe78ed70ed3e2316aefdb7420d 100644 --- a/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h +++ b/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h @@ -19,7 +19,8 @@ namespace epsilon { class EpsilonNFAEpsilonRemover { public: - static automaton::NFA remove( const automaton::EpsilonNFA & ); + static automaton::NFA remove(const automaton::EpsilonNFA &); + static automaton::NFA remove(const automaton::NFA &); }; } /* namespace epsilon */ diff --git a/alib2algo/test-src/conversions/playTest.cpp b/alib2algo/test-src/conversions/playTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..03a7af3387c5ee02b60d63767a15f99e83ba8932 --- /dev/null +++ b/alib2algo/test-src/conversions/playTest.cpp @@ -0,0 +1,105 @@ +#include "playTest.h" + +#include <iostream> +#include <cstdlib> +#include <ctime> + +#include "determinize/nfa/NFADeterminizer.h" +#include "minimize/dfa/MinimizeDFA.h" + +#include "generator/RandomAutomatonFactory.h" +#include "normalize/dfa/NormalizeDFA.h" +#include "trim/automaton/TrimFSM.h" +#include "epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h" +#include "minimize/dfa/MinimizeDFA.h" + +//#include "conversions/fa2re/StateElimination.h" +//#include "conversions/fa2re/BrzozowskiAlgebraic.h" +//#include "conversions/re2fa/Glushkov.h" +//#include "conversions/re2fa/Thompson.h" +//#include "conversions/re2fa/Brzozowski.h" +#include "conversions/fa2rg/fa2lrg/FAtoLRGConverter.h" +#include "conversions/fa2rg/fa2rrg/FAtoRRGConverter.h" +#include "conversions/rg2fa/lrg2fa/LRGtoFAConverter.h" +#include "conversions/rg2fa/rrg2fa/RRGtoFAConverter.h" +//#include "conversions/rg2re/rrg2re/RRGAlgebraic.h" +//#include "conversions/rg2re/lrg2re/LRGAlgebraic.h" +//#include "conversions/re2rg/re2rrg/GlushkovRRG.h" +//#include "conversions/re2rg/re2rrg/BrzozowskiDerivationRRG.h" +#include "conversions/rg2rg/lrg2rrg/LeftToRightRegularGrammar.h" +#include "conversions/rg2rg/rrg2lrg/RightToLeftRegularGrammar.h" + + +#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) + +#define TEST_ITERATIONS 100 +#define TEST_AUTOMATON_STATES_MAX 18 +#define TEST_AUTOMATON_DENSITY_MAX 2.5 +#define TEST_AUTOMATON_ALPHABET_MAX 4 + +CPPUNIT_TEST_SUITE_REGISTRATION( playTest ); + +void playTest::setUp() +{ + srand(time(NULL)); +} + +void playTest::tearDown(){} + +automaton::NFA playTest::randomNFA(void) const +{ + return generator::RandomAutomatonFactory::generateNFA( + rand() % TEST_AUTOMATON_STATES_MAX + 1, + rand() % TEST_AUTOMATON_ALPHABET_MAX + 1, + static_cast<double> (rand()) / (static_cast<double> (RAND_MAX/TEST_AUTOMATON_DENSITY_MAX)) + ); +} + +automaton::DFA playTest::mDFA(const automaton::NFA& automaton) const +{ + automaton::NFA nfa = epsilon::EpsilonNFAEpsilonRemover::remove(automaton); + nfa = trim::TrimFSM::trim(nfa); + automaton::DFA dfa = determinize::NFADeterminizer::determinize(nfa); + dfa = trim::TrimFSM::trim(dfa); + dfa = minimize::MinimizeDFA::minimize(dfa); + dfa = normalize::NormalizeDFA::normalize(dfa); + return dfa; +} + +/** + * Test case 1: + * - covers: FA -> LRG, FA -> RRG, RRG <-> LRG, RRG -> FA, LRG -> FA + * a. FA -> RRG -> LRG -> FA + * b. FA -> LRG -> RRG -> FA + */ +void playTest::testPlay1() +{ + for(int i = 0; i < TEST_ITERATIONS; i++) + this->case1a(); + for(int i = 0; i < TEST_ITERATIONS; i++) + this->case1b(); +} + +void playTest::case1a(void) const +{ + fa2rg::FAtoRRGConverter fa2rrg; + rg2rg::RightToLeftRegularGrammar rrg2lrg; + rg2fa::LRGtoFAConverter lrg2fa; + + automaton::NFA a1 = this->randomNFA(); + automaton::NFA a2 = lrg2fa.convert(rrg2lrg.convert(fa2rrg.convert(a1))); + + CPPUNIT_ASSERT(this->mDFA(a1) == this->mDFA(a2)); +} + +void playTest::case1b(void) const +{ + fa2rg::FAtoLRGConverter fa2lrg; + rg2rg::LeftToRightRegularGrammar lrg2rrg; + rg2fa::RRGtoFAConverter rrg2fa; + + automaton::NFA a1 = this->randomNFA(); + automaton::NFA a2 = rrg2fa.convert(lrg2rrg.convert(fa2lrg.convert(a1))); + + CPPUNIT_ASSERT(this->mDFA(a1) == this->mDFA(a2)); +} diff --git a/alib2algo/test-src/conversions/playTest.h b/alib2algo/test-src/conversions/playTest.h new file mode 100644 index 0000000000000000000000000000000000000000..45d8cdc9c1ff1f16b0c0ebab5ddae0eacfb95fb8 --- /dev/null +++ b/alib2algo/test-src/conversions/playTest.h @@ -0,0 +1,29 @@ +#ifndef PLAY_TEST_H_ +#define PLAY_TEST_H_ + +#include <cppunit/extensions/HelperMacros.h> + +#include <automaton/FSM/NFA.h> +#include <automaton/FSM/DFA.h> + +class playTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( playTest ); + CPPUNIT_TEST( testPlay1 ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testPlay1(); + +private: + automaton::NFA randomNFA(void) const; + automaton::DFA mDFA(const automaton::NFA& automaton) const; + + void case1a(void) const; + void case1b(void) const; +}; + +#endif // PLAY_TEST_H_ diff --git a/alib2algo/test-src/conversions/rg2rg/rg2rgTest.cpp b/alib2algo/test-src/conversions/rg2rg/rg2rgTest.cpp index aa812511ff4ea3be6e805baa0e5db0e96dedf7e8..24b8c9772e4cfe126a526fc59329c41d9951ef4d 100644 --- a/alib2algo/test-src/conversions/rg2rg/rg2rgTest.cpp +++ b/alib2algo/test-src/conversions/rg2rg/rg2rgTest.cpp @@ -32,8 +32,8 @@ void rg2rgTest::testConversion() { rrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))))); rrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a"))))); - rg2rg::RightToLeftRegularGrammar convertor(rrGrammar); - grammar::LeftRG lrGrammar = convertor.convert(); + rg2rg::RightToLeftRegularGrammar convertor;; + grammar::LeftRG lrGrammar = convertor.convert(rrGrammar); grammar::LeftRG lrGrammarRef(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(4))))); @@ -64,8 +64,8 @@ void rg2rgTest::testConversion2() { lrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2)))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))))); lrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(4)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))))); - rg2rg::LeftToRightRegularGrammar convertor(lrGrammar); - grammar::RightRG rrGrammar = convertor.convert(); + rg2rg::LeftToRightRegularGrammar convertor; + grammar::RightRG rrGrammar = convertor.convert(lrGrammar); grammar::RightRG rrGrammarRef(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(5))))); diff --git a/alib2algo/test-src/play/playTest.cpp b/alib2algo/test-src/play/playTest.cpp deleted file mode 100644 index 93439d189623107b1f57a55a87b6d07c7bf33c19..0000000000000000000000000000000000000000 --- a/alib2algo/test-src/play/playTest.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include <list> -#include "playTest.h" - -#include "conversions/re2fa/Glushkov.h" -#include "conversions/fa2re/BrzozowskiAlgebraic.h" -#include "determinize/nfa/NFADeterminizer.h" -#include "minimize/dfa/MinimizeDFA.h" - -#include "regexp/unbounded/UnboundedRegExp.h" -#include "regexp/RegExpFromStringParser.h" - -#include "automaton/FSM/NFA.h" - -#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) - -CPPUNIT_TEST_SUITE_REGISTRATION( playTest ); - -void playTest::setUp() { -} - -void playTest::tearDown() { -} - -void playTest::testPlay() { - { - std::string input = "a+a* b*"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::UnboundedRegExp regexp1( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); - - re2fa::Glushkov glushkov1; - automaton::NFA nfa1 = glushkov1.convert(regexp1); - - - regexp::UnboundedRegExp regexp2( static_cast<const regexp::UnboundedRegExp &>( fa2re::BrzozowskiAlgebraic::convert(nfa1) ) ); - - re2fa::Glushkov glushkov2; - automaton::NFA nfa2 = glushkov2.convert(regexp2); - - automaton::DFA dfa1 = determinize::NFADeterminizer::determinize(nfa1); - automaton::DFA dfa2 = determinize::NFADeterminizer::determinize(nfa2); - - automaton::DFA mdfa1 = minimize::MinimizeDFA::minimize(dfa1); - automaton::DFA mdfa2 = minimize::MinimizeDFA::minimize(dfa2); - - CPPUNIT_ASSERT( mdfa1 == mdfa2); - } -} diff --git a/alib2algo/test-src/play/playTest.h b/alib2algo/test-src/play/playTest.h deleted file mode 100644 index b7bc794188284710d3d9d6b4f4f40486a44460da..0000000000000000000000000000000000000000 --- a/alib2algo/test-src/play/playTest.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef PLAY_TEST_H_ -#define PLAY_TEST_H_ - -#include <cppunit/extensions/HelperMacros.h> - -class playTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( playTest ); - CPPUNIT_TEST( testPlay ); - CPPUNIT_TEST_SUITE_END(); - -public: - void setUp(); - void tearDown(); - - void testPlay(); -}; - -#endif // PLAY_TEST_H_