Skip to content
Snippets Groups Projects
PrefixRankedNotation.cpp 3.37 KiB
Newer Older
  • Learn to ignore specific revisions
  • Jan Trávníček's avatar
    Jan Trávníček committed
    /*
     * PrefixRankedNotation.cpp
     *
     *  Created on: Nov 23, 2013
     *      Author: Jan Travnicek
     */
    
    #include "PrefixRankedNotation.h"
    #include "../../exception/AlibException.h"
    
    #include <sstream>
    #include <algorithm>
    #include <deque>
    
    #include "RankedTree.h"
    
    namespace tree {
    
    
    PrefixRankedNotation::PrefixRankedNotation(std::set<alphabet::RankedSymbol> alphabet, std::vector<alphabet::RankedSymbol> data) {
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    	this->alphabet = std::move(alphabet);
    	setContent(std::move(data));
    }
    
    
    PrefixRankedNotation::PrefixRankedNotation(std::vector<alphabet::RankedSymbol> data) {
    
    	arityChecksum(data);
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    
    	alphabet = std::set<alphabet::RankedSymbol>(data.begin(), data.end());
    	m_Data = std::move(data);
    }
    
    PrefixRankedNotation::PrefixRankedNotation(const RankedTree& tree) {
    	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* PrefixRankedNotation::clone() const {
    	return new PrefixRankedNotation(*this);
    }
    
    TreeBase* PrefixRankedNotation::plunder() && {
    	return new PrefixRankedNotation(std::move(*this));
    }
    
    bool PrefixRankedNotation::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.");
    
    	return alphabet.erase(symbol);
    }
    
    const std::vector<alphabet::RankedSymbol>& PrefixRankedNotation::getContent() const {
    	return this->m_Data;
    }
    
    void PrefixRankedNotation::setContent(std::vector<alphabet::RankedSymbol> data) {
    
    	arityChecksum(data);
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    	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 PrefixRankedNotation::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");
    }
    
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    bool PrefixRankedNotation::isEmpty() const {
    	return this->m_Data.size() == 0;
    }
    
    int PrefixRankedNotation::compare(const PrefixRankedNotation& 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 PrefixRankedNotation::operator >>(std::ostream& out) const {
    	if( this->isEmpty() ) {
    		out << "(Epsilon)";
    	} else {
    		out << "(PrefixRankedNotation ";
    		for(const alphabet::RankedSymbol& symbol : this->m_Data)
    			out << symbol;
    		out << ")";
    	}
    }
    
    PrefixRankedNotation::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 */