Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
PrefixRankedBarPattern.cpp 10.50 KiB
/*
 * PrefixRankedBarPattern.cpp
 *
 *  Created on: Nov 23, 2013
 *      Author: Jan Travnicek
 */

#include "PrefixRankedBarPattern.h"
#include "../TreeException.h"

#include <sstream>
#include <algorithm>
#include <deque>

#include "RankedPattern.h"
#include "PrefixRankedBarTree.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/BarSymbol.h"
#include "../../alphabet/VariablesBarSymbol.h"
#include "../../alphabet/SubtreeWildcardSymbol.h"

namespace tree {

PrefixRankedBarPattern::PrefixRankedBarPattern ( alphabet::Symbol bar, alphabet::Symbol variablesBar, alphabet::RankedSymbol subtreeWildcard, std::set < alphabet::RankedSymbol > alphabet, std::vector < alphabet::RankedSymbol > data ) : std::Components < PrefixRankedBarPattern, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < SubtreeWildcard > > ( std::make_tuple ( std::move ( alphabet ) + std::set < alphabet::RankedSymbol > { subtreeWildcard } ), std::make_tuple ( subtreeWildcard ) ), bar ( std::move ( bar ) ), variablesBar ( std::move ( variablesBar ) ) {
	setContent ( std::move ( data ) );
}

PrefixRankedBarPattern::PrefixRankedBarPattern ( alphabet::Symbol bar, alphabet::Symbol variablesBar, alphabet::RankedSymbol subtreeWildcard, std::vector < alphabet::RankedSymbol > data ) : PrefixRankedBarPattern ( std::move ( bar ), std::move ( variablesBar ), std::move ( subtreeWildcard ), std::set < alphabet::RankedSymbol > ( data.begin ( ), data.end ( ) ), std::move ( data ) ) {
}

PrefixRankedBarPattern::PrefixRankedBarPattern ( alphabet::Symbol bar, alphabet::Symbol variablesBar, const RankedPattern & tree ) : std::Components < PrefixRankedBarPattern, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < SubtreeWildcard > > ( std::make_tuple ( std::set < alphabet::RankedSymbol > ( tree.getAlphabet ( ) ) ), std::make_tuple ( tree.getSubtreeWildcard ( ) ) ), bar ( std::move ( bar ) ), variablesBar ( std::move ( variablesBar ) ) {
	toPrefixRankedBar ( tree.getRoot ( ) );

	for ( const alphabet::RankedSymbol & symbol : tree.getAlphabet ( ) ) {
		accessComponent < GeneralAlphabet > ( ).add ( alphabet::RankedSymbol ( this->bar, symbol.getRank ( ) ) );
	}

	accessComponent < GeneralAlphabet > ( ).add ( alphabet::RankedSymbol ( this->variablesBar, tree.getSubtreeWildcard ( ).getRank ( ) ) );
}

PrefixRankedBarPattern::PrefixRankedBarPattern ( const PrefixRankedBarTree & tree ) : PrefixRankedBarPattern ( alphabet::Symbol ( alphabet::BarSymbol::BAR ), alphabet::Symbol ( alphabet::VariablesBarSymbol::BAR ), alphabet::RankedSymbol ( alphabet::Symbol ( alphabet::SubtreeWildcardSymbol::SUBTREE_WILDCARD ), 0 ), tree.getAlphabet ( ), tree.getContent ( ) ) {
}

PrefixRankedBarPattern::PrefixRankedBarPattern ( const RankedPattern & tree ) : PrefixRankedBarPattern ( alphabet::Symbol ( alphabet::BarSymbol::BAR ), alphabet::Symbol ( alphabet::VariablesBarSymbol::BAR ), tree ) {
}

void PrefixRankedBarPattern::toPrefixRankedBar ( const RankedNode & node ) {
	if ( node.getSymbol ( ) == accessElement < tree::SubtreeWildcard > ( ).get ( ) ) {
		m_Data.push_back ( node.getSymbol ( ) );
		m_Data.push_back ( alphabet::RankedSymbol ( variablesBar, node.getSymbol ( ).getRank ( ) ) );
	} else {
		m_Data.push_back ( node.getSymbol ( ) );

		for ( const RankedNode * child : node.getChildren ( ) )
			toPrefixRankedBar ( * child );

		m_Data.push_back ( alphabet::RankedSymbol ( bar, node.getSymbol ( ).getRank ( ) ) );
	}
}

RankedTreeBase * PrefixRankedBarPattern::clone ( ) const {
	return new PrefixRankedBarPattern ( * this );
}

RankedTreeBase * PrefixRankedBarPattern::plunder ( ) && {
	return new PrefixRankedBarPattern ( std::move ( * this ) );
}

const std::vector < alphabet::RankedSymbol > & PrefixRankedBarPattern::getContent ( ) const {
	return this->m_Data;
}

void PrefixRankedBarPattern::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 ( ), getAlphabet().begin ( ), getAlphabet().end ( ), std::inserter ( unknownSymbols, unknownSymbols.end ( ) ) );

	if ( unknownSymbols.size ( ) > 0 )
		throw TreeException ( "Input symbols not in the alphabet." );

	this->m_Data = std::move ( data );
}

