/* * RankedNonlinearPattern.cpp * * Created on: Nov 23, 2013 * Author: Jan Travnicek */ #include "RankedNonlinearPattern.h" #include "../TreeException.h" #include <iostream> #include <algorithm> #include <sstream> #include "../unranked/UnrankedPattern.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> namespace tree { RankedNonlinearPattern::RankedNonlinearPattern ( alphabet::RankedSymbol subtreeWildcard, std::set < alphabet::RankedSymbol > nonlinearVariables, std::set < alphabet::RankedSymbol > alphabet, RankedNode pattern ) : std::Components < RankedNonlinearPattern, alphabet::RankedSymbol, std::tuple < GeneralAlphabet, NonlinearAlphabet >, std::tuple < SubtreeWildcard > > ( std::make_tuple ( std::move ( alphabet ), std::move ( nonlinearVariables ) ), std::make_tuple ( std::move ( subtreeWildcard ) ) ), pattern ( nullptr ) { setTree ( std::move ( pattern ) ); } RankedNonlinearPattern::RankedNonlinearPattern ( alphabet::RankedSymbol subtreeWildcard, std::set < alphabet::RankedSymbol > nonlinearVariables, RankedNode pattern ) : RankedNonlinearPattern ( subtreeWildcard, nonlinearVariables, pattern.computeMinimalAlphabet() + nonlinearVariables + std::set < alphabet::RankedSymbol > { subtreeWildcard }, pattern ) { } RankedNonlinearPattern::RankedNonlinearPattern ( alphabet::RankedSymbol subtreeWildcard, RankedNode pattern ) : RankedNonlinearPattern ( subtreeWildcard, std::set < alphabet::RankedSymbol > { }, pattern ) { } RankedNonlinearPattern::RankedNonlinearPattern ( const RankedNonlinearPattern & other ) : std::Components < RankedNonlinearPattern, alphabet::RankedSymbol, std::tuple < GeneralAlphabet, NonlinearAlphabet >, std::tuple < SubtreeWildcard > > ( std::make_tuple ( other.getAlphabet ( ), other.getNonlinearVariables ( ) ), std::make_tuple ( other.getSubtreeWildcard ( ) ) ), pattern ( other.pattern ) { this->pattern->attachAlphabet ( & ( this->getAlphabet() ) ); } RankedNonlinearPattern::RankedNonlinearPattern ( RankedNonlinearPattern && other ) noexcept : std::Components < RankedNonlinearPattern, alphabet::RankedSymbol, std::tuple < GeneralAlphabet, NonlinearAlphabet >, std::tuple < SubtreeWildcard > > ( std::make_tuple ( std::move ( other.accessComponent < GeneralAlphabet > ( ).get ( ) ), std::move ( other.accessComponent < NonlinearAlphabet > ( ).get ( ) ) ), std::make_tuple ( std::move ( other.accessElement < SubtreeWildcard > ( ).get ( ) ) ) ), pattern ( std::move ( other.pattern ) ) { this->pattern->attachAlphabet ( & ( this->getAlphabet() ) ); } RankedTreeBase * RankedNonlinearPattern::clone ( ) const { return new RankedNonlinearPattern ( * this ); } RankedTreeBase * RankedNonlinearPattern::plunder ( ) && { return new RankedNonlinearPattern ( std::move ( * this ) ); } RankedNonlinearPattern & RankedNonlinearPattern::operator =( const RankedNonlinearPattern & other ) { if ( this == & other ) return * this; * this = RankedNonlinearPattern ( other ); return * this; } RankedNonlinearPattern & RankedNonlinearPattern::operator =( RankedNonlinearPattern && other ) noexcept { std::swap ( this->pattern, other.pattern ); std::swap ( accessComponent < GeneralAlphabet > ( ).get ( ), other.accessComponent < GeneralAlphabet > ( ).get ( ) ); std::swap ( accessComponent < NonlinearAlphabet > ( ).get ( ), other.accessComponent < NonlinearAlphabet > ( ).get ( ) ); std::swap ( accessElement < SubtreeWildcard > ( ).get ( ), other.accessElement < SubtreeWildcard > ( ).get ( ) ); return * this; } RankedNonlinearPattern::~RankedNonlinearPattern ( ) noexcept { } const RankedNode & RankedNonlinearPattern::getRoot ( ) const { return * pattern; } RankedNode & RankedNonlinearPattern::getRoot ( ) { return * pattern; } void RankedNonlinearPattern::setTree ( RankedNode pattern ) { this->pattern = std::make_smart < RankedNode > ( std::move ( pattern ) ); if ( !this->pattern->attachAlphabet ( & ( this->getAlphabet ( ) ) ) ) throw TreeException ( "Input symbols not in the alphabet." ); } void RankedNonlinearPattern::operator >>( std::ostream & out ) const { out << "(RankedNonlinearPattern " << * ( this->pattern ) << ")"; } int RankedNonlinearPattern::compare ( const RankedNonlinearPattern & other ) const { auto first = std::tie ( * pattern, getAlphabet(), getSubtreeWildcard(), getNonlinearVariables() ); auto second = std::tie ( * other.pattern, other.getAlphabet(), other.getSubtreeWildcard(), getNonlinearVariables() ); std::compare < decltype ( first ) > comp; return comp ( first, second ); } void RankedNonlinearPattern::nicePrint ( std::ostream & os ) const { pattern->nicePrint ( os ); } RankedNonlinearPattern::operator std::string ( ) const { std::stringstream ss; ss << * this; return ss.str ( ); } RankedNonlinearPattern RankedNonlinearPattern::parse ( std::deque < sax::Token >::iterator & input ) { sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, RankedNonlinearPattern::getXmlTagName() ); alphabet::RankedSymbol subtreeWildcardSymbol = TreeFromXMLParser::parseSubtreeWildcardRankedSymbol ( input ); std::set < alphabet::RankedSymbol > nonlinearVariables = TreeFromXMLParser::parseRankedNonlinearVariables ( input ); std::set < alphabet::RankedSymbol > rankedAlphabet = TreeFromXMLParser::parseRankedAlphabet ( input ); RankedNode root = alib::xmlApi < RankedNode >::parse ( input ); RankedNonlinearPattern tree ( std::move ( subtreeWildcardSymbol ), std::move ( nonlinearVariables ), std::move ( rankedAlphabet ), std::move ( root ) ); sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, RankedNonlinearPattern::getXmlTagName() ); return tree; } void RankedNonlinearPattern::compose ( std::deque < sax::Token > & out ) const { out.emplace_back ( RankedNonlinearPattern::getXmlTagName(), sax::Token::TokenType::START_ELEMENT ); TreeToXMLComposer::composeSubtreeWildcard ( out, getSubtreeWildcard() ); TreeToXMLComposer::composeNonlinearVariables ( out, getNonlinearVariables() ); TreeToXMLComposer::composeAlphabet ( out, getAlphabet() ); alib::xmlApi < RankedNode >::compose ( out, getRoot() ); out.emplace_back ( RankedNonlinearPattern::getXmlTagName(), sax::Token::TokenType::END_ELEMENT ); } } /* namespace tree */ namespace std { template < > bool tree::RankedNonlinearPattern::Component < tree::RankedNonlinearPattern, alphabet::RankedSymbol, tree::GeneralAlphabet >::used ( const alphabet::RankedSymbol & symbol ) const { const tree::RankedNonlinearPattern * pattern = static_cast < const tree::RankedNonlinearPattern * > ( this ); return pattern->getRoot ( ).testSymbol ( symbol ) || pattern->accessElement < tree::SubtreeWildcard > ( ).get ( ) == symbol || pattern->accessComponent < tree::NonlinearAlphabet > ( ).get ( ).count ( symbol ); } template < > bool tree::RankedNonlinearPattern::Component < tree::RankedNonlinearPattern, alphabet::RankedSymbol, tree::GeneralAlphabet >::available ( const alphabet::RankedSymbol & ) const { return true; } template < > void tree::RankedNonlinearPattern::Component < tree::RankedNonlinearPattern, alphabet::RankedSymbol, tree::GeneralAlphabet >::valid ( const alphabet::RankedSymbol & ) const { } template < > bool tree::RankedNonlinearPattern::Component < tree::RankedNonlinearPattern, alphabet::RankedSymbol, tree::NonlinearAlphabet >::used ( const alphabet::RankedSymbol & ) const { return false; } template < > bool tree::RankedNonlinearPattern::Component < tree::RankedNonlinearPattern, alphabet::RankedSymbol, tree::NonlinearAlphabet >::available ( const alphabet::RankedSymbol & symbol ) const { const tree::RankedNonlinearPattern * pattern = static_cast < const tree::RankedNonlinearPattern * > ( this ); return pattern->accessComponent < tree::GeneralAlphabet > ( ).get ( ).count ( symbol ); } template < > void tree::RankedNonlinearPattern::Component < tree::RankedNonlinearPattern, alphabet::RankedSymbol, tree::NonlinearAlphabet >::valid ( const alphabet::RankedSymbol & symbol ) const { const tree::RankedNonlinearPattern * pattern = static_cast < const tree::RankedNonlinearPattern * > ( this ); if( symbol.getRank().getData() != 0 ) throw tree::TreeException ( "SubtreeWildcard symbol has nonzero arity" ); if ( pattern->accessElement < tree::SubtreeWildcard > ( ).get ( ) == symbol ) throw tree::TreeException ( "Symbol " + ( std::string ) symbol + "cannot be set as nonlinear variable since it is already subtree wildcard" ); } template < > bool tree::RankedNonlinearPattern::Element < tree::RankedNonlinearPattern, alphabet::RankedSymbol, tree::SubtreeWildcard >::available ( const alphabet::RankedSymbol & symbol ) const { const tree::RankedNonlinearPattern * pattern = static_cast < const tree::RankedNonlinearPattern * > ( this ); return pattern->accessComponent < tree::GeneralAlphabet > ( ).get ( ).count ( symbol ); } template < > void tree::RankedNonlinearPattern::Element < tree::RankedNonlinearPattern, alphabet::RankedSymbol, tree::SubtreeWildcard >::valid ( const alphabet::RankedSymbol & symbol ) const { const tree::RankedNonlinearPattern * pattern = static_cast < const tree::RankedNonlinearPattern * > ( this ); if( symbol.getRank().getData() != 0 ) throw tree::TreeException ( "SubtreeWildcard symbol has nonzero arity" ); if ( pattern->accessComponent < tree::NonlinearAlphabet > ( ).get ( ).count ( symbol ) ) throw tree::TreeException ( "Symbol " + ( std::string ) symbol + "cannot be set as subtree wildcard since it is already nonlinear variable" ); } } /* namespace std */ namespace alib { auto RankedNonlinearPatternParserRegister = xmlApi < tree::Tree >::ParserRegister < tree::RankedNonlinearPattern > ( ); auto RankedNonlinearPatternParserRegister2 = xmlApi < tree::RankedTreeWrapper >::ParserRegister < tree::RankedNonlinearPattern > ( ); auto RankedNonlinearPatternParserRegister3 = xmlApi < alib::Object >::ParserRegister < tree::RankedNonlinearPattern > ( ); } /* namespace alib */