/* * PrefixRankedPattern.cpp * * Created on: Nov 23, 2013 * Author: Jan Travnicek */ #include "PrefixRankedPattern.h" #include "../../exception/AlibException.h" #include <sstream> #include <algorithm> #include <deque> #include "RankedPattern.h" #include "../../sax/FromXMLParserHelper.h" #include "../common/TreeFromXMLParser.h" #include "../common/TreeToXMLComposer.h" #include "../Tree.h" #include "../RankedTreeWrapper.h" #include "../../object/Object.h" #include "../../XmlApi.hpp" #include "../../CastApi.hpp" namespace tree { PrefixRankedPattern::PrefixRankedPattern ( alphabet::RankedSymbol subtreeWildcard, std::set < alphabet::RankedSymbol > alphabet, std::vector < alphabet::RankedSymbol > data ) : RankedPatternAlphabet ( std::move ( subtreeWildcard ) ) { addSymbolsToAlphabet ( std::move ( alphabet ) ); setContent ( std::move ( data ) ); } PrefixRankedPattern::PrefixRankedPattern ( alphabet::RankedSymbol subtreeWildcard, std::vector < alphabet::RankedSymbol > data ) : RankedPatternAlphabet ( std::move ( subtreeWildcard ) ) { arityChecksum ( data ); addSymbolsToAlphabet ( std::set < alphabet::RankedSymbol > ( data.begin ( ), data.end ( ) ) ); m_Data = std::move ( data ); } PrefixRankedPattern::PrefixRankedPattern ( const RankedPattern & tree ) : RankedPatternAlphabet ( tree.getSubtreeWildcard ( ) ) { toPrefixRanked ( tree.getRoot ( ) ); addSymbolsToAlphabet ( tree.getAlphabet ( ) ); } void PrefixRankedPattern::toPrefixRanked ( const RankedNode & node ) { if ( node.getSymbol ( ) == subtreeWildcard ) { m_Data.push_back ( node.getSymbol ( ) ); } else { m_Data.push_back ( node.getSymbol ( ) ); for ( const RankedNode * child : node.getChildren ( ) ) toPrefixRanked ( * child ); } } RankedTreeBase * PrefixRankedPattern::clone ( ) const { return new PrefixRankedPattern ( * this ); } RankedTreeBase * PrefixRankedPattern::plunder ( ) && { return new PrefixRankedPattern ( std::move ( * this ) ); } bool PrefixRankedPattern::removeSymbolFromAlphabet ( const alphabet::RankedSymbol & symbol ) { if ( std::any_of ( m_Data.begin ( ), m_Data.end ( ), [&] ( const alphabet::RankedSymbol & s ) { return s == symbol; } ) ) throw exception::AlibException ( "Input symbol \"" + ( std::string ) symbol + "\" is used." ); if ( this->subtreeWildcard == symbol ) throw exception::AlibException ( "Input symbol \"" + ( std::string ) symbol + "\" is subtreeWildcard." ); return alphabet.erase ( symbol ); } const std::vector < alphabet::RankedSymbol > & PrefixRankedPattern::getContent ( ) const { return this->m_Data; } void PrefixRankedPattern::setContent ( std::vector < alphabet::RankedSymbol > data ) { arityChecksum ( data ); std::set < alphabet::RankedSymbol > minimalAlphabet ( data.begin ( ), data.end ( ) ); std::set < alphabet::RankedSymbol > unknownSymbols; std::set_difference ( minimalAlphabet.begin ( ), minimalAlphabet.end ( ), alphabet.begin ( ), alphabet.end ( ), std::inserter ( unknownSymbols, unknownSymbols.end ( ) ) ); if ( unknownSymbols.size ( ) > 0 ) throw exception::AlibException ( "Input symbols not in the alphabet." ); this->m_Data = std::move ( data ); } void PrefixRankedPattern::arityChecksum ( const std::vector < alphabet::RankedSymbol > & data ) { int arityChecksum = 1; for ( const alphabet::RankedSymbol & symbol : data ) { arityChecksum += symbol.getRank ( ).getData ( ); arityChecksum -= 1; } if ( arityChecksum != 0 ) throw exception::AlibException ( "The string does not form a tree" ); } bool PrefixRankedPattern::isEmpty ( ) const { return this->m_Data.size ( ) == 0; } int PrefixRankedPattern::compare ( const PrefixRankedPattern & other ) const { auto first = std::tie ( m_Data, alphabet ); auto second = std::tie ( other.m_Data, other.alphabet ); std::compare < decltype ( first ) > comp; return comp ( first, second ); } void PrefixRankedPattern::operator >>( std::ostream & out ) const { if ( this->isEmpty ( ) ) { out << "(Epsilon)"; } else { out << "(PrefixRankedPattern "; for ( const alphabet::RankedSymbol & symbol : this->m_Data ) out << symbol; out << ")"; } } PrefixRankedPattern::operator std::string ( ) const { std::stringstream ss; if ( this->isEmpty ( ) ) { ss << "E"; } else { ss << "\""; for ( const alphabet::RankedSymbol & symbol : this->m_Data ) ss << ( std::string ) symbol; ss << "\""; } return std::move ( ss ).str ( ); } const std::string PrefixRankedPattern::XML_TAG_NAME = "PrefixRankedPattern"; PrefixRankedPattern PrefixRankedPattern::parse ( std::deque < sax::Token >::iterator & input ) { sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, PrefixRankedPattern::XML_TAG_NAME ); alphabet::RankedSymbol subtreeWildcardSymbol = TreeFromXMLParser::parseSubtreeWildcardRankedSymbol ( input ); std::set < alphabet::RankedSymbol > rankedAlphabet = TreeFromXMLParser::parseRankedAlphabet ( input ); std::vector < alphabet::RankedSymbol > data = TreeFromXMLParser::parseContentData ( input ); sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, PrefixRankedPattern::XML_TAG_NAME ); return PrefixRankedPattern ( std::move ( subtreeWildcardSymbol ), std::move ( rankedAlphabet ), std::move ( data ) ); } void PrefixRankedPattern::compose ( std::deque < sax::Token > & out ) const { out.emplace_back ( PrefixRankedPattern::XML_TAG_NAME, sax::Token::TokenType::START_ELEMENT ); TreeToXMLComposer::composeSubtreeWildcard ( out, subtreeWildcard ); TreeToXMLComposer::composeAlphabet ( out, alphabet ); TreeToXMLComposer::composeContent ( out, m_Data ); out.emplace_back ( PrefixRankedPattern::XML_TAG_NAME, sax::Token::TokenType::END_ELEMENT ); } } /* namespace tree */ namespace alib { xmlApi < tree::Tree >::ParserRegister < tree::PrefixRankedPattern > prefixRankedPatternParserRegister = xmlApi < tree::Tree >::ParserRegister < tree::PrefixRankedPattern > ( tree::PrefixRankedPattern::XML_TAG_NAME, tree::PrefixRankedPattern::parse ); xmlApi < tree::RankedTreeWrapper >::ParserRegister < tree::PrefixRankedPattern > prefixRankedPatternParserRegister2 = xmlApi < tree::RankedTreeWrapper >::ParserRegister < tree::PrefixRankedPattern > ( tree::PrefixRankedPattern::XML_TAG_NAME, tree::PrefixRankedPattern::parse ); xmlApi < alib::Object >::ParserRegister < tree::PrefixRankedPattern > prefixRankedPatternParserRegister3 = xmlApi < alib::Object >::ParserRegister < tree::PrefixRankedPattern > ( tree::PrefixRankedPattern::XML_TAG_NAME, tree::PrefixRankedPattern::parse ); auto PrefixRankedPatternFromRankedPattern = castApi::CastRegister < tree::PrefixRankedPattern, tree::RankedPattern > ( ); auto PrefixRankedPatternCastBinder = castApi::CastPoolStringBinder < tree::PrefixRankedPattern > ( tree::PrefixRankedPattern::XML_TAG_NAME ); } /* namespace alib */