/* * 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" namespace tree { PrefixRankedPattern::PrefixRankedPattern(alphabet::RankedSymbol subtreeWildcard, std::set<alphabet::RankedSymbol> alphabet, std::vector<alphabet::RankedSymbol> data) : RankedPatternAlphabet(std::move(subtreeWildcard)) { this->alphabet = std::move(alphabet); setContent(std::move(data)); } PrefixRankedPattern::PrefixRankedPattern(alphabet::RankedSymbol subtreeWildcard, std::vector<alphabet::RankedSymbol> data) : RankedPatternAlphabet(std::move(subtreeWildcard)) { arityChecksum(data); alphabet = std::set<alphabet::RankedSymbol>(data.begin(), data.end()); m_Data = std::move(data); } PrefixRankedPattern::PrefixRankedPattern(const RankedPattern& tree) : RankedPatternAlphabet(tree.getSubtreeWildcard()) { alphabet = tree.getAlphabet(); std::deque<const RankedNode*> queue {&tree.getRoot()}; while(!queue.empty()) { const RankedNode* elem = queue.back(); queue.pop_back(); m_Data.push_back(elem->getSymbol()); for(const RankedNode* child : elem->getChildren()) { queue.push_back(child); } } } TreeBase* PrefixRankedPattern::clone() const { return new PrefixRankedPattern(*this); } TreeBase* 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(); } } /* namespace tree */