From 14dfa8524519c54c945b0c1aa29810c49160e0b8 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Tue, 11 Sep 2018 22:04:39 +0200 Subject: [PATCH] partial template to CNF algorithm --- alib2algo/src/grammar/simplify/ToCNF.cpp | 13 ---- alib2algo/src/grammar/simplify/ToCNF.h | 82 +++++++++++++++++++++++- 2 files changed, 79 insertions(+), 16 deletions(-) diff --git a/alib2algo/src/grammar/simplify/ToCNF.cpp b/alib2algo/src/grammar/simplify/ToCNF.cpp index 3b5fc083ac..4c658b89f0 100644 --- a/alib2algo/src/grammar/simplify/ToCNF.cpp +++ b/alib2algo/src/grammar/simplify/ToCNF.cpp @@ -11,7 +11,6 @@ #include "SimpleRulesRemover.h" #include <common/DefaultSymbolsPairType.h> #include <exception/CommonException.h> -#include <common/createUnique.hpp> #include <registration/AlgoRegistration.hpp> #include <grammar/RawRules.h> @@ -128,10 +127,6 @@ grammar::CNF < > ToCNF::convert(const grammar::EpsilonFreeCFG < > & origGrammar) return convertInternal(grammar::simplify::SimpleRulesRemover::remove(origGrammar)); } -grammar::CNF < > ToCNF::convert(const grammar::CNF < > & origGrammar) { - return origGrammar; -} - grammar::CNF < > ToCNF::convert(const grammar::GNF < > & origGrammar) { return convertInternal(origGrammar); } @@ -144,18 +139,10 @@ grammar::CNF < > ToCNF::convert(const grammar::LeftLG< > & origGrammar) { return convertInternal(grammar::simplify::SimpleRulesRemover::remove(grammar::simplify::EpsilonRemover::remove(origGrammar))); } -grammar::CNF < > ToCNF::convert(const grammar::LeftRG < > & origGrammar) { - return convertInternal(origGrammar); -} - grammar::CNF < > ToCNF::convert(const grammar::RightLG < > & origGrammar) { return convertInternal(grammar::simplify::SimpleRulesRemover::remove(grammar::simplify::EpsilonRemover::remove(origGrammar))); } -grammar::CNF < > ToCNF::convert(const grammar::RightRG < > & origGrammar) { - return convertInternal(origGrammar); -} - auto ToCNFCFG = registration::AbstractRegister < ToCNF, grammar::CNF < >, const grammar::CFG < > & > ( ToCNF::convert ); auto ToCNFEpsilonFreeCFG = registration::AbstractRegister < ToCNF, grammar::CNF < >, const grammar::EpsilonFreeCFG < > & > ( ToCNF::convert ); auto ToCNFCNF = registration::AbstractRegister < ToCNF, grammar::CNF < >, const grammar::CNF < > & > ( ToCNF::convert ); diff --git a/alib2algo/src/grammar/simplify/ToCNF.h b/alib2algo/src/grammar/simplify/ToCNF.h index d1d96976f3..88165da160 100644 --- a/alib2algo/src/grammar/simplify/ToCNF.h +++ b/alib2algo/src/grammar/simplify/ToCNF.h @@ -18,6 +18,8 @@ #include <grammar/Regular/RightLG.h> #include <grammar/Regular/RightRG.h> +#include <common/createUnique.hpp> + namespace grammar { namespace simplify { @@ -25,16 +27,90 @@ namespace simplify { class ToCNF { public: static grammar::CNF < > convert( const grammar::CFG < > & grammar ); + static grammar::CNF < > convert( const grammar::EpsilonFreeCFG < > & grammar ); + static grammar::CNF < > convert( const grammar::GNF < > & grammar ); - static grammar::CNF < > convert( const grammar::CNF < > & grammar ); + + template < class SymbolType > + static grammar::CNF < SymbolType > convert( const grammar::CNF < SymbolType > & grammar ); + static grammar::CNF < > convert( const grammar::LG < > & grammar ); + static grammar::CNF < > convert( const grammar::LeftLG < > & grammar ); - static grammar::CNF < > convert( const grammar::LeftRG < > & grammar ); + + template < class SymbolType > + static grammar::CNF < SymbolType > convert( const grammar::LeftRG < SymbolType > & grammar ); + static grammar::CNF < > convert( const grammar::RightLG < > & grammar ); - static grammar::CNF < > convert( const grammar::RightRG < > & grammar ); + + template < class SymbolType > + static grammar::CNF < SymbolType > convert( const grammar::RightRG < SymbolType > & grammar ); }; +template < class SymbolType > +grammar::CNF < SymbolType > ToCNF::convert(const grammar::CNF < SymbolType > & origGrammar) { + return origGrammar; +} + +template < class SymbolType > +grammar::CNF < SymbolType > ToCNF::convert ( const grammar::LeftRG < SymbolType > & origGrammar ) { + grammar::CNF < SymbolType > result ( origGrammar.getInitialSymbol ( ) ); + + result.setNonterminalAlphabet ( origGrammar.getNonterminalAlphabet ( ) ); + result.setTerminalAlphabet ( origGrammar.getTerminalAlphabet ( ) ); + + ext::map < SymbolType, SymbolType > terminalToShadowNonterminal; + for ( const SymbolType & symbol : origGrammar.getTerminalAlphabet ( ) ) { + SymbolType shadowSymbol = common::createUnique ( symbol, result.getTerminalAlphabet ( ), result.getNonterminalAlphabet ( ) ); + terminalToShadowNonterminal.insert ( std::make_pair ( symbol, shadowSymbol ) ); + result.addNonterminalSymbol ( shadowSymbol ); + result.addRule ( std::move ( shadowSymbol ), symbol ); + } + + for ( const std::pair < SymbolType, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > > & rules : origGrammar.getRules ( ) ) { + for ( const ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > & rhs : rules.second ) { + if ( rhs.template is < SymbolType > ( ) ) { + result.addRule ( rules.first, rhs ); + } else { + const ext::pair < SymbolType, SymbolType > & rhsPair = rhs.template get < ext::pair < SymbolType, SymbolType > > ( ); + result.addRule ( rules.first, ext::make_pair ( rhsPair.first, terminalToShadowNonterminal.at ( rhsPair.second ) ) ); + } + } + } + + return result; +} + +template < class SymbolType > +grammar::CNF < SymbolType > ToCNF::convert ( const grammar::RightRG < SymbolType > & origGrammar ) { + grammar::CNF < SymbolType > result ( origGrammar.getInitialSymbol ( ) ); + + result.setNonterminalAlphabet ( origGrammar.getNonterminalAlphabet ( ) ); + result.setTerminalAlphabet ( origGrammar.getTerminalAlphabet ( ) ); + + ext::map < SymbolType, SymbolType > terminalToShadowNonterminal; + for ( const SymbolType & symbol : origGrammar.getTerminalAlphabet ( ) ) { + SymbolType shadowSymbol = common::createUnique ( symbol, result.getTerminalAlphabet ( ), result.getNonterminalAlphabet ( ) ); + terminalToShadowNonterminal.insert ( std::make_pair ( symbol, shadowSymbol ) ); + result.addNonterminalSymbol ( shadowSymbol ); + result.addRule ( std::move ( shadowSymbol ), symbol ); + } + + for ( const std::pair < SymbolType, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > > & rules : origGrammar.getRules ( ) ) { + for ( const ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > & rhs : rules.second ) { + if ( rhs.template is < SymbolType > ( ) ) { + result.addRule ( rules.first, rhs ); + } else { + const ext::pair < SymbolType, SymbolType > & rhsPair = rhs.template get < ext::pair < SymbolType, SymbolType > > ( ); + result.addRule ( rules.first, ext::make_pair ( terminalToShadowNonterminal.at ( rhsPair.first ), rhsPair.second ) ); + } + } + } + + return result; +} + } /* namespace simplify */ } /* namespace grammar */ -- GitLab