diff --git a/alib2/src/automaton/Automaton.cpp b/alib2/src/automaton/Automaton.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dcf865a23651aa6f7dcf59481b098db1d412b915 --- /dev/null +++ b/alib2/src/automaton/Automaton.cpp @@ -0,0 +1,120 @@ +/* + * Automaton.cpp + * + * Created on: Apr 16, 2013 + * Author: martin + */ + +#include "Automaton.h" + +#include <set> +#include "exception/AutomatonException.h" + +namespace automaton { + +Automaton::~Automaton() { + +} + +void Automaton::addState(const State& state) { + pair<set<State>::iterator, bool> ret = states.insert(state); + if (!ret.second) + throw AutomatonException("State \"" + state.getName() + "\" already exists."); +} + +const set<State>& Automaton::getStates() const { + return states; +} + +void Automaton::addInputSymbol(const Symbol& symbol) { + pair<set<Symbol>::iterator, bool> ret = inputAlphabet.insert(symbol); + if (!ret.second) + throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" already exists."); +} + +const set<Symbol>& Automaton::getInputAlphabet() const { + return inputAlphabet; +} + +void Automaton::addInitialState(const State& state) { + pair<set<State>::iterator, bool> ret = initialStates.insert(state); + if (!ret.second) + throw AutomatonException("State \"" + state.getName() + "\" is already initial state."); +} + +void Automaton::removeInitialState(const State& state) { + if (states.find(state) == states.end()) { + throw AutomatonException("State cannot be set as initial state. It is not present in the automaton."); + } + + int removed = initialStates.erase(state); + if (!removed) + throw AutomatonException("State \"" + state.getName() + "\" isn't initial state."); + +} + +const set<State>& Automaton::getInitialStates() const { + return initialStates; +} + +void Automaton::addFinalState(const State& state) { + if (states.find(state) == states.end()) { + throw AutomatonException("State cannot be set as final state. It is not present in the automaton."); + } + + pair<set<State>::iterator, bool> ret = finalStates.insert(state); + if (!ret.second) + throw AutomatonException("State \"" + state.getName() + "\" is already final state."); +} + +void Automaton::removeFinalState(const State& state) { + int removed = finalStates.erase(state); + if (!removed) + throw AutomatonException("State \"" + state.getName() + "\" isn't final state."); +} + +const set<State>& Automaton::getFinalStates() const { + return finalStates; +} + +const State& Automaton::createUniqueState(const string& name, bool integerSuffix){ + try{ + State uniqueState(name); + addState(uniqueState); + return * states.find(uniqueState); + } + catch(AutomatonException& e){ + } + + int i = 0; + string str = name; + + while(i < INT_MAX) + { + if(integerSuffix) + str = name + std::to_string(i++); + else + str += '\''; + + State uniqueState(str); + try{ + addState(uniqueState); + } + catch(AutomatonException& e){ + continue; + } + + return * states.find(uniqueState); + } + + throw AutomatonException("Could not create unique state with name " + name + "." ); +} + +ostream& operator <<(ostream& out, const Automaton& automaton) { + automaton.toXML(out); + return out; +} + +} /* namespace automaton */ + + diff --git a/alib2/src/automaton/Automaton.h b/alib2/src/automaton/Automaton.h new file mode 100644 index 0000000000000000000000000000000000000000..b7a41b9ce0211b972be1d74333c08482f50dc931 --- /dev/null +++ b/alib2/src/automaton/Automaton.h @@ -0,0 +1,140 @@ +/* + * Automaton.h + * + * Created on: Apr 10, 2013 + * Author: martin + */ + +#ifndef AUTOMATON_H_ +#define AUTOMATON_H_ + +#include <climits> +#include <ostream> +#include <set> +#include <string> +#include "State.h" +#include "../alphabet/Symbol.h" + + +namespace automaton { + +using namespace std; +using namespace alphabet; + +/** + * Abstract base class for all automatons. Contains common elements of automatons. + */ +class Automaton { +protected: + set<State> states; + set<Symbol> inputAlphabet; + set<State> initialStates; + set<State> finalStates; +public: + virtual ~Automaton(); + + /** + * Adds new state to the automaton. + * @param state State to add + * @throws AutomatonException when state already exist in the automaton + */ + void addState(const State& state); + + /** + * Removes the state from the automaton. + * @param state State to remove + * @throws AutomatonException when state is not part of the automaton, + * is set as initial or final or when it's used in a transition + */ + virtual void removeState(const State& state) = 0; + + /** + * @return list of states + */ + const set<State>& getStates() const; + + /** + * Adds input symbol to input alphabet. + * @param symbol Symbol to add + * @throws AutomatonException when symbol already exists + */ + virtual void addInputSymbol(const Symbol& symbol); + + /** + * Removes input symbol from the input alphabet. + * @param symbol Symbol to remove + * @throws AutomatonException when symbol is not present in input alphabet + * or when symbol is part of the transition + */ + virtual void removeInputSymbol(const Symbol& symbol) = 0; + + /** + * @return the input alphabet + */ + const set<Symbol>& getInputAlphabet() const; + + /** + * Adds the State to the initial states. + * @param state State to add + * @throws AutomatonException when state is not present + * in the automaton or when it's already initial state + */ + void addInitialState(const State& state); + + /** + * Removes the state from the initial states. + * @param state State to remove + * @throws AutomatonException when State is not initial state + */ + virtual void removeInitialState(const State& state); + + /** + * @return initial states + */ + const set<State>& getInitialStates() const; + + /** + * Adds the State to the final states. + * @param state State to add + * @throws AutomatonException when state is not present + * in the automaton or when it's already final state + */ + void addFinalState(const State& state); + + /** + * Removes the state from the final states. + * @param state State to remove + * @throws AutomatonException when State is not final state + */ + virtual void removeFinalState(const State& state); + + /** + * @return final states + */ + const set<State>& getFinalStates() const; + + /** + * Creates and adds unique state to automaton. If given state name is + * already used, appends apostrophe or integer suffix + * @param name name of the state + * @throws AutomatonException if state could not be created + * @return created state + */ + const State& createUniqueState(const std::string& name, bool integerSuffix = false); + + /** + * Prints XML representation of the automaton to the ostream. + * @param out output stream to which print the automaton + */ + virtual void toXML(ostream& out) const = 0; + + /** + * Prints XML representation of the automaton to the ostream. + * @param out output stream to which print the automaton + * @param automaton automaton to print + */ + friend ostream& operator<<(ostream& out, const Automaton& automaton); +}; + +} /* namespace automaton */ +#endif /* AUTOMATON_H_ */ diff --git a/alib2/src/automaton/AutomatonParser.cpp b/alib2/src/automaton/AutomatonParser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..425621665ad09a93d2a6c3caf967f96b1c74cac8 --- /dev/null +++ b/alib2/src/automaton/AutomatonParser.cpp @@ -0,0 +1,244 @@ +/* + * AutomatonParser.cpp + * + * Created on: Oct 12, 2013 + * Author: Martin Zak + */ + +#include "AutomatonParser.h" + +#include "../sax/ParserException.h" +#include "Shift.h" + +namespace automaton { + +using namespace std; +using namespace sax; + +UnknownAutomaton AutomatonParser::parse(list<Token> &input) { + UnknownAutomaton automaton; + + popToken(input, Token::START_ELEMENT, "automaton"); + + while (true) { + if (isToken(input, Token::END_ELEMENT, "automaton")) { + break; + } else if (isToken(input, Token::START_ELEMENT, "states")) { + parseStates(input, automaton); + } else if (isToken(input, Token::START_ELEMENT, "inputAlphabet")) { + parseInputAlphabet(input, automaton); + } else if (isToken(input, Token::START_ELEMENT, "initialStates")) { + parseInitialStates(input, automaton); + } else if (isToken(input, Token::START_ELEMENT, "finalStates")) { + parseFinalStates(input, automaton); + } else if (isToken(input, Token::START_ELEMENT, "stackAlphabet")) { + parseStackAlphabet(input, automaton); + } else if (isToken(input, Token::START_ELEMENT, "startSymbols")) { + parseStartSymbols(input, automaton); + } else if (isToken(input, Token::START_ELEMENT, "tapeAlphabet")) { + parseTapeAlphabet(input, automaton); + } else if (isToken(input, Token::START_ELEMENT, "blankSymbol")) { + parseBlankSymbol(input, automaton); + } else if (isToken(input, Token::START_ELEMENT, "transitions")) { + parseTransitions(input, automaton); + + } else { + throw ParserException(Token("automaton", Token::END_ELEMENT), input.front()); + } + } + + popToken(input, Token::END_ELEMENT, "automaton"); + return automaton; +} + +void AutomatonParser::parseStates(list<Token> &input, UnknownAutomaton& automaton) { + popToken(input, Token::START_ELEMENT, "states"); + while (isToken(input, Token::START_ELEMENT, "state")) { + automaton.addState(parseState(input)); + } + popToken(input, Token::END_ELEMENT, "states"); +} + +void AutomatonParser::parseInputAlphabet(list<Token> &input, UnknownAutomaton& automaton) { + popToken(input, Token::START_ELEMENT, "inputAlphabet"); + while (isToken(input, Token::START_ELEMENT, "symbol")) { + automaton.addInputSymbol(parseSymbol(input)); + } + popToken(input, Token::END_ELEMENT, "inputAlphabet"); +} + +void AutomatonParser::parseInitialStates(list<Token> &input, UnknownAutomaton& automaton) { + popToken(input, Token::START_ELEMENT, "initialStates"); + while (isToken(input, Token::START_ELEMENT, "state")) { + automaton.addInitialState(parseState(input)); + } + popToken(input, Token::END_ELEMENT, "initialStates"); +} + +void AutomatonParser::parseFinalStates(list<Token> &input, UnknownAutomaton& automaton) { + popToken(input, Token::START_ELEMENT, "finalStates"); + while (isToken(input, Token::START_ELEMENT, "state")) { + automaton.addFinalState(parseState(input)); + } + popToken(input, Token::END_ELEMENT, "finalStates"); +} + +void AutomatonParser::parseStackAlphabet(list<Token> &input, UnknownAutomaton& automaton) { + popToken(input, Token::START_ELEMENT, "stackAlphabet"); + while (isToken(input, Token::START_ELEMENT, "symbol")) { + automaton.addStackSymbol(parseSymbol(input)); + } + popToken(input, Token::END_ELEMENT, "stackAlphabet"); +} + +void AutomatonParser::parseStartSymbols(list<Token> &input, UnknownAutomaton& automaton) { + popToken(input, Token::START_ELEMENT, "startSymbols"); + list<Symbol> startSymbols; + while (isToken(input, Token::START_ELEMENT, "symbol")) { + startSymbols.push_back(parseSymbol(input)); + } + automaton.setStartSymbols(startSymbols); + popToken(input, Token::END_ELEMENT, "startSymbols"); +} + +void AutomatonParser::parseTapeAlphabet(list<Token>& input, UnknownAutomaton& automaton) { + popToken(input, Token::START_ELEMENT, "tapeAlphabet"); + while (isToken(input, Token::START_ELEMENT, "symbol")) { + automaton.addTapeSymbol(parseSymbol(input)); + } + popToken(input, Token::END_ELEMENT, "tapeAlphabet"); +} + +void AutomatonParser::parseBlankSymbol(list<Token>& input, UnknownAutomaton& automaton) { + popToken(input, Token::START_ELEMENT, "blankSymbol"); + if (input.front().getType() == Token::CHARACTER) { + automaton.setBlankSymbol(Symbol(input.front().getData())); + input.pop_front(); + } else { + throw ParserException(Token("", Token::CHARACTER), input.front()); + } + popToken(input, Token::END_ELEMENT, "blankSymbol"); +} + +void AutomatonParser::parseTransitions(list<Token> &input, UnknownAutomaton& automaton) { + popToken(input, Token::START_ELEMENT, "transitions"); + while (isToken(input, Token::START_ELEMENT, "transition")) { + automaton.addTransition(parseTransition(input)); + } + popToken(input, Token::END_ELEMENT, "transitions"); +} + +void AutomatonParser::parsePop(list<Token>& input, UnknownTransition* transition) { + popToken(input, Token::START_ELEMENT, "pop"); + while (isToken(input, Token::START_ELEMENT, "symbol")) { + transition->addPop(parseSymbol(input)); + } + popToken(input, Token::END_ELEMENT, "pop"); +} + +void AutomatonParser::parsePush(list<Token>& input, UnknownTransition* transition) { + popToken(input, Token::START_ELEMENT, "push"); + while (isToken(input, Token::START_ELEMENT, "symbol")) { + transition->addPush(parseSymbol(input)); + } + popToken(input, Token::END_ELEMENT, "push"); +} + +State AutomatonParser::parseState(list<Token> &input, string tagName) { + popToken(input, Token::START_ELEMENT, tagName); + + if (input.front().getType() == Token::CHARACTER) { + State state(input.front().getData()); + input.pop_front(); + popToken(input, Token::END_ELEMENT, tagName); + return state; + } else { + throw ParserException(Token("", Token::CHARACTER), input.front()); + } +} + +Symbol AutomatonParser::parseSymbol(list<Token>& input, string tagName) { + popToken(input, Token::START_ELEMENT, tagName); + + if (input.front().getType() == Token::CHARACTER) { + Symbol symbol(input.front().getData()); + input.pop_front(); + popToken(input, Token::END_ELEMENT, tagName); + return symbol; + } else if(isToken(input,Token::END_ELEMENT, tagName)){ + input.pop_front(); + return Symbol(""); + } else if(isToken(input,Token::START_ELEMENT, "eps")) { + input.pop_front(); + popToken(input, Token::END_ELEMENT,"eps"); + popToken(input, Token::END_ELEMENT, tagName); + return Symbol(""); + } else { + throw ParserException(Token("", Token::CHARACTER), input.front()); + } +} + +Shift AutomatonParser::parseShift(list<Token>& input) { + Shift shift; + + popToken(input, Token::START_ELEMENT, "shift"); + if (input.front().getType() == Token::CHARACTER) { + if (input.front().getData() == "left") + shift = LEFT; + if (input.front().getData() == "right") + shift = RIGHT; + if (input.front().getData() == "none") + shift = NONE; + input.pop_front(); + } else { + throw sax::ParserException(sax::Token("", sax::Token::CHARACTER), input.front()); + } + popToken(input, Token::END_ELEMENT, "shift"); + + return shift; + +} + +UnknownTransition AutomatonParser::parseTransition(list<Token>& input) { + UnknownTransition transition; + + popToken(input, Token::START_ELEMENT, "transition"); + while (true) { + if (isToken(input, Token::END_ELEMENT, "transition")) { + break; + } else if (isToken(input, Token::START_ELEMENT, "from")) { + transition.setFrom(parseState(input, "from")); + } else if (isToken(input, Token::START_ELEMENT, "input")) { + transition.setInput(parseSymbol(input, "input")); + } else if (isToken(input, Token::START_ELEMENT, "to")) { + transition.setTo(parseState(input, "to")); + } else if (isToken(input, Token::START_ELEMENT, "pop")) { + parsePop(input, &transition); + } else if (isToken(input, Token::START_ELEMENT, "push")) { + parsePush(input, &transition); + } else if (isToken(input, Token::START_ELEMENT, "output")) { + transition.setOutput(parseSymbol(input, "output")); + } else if (isToken(input, Token::START_ELEMENT, "shift")) { + transition.setShift(parseShift(input)); + } else { + throw ParserException(Token("transitions", Token::END_ELEMENT), input.front()); + } + } + popToken(input, Token::END_ELEMENT, "transition"); + + return transition; +} + +bool AutomatonParser::isToken(list<Token>& input, Token::TokenType type, string data) { + return input.front().getType() == type && input.front().getData() == data; +} + +void AutomatonParser::popToken(list<Token>& input, Token::TokenType type, string data) { + if (isToken(input, type, data)) { + input.pop_front(); + } else { + throw ParserException(Token(data, type), input.front()); + } +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/AutomatonParser.h b/alib2/src/automaton/AutomatonParser.h new file mode 100644 index 0000000000000000000000000000000000000000..e0ba16477108371befe7a22a584019e82c172727 --- /dev/null +++ b/alib2/src/automaton/AutomatonParser.h @@ -0,0 +1,59 @@ +/* + * AutomatonParser.h + * + * Created on: Oct 12, 2013 + * Author: martin + */ + +#ifndef AUTOMATONPARSER_H_ +#define AUTOMATONPARSER_H_ + +#include "UnknownAutomaton.h" + +#include <list> +#include <set> +#include "../sax/Token.h" + +namespace automaton { + +using namespace std; +using namespace sax; + +/** + * Parser used to get UnknownAutomaton from XML parsed into list of Tokens. + */ +class AutomatonParser { +protected: + static void parseStates(list<Token> &input, UnknownAutomaton& automaton); + static void parseInputAlphabet(list<Token> &input, UnknownAutomaton& automaton); + static void parseInitialStates(list<Token> &input, UnknownAutomaton& automaton); + static void parseFinalStates(list<Token> &input, UnknownAutomaton& automaton); + static void parseStackAlphabet(list<Token> &input, UnknownAutomaton& automaton); + static void parseStartSymbols(list<Token> &input, UnknownAutomaton& automaton); + static void parseTapeAlphabet(list<Token> &input, UnknownAutomaton& automaton); + static void parseBlankSymbol(list<Token> &input, UnknownAutomaton& automaton); + + static void parseTransitions(list<Token> &input, UnknownAutomaton& automaton); + static UnknownTransition parseTransition(list<Token>& input); + static void parsePop(list<Token>& input, UnknownTransition* transition); + static void parsePush(list<Token>& input, UnknownTransition* transition); + + static State parseState(list<Token> &input, string tagName = "state"); + static Symbol parseSymbol(list<Token> &input, string tagName = "symbol"); + static Shift parseShift(list<Token> &input); + + static bool isToken(list<Token> &input, Token::TokenType type, string data); + static void popToken(list<Token> &input, Token::TokenType type, string data); + +public: + /** + * Parses the xml and returns the automaton. The input is destroyed in the process. + * @param input XML represented as list of Tokens + * @return UnknownAutomaton + * @throws ParserException when an error occurs + */ + static UnknownAutomaton parse(list<Token> &input); +}; + +} /* namespace automaton */ +#endif /* AUTOMATONPARSER_H_ */ diff --git a/alib2/src/automaton/AutomatonPrinter.cpp b/alib2/src/automaton/AutomatonPrinter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..62bafb9c3d668ce21526f1da9cc1f73ba7bfb95a --- /dev/null +++ b/alib2/src/automaton/AutomatonPrinter.cpp @@ -0,0 +1,212 @@ +/* + * AutomatonPrinter.cpp + * + * Created on: Nov 11, 2013 + * Author: martin + */ + +#include "AutomatonPrinter.h" + +namespace automaton { + +const string AutomatonPrinter::INDENTATION = "\t"; + +void AutomatonPrinter::printStates(const set<State>& states, ostream& out, string tagName, string prefix) { + out << prefix << "<" << tagName << ">\n"; + for (auto state : states) { + printState(state, out, "state", prefix + INDENTATION); + } + out << prefix << "</" << tagName << ">\n"; +} + +void AutomatonPrinter::printAlphabet(const set<Symbol>& alphabet, ostream& out, string tagName, string prefix) { + out << prefix << "<" << tagName << ">\n"; + for (auto symbol : alphabet) { + printSymbol(symbol, out, "symbol", prefix + INDENTATION); + } + out << prefix << "</" << tagName << ">\n"; +} + +void AutomatonPrinter::printUnknownTransitions(const set<UnknownTransition>& transitions, ostream& out, string prefix) { + string contentPrefix = prefix + INDENTATION + INDENTATION; + + out << prefix << "<transitions>\n"; + for (auto transition : transitions) { + out << prefix << INDENTATION << "<transition>\n"; + printState(transition.getFrom(), out, "from", contentPrefix); + printSymbol(transition.getInput(), out, "input", contentPrefix); + printState(transition.getTo(), out, "to", contentPrefix); + + if (transition.getPop().size() > 0) { + printSymbolList(transition.getPop(), out, "pop", contentPrefix); + } + if (transition.getPush().size() > 0) { + printSymbolList(transition.getPush(), out, "push", contentPrefix); + } + + if (transition.getOutput().getSymbol() != "") { + printSymbol(transition.getOutput(), out, "output", contentPrefix); + } + + if (transition.getShift() != Shift::NOT_SET) { + printShift(transition.getShift(), out, "shift", contentPrefix); + } + + out << prefix << INDENTATION << "</transition>\n"; + } + + out << prefix << "</transitions>\n"; +} + +void AutomatonPrinter::printTransitionsFSM(const std::set<automaton::TransitionFSM*, automaton::TransitionFSM::TransitionFSMPointerLess>& transitions, ostream& out, string prefix) { + string contentPrefix = prefix + INDENTATION + INDENTATION; + + out << prefix << "<transitions>\n"; + for (auto transition : transitions) { + out << prefix << INDENTATION << "<transition>\n"; + printState(transition->getFrom(), out, "from", contentPrefix); + if(dynamic_cast<TransitionFSMSymbol*>(transition)) printSymbol(((TransitionFSMSymbol*) transition)->getInput(), out, "input", contentPrefix); + printState(transition->getTo(), out, "to", contentPrefix); + out << prefix << INDENTATION << "</transition>\n"; + } + out << prefix << "</transitions>\n"; +} + +void AutomatonPrinter::printTransitionsPDA(const set<TransitionPDA>& transitions, ostream& out, string prefix) { + string contentPrefix = prefix + INDENTATION + INDENTATION; + + out << prefix << "<transitions>\n"; + for (auto transition : transitions) { + out << prefix << INDENTATION << "<transition>\n"; + printState(transition.getFrom(), out, "from", contentPrefix); + printSymbol(transition.getInput(), out, "input", contentPrefix); + printState(transition.getTo(), out, "to", contentPrefix); + printSymbolList(transition.getPop(), out, "pop", contentPrefix); + printSymbolList(transition.getPush(), out, "push", contentPrefix); + out << prefix << INDENTATION << "</transition>\n"; + } + out << prefix << "</transitions>\n"; +} + +void AutomatonPrinter::printTransitionsTM(const set<TransitionTM>& transitions, ostream& out, string prefix) { + string contentPrefix = prefix + INDENTATION + INDENTATION; + + out << prefix << "<transitions>\n"; + for (auto transition : transitions) { + out << prefix << INDENTATION << "<transition>\n"; + printState(transition.getFrom(), out, "from", contentPrefix); + printSymbol(transition.getInput(), out, "input", contentPrefix); + printState(transition.getTo(), out, "to", contentPrefix); + printSymbol(transition.getOutput(), out, "output", contentPrefix); + printShift(transition.getShift(), out, "shift", contentPrefix); + out << prefix << INDENTATION << "</transition>\n"; + } + out << prefix << "</transitions>\n"; +} + +void AutomatonPrinter::printState(const State& state, ostream& out, string tagName, string prefix) { + out << prefix << "<" << tagName << ">"; + out << state.getName(); + out << "</" << tagName << ">\n"; +} + +void AutomatonPrinter::printSymbol(const Symbol& symbol, ostream& out, string tagName, string prefix) { + out << prefix << "<" << tagName << ">"; + out << symbol.getSymbol(); + out << "</" << tagName << ">\n"; +} + +void AutomatonPrinter::printSymbolList(const list<Symbol>& symbols, ostream& out, string tagName, string prefix) { + out << prefix << "<" << tagName << ">\n"; + for (auto symbol : symbols) { + printSymbol(symbol, out, "symbol", prefix + INDENTATION); + } + out << prefix << "</" << tagName << ">\n"; +} + +void AutomatonPrinter::printShift(const Shift& shift, ostream& out, string tagName, string prefix) { + out << prefix << "<" << tagName << ">"; + out << (std::string[] ) { "left", "right", "none" } [shift]; + out << "</" << tagName << ">\n"; +} + +void AutomatonPrinter::toXML(const UnknownAutomaton& automaton, ostream& out) { + out << "<automaton>\n"; + + if (automaton.getStates().size() > 0) { + printStates(automaton.getStates(), out, "states", INDENTATION); + } + + if (automaton.getInputAlphabet().size() > 0) { + printAlphabet(automaton.getInputAlphabet(), out, "inputAlphabet", INDENTATION); + } + if (automaton.getTapeAlphabet().size() > 0) { + printAlphabet(automaton.getTapeAlphabet(), out, "tapeAlphabet", INDENTATION); + } + if (automaton.getStackAlphabet().size() > 0) { + printAlphabet(automaton.getStackAlphabet(), out, "stackAlphabet", INDENTATION); + } + + if (automaton.getTransitions().size() > 0) { + printUnknownTransitions(automaton.getTransitions(), out, INDENTATION); + } + + if (automaton.getBlankSymbol().getSymbol() != "") { + printSymbol(automaton.getBlankSymbol(), out, "blankSymbol", INDENTATION); + } + if (automaton.getStartSymbols().size() > 0) { + printSymbolList(automaton.getStartSymbols(), out, "startSymbols", INDENTATION); + } + + if (automaton.getInitialStates().size() > 0) { + printStates(automaton.getInitialStates(), out, "initialStates", INDENTATION); + } + if (automaton.getFinalStates().size() > 0) { + printStates(automaton.getFinalStates(), out, "finalStates", INDENTATION); + } + + out << "</automaton>\n"; + +} + +void AutomatonPrinter::toXML(const FSM& automaton, ostream& out) { + out << "<automaton>\n"; + printStates(automaton.getStates(), out, "states", INDENTATION); + printAlphabet(automaton.getInputAlphabet(), out, "inputAlphabet", INDENTATION); + printTransitionsFSM(automaton.getTransitions(), out, INDENTATION); + printStates(automaton.getInitialStates(), out, "initialStates", INDENTATION); + printStates(automaton.getFinalStates(), out, "finalStates", INDENTATION); + out << "</automaton>\n"; +} + +void AutomatonPrinter::toXML(const ExtendedFSM& automaton, ostream& out) { + out << "<automaton>\n"; + out << "</automaton>\n"; +} + +void AutomatonPrinter::toXML(const PDA& automaton, ostream& out) { + out << "<automaton>\n"; + printStates(automaton.getStates(), out, "states", INDENTATION); + printAlphabet(automaton.getInputAlphabet(), out, "inputAlphabet", INDENTATION); + printAlphabet(automaton.getStackAlphabet(), out, "stackAlphabet", INDENTATION); + printTransitionsPDA(automaton.getTransitions(), out, INDENTATION); + printSymbolList(automaton.getStartSymbols(), out, "startSymbols", INDENTATION); + printStates(automaton.getInitialStates(), out, "initialStates", INDENTATION); + printStates(automaton.getFinalStates(), out, "finalStates", INDENTATION); + out << "</automaton>\n"; +} + +void AutomatonPrinter::toXML(const TM& automaton, ostream& out) { + out << "<automaton>\n"; + printStates(automaton.getStates(), out, "states", INDENTATION); + printAlphabet(automaton.getTapeAlphabet(), out, "tapeAlphabet", INDENTATION); + printAlphabet(automaton.getInputAlphabet(), out, "inputAlphabet", INDENTATION); + printTransitionsTM(automaton.getTransitions(), out, INDENTATION); + printSymbol(automaton.getBlankSymbol(), out, "blankSymbol", INDENTATION); + printStates(automaton.getInitialStates(), out, "initialStates", INDENTATION); + printStates(automaton.getFinalStates(), out, "finalStates", INDENTATION); + out << "</automaton>\n"; +} + +} /* namespace automaton */ + diff --git a/alib2/src/automaton/AutomatonPrinter.h b/alib2/src/automaton/AutomatonPrinter.h new file mode 100644 index 0000000000000000000000000000000000000000..fb174c64285aa058be9df966817afc114a49b7ea --- /dev/null +++ b/alib2/src/automaton/AutomatonPrinter.h @@ -0,0 +1,81 @@ +/* + * AutomatonPrinter.h + * + * Created on: Nov 11, 2013 + * Author: martin + */ + +#ifndef AUTOMATONPRINTER_H_ +#define AUTOMATONPRINTER_H_ + +#include <ostream> +#include "UnknownAutomaton.h" +#include "FSM/ExtendedFSM.h" +#include "FSM/FSM.h" +#include "PDA/PDA.h" +#include "TM/TM.h" + +namespace automaton { + +using namespace std; + +/** + * This class contains methods to print XML representation of automata to the output stream. + */ +class AutomatonPrinter { +protected: + static const string INDENTATION; + + static void printStates(const set<State>& states, ostream& out, string tagName, string prefix); + static void printAlphabet(const set<Symbol>& alphabet, ostream& out, string tagName, string prefix); + + static void printUnknownTransitions(const set<UnknownTransition>& transitions, ostream& out, string prefix); + static void printTransitionsFSM(const std::set<automaton::TransitionFSM*, automaton::TransitionFSM::TransitionFSMPointerLess>& transitions, ostream& out, string prefix); + static void printTransitionsPDA(const set<TransitionPDA>& transitions, ostream& out, string prefix); + static void printTransitionsTM(const set<TransitionTM>& transitions, ostream& out, string prefix); + + + static void printState(const State& state, ostream& out, string tagName, string prefix); + static void printSymbol(const Symbol& symbol, ostream& out, string tagName, string prefix); + static void printSymbolList(const list<Symbol>& symbols, ostream& out, string tagName, string prefix); + static void printShift(const Shift& shift, ostream& out, string tagName, string prefix); + +public: + /** + * Prints XML representation of UnknownAutomaton to the output stream. + * @param automaton automaton to print + * @param out output stream to which print the automaton + */ + static void toXML(const UnknownAutomaton& automaton, ostream& out); + + /** + * Prints XML representation of FSM to the output stream. + * @param automaton automaton to print + * @param out output stream to which print the automaton + */ + static void toXML(const FSM& automaton, ostream& out); + + /** + * Prints XML representation of FSM to the output stream. + * @param automaton automaton to print + * @param out output stream to which print the automaton + */ + static void toXML(const ExtendedFSM& automaton, ostream& out); + + /** + * Prints XML representation of PDA to the output stream. + * @param automaton automaton to print + * @param out output stream to which print the automaton + */ + static void toXML(const PDA& automaton, ostream& out); + + /** + * Prints XML representation of TM to the output stream. + * @param automaton automaton to print + * @param out output stream to which print the automaton + */ + static void toXML(const TM& automaton, ostream& out); +}; + +} /* namespace automaton */ +#endif /* AUTOMATONPRINTER_H_ */ diff --git a/alib2/src/automaton/FSM/ExtendedFSM.cpp b/alib2/src/automaton/FSM/ExtendedFSM.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bba90def90e920070989c88552cb7f7f8a8b1e4c --- /dev/null +++ b/alib2/src/automaton/FSM/ExtendedFSM.cpp @@ -0,0 +1,127 @@ +/* + * FSM.cpp + * + * Created on: Mar 25, 2013 + * Author: martin + */ + +#include "ExtendedFSM.h" +#include "../AutomatonPrinter.h" +#include "../exception/AutomatonException.h" +#include <ostream> + +namespace automaton { + +using namespace std; +using namespace alphabet; + +ExtendedFSM::~ExtendedFSM() { + +} + +void ExtendedFSM::removeState(const State& state) { + for (set<State>::const_iterator initialState = initialStates.begin(); initialState != initialStates.end(); + initialState++) { + if (*initialState == state) { + throw AutomatonException("State \"" + state.getName() + "\" is initial state."); + } + } + + for (set<State>::const_iterator finalState = finalStates.begin(); finalState != finalStates.end(); finalState++) { + if (*finalState == state) { + throw AutomatonException("State \"" + state.getName() + "\" is final state."); + } + } + + for (set<TransitionFSMExtended>::const_iterator t = transitions.begin(); t != transitions.end(); t++) { + if (state == t->getFrom() || state == t->getTo()) + throw AutomatonException("State \"" + state.getName() + "\" is used in transition."); + } + + int removed = states.erase(state); + if (!removed) + throw AutomatonException("State \"" + state.getName() + "\" doesn't exist."); +} + +void ExtendedFSM::removeInputSymbol(const Symbol& symbol) { + for (set<TransitionFSMExtended>::const_iterator transition = transitions.begin(); transition != transitions.end(); + transition++) { + if (transition->isReading(symbol)) + throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" is used."); + } + + int removed = inputAlphabet.erase(symbol); + if (!removed) + throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" doesn't exist."); + +} + +void ExtendedFSM::addTransition(const State& from, const regexp::RegExp& input, const State& to) { + addTransition(TransitionFSMExtended(from, input, to)); +} + +void ExtendedFSM::addTransition(const TransitionFSMExtended& transition) { + const State& from = transition.getFrom(); + const regexp::RegExp& input = transition.getInput(); + const State& to = transition.getTo(); + + if (states.find(from) == states.end()) + throw AutomatonException("State \"" + from.getName() + "\" doesn't exist."); + + /*if (inputAlphabet.find(input) == inputAlphabet.end()) + throw AutomatonException("Input symbol \"" + input.getSymbol() + "\" doesn't exist.");*/ + + if (states.find(to) == states.end()) + throw AutomatonException("State \"" + to.getName() + "\" doesn't exist."); + + pair<set<TransitionFSMExtended>::iterator, bool> ret = transitions.insert(TransitionFSMExtended(transition)); + if (!ret.second) + throw AutomatonException( + "Transition (\"" + from.getName() + "\", \"Regexp\") -> \"" + to.getName() + + "\" already exists."); +} +void ExtendedFSM::removeTransition(const TransitionFSMExtended& transition) { + /*int removed = transitions.erase(transition); + if (!removed) + throw AutomatonException( + "Transition (\"" + transition.getFrom().getName() + "\", \"" + transition.getInput().getSymbol() + + "\") -> \"" + transition.getTo().getName() + "\" doesn't exist.");*/ +} + +const set<TransitionFSMExtended>& ExtendedFSM::getTransitions() const { + return transitions; +} + +const set<TransitionFSMExtended> ExtendedFSM::getTransitionsFromState(const State& from) const { + if( states.find(from) == states.end()) + throw AutomatonException("State \"" + from.getName() + "\" doesn't exist"); + + set<TransitionFSMExtended> transitionsFromState; + for(auto const & transition : transitions){ + if (transition.getFrom() == from){ + transitionsFromState.insert(transition); + } + } + + return transitionsFromState; +} + +const set<TransitionFSMExtended> ExtendedFSM::getTransitionsToState(const State& to) const { + if( states.find(to) == states.end()) + throw AutomatonException("State \"" + to.getName() + "\" doesn't exist"); + + set<TransitionFSMExtended> transitionsToState; + for(auto const& transition : transitions){ + if (transition.getTo() == to){ + transitionsToState.insert(transition); + } + } + + return transitionsToState; +} + +void ExtendedFSM::toXML(ostream& out) const { + AutomatonPrinter::toXML(*this, out); +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/ExtendedFSM.h b/alib2/src/automaton/FSM/ExtendedFSM.h new file mode 100644 index 0000000000000000000000000000000000000000..26d979d5e2f8aea0dba272a5d490616fd8bdb059 --- /dev/null +++ b/alib2/src/automaton/FSM/ExtendedFSM.h @@ -0,0 +1,91 @@ +/* + * EXTENDED_FSM.h + * + * Created on: Mar 25, 2013 + * Author: Jan TrávnĂÄŤek + */ + +#ifndef EXTENDED_FSM_H_ +#define EXTENDED_FSM_H_ + +#include <set> +#include "../Automaton.h" +#include "../State.h" +#include "../../alphabet/Symbol.h" +#include "../../regexp/RegExp.h" +#include "TransitionFSM.h" +#include "TransitionFSMExtended.h" +#include "TransitionFSMSymbol.h" +#include "TransitionFSMEpsilon.h" + +namespace automaton { + +using namespace std; +using namespace alphabet; + +/** + * Represents Finite State Machine. + * Can store nondeterministic finite state machines with epsilon transitions. + */ +class ExtendedFSM: public Automaton { +protected: + set<TransitionFSMExtended> transitions; +public: + ~ExtendedFSM(); + + /** + * @copydoc Automaton::removeState(const State&) + */ + virtual void removeState(const State& state); + + /** + * @copydoc Automaton::removeInputSymbol(const Symbol&) + */ + virtual void removeInputSymbol(const Symbol& symbol); + + /** + * Adds transition defined by parameters to the automaton. + * @param current current state + * @param input input regexp + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + void addTransition(const State& from, const regexp::RegExp& input, const State& to); + + /** + * Adds transition to the automaton. + * @param transition transition to add + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + void addTransition(const TransitionFSMExtended& transition); + + /** + * Removes transition from the automaton. + * @param transition transition to remove + * @throws AutomatonException when transition doesn't exists. + */ + void removeTransition(const TransitionFSMExtended& transition); + + /** + * @return automaton transitions + */ + const set<TransitionFSMExtended>& getTransitions() const; + + /** + * @return automaton transitions from state + */ + const set<TransitionFSMExtended> getTransitionsFromState(const State& from) const; + + /** + * @return automaton transitions to state + */ + const set<TransitionFSMExtended> getTransitionsToState(const State& to) const; + + /** + * @copydoc Automaton::toXML(ostream&) const + */ + virtual void toXML(ostream& out) const; +}; + +} /* namespace automaton */ +#endif /* EXTENDED_FSM_H_ */ diff --git a/alib2/src/automaton/FSM/FSM.cpp b/alib2/src/automaton/FSM/FSM.cpp new file mode 100644 index 0000000000000000000000000000000000000000..538cb964d01e94726372678074334473f599bcce --- /dev/null +++ b/alib2/src/automaton/FSM/FSM.cpp @@ -0,0 +1,196 @@ +/* + * FSM.cpp + * + * Created on: Mar 25, 2013 + * Author: martin + */ + +#include "FSM.h" +#include "../AutomatonPrinter.h" +#include "../exception/AutomatonException.h" +#include <ostream> + +namespace automaton { + +using namespace std; +using namespace alphabet; + +FSM::~FSM() { + for(auto const & transition : transitions){ + delete transition; + } +} + +void FSM::removeState(const State& state) { + for (set<State>::const_iterator initialState = initialStates.begin(); initialState != initialStates.end(); + initialState++) { + if (*initialState == state) { + throw AutomatonException("State \"" + state.getName() + "\" is initial state."); + } + } + + for (set<State>::const_iterator finalState = finalStates.begin(); finalState != finalStates.end(); finalState++) { + if (*finalState == state) { + throw AutomatonException("State \"" + state.getName() + "\" is final state."); + } + } + + for (set<TransitionFSM*, TransitionFSM::TransitionFSMPointerLess>::const_iterator t = transitions.begin(); t != transitions.end(); t++) { + if (state == (*t)->getFrom() || state == (*t)->getTo()) + throw AutomatonException("State \"" + state.getName() + "\" is used in transition."); + } + + int removed = states.erase(state); + if (!removed) + throw AutomatonException("State \"" + state.getName() + "\" doesn't exist."); +} + +void FSM::removeInputSymbol(const Symbol& symbol) { + for (set<TransitionFSM*, TransitionFSM::TransitionFSMPointerLess>::const_iterator transition = transitions.begin(); transition != transitions.end(); + transition++) { + if ((*transition)->isReading(symbol)) + throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" is used."); + } + + int removed = inputAlphabet.erase(symbol); + if (!removed) + throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" doesn't exist."); + +} + +void FSM::addTransition(const State& from, const Symbol& input, const State& to) { + addTransition(TransitionFSMSymbol(from, input, to)); +} + +void FSM::addTransition(const State& from, const State& to) { + addTransition(TransitionFSMEpsilon(from, to)); +} + +void FSM::addTransition(const TransitionFSMSymbol& transition) { + const State& from = transition.getFrom(); + const Symbol& input = transition.getInput(); + const State& to = transition.getTo(); + + if (states.find(from) == states.end()) + throw AutomatonException("State \"" + from.getName() + "\" doesn't exist."); + + if (inputAlphabet.find(input) == inputAlphabet.end()) + throw AutomatonException("Input symbol \"" + input.getSymbol() + "\" doesn't exist."); + + if (states.find(to) == states.end()) + throw AutomatonException("State \"" + to.getName() + "\" doesn't exist."); + + pair<set<TransitionFSM*, TransitionFSM::TransitionFSMPointerLess>::iterator, bool> ret = transitions.insert(new TransitionFSMSymbol(transition)); + if (!ret.second) + throw AutomatonException( + "Transition (\"" + from.getName() + "\", \"" + input.getSymbol() + "\") -> \"" + to.getName() + + "\" already exists."); +} + +void FSM::addTransition(const TransitionFSMEpsilon& transition) { + const State& from = transition.getFrom(); + const State& to = transition.getTo(); + + if (states.find(from) == states.end()) + throw AutomatonException("State \"" + from.getName() + "\" doesn't exist."); + + if (states.find(to) == states.end()) + throw AutomatonException("State \"" + to.getName() + "\" doesn't exist."); + + pair<set<TransitionFSM*, TransitionFSM::TransitionFSMPointerLess>::iterator, bool> ret = transitions.insert(new TransitionFSMEpsilon(transition)); + if (!ret.second) + throw AutomatonException( + "Transition (\"" + from.getName() + "\", \" \\eps \") -> \"" + to.getName() + + "\" already exists."); +} + +void FSM::removeTransition(const TransitionFSMSymbol& transition) { + /*int removed = transitions.erase(transition); + if (!removed) + throw AutomatonException( + "Transition (\"" + transition.getFrom().getName() + "\", \"" + transition.getInput().getSymbol() + + "\") -> \"" + transition.getTo().getName() + "\" doesn't exist.");*/ +} + +void FSM::removeTransition(const TransitionFSMEpsilon& transition) { + /*int removed = transitions.erase(transition); + if (!removed) + throw AutomatonException( + "Transition (\"" + transition.getFrom().getName() + "\", \"" + transition.getInput().getSymbol() + + "\") -> \"" + transition.getTo().getName() + "\" doesn't exist.");*/ +} + +const set<TransitionFSM*, TransitionFSM::TransitionFSMPointerLess>& FSM::getTransitions() const { + return transitions; +} + +const set<TransitionFSM*, TransitionFSM::TransitionFSMPointerLess> FSM::getTransitionsFromState(const State& from) const { + if( states.find(from) == states.end()) + throw AutomatonException("State \"" + from.getName() + "\" doesn't exist"); + + set<TransitionFSM*, TransitionFSM::TransitionFSMPointerLess> transitionsFromState; + for(auto const & transition : transitions){ + if (transition->getFrom() == from){ + transitionsFromState.insert(transition); + } + } + + return transitionsFromState; +} + +const set<TransitionFSM*, TransitionFSM::TransitionFSMPointerLess> FSM::getTransitionsToState(const State& to) const { + if( states.find(to) == states.end()) + throw AutomatonException("State \"" + to.getName() + "\" doesn't exist"); + + set<TransitionFSM*, TransitionFSM::TransitionFSMPointerLess> transitionsToState; + for(auto const& transition : transitions){ + if (transition->getTo() == to){ + transitionsToState.insert(transition); + } + } + + return transitionsToState; +} + +void FSM::toXML(ostream& out) const { + AutomatonPrinter::toXML(*this, out); +} + +bool FSM::isEpsilonFree() const { + for (const auto & transition : transitions) { + if (dynamic_cast<const TransitionFSMEpsilon*>(transition)) { + return false; + } + } + return true; +} + +bool FSM::isDeterministic() const { + if (initialStates.size() != 1 || !isEpsilonFree()) { + return false; + } + + for (auto tmp = transitions.begin(); tmp != transitions.end(); tmp++) { + TransitionFSMSymbol* transition = (TransitionFSMSymbol*) &*tmp; + + auto subTmp = tmp; + subTmp++; + + for (; subTmp != transitions.end(); subTmp++) { + TransitionFSMSymbol* subTransition = (TransitionFSMSymbol*) &*subTmp; + + if (subTransition->getFrom() == transition->getFrom() + && subTransition->getInput() == transition->getInput()) { + return false; + } + } + } + + return true; +} + +bool FSM::isTotal() const { + return isDeterministic() && transitions.size() == inputAlphabet.size() * states.size(); +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/FSM.h b/alib2/src/automaton/FSM/FSM.h new file mode 100644 index 0000000000000000000000000000000000000000..7058689b5b4c225c10a4091044ae9a3854604d37 --- /dev/null +++ b/alib2/src/automaton/FSM/FSM.h @@ -0,0 +1,131 @@ +/* + * FSM.h + * + * Created on: Mar 25, 2013 + * Author: martin + */ + +#ifndef FSM_H_ +#define FSM_H_ + +#include <set> +#include "../Automaton.h" +#include "../State.h" +#include "../../alphabet/Symbol.h" +#include "../../regexp/RegExp.h" +#include "TransitionFSM.h" +#include "TransitionFSMExtended.h" +#include "TransitionFSMSymbol.h" +#include "TransitionFSMEpsilon.h" + +namespace automaton { + +using namespace std; +using namespace alphabet; + +/** + * Represents Finite State Machine. + * Can store nondeterministic finite state machines with epsilon transitions. + */ +class FSM: public Automaton { +protected: + set<TransitionFSM*, TransitionFSM::TransitionFSMPointerLess> transitions; +public: + ~FSM(); + + /** + * @copydoc Automaton::removeState(const State&) + */ + virtual void removeState(const State& state); + + /** + * @copydoc Automaton::removeInputSymbol(const Symbol&) + */ + virtual void removeInputSymbol(const Symbol& symbol); + + /** + * Adds transition defined by parameters to the automaton. + * @param current current state + * @param input input symbol + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + void addTransition(const State& current, const Symbol& input, const State& next); + + /** + * Adds transition defined by parameters to the automaton. + * @param current current state + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + void addTransition(const State& current, const State& next); + + /** + * Adds transition to the automaton. + * @param transition transition to add + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + void addTransition(const TransitionFSMSymbol& transition); + + /** + * Adds transition to the automaton. + * @param transition transition to add + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + void addTransition(const TransitionFSMEpsilon& transition); + + /** + * Removes transition from the automaton. + * @param transition transition to remove + * @throws AutomatonException when transition doesn't exists. + */ + void removeTransition(const TransitionFSMSymbol& transition); + + /** + * Removes transition from the automaton. + * @param transition transition to remove + * @throws AutomatonException when transition doesn't exists. + */ + void removeTransition(const TransitionFSMEpsilon& transition); + + /** + * @return automaton transitions + */ + const set<TransitionFSM*, TransitionFSM::TransitionFSMPointerLess>& getTransitions() const; + + /** + * @return automaton transitions from state + */ + const set<TransitionFSM*, TransitionFSM::TransitionFSMPointerLess> getTransitionsFromState(const State& from) const; + + /** + * @return automaton transitions to state + */ + const set<TransitionFSM*, TransitionFSM::TransitionFSMPointerLess> getTransitionsToState(const State& to) const; + + /** + * Determines whether FSM contains epsilon transitions. + * @return true when automaton doesn't contain epsilon transitions, false otherwise + */ + bool isEpsilonFree() const; + + /** + * Determines whether FSM is deterministic. + * FSM is deterministic when: + * \li \c contains only 1 initial state. + * \li \c doesn't contain epsilon transitions. + * \li doesn't contain more than one transition with combination (from state, input symbol) + * @return true when automaton is deterministic, false otherwise + */ + bool isDeterministic() const; + + bool isTotal() const; + + /** + * @copydoc Automaton::toXML(ostream&) const + */ + virtual void toXML(ostream& out) const; +}; + +} /* namespace automaton */ +#endif /* FSM_H_ */ diff --git a/alib2/src/automaton/FSM/TransitionFSM.cpp b/alib2/src/automaton/FSM/TransitionFSM.cpp new file mode 100644 index 0000000000000000000000000000000000000000..da55b5eafaee7ae381629b026158be9ac2ddbe4f --- /dev/null +++ b/alib2/src/automaton/FSM/TransitionFSM.cpp @@ -0,0 +1,55 @@ +/* + * TransitionFSM.cpp + * + * Created on: Mar 26, 2013 + * Author: martin + */ + +#include "TransitionFSM.h" + +namespace automaton { + +TransitionFSM::TransitionFSM(const State& from,const State& to) : Transition(from, to) { +} + +bool TransitionFSM::TransitionFSMPointerLess::operator() (const TransitionFSM* lhs, const TransitionFSM* rhs) const { + return *lhs < *rhs; +} + +bool TransitionFSM::operator>=(const TransitionFSM& other) const { + return !(*this < other); +} + +bool TransitionFSM::operator<=(const TransitionFSM& other) const { + return !(*this > other); +} + +bool TransitionFSM::operator!=(const TransitionFSM& other) const { + return !(*this == other); +} + +bool TransitionFSM::operator<(const TransitionFSMExtended&) const { + return false; +} + +bool TransitionFSM::operator<(const TransitionFSMSymbol&) const { + return false; +} + +bool TransitionFSM::operator<(const TransitionFSMEpsilon&) const { + return false; +} + +bool TransitionFSM::operator==(const TransitionFSMExtended&) const { + return false; +} + +bool TransitionFSM::operator==(const TransitionFSMSymbol&) const { + return false; +} + +bool TransitionFSM::operator==(const TransitionFSMEpsilon&) const { + return false; +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/TransitionFSM.h b/alib2/src/automaton/FSM/TransitionFSM.h new file mode 100644 index 0000000000000000000000000000000000000000..ca1eb81beaa5c1b948691c0d8c2468d23f2c1192 --- /dev/null +++ b/alib2/src/automaton/FSM/TransitionFSM.h @@ -0,0 +1,59 @@ +/* + * TransitionFSM.h + * + * Created on: Mar 26, 2013 + * Author: martin + */ + +#ifndef TRANSITIONFSM_H_ +#define TRANSITIONFSM_H_ + +#include "../Transition.h" +#include "../../alphabet/Symbol.h" +#include <ostream> + +namespace automaton { + +class TransitionFSMExtended; +class TransitionFSMSymbol; +class TransitionFSMEpsilon; + +/** + * Represents transition rule for FSM. + */ +class TransitionFSM : public Transition { +public: + + struct TransitionFSMPointerLess { + bool operator() (const TransitionFSM* lhs, const TransitionFSM* rhs) const; + }; + + /** + * Creates new transition with given parameters. + * @param from from state + * @param to to state + */ + TransitionFSM(const State& from,const State& to); + + virtual bool isReading(const alphabet::Symbol& symbol) const = 0; + + // TransitionFSMEpsilon < TransitionFSMSymbol < TransitionFSMExtended + virtual bool operator<(const TransitionFSM&) const = 0; + virtual bool operator==(const TransitionFSM&) const = 0; + virtual bool operator>(const TransitionFSM&) const = 0; + + virtual bool operator>=(const TransitionFSM&) const; + virtual bool operator<=(const TransitionFSM&) const; + virtual bool operator!=(const TransitionFSM&) const; + + virtual bool operator<(const TransitionFSMExtended&) const; + virtual bool operator<(const TransitionFSMSymbol&) const; + virtual bool operator<(const TransitionFSMEpsilon&) const; + + virtual bool operator==(const TransitionFSMExtended&) const; + virtual bool operator==(const TransitionFSMSymbol&) const; + virtual bool operator==(const TransitionFSMEpsilon&) const; +}; + +} /* namespace automaton */ +#endif /* TRANSITIONFSM_H_ */ diff --git a/alib2/src/automaton/FSM/TransitionFSMEpsilon.cpp b/alib2/src/automaton/FSM/TransitionFSMEpsilon.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9d280f12035a9094d2782729ca7faa541b05c248 --- /dev/null +++ b/alib2/src/automaton/FSM/TransitionFSMEpsilon.cpp @@ -0,0 +1,60 @@ +/* + * TransitionFSMEpsilon.cpp + * + * Created on: Mar 26, 2013 + * Author: Jan Travnicek + */ + +#include "TransitionFSMEpsilon.h" + +namespace automaton { + +TransitionFSMEpsilon::TransitionFSMEpsilon(const State& from,const State& to) : TransitionFSM(from, to) { +} + +bool TransitionFSMEpsilon::isReading(const alphabet::Symbol& symbol) const { + return false; +} + +bool TransitionFSMEpsilon::operator < (const TransitionFSM& other) const { + return other > *this; +} + +bool TransitionFSMEpsilon::operator == (const TransitionFSM& other) const { + return other == *this; +} + +bool TransitionFSMEpsilon::operator > (const TransitionFSM& other) const { + return other < *this; +} + + +bool TransitionFSMEpsilon::operator < (const TransitionFSMExtended& other) const { + return true; +} + +bool TransitionFSMEpsilon::operator < (const TransitionFSMSymbol& other) const { + return true; +} + +bool TransitionFSMEpsilon::operator < (const TransitionFSMEpsilon& other) const { + if(from != other.from) { + return from < other.from; + } else { + return to < other.to; + } +} + + +bool TransitionFSMEpsilon::operator == (const TransitionFSMEpsilon& other) const { + return from == other.from && to == other.to; +} + +std::ostream& TransitionFSMEpsilon::operator>>(std::ostream& out) const { + out << "TransitionFSMEpsilon from = " << this->from + << " to = " << this->to; + + return out; +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/TransitionFSMEpsilon.h b/alib2/src/automaton/FSM/TransitionFSMEpsilon.h new file mode 100644 index 0000000000000000000000000000000000000000..fcdf049368f4b580321879b81c80ab606696e40b --- /dev/null +++ b/alib2/src/automaton/FSM/TransitionFSMEpsilon.h @@ -0,0 +1,44 @@ +/* + * TransitionFSMEpsilon.h + * + * Created on: Mar 26, 2013 + * Author: Jan Travnicek + */ + +#ifndef TRANSITION_FSM_EPSILON_H_ +#define TRANSITION_FSM_EPSILON_H_ + +#include "TransitionFSM.h" +#include <ostream> + +namespace automaton { + +/** + * Represents transition rule for FSM. + */ +class TransitionFSMEpsilon : public TransitionFSM { +public: + /** + * Creates new transition with given parameters. + * @param from from state + * @param to to state + */ + TransitionFSMEpsilon(const State& from,const State& to); + + virtual bool isReading(const alphabet::Symbol& symbol) const; + + virtual bool operator < (const TransitionFSM& other) const; + virtual bool operator == (const TransitionFSM& other) const; + virtual bool operator > (const TransitionFSM& other) const; + + virtual bool operator < (const TransitionFSMExtended& other) const; + virtual bool operator < (const TransitionFSMSymbol& other) const; + virtual bool operator < (const TransitionFSMEpsilon& other) const; + + virtual bool operator == (const TransitionFSMEpsilon& other) const; + + virtual std::ostream& operator>>(std::ostream& out) const; +}; + +} /* namespace automaton */ +#endif /* TRANSITION_FSM_EPSILON_H_ */ diff --git a/alib2/src/automaton/FSM/TransitionFSMExtended.cpp b/alib2/src/automaton/FSM/TransitionFSMExtended.cpp new file mode 100644 index 0000000000000000000000000000000000000000..58286997aee110cb0035dddfb250c225ef915be7 --- /dev/null +++ b/alib2/src/automaton/FSM/TransitionFSMExtended.cpp @@ -0,0 +1,61 @@ +/* + * TransitionFSMExtended.cpp + * + * Created on: Mar 26, 2013 + * Author: martin + */ + +#include "TransitionFSMExtended.h" + +namespace automaton { +TransitionFSMExtended::TransitionFSMExtended(const State& from,const regexp::RegExp& input,const State& to) : TransitionFSM(from, to), input(input) { +} + + +bool TransitionFSMExtended::isReading(const alphabet::Symbol& symbol) const { + // TODO + return true; +} + +const regexp::RegExp& TransitionFSMExtended::getInput() const { + return this->input; +} + + +bool TransitionFSMExtended::operator < (const TransitionFSM& other) const { + return other > *this; +} + +bool TransitionFSMExtended::operator == (const TransitionFSM& other) const { + return other == *this; +} + +bool TransitionFSMExtended::operator > (const TransitionFSM& other) const { + return other < *this; +} + + +bool TransitionFSMExtended::operator < (const TransitionFSMExtended& other) const { + if(from != other.from) { + return from < other.from; + } else if(input != other.input) { + return input < other.input; + } else { + return to < other.to; + } +} + +bool TransitionFSMExtended::operator == (const TransitionFSMExtended& other) const { + return from == other.from && input == other.input && to == other.to; +} + + +std::ostream& TransitionFSMExtended::operator>>(std::ostream& out) const { + out << "TransitionFSMExtended from = " << this->from + << " to = " << this->to + << " input = " << this->input; + + return out; +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/TransitionFSMExtended.h b/alib2/src/automaton/FSM/TransitionFSMExtended.h new file mode 100644 index 0000000000000000000000000000000000000000..eeecad214d94535b97f1ee96489159ba6e639dc6 --- /dev/null +++ b/alib2/src/automaton/FSM/TransitionFSMExtended.h @@ -0,0 +1,47 @@ +/* + * TransitionFSMExtended.h + * + * Created on: Mar 26, 2013 + * Author: martin + */ + +#ifndef TRANSITIONFSMEXTENDED_H_ +#define TRANSITIONFSMEXTENDED_H_ + +#include "TransitionFSM.h" +#include "../../regexp/RegExp.h" +#include <ostream> + +namespace automaton { + +/** + * Represents transition rule for FSM. + */ +class TransitionFSMExtended : public TransitionFSM { + regexp::RegExp input; +public: + /** + * Creates new transition with given parameters. + * @param from from state + * @param input input regexp + * @param to to state + */ + TransitionFSMExtended(const State& from,const regexp::RegExp& input,const State& to); + + virtual bool isReading(const alphabet::Symbol& symbol) const; + + const regexp::RegExp& getInput() const; + + virtual bool operator < (const TransitionFSM& other) const; + virtual bool operator == (const TransitionFSM& other) const; + virtual bool operator > (const TransitionFSM& other) const; + + virtual bool operator < (const TransitionFSMExtended& other) const; + + virtual bool operator == (const TransitionFSMExtended& other) const; + + std::ostream& operator>>(std::ostream& out) const; +}; + +} /* namespace automaton */ +#endif /* TRANSITIONFSMEXTENDED_H_ */ diff --git a/alib2/src/automaton/FSM/TransitionFSMSymbol.cpp b/alib2/src/automaton/FSM/TransitionFSMSymbol.cpp new file mode 100644 index 0000000000000000000000000000000000000000..13868dcdd0e2a0f8ad4e24b08824937ab0a7f5fa --- /dev/null +++ b/alib2/src/automaton/FSM/TransitionFSMSymbol.cpp @@ -0,0 +1,64 @@ +/* + * TransitionFSMSymbol.cpp + * + * Created on: Mar 26, 2013 + * Author: martin + */ + +#include "TransitionFSMSymbol.h" + +namespace automaton { + +TransitionFSMSymbol::TransitionFSMSymbol(const State& from,const Symbol& input,const State& to) : TransitionFSM(from, to), input(input) { +} + +bool TransitionFSMSymbol::isReading(const alphabet::Symbol& symbol) const { + return this->input == symbol; +} + +const Symbol& TransitionFSMSymbol::getInput() const { + return this->input; +} + + +bool TransitionFSMSymbol::operator < (const TransitionFSM& other) const { + return other > *this; +} + +bool TransitionFSMSymbol::operator == (const TransitionFSM& other) const { + return other == *this; +} + +bool TransitionFSMSymbol::operator > (const TransitionFSM& other) const { + return other < *this; +} + + +bool TransitionFSMSymbol::operator < (const TransitionFSMExtended& other) const { + return true; +} + +bool TransitionFSMSymbol::operator < (const TransitionFSMSymbol& other) const { + if(from != other.from) { + return from < other.from; + } else if(input != other.input) { + return input < other.input; + } else { + return to < other.to; + } +} + +bool TransitionFSMSymbol::operator == (const TransitionFSMSymbol& other) const { + return from == other.from && input == other.input && to == other.to; +} + + +std::ostream& TransitionFSMSymbol::operator>>(std::ostream& out) const { + out << "TransitionFSMSymbol from = " << this->from + << " to = " << this->to + << " input = " << this->input; + + return out; +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/TransitionFSMSymbol.h b/alib2/src/automaton/FSM/TransitionFSMSymbol.h new file mode 100644 index 0000000000000000000000000000000000000000..fe5c9be156e07294fc1898c2a82bd237dea7ea8c --- /dev/null +++ b/alib2/src/automaton/FSM/TransitionFSMSymbol.h @@ -0,0 +1,50 @@ +/* + * TransitionFSMSymbol.h + * + * Created on: Mar 26, 2013 + * Author: Jan Travnicek + */ + +#ifndef TRANSITION_FSM_SYMBOL_H_ +#define TRANSITION_FSM_SYMBOL_H_ + +#include "TransitionFSM.h" +#include "../../alphabet/Symbol.h" +#include <ostream> + +namespace automaton { + +using namespace alphabet; + +/** + * Represents transition rule for FSM. + */ +class TransitionFSMSymbol : public TransitionFSM { + Symbol input; +public: + /** + * Creates new transition with given parameters. + * @param from from state + * @param input input symbol + * @param to to state + */ + TransitionFSMSymbol(const State& from,const Symbol& input,const State& to); + + const Symbol& getInput() const; + + virtual bool isReading(const Symbol& symbol) const; + + virtual bool operator < (const TransitionFSM& other) const; + virtual bool operator == (const TransitionFSM& other) const; + virtual bool operator > (const TransitionFSM& other) const; + + virtual bool operator < (const TransitionFSMExtended& other) const; + virtual bool operator < (const TransitionFSMSymbol& other) const; + + virtual bool operator == (const TransitionFSMSymbol& other) const; + + virtual std::ostream& operator>>(std::ostream& out) const; +}; + +} /* namespace automaton */ +#endif /* TRANSITION_FSM_SYMBOL_H_ */ diff --git a/alib2/src/automaton/PDA/PDA.cpp b/alib2/src/automaton/PDA/PDA.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7866cd1cfb1226cce6da46d2ebb832fbb661f0c9 --- /dev/null +++ b/alib2/src/automaton/PDA/PDA.cpp @@ -0,0 +1,158 @@ +/* + * PDA.cpp + * + * Created on: Apr 10, 2013 + * Author: martin + */ + +#include "PDA.h" +#include "../AutomatonPrinter.h" +#include "../exception/AutomatonException.h" +#include <algorithm> + +namespace automaton { + +using namespace std; + +PDA::PDA() { + +} + +void PDA::removeState(const State& state) { + for (set<State>::const_iterator initialState = initialStates.begin(); initialState != initialStates.end(); + initialState++) { + if (*initialState == state) { + throw AutomatonException("State \"" + state.getName() + "\" is initial state."); + } + } + + for (set<State>::const_iterator finalState = finalStates.begin(); finalState != finalStates.end(); finalState++) { + if (*finalState == state) { + throw AutomatonException("State \"" + state.getName() + "\" is final state."); + } + } + + for (set<TransitionPDA>::const_iterator t = transitions.begin(); t != transitions.end(); t++) { + if (state == t->getFrom() || state == t->getTo()) + throw AutomatonException("State \"" + state.getName() + "\" is used in transition."); + } + + int removed = states.erase(state); + if (!removed) + throw AutomatonException("State \"" + state.getName() + "\" doesn't exist."); +} + +void PDA::removeInputSymbol(const Symbol& symbol) { + for (set<TransitionPDA>::const_iterator t = transitions.begin(); t != transitions.end(); t++) { + if (symbol == t->getInput()) + throw AutomatonException("Symbol \"" + symbol.getSymbol() + "\" is used in transition."); + } + + int removed = inputAlphabet.erase(symbol); + if (!removed) + throw AutomatonException("Symbol \"" + symbol.getSymbol() + "\" doesn't exist."); +} + +void PDA::addStackSymbol(const Symbol& symbol) { + pair<set<Symbol>::iterator, bool> ret = stackAlphabet.insert(symbol); + if (!ret.second) + throw AutomatonException("Stack symbol \"" + symbol.getSymbol() + "\" already exists."); +} + +void PDA::removeStackSymbol(const Symbol& symbol) { + for (set<TransitionPDA>::const_iterator t = transitions.begin(); t != transitions.end(); t++) { + for (list<Symbol>::const_iterator popSymbol = t->getPop().begin(); popSymbol != t->getPop().end(); + popSymbol++) { + if (symbol == (*popSymbol)) + throw AutomatonException("Stack symbol \"" + symbol.getSymbol() + "\" is used in transition."); + } + for (list<Symbol>::const_iterator pushSymbol = t->getPush().begin(); pushSymbol != t->getPush().end(); + pushSymbol++) { + if (symbol == (*pushSymbol)) + throw AutomatonException("Stack symbol \"" + symbol.getSymbol() + "\" is used in transition."); + } + } + + for(list<Symbol>::const_iterator startSymbol = startSymbols.begin(); startSymbol != startSymbols.end(); startSymbol++){ + if(*startSymbol == symbol) { + throw AutomatonException("Stack symbol \"" + symbol.getSymbol() + "\" is start symbol."); + } + } + + int removed = stackAlphabet.erase(symbol); + if (!removed) + throw AutomatonException("Stack symbol \"" + symbol.getSymbol() + "\" doesn't exist."); + +} + +const set<Symbol>& PDA::getStackAlphabet() const { + return stackAlphabet; +} + +void PDA::addTransition(const TransitionPDA& transition) { + if (states.find(transition.getFrom()) == states.end()) { + throw AutomatonException("State \"" + transition.getFrom().getName() + "\" doesn't exist."); + } + + if (transition.getInput().getSymbol().compare("") != 0) { + if (inputAlphabet.find(transition.getInput()) == inputAlphabet.end()) { + throw AutomatonException("Input symbol \"" + transition.getInput().getSymbol() + "\" doesn't exist."); + } + } + + if (states.find(transition.getTo()) == states.end()) { + throw AutomatonException("State \"" + transition.getFrom().getName() + "\" doesn't exist."); + } + + list<Symbol>::const_iterator popSymbol = transition.getPop().begin(); + while (popSymbol != transition.getPop().end()) { + if (stackAlphabet.find(*popSymbol) == stackAlphabet.end()) { + throw AutomatonException("Stack symbol \"" + popSymbol->getSymbol() + "\" doesn't exist."); + } + popSymbol++; + } + + list<Symbol>::const_iterator pushSymbol = transition.getPush().begin(); + while (pushSymbol != transition.getPush().end()) { + if (stackAlphabet.find(*pushSymbol) == stackAlphabet.end()) { + throw AutomatonException("Stack symbol \"" + pushSymbol->getSymbol() + "\" doesn't exist."); + } + pushSymbol++; + } + + pair<set<TransitionPDA>::iterator, bool> ret = transitions.insert(transition); + if (!ret.second) { + throw AutomatonException("Transition already exists."); + } +} + +void PDA::removeTransition(const TransitionPDA& transition) { + int removed = transitions.erase(transition); + if (!removed) { + throw AutomatonException("Transition doesn't exist."); + } +} + +const set<TransitionPDA>& PDA::getTransitions() const { + return transitions; +} + +void PDA::setStartSymbols(const list<Symbol>& start) { + for (list<Symbol>::const_iterator symbol = start.begin(); symbol != start.end(); symbol++) { + if (stackAlphabet.find(*symbol) == stackAlphabet.end()) { + throw AutomatonException("Stack symbol \"" + symbol->getSymbol() + "\" doesn't exist."); + } + } + + this->startSymbols = start; +} + +const list<Symbol>& PDA::getStartSymbols() const { + return startSymbols; +} + +void PDA::toXML(ostream& out) const { + AutomatonPrinter::toXML(*this, out); +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/PDA/PDA.h b/alib2/src/automaton/PDA/PDA.h new file mode 100644 index 0000000000000000000000000000000000000000..0aa2bb8e872d7821e3f692d9730b24b2b4c2d0f0 --- /dev/null +++ b/alib2/src/automaton/PDA/PDA.h @@ -0,0 +1,105 @@ +/* + * PDA.h + * + * Created on: Apr 10, 2013 + * Author: martin + */ + +#ifndef PDA_H_ +#define PDA_H_ + +#include <set> +#include <list> +#include "../Automaton.h" +#include "../State.h" +#include "../../alphabet/Symbol.h" +#include "TransitionPDA.h" + +namespace automaton { + +using namespace std; +using namespace alphabet; + +/** + * Push Down Automaton + */ +class PDA: public Automaton { +protected: + set<Symbol> stackAlphabet; + set<TransitionPDA> transitions; + list<Symbol> startSymbols; +public: + PDA(); + + /** + * @copydoc Automaton::removeState(const State&) + */ + virtual void removeState(const State& state); + + /** + * @copydoc Automaton::removeInputSymbol(const Symbol&) + */ + virtual void removeInputSymbol(const Symbol& symbol); + + /** + * Adds symbol to the stack alphabet. + * @param symbol Symbol to add + * @throws AutomatonException when symbol is already present in stack alphabet + */ + void addStackSymbol(const Symbol& symbol); + + /** + * Removes symbol from the stack alphabet. + * @param symbol Symbol to remove + * @throws AutomatonException when symbol is used in transition + * (popped from or pushed to the stack), when it is a start symbol + * or when it is not present in the stack alphabet + */ + void removeStackSymbol(const Symbol& symbol); + + /** + * @return the stack alphabet + */ + const set<Symbol>& getStackAlphabet() const; + + /** + * Adds transition to the PDA. + * @param transition transition to add + * @throws AutomatonException when some part of the transition is not present + * in the PDA (state, input symbol, stack symbol) or when transition already exists + */ + void addTransition(const TransitionPDA& transition); + + /** + * Removes the transition from the PDA. + * @param transition transition to remove + * @throws AutomatonException when transition is not present in the PDA + */ + void removeTransition(const TransitionPDA& transition); + + /** + * @return PDA transitions + */ + const set<TransitionPDA>& getTransitions() const; + + /** + * Sets the list of start symbols. Start symbols are symbols that are pushed + * to the stack when PDA is created. + * @param start symbols that are pushed to the stack + * @throws AutomatonException when any of the symbols is not present in the stack alphabet + */ + void setStartSymbols(const list<Symbol>& start); + + /** + * @return list of start symbols + */ + const list<Symbol>& getStartSymbols() const; + + /** + * @copydoc Automaton::toXML(ostream&) const + */ + void toXML(ostream& out) const; +}; + +} /* namespace automaton */ +#endif /* PDA_H_ */ diff --git a/alib2/src/automaton/PDA/TransitionPDA.cpp b/alib2/src/automaton/PDA/TransitionPDA.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ea540488ccc94c1bfbc4d111423fb7d8af8834d1 --- /dev/null +++ b/alib2/src/automaton/PDA/TransitionPDA.cpp @@ -0,0 +1,158 @@ +/* + * TransitionPDA.cpp + * + * Created on: Apr 10, 2013 + * Author: martin + */ + +#include "TransitionPDA.h" + +namespace automaton { + +TransitionPDA::TransitionPDA(const State& from, const Symbol& input, const State& to) : Transition(from, to), input(input) { + +} + +TransitionPDA::TransitionPDA(const State& from, const Symbol& input, const State& to, const list<Symbol>& pop, + const list<Symbol>& push) : + Transition(from, to), input(input), pop(pop), push(push) { + +} + +void TransitionPDA::setInput(const Symbol& input) { + this->input = input; +} + +const Symbol& TransitionPDA::getInput() const { + return this->input; +} + +void TransitionPDA::setPop(const list<Symbol>& pop) { + this->pop = pop; +} + +const list<Symbol>& TransitionPDA::getPop() const { + return pop; +} + +void TransitionPDA::setPush(const list<Symbol>& push) { + this->push = push; +} + +const list<Symbol>& TransitionPDA::getPush() const { + return push; +} + +bool TransitionPDA::operator <(const TransitionPDA& other) const { + if (from != other.from) { + return from < other.from; + } else if (input != other.input) { + return input < other.input; + } else if (to != other.to) { + return to < other.to; + } + + list<Symbol>::const_iterator it; + list<Symbol>::const_iterator it2; + + //compare pop size + if (pop.size() != other.pop.size()) + return pop.size() < other.pop.size(); + + //compare pop content + it = pop.begin(); + it2 = other.pop.begin(); + while (it != pop.end()) { + if ((*it) != (*it2)) + return (*it) < (*it2); + it++; + it2++; + } + + //compare push size + if (push.size() != other.push.size()) + return push.size() < other.push.size(); + + //compare push content + it = push.begin(); + it2 = other.push.begin(); + while (it != push.end()) { + if ((*it) != (*it2)) + return (*it) < (*it2); + it++; + it2++; + } + + return false; +} + +bool TransitionPDA::operator ==(const TransitionPDA& other) const { + if (from == other.from && input == other.input && to == other.to) { + + //compare pop size + if (pop.size() != other.pop.size()) + return false; + //compare push size + if (push.size() != other.push.size()) + return false; + + list<Symbol>::const_iterator it; + list<Symbol>::const_iterator it2; + + //compare pop content + it = pop.begin(); + it2 = other.pop.begin(); + while (it != pop.end()) { + if ((*it) != (*it2)) + return false; + it++; + it2++; + } + + //compare push content + it = push.begin(); + it2 = other.push.begin(); + while (it != push.end()) { + if ((*it) != (*it2)) + return false; + it++; + it2++; + } + return true; + } else { + return false; + } +} + +bool TransitionPDA::operator !=(const TransitionPDA& other) const { + return !((*this) == other); +} + +std::ostream& TransitionPDA::operator>>(std::ostream& out) const { + bool first; + out << "TransitionPDA from = " << this->from + << " to = " << this->to + << " input = " << this->input + << " pop = ["; + + first = true; + for(list<Symbol>::const_iterator iter = this->pop.begin(); iter != this->pop.end(); iter++) { + if(!first) out << ", "; + first = false; + out << *iter; + } + + out << "] push = ["; + + first = true; + for(list<Symbol>::const_iterator iter = this->push.begin(); iter != this->push.end(); iter++) { + if(!first) out << ", "; + first = false; + out << *iter; + } + out << "]"; + + return out; +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/PDA/TransitionPDA.h b/alib2/src/automaton/PDA/TransitionPDA.h new file mode 100644 index 0000000000000000000000000000000000000000..1c752bbd7f1afbe9088fe3447548995286d857d3 --- /dev/null +++ b/alib2/src/automaton/PDA/TransitionPDA.h @@ -0,0 +1,46 @@ +/* + * TransitionPDA.h + * + * Created on: Apr 10, 2013 + * Author: martin + */ + +#ifndef TRANSITIONPDA_H_ +#define TRANSITIONPDA_H_ + +#include "../Transition.h" +#include "../../alphabet/Symbol.h" +#include <list> + +namespace automaton { + +using namespace std; +using namespace alphabet; + +class TransitionPDA: public Transition { +protected: + Symbol input; + list<Symbol> pop; + list<Symbol> push; + +public: + TransitionPDA(const State& from, const Symbol& input, const State& to); + TransitionPDA(const State& from, const Symbol& input, const State& to, const list<Symbol>& pop, + const list<Symbol>& push); + + void setInput(const Symbol& input); + const Symbol& getInput() const; + void setPop(const list<Symbol>& pop); + const list<Symbol>& getPop() const; + void setPush(const list<Symbol>& push); + const list<Symbol>& getPush() const; + + bool operator <(const TransitionPDA& other) const; + bool operator ==(const TransitionPDA& other) const; + bool operator !=(const TransitionPDA& other) const; + + std::ostream& operator>>(std::ostream& out) const; +}; + +} /* namespace automaton */ +#endif /* TRANSITIONPDA_H_ */ diff --git a/alib2/src/automaton/Shift.cpp b/alib2/src/automaton/Shift.cpp new file mode 100644 index 0000000000000000000000000000000000000000..03f2e55c21ad5cb07091c953f7ea6c2334bae539 --- /dev/null +++ b/alib2/src/automaton/Shift.cpp @@ -0,0 +1,10 @@ +/* + * Shift.cpp + * + * Created on: Dec 8, 2013 + * Author: honza + */ + +#include "Shift.h" + +std::string SHIFT_NAMES[] = {"LEFT", "RIGHT", "NONE", "NOT_SET" }; diff --git a/alib2/src/automaton/Shift.h b/alib2/src/automaton/Shift.h new file mode 100644 index 0000000000000000000000000000000000000000..721caff2ad9be5795e5612e118c8e51a85572a85 --- /dev/null +++ b/alib2/src/automaton/Shift.h @@ -0,0 +1,22 @@ +/* + * Shift.h + * + * Created on: Oct 13, 2013 + * Author: martin + */ + +#ifndef SHIFT_H_ +#define SHIFT_H_ + +#include <string> + +/** + * Represent movement of the reading head in the Turing machine. + */ +enum Shift { + LEFT, RIGHT, NONE, NOT_SET +}; + +extern std::string SHIFT_NAMES[4]; + +#endif /* SHIFT_H_ */ diff --git a/alib2/src/automaton/State.cpp b/alib2/src/automaton/State.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d278b21fb39be9c9f29b76062e075b60c72982f2 --- /dev/null +++ b/alib2/src/automaton/State.cpp @@ -0,0 +1,36 @@ +/* + * State.cpp + * + * Created on: Mar 26, 2013 + * Author: martin + */ + +#include "State.h" + +namespace automaton { + +State::State(const std::string& name) { + this->name = name; +} + +const std::string& State::getName() const { + return name; +} + +bool State::operator < (const State& other) const { + return name < other.name; +} + +bool State::operator == (const State& other) const { + return name == other.name; +} +bool State::operator != (const State& other) const{ + return name != other.name; +} + +std::ostream& operator<<(std::ostream& out, const State& state) { + out << "State " << state.name; + return out; +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/State.h b/alib2/src/automaton/State.h new file mode 100644 index 0000000000000000000000000000000000000000..1cb546d3cafaf3896ca73aaa006962f65916c64c --- /dev/null +++ b/alib2/src/automaton/State.h @@ -0,0 +1,34 @@ +/* + * StateFSM.h + * + * Created on: Mar 26, 2013 + * Author: martin + */ + +#ifndef STATEFSM_H_ +#define STATEFSM_H_ + +#include <string> +#include <ostream> + +namespace automaton { + +/** + * Class representing state in an automaton. + */ +class State { +private: + std::string name; +public: + State(const std::string& name); + const std::string& getName() const; + + bool operator < (const State& other) const; + bool operator == (const State& other) const; + bool operator != (const State& other) const; + + friend std::ostream& operator<<(std::ostream&, const State&); +}; + +} /* namespace automaton */ +#endif /* STATEFSM_H_ */ diff --git a/alib2/src/automaton/TM/TM.cpp b/alib2/src/automaton/TM/TM.cpp new file mode 100644 index 0000000000000000000000000000000000000000..edb73c66b5e7d312ac29d2aabe6ba192abca4270 --- /dev/null +++ b/alib2/src/automaton/TM/TM.cpp @@ -0,0 +1,151 @@ +/* + * TM.cpp + * + * Created on: Apr 24, 2013 + * Author: martin + */ + +#include "TM.h" +#include "../AutomatonPrinter.h" +#include "../exception/AutomatonException.h" + +namespace automaton { + +using namespace std; +using namespace alphabet; + +TM::TM() : + blankSymbol(Symbol("")) { +} + +void TM::addInputSymbol(const Symbol& symbol) { + if (tapeAlphabet.find(symbol) == tapeAlphabet.end()) { + throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" is not in tape alphabet."); + } + + if (symbol == blankSymbol) { + throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" cannot be blank symbol."); + } + + std::pair<std::set<Symbol>::iterator, bool> ret = inputAlphabet.insert(symbol); + if (!ret.second) + throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" already exists."); +} + +void TM::removeState(const State& state) { + for (set<State>::const_iterator initialState = initialStates.begin(); initialState != initialStates.end(); + initialState++) { + if (*initialState == state) { + throw AutomatonException("State \"" + state.getName() + "\" is initial state."); + } + } + + for (set<State>::const_iterator finalState = finalStates.begin(); finalState != finalStates.end(); finalState++) { + if (*finalState == state) { + throw AutomatonException("State \"" + state.getName() + "\" is final state."); + } + } + + for (set<TransitionTM>::const_iterator t = transitions.begin(); t != transitions.end(); t++) { + if (state == t->getFrom() || state == t->getTo()) + throw AutomatonException("State \"" + state.getName() + "\" is used."); + } + + int removed = states.erase(state); + if (!removed) + throw AutomatonException("State \"" + state.getName() + "\" doesn't exist."); +} + +void TM::removeInputSymbol(const Symbol& symbol) { + int removed = inputAlphabet.erase(symbol); + if (!removed) + throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" doesn't exist."); +} + +void TM::addTapeSymbol(const Symbol& symbol) { + pair<set<Symbol>::iterator, bool> ret = tapeAlphabet.insert(symbol); + if (!ret.second) + throw AutomatonException("Tape symbol \"" + symbol.getSymbol() + "\" already exists."); +} + +void TM::removeTapeSymbol(const Symbol& symbol) { + for (set<Symbol>::const_iterator it = inputAlphabet.begin(); it != inputAlphabet.end(); it++) { + if (symbol == (*it)) { + throw AutomatonException("Tape symbol \"" + symbol.getSymbol() + "\" is in input alphabet."); + } + } + + for (set<TransitionTM>::const_iterator t = transitions.begin(); t != transitions.end(); t++) { + if (symbol == t->getInput() || symbol == t->getOutput()) + throw AutomatonException("Tape symbol \"" + symbol.getSymbol() + "\" is used in transition."); + } + + int removed = inputAlphabet.erase(symbol); + if (!removed) + throw AutomatonException("Tape symbol \"" + symbol.getSymbol() + "\" doesn't exist."); + +} + +const std::set<Symbol>& TM::getTapeAlphabet() const { + return tapeAlphabet; +} + +void TM::addTransition(const TransitionTM& transition) { + if (states.find(transition.getFrom()) == states.end()) { + throw AutomatonException("State \"" + transition.getFrom().getName() + "\" doesn't exist."); + } + + if (transition.getInput().getSymbol() != "") { + if (tapeAlphabet.find(transition.getInput()) == tapeAlphabet.end()) { + throw AutomatonException("Tape symbol \"" + transition.getInput().getSymbol() + "\" doesn't exist."); + } + } + + if (states.find(transition.getTo()) == states.end()) { + throw AutomatonException("State \"" + transition.getTo().getName() + "\" doesn't exist."); + } + + if (tapeAlphabet.find(transition.getOutput()) == tapeAlphabet.end()) { + throw AutomatonException("Tape symbol \"" + transition.getOutput().getSymbol() + "\" doesn't exist."); + } + + pair<set<TransitionTM>::iterator, bool> ret = transitions.insert(transition); + if (!ret.second) { + throw AutomatonException("Transition already exists."); + } + +} + +void TM::removeTransition(const TransitionTM& transition) { + int removed = transitions.erase(transition); + if (!removed) { + throw AutomatonException("Transition doesn't exist."); + } +} + +const std::set<TransitionTM>& TM::getTransitions() const { + return transitions; +} + +void TM::setBlankSymbol(const Symbol& symbol) { + for (set<Symbol>::const_iterator it = inputAlphabet.begin(); it != inputAlphabet.end(); it++) { + if (symbol == (*it)) { + throw AutomatonException("Blank symbol \"" + symbol.getSymbol() + "\" is in input alphabet."); + } + } + + if (tapeAlphabet.find(symbol) == tapeAlphabet.end()) + throw AutomatonException("Blank symbol \"" + symbol.getSymbol() + "\" is not in tape alphabet."); + + blankSymbol = symbol; + +} +const Symbol& TM::getBlankSymbol() const { + return blankSymbol; +} + +void TM::toXML(std::ostream& out) const { + AutomatonPrinter::toXML(*this, out); +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/TM/TM.h b/alib2/src/automaton/TM/TM.h new file mode 100644 index 0000000000000000000000000000000000000000..550e7404d1d0c611fb33dd9a254625714ffe1f2e --- /dev/null +++ b/alib2/src/automaton/TM/TM.h @@ -0,0 +1,109 @@ +/* + * TM.h + * + * Created on: Apr 24, 2013 + * Author: martin + */ + +#ifndef TM_H_ +#define TM_H_ + +#include "../Automaton.h" +#include "TransitionTM.h" + +namespace automaton { + +using namespace std; +using namespace alphabet; + +/** + * Turing machine + */ +class TM: public automaton::Automaton { +protected: + set<Symbol> tapeAlphabet; + set<TransitionTM> transitions; + Symbol blankSymbol; + +public: + TM(); + + /** + * Adds symbol to the input alphabet. + * @param symbol Symbol to add + * @throws AutomatonException when symbol is not present in tape alphabet, + * when it's blank symbol or when it is already present in input alphabet + */ + virtual void addInputSymbol(const Symbol& symbol); + + /** + * @copydoc Automaton::removeState(const State&) + */ + virtual void removeState(const State& state); + + /** + * Removes input symbol from the input alphabet. + * @param symbol Symbol to remove + * @throws AutomatonException when symbol is part of the transition + */ + virtual void removeInputSymbol(const Symbol& symbol); + + /** + * Adds symbol to the tape alphabet. + * @param symbol Symbol to add + * @throw AutomatonException when Symbol is already present in tape alphabet + */ + void addTapeSymbol(const Symbol& symbol); + + /** + * Removes symbol from the tape alphabet. + * @param symbol Symbol to remove + * @throw AutomatonException when Symbol is not present in the tape alphabet, + * when it is used in transition or when it is present in input alphabet + */ + void removeTapeSymbol(const Symbol& symbol); + + /** + * @return tape alphabet + */ + const set<Symbol>& getTapeAlphabet() const; + + /** + * Adds transition to the automaton. + * @param transition transition to add + * @throws AutomatonException when some part of the transition is not present + * in the TM (state, tape symbol) or when transition already exists + */ + void addTransition(const TransitionTM& transition); + + /** + * Removes the transition from the TM. + * @param transition transition to remove + * @throws AutomatonException when transition is not present in the TM + */ + void removeTransition(const TransitionTM& transition); + + /** + * @return TM transitions + */ + const set<TransitionTM>& getTransitions() const; + + /** + * Sets the blank symbol = symbol representing empty cell of the tape + * @param symbol Symbol to set + */ + void setBlankSymbol(const Symbol& symbol); + + /** + * @return symbol representing empty cell of the tape + */ + const Symbol& getBlankSymbol() const; + + /** + * @copydoc Automaton::toXML(ostream&) const + */ + virtual void toXML(ostream& out) const; +}; + +} /* namespace automaton */ +#endif /* TM_H_ */ diff --git a/alib2/src/automaton/TM/TransitionTM.cpp b/alib2/src/automaton/TM/TransitionTM.cpp new file mode 100644 index 0000000000000000000000000000000000000000..21df387bee1019e1b8236b2f3fc9ad2f1c400cf3 --- /dev/null +++ b/alib2/src/automaton/TM/TransitionTM.cpp @@ -0,0 +1,68 @@ +/* + * TransitionTM.cpp + * + * Created on: Apr 24, 2013 + * Author: martin + */ + +#include "TransitionTM.h" + +namespace automaton { + +TransitionTM::TransitionTM(const State& from, const Symbol& input, const State& to, const Symbol& output, + Shift shift) : + Transition(from, to), input(input), output(output), shift(shift) { +} + +const Symbol& TransitionTM::getOutput() const { + return output; +} +void TransitionTM::setOutput(const Symbol& output) { + this->output = output; +} +const Symbol& TransitionTM::getInput() const { + return input; +} +void TransitionTM::setInput(const Symbol& input) { + this->input = input; +} +Shift TransitionTM::getShift() const { + return shift; +} +void TransitionTM::setShift(Shift shift) { + this->shift = shift; +} + +bool TransitionTM::operator <(const TransitionTM& other) const { + if (from != other.from) { + return from < other.from; + } else if (input != other.input) { + return input < other.input; + } else if (to != to) { + return to < other.to; + } else if (output != output) { + return output < other.output; + } else { + return shift < other.shift; + } + +} +bool TransitionTM::operator ==(const TransitionTM& other) const { + return from == other.from && input == other.input && to == other.to && output == other.output + && shift == other.shift; +} +bool TransitionTM::operator !=(const TransitionTM& other) const { + return !((*this) == other); +} + +std::ostream& TransitionTM::operator>>(std::ostream& out) const { + out << "TransitionTM from = " << this->from + << " to = " << this->to + << " input = " << this->input + << " output = " << this->output + << " shift = " << SHIFT_NAMES[this->shift]; + + return out; +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/TM/TransitionTM.h b/alib2/src/automaton/TM/TransitionTM.h new file mode 100644 index 0000000000000000000000000000000000000000..124274b023f4895487eca123378d1000acadabc3 --- /dev/null +++ b/alib2/src/automaton/TM/TransitionTM.h @@ -0,0 +1,78 @@ +/* + * TransitionTM.h + * + * Created on: Apr 24, 2013 + * Author: martin + */ + +#ifndef TRANSITIONTM_H_ +#define TRANSITIONTM_H_ + +#include "../../alphabet/Symbol.h" +#include "../Transition.h" +#include "../Shift.h" + +namespace automaton { + +using namespace std; +using namespace alphabet; + +class TransitionTM: public Transition { +protected: + Symbol input; + Symbol output; + Shift shift; +public: + + /** + * Creates new transition with given parameters. + * @param from from state + * @param input input symbol + * @param to to state + * @param output output symbol + * @param shift direction of movement of the reading head + */ + TransitionTM(const State& from, const Symbol& input, const State& to, const Symbol& output, Shift shift); + + /** + * @return input Symbol + */ + const Symbol& getInput() const; + + /** + * Sets the input symbol. + * @param input Symbol + */ + void setInput(const Symbol& input); + + /** + * @return output Symbol + */ + const Symbol& getOutput() const; + + /** + * Sets the output symbol. + * @param output Symbol + */ + void setOutput(const Symbol& output); + + /** + * @return direction of movement of the reading head + */ + Shift getShift() const; + + /** + * Sets the direction of movement of the reading head + * @param shift Shift to set + */ + void setShift(Shift shift); + + bool operator <(const TransitionTM& other) const; + bool operator ==(const TransitionTM& other) const; + bool operator !=(const TransitionTM& other) const; + + std::ostream& operator>>(std::ostream& out) const; +}; + +} /* namespace automaton */ +#endif /* TRANSITIONTM_H_ */ diff --git a/alib2/src/automaton/Transition.cpp b/alib2/src/automaton/Transition.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ee404b7352ecd632a4aecf8e84d3713eb9cd0d54 --- /dev/null +++ b/alib2/src/automaton/Transition.cpp @@ -0,0 +1,45 @@ +/* + * Transition.cpp + * + * Created on: Apr 16, 2013 + * Author: martin + */ + +#include "Transition.h" + +namespace automaton { + +Transition::Transition(const State& current, const State& next) : + from(current), to(next) { + +} + +Transition::~Transition() { + +} +void Transition::setFrom(const State& state) { + from = state; +} + +const State& Transition::getFrom() const { + return from; +} + +void Transition::setTo(const State& state) { + to = state; +} + +const State& Transition::getTo() const { + return to; +} + +bool Transition::containsState(const State& state) const { + return from == state || to == state; +} + +std::ostream& operator<<(std::ostream& out, const Transition& transition) { + transition >> out; + return out; +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/Transition.h b/alib2/src/automaton/Transition.h new file mode 100644 index 0000000000000000000000000000000000000000..b89f3b0c44cac25ddddcfa2a181cb562a22ae139 --- /dev/null +++ b/alib2/src/automaton/Transition.h @@ -0,0 +1,58 @@ +/* + * Transition.h + * + * Created on: Apr 16, 2013 + * Author: martin + */ + +#ifndef TRANSITION_H_ +#define TRANSITION_H_ + +#include "State.h" + +namespace automaton { + +/** + * Abstract base class for all transitions. Contains common elements of transitions. + */ +class Transition { +protected: + State from; + State to; +public: + Transition(const State& current, const State& next); + virtual ~Transition(); + + /** + * @param state State from which the transition goes + */ + void setFrom(const State& state); + + /** + * @return State form which the transition goes + */ + const State& getFrom() const; + + /** + * @param state State to which the transition goes + */ + void setTo(const State& state); + + /** + * @return State to which the transition goes + */ + const State& getTo() const; + + /** + * Determines whether State is used in this transition either as from state or to state. + * @return true when transition contains the state, false otherwise + */ + bool containsState(const State& state) const; + + friend std::ostream& operator<<(std::ostream&, const Transition&); + + virtual std::ostream& operator>>(std::ostream& out) const = 0; +}; + +} /* namespace automaton */ +#endif /* TRANSITION_H_ */ diff --git a/alib2/src/automaton/UnknownAutomaton.cpp b/alib2/src/automaton/UnknownAutomaton.cpp new file mode 100644 index 0000000000000000000000000000000000000000..225802e24b83bd77face09d7504da9d4f8ddfe1e --- /dev/null +++ b/alib2/src/automaton/UnknownAutomaton.cpp @@ -0,0 +1,101 @@ +/* + * UnknownAutomaton.cpp + * + * Created on: Oct 12, 2013 + * Author: martin + */ + +#include "UnknownAutomaton.h" + +#include "AutomatonPrinter.h" +#include "exception/AutomatonException.h" + +namespace automaton { + +UnknownAutomaton::UnknownAutomaton() : + blankSymbol("") { + +} + +UnknownAutomaton::~UnknownAutomaton() { +} + +void UnknownAutomaton::removeState(const State& state) { + if (!states.erase(state)) + throw AutomatonException("State \"" + state.getName() + "\" doesn't exist."); +} + +void UnknownAutomaton::removeInputSymbol(const Symbol& symbol) { + if (!inputAlphabet.erase(symbol)) + throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" doesn't exist."); +} + +const set<Symbol>& UnknownAutomaton::getStackAlphabet() const { + return stackAlphabet; +} + +void UnknownAutomaton::addStackSymbol(const Symbol& symbol) { + if (!stackAlphabet.insert(symbol).second) { + throw AutomatonException("Stack symbol \"" + symbol.getSymbol() + "\" already exists."); + } +} + +void UnknownAutomaton::removeStackSymbol(const Symbol& symbol) { + if (!stackAlphabet.erase(symbol)) + throw AutomatonException("Stack symbol \"" + symbol.getSymbol() + "\" doesn't exist."); +} + +const list<Symbol>& UnknownAutomaton::getStartSymbols() const { + return startSymbols; +} + +void UnknownAutomaton::setStartSymbols(const list<Symbol>& newSymbols) { + this->startSymbols = newSymbols; +} + +const set<Symbol>& UnknownAutomaton::getTapeAlphabet() const { + return tapeAlphabet; +} + +void UnknownAutomaton::addTapeSymbol(const Symbol& symbol) { + if (!tapeAlphabet.insert(symbol).second) { + throw AutomatonException("Tape symbol \"" + symbol.getSymbol() + "\" already exists."); + } +} + +void UnknownAutomaton::removeTapeSymbol(const Symbol& symbol) { + int removed = tapeAlphabet.erase(symbol); + if (!removed) { + throw AutomatonException("Tape symbol \"" + symbol.getSymbol() + "\" doesn't exist."); + } +} + +const Symbol& UnknownAutomaton::getBlankSymbol() const { + return blankSymbol; +} + +void UnknownAutomaton::setBlankSymbol(const Symbol& symbol) { + blankSymbol = symbol; +} + +const set<UnknownTransition>& UnknownAutomaton::getTransitions() const { + return transitions; +} + +void UnknownAutomaton::addTransition(const UnknownTransition& transition) { + if (!transitions.insert(transition).second) { + throw AutomatonException("Transition already exists."); + } +} + +void UnknownAutomaton::removeTransition(const UnknownTransition& transition) { + if (!transitions.erase(transition)) { + throw AutomatonException("Transition doesn't exist."); + } +} + +void UnknownAutomaton::toXML(ostream& out) const { + AutomatonPrinter::toXML(*this, out); +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/UnknownAutomaton.h b/alib2/src/automaton/UnknownAutomaton.h new file mode 100644 index 0000000000000000000000000000000000000000..3adf1b62f34dd5621580c7414aa15424697e4e00 --- /dev/null +++ b/alib2/src/automaton/UnknownAutomaton.h @@ -0,0 +1,139 @@ +/* + * UnknownAutomaton.h + * + * Created on: Oct 12, 2013 + * Author: Martin Zak + */ + +#ifndef UNKNOWNAUTOMATON_H_ +#define UNKNOWNAUTOMATON_H_ + +#include <set> +#include <list> + +#include "Automaton.h" +#include "State.h" +#include "../alphabet/Symbol.h" +#include "UnknownTransition.h" + +namespace automaton { + +using namespace std; +using namespace alphabet; + +/** + * Class representing unknown automaton parsed from XML. + */ +class UnknownAutomaton: public Automaton { +protected: + set<Symbol> stackAlphabet; + list<Symbol> startSymbols; + set<Symbol> tapeAlphabet; + Symbol blankSymbol; + + set<UnknownTransition> transitions; +public: + UnknownAutomaton(); + virtual ~UnknownAutomaton(); + + /** + * Removes the state from the automaton. + * @param state State to remove + * @throws AutomatonException when state is not present in the automaton + */ + void removeState(const State& state); + + /** + * Removes input symbol from the input alphabet. + * @param symbol Symbol to remove + * @throws AutomatonException when symbol is not present in input alphabet + */ + void removeInputSymbol(const Symbol& symbol); + + /** + * @return the stack alphabet + */ + const set<Symbol>& getStackAlphabet() const; + + /** + * Adds symbol to the stack alphabet. + * @param symbol Symbol to add + * @throw AutomatonException when Symbol is already present in stack alphabet + */ + void addStackSymbol(const Symbol& symbol); + + /** + * Removes symbol from the stack alphabet. + * @param symbol Symbol to remove + * @throw AutomatonException when Symbol is not present in input alphabet + */ + void removeStackSymbol(const Symbol& symbol); + + /** + * @return list of start symbols + */ + const list<Symbol>& getStartSymbols() const; + + /** + * Set the start symbol list. + * @param newSymbols symbols to set + */ + void setStartSymbols(const list<Symbol>& newSymbols); + + /** + * @return the tape alphabet + */ + const set<Symbol>& getTapeAlphabet() const; + + /** + * Adds symbol to the tape alphabet. + * @param symbol Symbol to add + * @throw AutomatonException when Symbol is already present in tape alphabet + */ + void addTapeSymbol(const Symbol& symbol); + + /** + * Removes symbol from the tape alphabet. + * @param symbol Symbol to remove + * @throw AutomatonException when Symbol is not present in tape alphabet + */ + void removeTapeSymbol(const Symbol& symbol); + + /** + * @return the blank symbol + */ + const Symbol& getBlankSymbol() const; + + /** + * Sets the blank symbol. + * @param symbol the Symbol to set + */ + void setBlankSymbol(const Symbol& symbol); + + /** + * @return transitions of the automaton + */ + const set<UnknownTransition>& getTransitions() const; + + /** + * Adds new transition to the automaton. + * @param transition UnknownTransition to add + * @throws AutomatonException when transition is already present in the automaton + */ + void addTransition(const UnknownTransition& transition); + + /** + * Removes the transition from the automaton. + * @param transition UnknownTransition to remove + * @throws AutomatonException when transition is not present in the automaton + */ + void removeTransition(const UnknownTransition& transition); + + /** + * @copydoc Automaton::toXML(ostream&) const + */ + void toXML(std::ostream& out) const; +}; + +} /* namespace automaton */ +#endif /* UNKNOWNAUTOMATON_H_ */ diff --git a/alib2/src/automaton/UnknownTransition.cpp b/alib2/src/automaton/UnknownTransition.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8543dccb7fb92ff99677b2351fe922223785e99e --- /dev/null +++ b/alib2/src/automaton/UnknownTransition.cpp @@ -0,0 +1,177 @@ +/* + * UnknownTransition.cpp + * + * Created on: Oct 13, 2013 + * Author: martin + */ + +#include "UnknownTransition.h" + +namespace automaton { + +using namespace std; + +UnknownTransition::UnknownTransition() : + Transition(State(""), State("")), output(""), input("") { + shift = NOT_SET; +} + +const list<Symbol>& UnknownTransition::getPop() const { + return pop; +} + +void UnknownTransition::addPop(const Symbol& symbol) { + pop.push_back(symbol); +} + +const list<Symbol>& UnknownTransition::getPush() const { + return push; +} + +void UnknownTransition::addPush(const Symbol& symbol) { + push.push_back(symbol); +} + +const Symbol& UnknownTransition::getOutput() const { + return output; +} + +void UnknownTransition::setOutput(const Symbol& symbol) { + output = symbol; +} + +const Symbol& UnknownTransition::getInput() const { + return output; +} + +void UnknownTransition::setInput(const Symbol& symbol) { + output = symbol; +} + +const Shift& UnknownTransition::getShift() const { + return shift; +} + +void UnknownTransition::setShift(const Shift& shift) { + this->shift = shift; +} + +bool UnknownTransition::operator <(const UnknownTransition& other) const { + if (from != other.from) { + return from < other.from; + } else if (input != other.input) { + return input < other.input; + } else if (to != other.to) { + return to < other.to; + } else if (output != other.output) { + return output < other.output; + } else if (shift != other.shift) { + return shift < other.shift; + } + + std::list<Symbol>::const_iterator it; + std::list<Symbol>::const_iterator it2; + + //compare pop size + if (pop.size() != other.pop.size()) + return pop.size() < other.pop.size(); + + //compare pop content + it = pop.begin(); + it2 = other.pop.begin(); + while (it != pop.end()) { + if ((*it) != (*it2)) + return (*it) < (*it2); + it++; + it2++; + } + + //compare push size + if (push.size() != other.push.size()) + return push.size() < other.push.size(); + + //compare push content + it = push.begin(); + it2 = other.push.begin(); + while (it != push.end()) { + if ((*it) != (*it2)) + return (*it) < (*it2); + it++; + it2++; + } + + return false; +} + +bool UnknownTransition::operator ==(const UnknownTransition& other) const { + if (from == other.from && input == other.input && to == other.to && output == other.output + && shift == other.shift) { + + //compare pop size + if (pop.size() != other.pop.size()) + return false; + //compare push size + if (push.size() != other.push.size()) + return false; + + std::list<Symbol>::const_iterator it; + std::list<Symbol>::const_iterator it2; + + //compare pop content + it = pop.begin(); + it2 = other.pop.begin(); + while (it != pop.end()) { + if ((*it) != (*it2)) + return false; + it++; + it2++; + } + + //compare push content + it = push.begin(); + it2 = other.push.begin(); + while (it != push.end()) { + if ((*it) != (*it2)) + return false; + it++; + it2++; + } + return true; + } else { + return false; + } +} + +bool UnknownTransition::operator !=(const UnknownTransition& other) const { + return !((*this) == other); +} + +std::ostream& UnknownTransition::operator>>(std::ostream& out) const { + bool first; + out << "UnknownTransition from = " << this->from + << " to = " << this->to + << " input = " << this->input + << " output = " << this->output + << " pop = ["; + + first = true; + for(list<Symbol>::const_iterator iter = this->pop.begin(); iter != this->pop.end(); iter++) { + if(!first) out << ", "; + first = false; + out << *iter; + } + + out << "] push = ["; + + first = true; + for(list<Symbol>::const_iterator iter = this->push.begin(); iter != this->push.end(); iter++) { + if(!first) out << ", "; + first = false; + out << *iter; + } + out << "] shift = " << SHIFT_NAMES[this->shift]; + + return out; +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/UnknownTransition.h b/alib2/src/automaton/UnknownTransition.h new file mode 100644 index 0000000000000000000000000000000000000000..18ba5b0d21fe3088e0d53d9ceb45c0494ed30fc3 --- /dev/null +++ b/alib2/src/automaton/UnknownTransition.h @@ -0,0 +1,101 @@ +/* + * UnknownTransition.h + * + * Created on: Oct 13, 2013 + * Author: Martin Zak + */ + +#ifndef UNKNOWNTRANSITION_H_ +#define UNKNOWNTRANSITION_H_ + +#include <list> + +#include "Transition.h" +#include "State.h" +#include "../alphabet/Symbol.h" +#include "Shift.h" + +namespace automaton { + +using namespace std; +using namespace alphabet; + +/** + * Class representing unknown transition parsed from XML. Part of UnknownAutomaton. + */ +class UnknownTransition: public Transition { +protected: + list<Symbol> pop; + list<Symbol> push; + + Symbol output; + Symbol input; + Shift shift; + +public: + UnknownTransition(); + + /** + * @return list of symbols that are popped from the stack + */ + const list<Symbol>& getPop() const; + + /** + * Add symbol to the end of the list of symbols that are popped from the stack. + * @param symbol Symbol to add + */ + void addPop(const Symbol& symbol); + + /** + * @return list of symbols that are pushed to the stack + */ + const list<Symbol>& getPush() const; + + /** + * Add symbol to the end of the list of symbols that are pushed to the stack. + * @param symbol Symbol to add + */ + void addPush(const Symbol& symbol); + + /** + * @return the output symbol of the transition + */ + const Symbol& getOutput() const; + + /** + * Sets the output Symbol of the transition. + * @param symbol Symbol to set + */ + void setOutput(const Symbol& symbol); + + /** + * @return the output symbol of the transition + */ + const Symbol& getInput() const; + + /** + * Sets the output Symbol of the transition. + * @param symbol Symbol to set + */ + void setInput(const Symbol& symbol); + + /** + * @return direction of movement of the reading head + */ + const Shift& getShift() const; + + /** + * Sets the direction of movement of reading head. + * @param shift the direction + */ + void setShift(const Shift& shift); + + bool operator <(const UnknownTransition& other) const; + bool operator ==(const UnknownTransition& other) const; + bool operator !=(const UnknownTransition& other) const; + + virtual std::ostream& operator>>(std::ostream&) const; +}; + +} /* namespace automaton */ +#endif /* UNKNOWNTRANSITION_H_ */ diff --git a/alib2/src/automaton/exception/AutomatonException.cpp b/alib2/src/automaton/exception/AutomatonException.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f432776b2daa7b49e68dd94ff779b14d6bb0c656 --- /dev/null +++ b/alib2/src/automaton/exception/AutomatonException.cpp @@ -0,0 +1,23 @@ +/* + * AutomatonException.cpp + * + * Created on: Apr 1, 2013 + * Author: Martin Zak + */ + +#include "AutomatonException.h" + +namespace automaton { + +AutomatonException::AutomatonException() { +} + +AutomatonException::AutomatonException(const string& cause) : + AlibException(cause) { +} + +AutomatonException::~AutomatonException() throw () { + +} + +} /* namespace automaton */ diff --git a/alib2/src/automaton/exception/AutomatonException.h b/alib2/src/automaton/exception/AutomatonException.h new file mode 100644 index 0000000000000000000000000000000000000000..fe0fffe1babd18f8dd10f20e4e43d52593780fa6 --- /dev/null +++ b/alib2/src/automaton/exception/AutomatonException.h @@ -0,0 +1,28 @@ +/* + * AutomatonException.h + * + * Created on: Apr 1, 2013 + * Author: Martin Zak + */ + +#ifndef AUTOMATONEXCEPTION_H_ +#define AUTOMATONEXCEPTION_H_ + +#include "../../AlibException.h" + +namespace automaton { + +using namespace std; + +/** + * Exception thrown by an automaton, automaton parser or automaton printer. + */ +class AutomatonException: public alib::AlibException { +public: + AutomatonException(); + AutomatonException(const string& cause); + virtual ~AutomatonException() throw (); +}; + +} /* namespace automaton */ +#endif /* AUTOMATONEXCEPTION_H_ */