From b1c652aff9f1e9ad7ee49a9b2c120ac2d2dd8452 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Thu, 8 May 2014 12:24:04 +0200 Subject: [PATCH] fix set symmetric difference --- alib2/src/automaton/FSM/CompactFA.cpp | 5 +++-- alib2/src/automaton/FSM/ExtendedFA.cpp | 7 ++++--- alib2/src/automaton/PDA/PDA.cpp | 5 +++-- alib2/src/regexp/RegExp.cpp | 12 ++++++++++++ alib2/src/regexp/RegExp.h | 9 +++++++-- 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/alib2/src/automaton/FSM/CompactFA.cpp b/alib2/src/automaton/FSM/CompactFA.cpp index 1e52c44734..639d63b7c5 100644 --- a/alib2/src/automaton/FSM/CompactFA.cpp +++ b/alib2/src/automaton/FSM/CompactFA.cpp @@ -8,6 +8,7 @@ #include "CompactFA.h" #include "../AutomatonException.h" #include <ostream> +#include <algorithm> namespace automaton { @@ -53,8 +54,8 @@ void CompactFA::addTransition(const State& from, const string::String& input, co if (states.find(from) == states.end()) throw AutomatonException("State \"" + from.getName() + "\" doesn't exist."); - std::set<alphabet::Symbol> inputStringAlphabet = input.getAlphabet(); - inputStringAlphabet.erase(inputAlphabet.begin(), inputAlphabet.end()); + std::set<alphabet::Symbol> inputStringAlphabet; + std::set_symmetric_difference(inputAlphabet.begin(), inputAlphabet.end(), input.getAlphabet().begin(), input.getAlphabet().end(), std::inserter(inputStringAlphabet, inputStringAlphabet.end())); if (inputStringAlphabet.size() != 0) throw AutomatonException("Input string is over different alphabet than automaton"); diff --git a/alib2/src/automaton/FSM/ExtendedFA.cpp b/alib2/src/automaton/FSM/ExtendedFA.cpp index 15d92b3edb..6923fab46c 100644 --- a/alib2/src/automaton/FSM/ExtendedFA.cpp +++ b/alib2/src/automaton/FSM/ExtendedFA.cpp @@ -8,6 +8,7 @@ #include "ExtendedFA.h" #include "../AutomatonException.h" #include <ostream> +#include <algorithm> namespace automaton { @@ -53,9 +54,9 @@ void ExtendedFA::addTransition(const State& from, const regexp::RegExp& input, c if (states.find(from) == states.end()) throw AutomatonException("State \"" + from.getName() + "\" doesn't exist."); - std::set<alphabet::Symbol> inputStringAlphabet = input.getAlphabet(); - inputStringAlphabet.erase(inputAlphabet.begin(), inputAlphabet.end()); - if (inputStringAlphabet.size() != 0) + std::set<alphabet::Symbol> inputRegExpAlphabet; + std::set_symmetric_difference(inputAlphabet.begin(), inputAlphabet.end(), input.getAlphabet().begin(), input.getAlphabet().end(), std::inserter(inputRegExpAlphabet, inputRegExpAlphabet.end())); + if (inputRegExpAlphabet.size() != 0) throw AutomatonException("Input string is over different alphabet than automaton"); if (states.find(to) == states.end()) diff --git a/alib2/src/automaton/PDA/PDA.cpp b/alib2/src/automaton/PDA/PDA.cpp index 80cc0edc1a..5fac6f78fc 100644 --- a/alib2/src/automaton/PDA/PDA.cpp +++ b/alib2/src/automaton/PDA/PDA.cpp @@ -160,8 +160,9 @@ void PDA::removeInitialSymbol(const alphabet::Symbol& start) { void PDA::setInitialSymbols(const std::set<alphabet::Symbol>& symbols) { if(symbols.size() < 1) throw AutomatonException("There must be at least one initial symbol"); - std::set<alphabet::Symbol> tmp(symbols); - tmp.erase(this->stackAlphabet.begin(), this->stackAlphabet.end()); + + std::set<alphabet::Symbol> tmp; + std::set_symmetric_difference(symbols.begin(), symbols.end(), this->stackAlphabet.begin(), this->stackAlphabet.end(), std::inserter(tmp, tmp.end())); if(tmp.size() != 0) throw AutomatonException("Initial symbols not in stack alphabet"); diff --git a/alib2/src/regexp/RegExp.cpp b/alib2/src/regexp/RegExp.cpp index 98fa3f655e..c5082cd1a2 100644 --- a/alib2/src/regexp/RegExp.cpp +++ b/alib2/src/regexp/RegExp.cpp @@ -11,6 +11,7 @@ #include "RegExpSymbol.h" #include <iostream> +#include <algorithm> namespace regexp { @@ -101,6 +102,17 @@ void RegExp::addSymbolToAlphabet(const alphabet::Symbol & symbol) { throw alib::AlibException("Symbol \"" + symbol.getSymbol() + "\" is already in the alphabet."); } +void RegExp::setAlphabet(const std::set<alphabet::Symbol> & symbols) { + std::set<alphabet::Symbol> removedSymbols; + std::set_symmetric_difference(this->alphabet.begin(), this->alphabet.end(), symbols.begin(), symbols.end(), std::inserter(removedSymbols, removedSymbols.end())); + + for(const alphabet::Symbol& symbol : removedSymbols) { + if(this->regExp->testSymbol(symbol)) + throw alib::AlibException("Input symbol \"" + symbol.getSymbol() + "\" is used."); + } + this->alphabet = symbols; +} + void RegExp::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) { if(this->regExp->testSymbol(symbol)) throw alib::AlibException("Input symbol \"" + symbol.getSymbol() + "\" is used."); diff --git a/alib2/src/regexp/RegExp.h b/alib2/src/regexp/RegExp.h index 5906e3cf83..11a50be843 100644 --- a/alib2/src/regexp/RegExp.h +++ b/alib2/src/regexp/RegExp.h @@ -64,8 +64,7 @@ public: void setRegExp(const RegExpElement& regExp); /** - * Sets the root node of the regular expression tree. Doesn't perform copy of the regExp param, - * just stores it! + * Sets the root node of the regular expression tree * @param regExp root node to set */ void setRegExp(RegExpElement&& regExp); @@ -81,6 +80,12 @@ public: * @param symbol new symbol added to the alphabet */ void addSymbolToAlphabet(const alphabet::Symbol & symbol); + + /** + * Sets the alphabet of the regular expression + * @param symbols new alphabet + */ + void setAlphabet(const std::set<alphabet::Symbol>& symbols); /** * Removes symbol from the alphabet of symbol available in the regular expression -- GitLab