Skip to content
Snippets Groups Projects
NFA.cpp 4.71 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * NFA.cpp
     *
     *  Created on: Mar 25, 2013
     *      Author: Jan Travnicek
     */
    
    #include "NFA.h"
    #include "../AutomatonException.h"
    #include <ostream>
    
    namespace automaton {
    
    
    AutomatonBase* NFA::clone() const {
    	return new NFA(*this);
    }
    
    AutomatonBase* NFA::plunder() && {
    	return new NFA(std::move(*this));
    }
    
    
    bool NFA::removeState(const State& state) {
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    	if (initialStates.find(state) != initialStates.end()) {
    		throw AutomatonException("State \"" + state.getName() + "\" is initial state.");
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    	if (finalStates.find(state) != finalStates.end()) {
    		throw AutomatonException("State \"" + state.getName() + "\" is final state.");
    
    	}
    
    	for (std::map<std::pair<State, alphabet::Symbol>, std::set<State> >::const_iterator t = transitions.begin(); t != transitions.end(); t++) {
    		if (t->first.first == state || t->second.find(state) != t->second.end())
    			throw AutomatonException("State \"" + state.getName() + "\" is used in transition.");
    	}
    
    
    	return states.erase(state);
    
    bool NFA::removeInputSymbol(const alphabet::Symbol& symbol) {
    
    	for (std::map<std::pair<State, alphabet::Symbol>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end();
    			transition++) {
    		if (transition->first.second == symbol)
    
    			throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used.");
    
    	return inputAlphabet.erase(symbol);
    
    bool NFA::addTransition(const State& from, const alphabet::Symbol& input, const State& to) {
    
    	if (states.find(from) == states.end())
    		throw AutomatonException("State \"" + from.getName() + "\" doesn't exist.");
    
    	if (inputAlphabet.find(input) == inputAlphabet.end())
    
    		throw AutomatonException("Input symbol \"" + (std::string) input + "\" doesn't exist.");
    
    
    	if (states.find(to) == states.end())
    		throw AutomatonException("State \"" + to.getName() + "\" doesn't exist.");
    
    	std::pair<State, alphabet::Symbol> key = std::make_pair(from, input);
    	
    
    	return transitions[key].insert(to).second;
    
    bool NFA::removeTransition(const State& from, const alphabet::Symbol& input, const State& to) {
    
    	std::pair<State, alphabet::Symbol> key = std::make_pair(from, input);
    	
    
    	return transitions[key].erase(to);
    
    }
    
    const std::map<std::pair<State, alphabet::Symbol>, std::set<State> >& NFA::getTransitions() const {
    	return transitions;
    }
    
    std::map<std::pair<State, alphabet::Symbol>, std::set<State> > NFA::getTransitionsFromState(const State& from) const {
    	if( states.find(from) == states.end())
    		throw AutomatonException("State \"" + from.getName() + "\" doesn't exist");
    
    	std::map<std::pair<State, alphabet::Symbol>, std::set<State> > transitionsFromState;
    	for (std::map<std::pair<State, alphabet::Symbol>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end();
    			transition++) {
    		if (transition->first.first == from) {
    			transitionsFromState[transition->first].insert(transition->second.begin(), transition->second.end());
    		}
    	}
    
    	return transitionsFromState;
    }
    
    std::map<std::pair<State, alphabet::Symbol>, std::set<State> > NFA::getTransitionsToState(const State& to) const {
    	if( states.find(to) == states.end())
    		throw AutomatonException("State \"" + to.getName() + "\" doesn't exist");
    
    	std::map<std::pair<State, alphabet::Symbol>, std::set<State> > transitionsToState;
    	for (std::map<std::pair<State, alphabet::Symbol>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end();
    			transition++) {
    		if (transition->second.find(to) != transition->second.end()) {
    			transitionsToState[transition->first].insert(transition->second.begin(), transition->second.end());
    		}
    	}
    
    	return transitionsToState;
    }
    
    bool NFA::isDeterministic() const {
    	if (initialStates.size() != 1) {
    		return false;
    	}
    
    	for (std::map<std::pair<State, alphabet::Symbol>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end();
    			transition++) {
    		if (transition->second.size() != 1 || transition->second.size() != 0) {
    			return false;
    		}
    	}
    
    	return true;
    }
    
    bool NFA::isTotal() const {
    	return isDeterministic() && transitions.size() == inputAlphabet.size() * states.size();
    }
    
    
    bool NFA::operator==(const AutomatonBase& other) const {
    
    	return other == *this;
    }
    
    bool NFA::operator==(const NFA& other) const {
    	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->transitions == other.transitions;
    }
    
    void NFA::operator>>(std::ostream& out) const {
    	out << "(NFA"
    		<< " states = " << states
    		<< " inputAlphabet = " << inputAlphabet
    		<< " initialStates = " << initialStates
    		<< " finalStates = " << finalStates
    		<< " transitions = " << transitions
    		<< ")";
    }
    
    
    } /* namespace automaton */