From 33583f33eb784f639bc6b829fb464a8726672e0f Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Tue, 5 Feb 2019 11:46:15 +0100 Subject: [PATCH] share implementation in CYK algorithm --- .../grammar/generate/CockeYoungerKasami.cpp | 7 +- .../src/grammar/generate/CockeYoungerKasami.h | 68 ++++--------------- .../generate/CockeYoungerKasamiVerbose.cpp | 7 +- .../generate/CockeYoungerKasamiVerbose.h | 13 +++- 4 files changed, 38 insertions(+), 57 deletions(-) diff --git a/alib2algo/src/grammar/generate/CockeYoungerKasami.cpp b/alib2algo/src/grammar/generate/CockeYoungerKasami.cpp index d3b4a03839..44bf5ef80e 100644 --- a/alib2algo/src/grammar/generate/CockeYoungerKasami.cpp +++ b/alib2algo/src/grammar/generate/CockeYoungerKasami.cpp @@ -12,7 +12,12 @@ namespace grammar { namespace generate { -auto CockeYoungerKasamiCNF = registration::AbstractRegister < CockeYoungerKasami, bool, const grammar::CNF < > &, const string::LinearString < > & > ( CockeYoungerKasami::generate ); +auto CockeYoungerKasamiCNF = registration::AbstractRegister < CockeYoungerKasami, bool, const grammar::CNF < > &, const string::LinearString < > & > ( CockeYoungerKasami::generate, "grammar", "string" ).setDocumentation ( +"Implements the Cocke Younger Kasami algorithm to test whether string is in language generated by a grammar\n\ +\n\ +@param grammar context free grammar in chomsky's normal form.\n\ +@param string the tested string\n\ +@return true if the @p grammar generates a language containing @p string" ); } /* namespace generate */ diff --git a/alib2algo/src/grammar/generate/CockeYoungerKasami.h b/alib2algo/src/grammar/generate/CockeYoungerKasami.h index 16ac57768d..7b75c4973d 100644 --- a/alib2algo/src/grammar/generate/CockeYoungerKasami.h +++ b/alib2algo/src/grammar/generate/CockeYoungerKasami.h @@ -12,16 +12,28 @@ #include <grammar/ContextFree/CNF.h> #include <string/LinearString.h> +#include <grammar/generate/CockeYoungerKasamiVerbose.h> namespace grammar { namespace generate { /** - * Implements algorithms from Melichar, chapter 3.3 + * Implements the Cocke Younger Kasami algorithm. */ class CockeYoungerKasami { public: + /** + * Implements the Cocke Younger Kasami algorithm to test whether string is in language generated by a grammar + * + * \tparam TerminalSymbolType the type of terminal symbol of the grammar + * \tparam NonterminalSymbolType the type of nonterminal symbol of the grammar + * + * \param grammar context free grammar in chomsky's normal form. + * \param string the tested string + * + * \return true if the @p grammar generates a language containing @p string + */ template < class TerminalSymbolType, class NonterminalSymbolType > static bool generate ( const grammar::CNF < TerminalSymbolType, NonterminalSymbolType > & grammar, const string::LinearString < TerminalSymbolType > & string ); @@ -33,59 +45,7 @@ bool CockeYoungerKasami::generate ( const grammar::CNF < TerminalSymbolType, Non if ( ( stringSize == 0 ) && grammar.getGeneratesEpsilon ( ) ) return true; - ext::vector < ext::vector < ext::set < NonterminalSymbolType > > > data; - data.resize ( stringSize ); - - for ( unsigned i = 0; i < stringSize; i++ ) - data[i].resize ( stringSize - i ); - - for ( unsigned i = 0; i < stringSize; i++ ) - for ( const std::pair < const NonterminalSymbolType, ext::set < ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, NonterminalSymbolType > > > > rule : grammar.getRules ( ) ) { - const NonterminalSymbolType & lhs = rule.first; - - for ( const ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, NonterminalSymbolType > > rhs : rule.second ) - if ( rhs.template is < TerminalSymbolType > ( ) && ( rhs.template get < TerminalSymbolType > ( ) == string.getContent ( )[i] ) ) - data[0][i].insert ( lhs ); - - } - - for ( unsigned i = 1; i < stringSize; i++ ) - for ( unsigned j = 0; j < stringSize - i; j++ ) { - ext::set < NonterminalSymbolType > & targetCell = data[i][j]; // Element to compute - - for ( unsigned k = 0; k < i; k++ ) { - const ext::set < NonterminalSymbolType > & vertical = data[k][j]; - const ext::set < NonterminalSymbolType > & diagonal = data[i - 1 - k][j + 1 + k]; // Sources of data - - for ( const NonterminalSymbolType & verticalElement : vertical ) { - for ( const NonterminalSymbolType & diagonalElement : diagonal ) - - for ( const std::pair < const NonterminalSymbolType, ext::set < ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, NonterminalSymbolType > > > > rule : grammar.getRules ( ) ) { - const NonterminalSymbolType & lhs = rule.first; - - for ( const ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, NonterminalSymbolType > > rhs : rule.second ) - if ( rhs.template is < ext::pair < NonterminalSymbolType, NonterminalSymbolType > > ( ) ) { - const ext::pair < NonterminalSymbolType, NonterminalSymbolType > rhsp = rhs.template get < ext::pair < NonterminalSymbolType, NonterminalSymbolType > > ( ); - - if ( ( rhsp.first == verticalElement ) && ( rhsp.second == diagonalElement ) ) - targetCell.insert ( lhs ); - } - - } - - } - } - } - - - - if ( common::GlobalData::verbose ) - for ( const ext::vector < ext::set < NonterminalSymbolType > > & row : data ) { - for ( const ext::set < NonterminalSymbolType > & element : row ) - common::Streams::log << element << " "; - - common::Streams::log << std::endl; - } + ext::vector < ext::vector < ext::set < NonterminalSymbolType > > > data = CockeYoungerKasamiVerbose::generate ( grammar, string ); return data[stringSize - 1][0].count ( grammar.getInitialSymbol ( ) ); } diff --git a/alib2algo/src/grammar/generate/CockeYoungerKasamiVerbose.cpp b/alib2algo/src/grammar/generate/CockeYoungerKasamiVerbose.cpp index 7a9dc7ec32..9fd8d3e440 100644 --- a/alib2algo/src/grammar/generate/CockeYoungerKasamiVerbose.cpp +++ b/alib2algo/src/grammar/generate/CockeYoungerKasamiVerbose.cpp @@ -12,7 +12,12 @@ namespace grammar { namespace generate { -auto CockeYoungerKasamiVerboseCNF = registration::AbstractRegister < CockeYoungerKasamiVerbose, ext::vector < ext::vector < ext::set < DefaultSymbolType > > >, const grammar::CNF < > &, const string::LinearString < > & > ( CockeYoungerKasamiVerbose::generate ); +auto CockeYoungerKasamiVerboseCNF = registration::AbstractRegister < CockeYoungerKasamiVerbose, ext::vector < ext::vector < ext::set < DefaultSymbolType > > >, const grammar::CNF < > &, const string::LinearString < > & > ( CockeYoungerKasamiVerbose::generate, "grammar", "string" ).setDocumentation ( +"Implements the Cocke Younger Kasami algorithm to test whether string is in language generated by a grammar.\n\ +\n\ +@param grammar context free grammar in chomsky's normal form\n\ +@param string the tested string\n\ +@return the internal table constructed by the Cock Younger Kasami algorithm" ); } /* namespace generate */ diff --git a/alib2algo/src/grammar/generate/CockeYoungerKasamiVerbose.h b/alib2algo/src/grammar/generate/CockeYoungerKasamiVerbose.h index a70aa96c05..721a17c4c1 100644 --- a/alib2algo/src/grammar/generate/CockeYoungerKasamiVerbose.h +++ b/alib2algo/src/grammar/generate/CockeYoungerKasamiVerbose.h @@ -18,10 +18,21 @@ namespace grammar { namespace generate { /** - * Implements algorithms from Melichar, chapter 3.3 + * Implements the Cocke Younger Kasami algorithm. */ class CockeYoungerKasamiVerbose { public: + /** + * Implements the Cocke Younger Kasami algorithm to test whether string is in language generated by a grammar. This version returns the internal data structures. + * + * \tparam TerminalSymbolType the type of terminal symbol of the grammar + * \tparam NonterminalSymbolType the type of nonterminal symbol of the grammar + * + * \param grammar context free grammar in chomsky's normal form + * \param string the tested string + * + * \return the internal table constructed by the Cock Younger Kasami algorithm + */ template < class TerminalSymbolType, class NonterminalSymbolType > static ext::vector < ext::vector < ext::set < NonterminalSymbolType > > > generate ( const grammar::CNF < TerminalSymbolType, NonterminalSymbolType > & grammar, const string::LinearString < TerminalSymbolType > & string ); -- GitLab