-
Jan Trávníček authoredJan Trávníček authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
SinglePopNPDA.cpp 7.30 KiB
/*
* SinglePopNPDA.cpp
*
* Created on: Apr 10, 2013
* Author: martin
*/
#include "SinglePopNPDA.h"
#include "../../std/map.hpp"
#include "../AutomatonException.h"
#include <algorithm>
namespace automaton {
AutomatonBase* SinglePopNPDA::clone() const {
return new SinglePopNPDA(*this);
}
AutomatonBase* SinglePopNPDA::plunder() && {
return new SinglePopNPDA(std::move(*this));
}
bool SinglePopNPDA::removeState(const State& state) {
if (initialStates.find(state) != initialStates.end()) {
throw AutomatonException("State \"" + (std::string) state.getName() + "\" is initial state.");
}
if (finalStates.find(state) != finalStates.end()) {
throw AutomatonException("State \"" + (std::string) state.getName() + "\" is final state.");
}
for (std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::set<std::pair<State, std::vector<alphabet::Symbol> > > >::const_iterator transition = transitions.begin(); transition != transitions.end(); transition++) {
if (state == std::get<0>(transition->first))
throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition.");
for(std::set<std::pair<State, std::vector<alphabet::Symbol> > >::iterator target = transition->second.begin(); target != transition->second.end(); target++) {
if(target->first == state)
throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition.");
}
}
return states.erase(state);
}
bool SinglePopNPDA::removeInputSymbol(const alphabet::Symbol& symbol) {
for (std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::set<std::pair<State, std::vector<alphabet::Symbol> > > >::const_iterator transition = transitions.begin(); transition != transitions.end(); transition++) {
if (std::get<1>(transition->first).is<alphabet::Symbol>() && symbol == std::get<1>(transition->first).get<alphabet::Symbol>())
throw AutomatonException("Symbol \"" + (std::string) symbol + "\" is used in transition.");
}
return inputAlphabet.erase(symbol);
}
bool SinglePopNPDA::removeStackSymbol(const alphabet::Symbol& symbol) {
for (std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::set<std::pair<State, std::vector<alphabet::Symbol> > > >::const_iterator transition = transitions.begin(); transition != transitions.end(); transition++) {
if (symbol == std::get<2>(transition->first))
throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is used in transition.");
for (std::set<std::pair<State, std::vector<alphabet::Symbol> > >::const_iterator target = transition->second.begin(); target != transition->second.end(); target++) {
if (std::find(target->second.begin(), target->second.end(), symbol) != target->second.end())
throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is used in transition.");
}
}
if(initialSymbols.find(symbol) != initialSymbols.end()) {
throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is start symbol.");
}
return stackAlphabet.erase(symbol);
}
bool SinglePopNPDA::addTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
if (states.find(from) == states.end()) {
throw AutomatonException("State \"" + (std::string) from.getName() + "\" doesn't exist.");
}
if (input.is<alphabet::Symbol>() && inputAlphabet.find(input.get<alphabet::Symbol>()) == inputAlphabet.end()) {
throw AutomatonException("Input symbol \"" + (std::string) input.get<alphabet::Symbol>() + "\" doesn't exist.");
}
if (states.find(to) == states.end()) {
throw AutomatonException("State \"" + (std::string) to.getName() + "\" doesn't exist.");
}
if (stackAlphabet.find(pop) == stackAlphabet.end()) {
throw AutomatonException("Stack symbol \"" + (std::string) pop + "\" doesn't exist.");
}
for(std::vector<alphabet::Symbol>::const_iterator pushSymbol = push.begin(); pushSymbol != push.end(); pushSymbol++) {
if (stackAlphabet.find(*pushSymbol) == stackAlphabet.end()) {
throw AutomatonException("Stack symbol \"" + (std::string) *pushSymbol + "\" doesn't exist.");
}
}
std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol> key(from, input, pop);
std::pair<automaton::State, std::vector<alphabet::Symbol> > value = std::make_pair(to, push);
return transitions[key].insert(value).second;
}
bool SinglePopNPDA::addTransition(const State& from, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
std::variant<string::Epsilon, alphabet::Symbol> inputVariant;
inputVariant.set<alphabet::Symbol>(input);
return addTransition(from, inputVariant, pop, to, push);
}
bool SinglePopNPDA::addTransition(const State& from, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
std::variant<string::Epsilon, alphabet::Symbol> inputVariant;
inputVariant.set<string::Epsilon>(string::Epsilon::EPSILON);
return addTransition(from, inputVariant, pop, to, push);
}
bool SinglePopNPDA::removeTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol> key(from, input, pop);
std::pair<automaton::State, std::vector<alphabet::Symbol> > value = std::make_pair(to, push);
return transitions[key].erase(value);
}
bool SinglePopNPDA::removeTransition(const State& from, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
std::variant<string::Epsilon, alphabet::Symbol> inputVariant;
inputVariant.set<alphabet::Symbol>(input);
return removeTransition(from, inputVariant, pop, to, push);
}
bool SinglePopNPDA::removeTransition(const State& from, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
std::variant<string::Epsilon, alphabet::Symbol> inputVariant;
inputVariant.set<string::Epsilon>(string::Epsilon::EPSILON);
return removeTransition(from, inputVariant, pop, to, push);
}
const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::set<std::pair<State, std::vector<alphabet::Symbol> > > >& SinglePopNPDA::getTransitions() const {
return transitions;
}
bool SinglePopNPDA::operator==(const AutomatonBase& other) const {
return other == *this;
}
bool SinglePopNPDA::operator==(const SinglePopNPDA& other) const {
return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->stackAlphabet == other.stackAlphabet && this->initialSymbols == other.initialSymbols && this->transitions == other.transitions;
}
void SinglePopNPDA::operator>>(std::ostream& out) const {
out << "(SinglePopNPDA"
<< "states = " << states
<< "inputAlphabet = " << inputAlphabet
<< "initialStates = " << initialStates
<< "finalStates = " << finalStates
<< "stackAlphabet = " << stackAlphabet
<< "initialSymbols = " << initialSymbols
<< "transitions = " << transitions
<< ")";
}
} /* namespace automaton */