const alphabet::Symbol & PrefixRankedBarPattern::getBarSymbol ( ) const {
	return bar;
}

const alphabet::Symbol & PrefixRankedBarPattern::getVariablesBarSymbol ( ) const {
	return variablesBar;
}

void PrefixRankedBarPattern::arityChecksum ( const std::vector < alphabet::RankedSymbol > & data ) {
	int arityChecksumTerminals = 1;
	int arityChecksumBars  = 1;
	int arityChecksumTypes = 0;

	for ( const alphabet::RankedSymbol & symbol : data ) {
		if ( ( symbol.getSymbol ( ) != bar ) && ( symbol.getSymbol ( ) != variablesBar ) ) {
			arityChecksumTerminals += symbol.getRank ( ).getData ( );
			arityChecksumTerminals -= 1;
			arityChecksumTypes += 1;
		} else {
			arityChecksumBars  += symbol.getRank ( ).getData ( );
			arityChecksumBars  -= 1;
			arityChecksumTypes -= 1;
		}
	}

	if ( ( arityChecksumTerminals != 0 ) || ( arityChecksumBars != 0 ) || ( arityChecksumTypes != 0 ) ) throw TreeException ( "The string does not form a tree" );

	for ( unsigned i = 0; i < data.size ( ); ++i )
		if ( ( data[i] == accessElement < tree::SubtreeWildcard > ( ).get ( ) ) && ( ( ( i + 1 ) == data.size ( ) ) || ( data[i + 1].getSymbol ( ) != variablesBar ) ) )
			throw TreeException ( "Inconsystency of SubtreeWildcard and variablesBar" );

}

bool PrefixRankedBarPattern::isEmpty ( ) const {
	return this->m_Data.size ( ) == 0;
}

int PrefixRankedBarPattern::compare ( const PrefixRankedBarPattern & other ) const {
	auto first = std::tie ( m_Data, getAlphabet(), getSubtreeWildcard(), bar, variablesBar );
	auto second = std::tie ( other.m_Data, other.getAlphabet(), other.getSubtreeWildcard(), bar, variablesBar );

	std::compare < decltype ( first ) > comp;

	return comp ( first, second );
}
void PrefixRankedBarPattern::operator >>( std::ostream & out ) const {
	out << "(PrefixRankedBarPattern ";

	for ( const alphabet::RankedSymbol & symbol : this->m_Data )
		out << symbol;

	out << ")";
}

PrefixRankedBarPattern::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 PrefixRankedBarPattern::XML_TAG_NAME = "PrefixRankedBarPattern";

