/* * PrefixRankedPattern.cpp * * Created on: Nov 23, 2013 * Author: Jan Travnicek */ #include "PrefixRankedPattern.h" #include "../TreeException.h" #include <sstream> #include <algorithm> #include <deque> #include "RankedPattern.h" #include "PrefixRankedTree.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 <cast/CastApi.hpp> #include "../../alphabet/SubtreeWildcardSymbol.h" 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 PrefixRankedTree & tree ) : PrefixRankedPattern ( alphabet::RankedSymbol ( alphabet::Symbol ( alphabet::SubtreeWildcardSymbol::SUBTREE_WILDCARD ), 0 ), tree.getAlphabet ( ), tree.getContent ( ) ) { } 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 TreeException ( "Input symbol \"" + ( std::string ) symbol + "\" is used." ); if ( this->subtreeWildcard == symbol ) throw TreeException ( "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 TreeException ( "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 TreeException ( "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 { out << "(PrefixRankedPattern "; for ( const alphabet::RankedSymbol & symbol : this->m_Data ) out << symbol; out << ")"; } PrefixRankedPattern::operator std::string ( ) const { std::stringstream ss; 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::parseRankedContent ( 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 { auto prefixRankedPatternParserRegister = xmlApi < tree::Tree >::ParserRegister < tree::PrefixRankedPattern > (); auto prefixRankedPatternParserRegister2 = xmlApi < tree::RankedTreeWrapper >::ParserRegister < tree::PrefixRankedPattern > (); auto prefixRankedPatternParserRegister3 = xmlApi < alib::Object >::ParserRegister < tree::PrefixRankedPattern > (); auto PrefixRankedPatternFromRankedPattern = castApi::CastRegister < tree::PrefixRankedPattern, tree::RankedPattern > ( ); auto PrefixRankedPatternCastBinder = castApi::CastPoolStringBinder < tree::PrefixRankedPattern > ( tree::PrefixRankedPattern::XML_TAG_NAME ); } /* namespace alib */