PrefixRankedBarPattern PrefixRankedBarPattern::parse ( std::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, PrefixRankedBarPattern::XML_TAG_NAME );
	alphabet::Symbol bar = TreeFromXMLParser::parseBar ( input );
	alphabet::Symbol variablesBarSymbol = TreeFromXMLParser::parseVariablesBar ( input );
	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, PrefixRankedBarPattern::XML_TAG_NAME );

	return PrefixRankedBarPattern ( std::move ( bar ), std::move ( variablesBarSymbol ), std::move ( subtreeWildcardSymbol ), std::move ( rankedAlphabet ), std::move ( data ) );
}

void PrefixRankedBarPattern::compose ( std::deque < sax::Token > & out ) const {
	out.emplace_back ( PrefixRankedBarPattern::XML_TAG_NAME, sax::Token::TokenType::START_ELEMENT );
	TreeToXMLComposer::composeBar ( out, bar );
	TreeToXMLComposer::composeVariablesBar ( out, variablesBar );
	TreeToXMLComposer::composeSubtreeWildcard ( out, getSubtreeWildcard() );
	TreeToXMLComposer::composeAlphabet ( out, getAlphabet() );
	TreeToXMLComposer::composeContent ( out, m_Data );
	out.emplace_back ( PrefixRankedBarPattern::XML_TAG_NAME, sax::Token::TokenType::END_ELEMENT );
}

} /* namespace tree */

namespace std {

template < >
bool tree::PrefixRankedBarPattern::Component < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::GeneralAlphabet >::used ( const alphabet::RankedSymbol & symbol ) const {
	const tree::PrefixRankedBarPattern * pattern = static_cast < const tree::PrefixRankedBarPattern * > ( this );
	const std::vector < alphabet::RankedSymbol > & content = pattern->getContent ( );

	return std::find ( content.begin ( ), content.end ( ), symbol ) != content.end ( ) || pattern->accessElement < tree::SubtreeWildcard > ( ).get ( ) == symbol;
}

template < >
bool tree::PrefixRankedBarPattern::Component < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::GeneralAlphabet >::available ( const alphabet::RankedSymbol & ) const {
	return true;
}

template < >
void tree::PrefixRankedBarPattern::Component < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::GeneralAlphabet >::valid ( const alphabet::RankedSymbol & ) const {
}

template < >
bool tree::PrefixRankedBarPattern::Element < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::SubtreeWildcard >::available ( const alphabet::RankedSymbol & symbol ) const {
	return static_cast < const tree::PrefixRankedBarPattern * > ( this )->accessComponent < tree::GeneralAlphabet > ( ).get ( ).count ( symbol );
}
template < >
void tree::PrefixRankedBarPattern::Element < tree::PrefixRankedBarPattern, alphabet::RankedSymbol, tree::SubtreeWildcard >::valid ( const alphabet::RankedSymbol & ) const {
}

} /* namespace std */

namespace alib {

auto prefixRankedBarPatternParserRegister = xmlApi < tree::Tree >::ParserRegister < tree::PrefixRankedBarPattern > ();
auto prefixRankedBarPatternParserRegister2 = xmlApi < tree::RankedTreeWrapper >::ParserRegister < tree::PrefixRankedBarPattern > ();
auto prefixRankedBarPatternParserRegister3 = xmlApi < alib::Object >::ParserRegister < tree::PrefixRankedBarPattern > ();

auto PrefixRankedBarPatternFromRankedPattern = castApi::CastRegister < tree::PrefixRankedBarPattern, tree::RankedPattern > ( );
auto PrefixRankedBarPatternFromRankedTree = castApi::CastRegister < tree::PrefixRankedBarPattern, tree::PrefixRankedBarTree > ( );
auto PrefixRankedBarPatternCastBinder = castApi::CastPoolStringBinder < tree::PrefixRankedBarPattern > ( tree::PrefixRankedBarPattern::XML_TAG_NAME );

} /* namespace alib */