Skip to content
Snippets Groups Projects
Commit 5914d1cd authored by Jan Trávníček's avatar Jan Trávníček
Browse files

DPDA use components

parent df1f7bee
No related branches found
No related tags found
No related merge requests found
......@@ -20,8 +20,10 @@
 
namespace automaton {
 
DPDA::DPDA(State initialState, alphabet::Symbol initialPushdownSymbol) : SingleInitialSymbolPushdownStoreAlphabet(std::move(initialPushdownSymbol)), SingleInitialState(std::move(initialState)) {
DPDA::DPDA ( std::set < State > states, std::set < alphabet::Symbol > inputAlphabet, std::set < alphabet::Symbol > pushdownStoreAlphabet, State initialState, alphabet::Symbol initialSymbol, std::set < State > finalStates ) : std::Components < DPDA, alphabet::Symbol, std::tuple < InputAlphabet, PushdownStoreAlphabet >, std::tuple < InitialSymbol >, automaton::State, std::tuple < States, FinalStates >, std::tuple < InitialState > > ( std::make_tuple ( std::move ( inputAlphabet ), std::move ( pushdownStoreAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ), std::make_tuple ( std::move ( states ), std::move ( finalStates ) ), std::make_tuple ( std::move ( initialState ) ) ) {
}
 
DPDA::DPDA(State initialState, alphabet::Symbol initialPushdownSymbol) : DPDA ( std::set < State > { initialState }, std::set < alphabet::Symbol > { }, std::set < alphabet::Symbol > { initialPushdownSymbol }, initialState, initialPushdownSymbol, std::set < automaton::State > { }) {
}
 
AutomatonBase* DPDA::clone() const {
......@@ -32,72 +34,27 @@ AutomatonBase* DPDA::plunder() && {
return new DPDA(std::move(*this));
}
 
bool DPDA::removeState(const State& state) {
if (initialState == state) {
throw AutomatonException("State \"" + (std::string) state.getName() + "\" is initial state.");
}
if (finalStates.find(state) != finalStates.end()) {
throw AutomatonException("State \"" + (std::string) state.getName() + "\" is final state.");
}
for (const std::pair<const std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > >& transition : transitions) {
if (state == std::get<0>(transition.first))
throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition.");
if( transition.second.first == state)
throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition.");
}
return states.erase(state);
}
bool DPDA::removeInputSymbol(const alphabet::Symbol& symbol) {
for (const std::pair<const std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > >& transition : transitions) {
if (std::get<1>(transition.first).is<alphabet::Symbol>() && symbol == std::get<1>(transition.first).get<alphabet::Symbol>())
throw AutomatonException("Symbol \"" + (std::string) symbol + "\" is used in transition.");
}
return inputAlphabet.erase(symbol);
}
bool DPDA::removePushdownStoreSymbol(const alphabet::Symbol& symbol) {
for (const std::pair<const std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > >& transition : transitions) {
for (const alphabet::Symbol& popSymbol : std::get<2>(transition.first)) {
if (symbol == popSymbol)
throw AutomatonException("Pushdown store symbol \"" + (std::string) symbol + "\" is used in transition.");
}
if (std::find(transition.second.second.begin(), transition.second.second.end(), symbol) != transition.second.second.end())
throw AutomatonException("Pushdown store symbol \"" + (std::string) symbol + "\" is used in transition.");
}
if(initialSymbol == symbol) {
throw AutomatonException("Pushdown store symbol \"" + (std::string) symbol + "\" is start symbol.");
}
return pushdownStoreAlphabet.erase(symbol);
}
bool DPDA::addTransition(State from, std::variant<string::Epsilon, alphabet::Symbol> input, std::vector<alphabet::Symbol> pop, State to, std::vector<alphabet::Symbol> push) {
if (states.find(from) == states.end()) {
if (! getStates().count(from)) {
throw AutomatonException("State \"" + (std::string) from.getName() + "\" doesn't exist.");
}
 
if (input.is<alphabet::Symbol>() && inputAlphabet.find(input.get<alphabet::Symbol>()) == inputAlphabet.end()) {
if (input.is<alphabet::Symbol>() && ! getInputAlphabet().count(input.get<alphabet::Symbol>())) {
throw AutomatonException("Input symbol \"" + (std::string) input.get<alphabet::Symbol>() + "\" doesn't exist.");
}
 
if (states.find(to) == states.end()) {
if (! getStates().count(to)) {
throw AutomatonException("State \"" + (std::string) to.getName() + "\" doesn't exist.");
}
 
for(const alphabet::Symbol& popSymbol : pop) {
if (pushdownStoreAlphabet.find(popSymbol) == pushdownStoreAlphabet.end()) {
if (! getPushdownStoreAlphabet().count(popSymbol)) {
throw AutomatonException("Pushdown store symbol \"" + (std::string) popSymbol + "\" doesn't exist.");
}
}
 
for(const alphabet::Symbol& pushSymbol : push) {
if (pushdownStoreAlphabet.find(pushSymbol) == pushdownStoreAlphabet.end()) {
if (! getPushdownStoreAlphabet().count(pushSymbol)) {
throw AutomatonException("Pushdown store symbol \"" + (std::string) pushSymbol + "\" doesn't exist.");
}
}
......@@ -201,7 +158,7 @@ const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>
}
 
std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > > DPDA::getTransitionsFromState(const State& from) const {
if( states.find(from) == states.end())
if( ! getStates().count(from) )
throw AutomatonException("State \"" + (std::string) from.getName() + "\" doesn't exist");
 
std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > > transitionsFromState;
......@@ -215,7 +172,7 @@ std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std:
}
 
std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > > DPDA::getTransitionsToState(const State& to) const {
if( states.find(to) == states.end())
if( ! getStates().count(to))
throw AutomatonException("State \"" + (std::string) to.getName() + "\" doesn't exist");
 
std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > > transitionsToState;
......@@ -229,8 +186,8 @@ std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std:
}
 
int DPDA::compare(const DPDA& other) const {
auto first = std::tie(states, inputAlphabet, initialState, finalStates, pushdownStoreAlphabet, initialSymbol, transitions);
auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.pushdownStoreAlphabet, other.initialSymbol, other.transitions);
auto first = std::tie(getStates(), getInputAlphabet(), getInitialState(), getFinalStates(), getPushdownStoreAlphabet(), getInitialSymbol(), transitions);
auto second = std::tie(other.getStates(), other.getInputAlphabet(), other.getInitialState(), other.getFinalStates(), other.getPushdownStoreAlphabet(), other.getInitialSymbol(), other.transitions);
 
std::compare<decltype(first)> comp;
return comp(first, second);
......@@ -238,12 +195,12 @@ int DPDA::compare(const DPDA& other) const {
 
void DPDA::operator>>(std::ostream& out) const {
out << "(DPDA "
<< "states = " << states
<< "inputAlphabet = " << inputAlphabet
<< "initialState = " << initialState
<< "finalStates = " << finalStates
<< "pushdownStoreAlphabet = " << pushdownStoreAlphabet
<< "initialSymbol = " << initialSymbol
<< "states = " << getStates()
<< "inputAlphabet = " << getInputAlphabet()
<< "initialState = " << getInitialState()
<< "finalStates = " << getFinalStates()
<< "pushdownStoreAlphabet = " << getPushdownStoreAlphabet()
<< "initialSymbol = " << getInitialSymbol()
<< "transitions = " << transitions
<< ")";
}
......@@ -261,7 +218,7 @@ DPDA DPDA::parse(std::deque<sax::Token>::iterator& input) {
 
std::set<State> states = AutomatonFromXMLParser::parseStates(input);
std::set<alphabet::Symbol> inputSymbols = AutomatonFromXMLParser::parseInputAlphabet(input);
std::set<alphabet::Symbol> stackSymbols = AutomatonFromXMLParser::parsePushdownStoreAlphabet(input);
std::set<alphabet::Symbol> pushdownStoreSymbols = AutomatonFromXMLParser::parsePushdownStoreAlphabet(input);
State initialState = AutomatonFromXMLParser::parseInitialState(input);
alphabet::Symbol initialPushdownStoreSymbol = AutomatonFromXMLParser::parseInitialPushdownStoreSymbol(input);
std::set<State> finalStates = AutomatonFromXMLParser::parseFinalStates(input);
......@@ -269,7 +226,7 @@ DPDA DPDA::parse(std::deque<sax::Token>::iterator& input) {
DPDA automaton(std::move(initialState), std::move(initialPushdownStoreSymbol));
automaton.setStates(std::move(states));
automaton.setInputAlphabet(std::move(inputSymbols));
automaton.setPushdownStoreAlphabet(std::move(stackSymbols));
automaton.setPushdownStoreAlphabet(std::move(pushdownStoreSymbols));
automaton.setFinalStates(std::move(finalStates));
 
AutomatonFromXMLParser::parseTransitions<DPDA>(input, automaton);
......@@ -323,6 +280,120 @@ void DPDA::composeTransitions(std::deque<sax::Token>& out) const {
 
} /* namespace automaton */
 
namespace std {
template < >
bool automaton::DPDA::Component < automaton::DPDA, alphabet::Symbol, automaton::InputAlphabet >::used ( const alphabet::Symbol & symbol ) const {
const automaton::DPDA * automaton = static_cast < const automaton::DPDA * > ( this );
for (const std::pair<const std::tuple<automaton::State, std::variant<::string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<automaton::State, std::vector<alphabet::Symbol> > >& transition : automaton->getTransitions())
if (std::get<1>(transition.first).is<alphabet::Symbol>() && symbol == std::get<1>(transition.first).get<alphabet::Symbol>())
return true;
return false;
}
template < >
bool automaton::DPDA::Component < automaton::DPDA, alphabet::Symbol, automaton::InputAlphabet >::available ( const alphabet::Symbol & ) const {
return true;
}
template < >
void automaton::DPDA::Component < automaton::DPDA, alphabet::Symbol, automaton::InputAlphabet >::valid ( const alphabet::Symbol & ) const {
}
template < >
bool automaton::DPDA::Component < automaton::DPDA, alphabet::Symbol, automaton::PushdownStoreAlphabet >::used ( const alphabet::Symbol & symbol ) const {
const automaton::DPDA * automaton = static_cast < const automaton::DPDA * > ( this );
for (const std::pair<const std::tuple<automaton::State, std::variant<::string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<automaton::State, std::vector<alphabet::Symbol> > >& transition : automaton->getTransitions()) {
const auto & popSymbols = std::get<2>(transition.first);
const auto & pushSymbols = transition.second.second;
if(std::contains(popSymbols.begin(), popSymbols.end(), symbol ) || std::contains(pushSymbols.begin(), pushSymbols.end(), symbol))
return true;
}
if(automaton->getInitialSymbol() == symbol)
return true;
return false;
}
template < >
bool automaton::DPDA::Component < automaton::DPDA, alphabet::Symbol, automaton::PushdownStoreAlphabet >::available ( const alphabet::Symbol & ) const {
return true;
}
template < >
void automaton::DPDA::Component < automaton::DPDA, alphabet::Symbol, automaton::PushdownStoreAlphabet >::valid ( const alphabet::Symbol & ) const {
}
template < >
bool automaton::DPDA::Element < automaton::DPDA, alphabet::Symbol, automaton::InitialSymbol >::available ( const alphabet::Symbol & symbol ) const {
const automaton::DPDA * automaton = static_cast < const automaton::DPDA * > ( this );
return automaton->accessComponent < automaton::PushdownStoreAlphabet > ( ).get ( ).count ( symbol );
}
template < >
void automaton::DPDA::Element < automaton::DPDA, alphabet::Symbol, automaton::InitialSymbol >::valid ( const alphabet::Symbol & ) const {
}
template < >
bool automaton::DPDA::Component < automaton::DPDA, automaton::State, automaton::States >::used ( const automaton::State & state ) const {
const automaton::DPDA * automaton = static_cast < const automaton::DPDA * > ( this );
if ( automaton->getInitialState ( ) == state )
return true;
if ( automaton->getFinalStates ( ).count ( state ) )
return true;
for (const std::pair<const std::tuple<automaton::State, std::variant<::string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<automaton::State, std::vector<alphabet::Symbol> > >& transition : automaton->getTransitions())
if ( state == std::get<0>(transition.first) || transition.second.first == state )
return true;
return false;
}
template < >
bool automaton::DPDA::Component < automaton::DPDA, automaton::State, automaton::States >::available ( const automaton::State & ) const {
return true;
}
template < >
void automaton::DPDA::Component < automaton::DPDA, automaton::State, automaton::States >::valid ( const automaton::State & ) const {
}
template < >
bool automaton::DPDA::Component < automaton::DPDA, automaton::State, automaton::FinalStates >::used ( const automaton::State & ) const {
return false;
}
template < >
bool automaton::DPDA::Component < automaton::DPDA, automaton::State, automaton::FinalStates >::available ( const automaton::State & state ) const {
const automaton::DPDA * automaton = static_cast < const automaton::DPDA * > ( this );
return automaton->accessComponent < automaton::States > ( ).get ( ).count ( state );
}
template < >
void automaton::DPDA::Component < automaton::DPDA, automaton::State, automaton::FinalStates >::valid ( const automaton::State & ) const {
}
template < >
bool automaton::DPDA::Element < automaton::DPDA, automaton::State, automaton::InitialState >::available ( const automaton::State & state ) const {
const automaton::DPDA * automaton = static_cast < const automaton::DPDA * > ( this );
return automaton->accessComponent < automaton::States > ( ).get ( ).count ( state );
}
template < >
void automaton::DPDA::Element < automaton::DPDA, automaton::State, automaton::InitialState >::valid ( const automaton::State & ) const {
}
} /* namespace std */
namespace alib {
 
auto DPDAParserRegister = xmlApi<automaton::Automaton>::ParserRegister<automaton::DPDA>();
......
......@@ -12,15 +12,21 @@
#include <map>
#include <vector>
#include <variant>
#include <core/components.hpp>
#include "../AutomatonBase.h"
#include "../common/SingleInitialState.h"
#include "../common/SingleInitialSymbolPushdownStoreAlphabet.h"
#include "../common/InputAlphabet.h"
#include "../common/State.h"
#include "../../alphabet/Symbol.h"
#include "../../string/Epsilon.h"
 
namespace automaton {
 
class InputAlphabet;
class PushdownStoreAlphabet;
class InitialSymbol;
class States;
class FinalStates;
class InitialState;
/**
* Push Down Automaton
*
......@@ -28,31 +34,105 @@ namespace automaton {
* if $\delta (q, a, \alpha) \neq \emptyset$, $\delta (q, a, \beta) \neq \emptyset$ and $\alpha \neq \beta$, then $\alpha$ is not suffix of $\beta$ and $\beta$ is not suffix of $\alpha$ (formally $\gamma \alpha \neq \beta and \alpha \neq \gamma \beta$).
* if $\delta(q, a, \alpha) \neq \emptyset$, $\delta (q, \varepsilon, \beta) \neq \emptyset$, then $\alpha$ is not suffix of $\beta$ and $\beta$ is not suffix of $\alpha$ (fornally $\gamma \alpha \neq \beta and \alpha \neq \gamma \beta$).
*/
class DPDA : public AutomatonBase, public SingleInitialSymbolPushdownStoreAlphabet, public SingleInitialState, public InputAlphabet {
class DPDA : public AutomatonBase, public std::Components < DPDA, alphabet::Symbol, std::tuple < InputAlphabet, PushdownStoreAlphabet >, std::tuple < InitialSymbol >, automaton::State, std::tuple < States, FinalStates >, std::tuple < InitialState > > {
protected:
std::map < std::tuple < State, std::variant < string::Epsilon, alphabet::Symbol >, std::vector < alphabet::Symbol > >, std::pair < State, std::vector < alphabet::Symbol > > > transitions;
 
public:
explicit DPDA ( std::set < State > states, std::set < alphabet::Symbol > inputAlphabet, std::set < alphabet::Symbol > pushdownStoreSymbol, State initialState, alphabet::Symbol initialPushdownSymbol, std::set < automaton::State > finalStates );
explicit DPDA ( State initialState, alphabet::Symbol initialPushdownSymbol );
 
virtual AutomatonBase * clone ( ) const;
 
virtual AutomatonBase * plunder ( ) &&;
 
/**
* @copydoc Automaton::removeState(const State&)
*/
virtual bool removeState ( const State & state );
const State & getInitialState ( ) const {
return accessElement < InitialState > ( ).get ( );
}
 
/**
* @copydoc Automaton::removeInputSymbol(const Symbol&)
*/
virtual bool removeInputSymbol ( const alphabet::Symbol & symbol );
bool setInitialState ( State state ) {
return accessElement < InitialState > ( ).set ( std::move ( state ) );
}
 
/**
* @copydoc Automaton::removePushdownStoreSymbol(const Symbol&)
*/
virtual bool removePushdownStoreSymbol ( const alphabet::Symbol & symbol );
const std::set < State > & getStates ( ) const {
return accessComponent < States > ( ).get ( );
}
bool addState ( State state ) {
return accessComponent < States > ( ).add ( std::move ( state ) );
}
void setStates ( std::set < State > states ) {
accessComponent < States > ( ).set ( std::move ( states ) );
}
void removeState ( const State & state ) {
accessComponent < States > ( ).remove ( state );
}
const std::set < State > & getFinalStates ( ) const {
return accessComponent < FinalStates > ( ).get ( );
}
bool addFinalState ( State state ) {
return accessComponent < FinalStates > ( ).add ( std::move ( state ) );
}
void setFinalStates ( std::set < State > states ) {
accessComponent < FinalStates > ( ).set ( std::move ( states ) );
}
void removeFinalState ( const State & state ) {
accessComponent < FinalStates > ( ).remove ( state );
}
const std::set < alphabet::Symbol > & getPushdownStoreAlphabet ( ) const {
return accessComponent < PushdownStoreAlphabet > ( ).get ( );
}
bool addPushdownStoreSymbol ( alphabet::Symbol symbol ) {
return accessComponent < PushdownStoreAlphabet > ( ).add ( std::move ( symbol ) );
}
void addPushdownStoreSymbols ( std::set < alphabet::Symbol > symbols ) {
accessComponent < PushdownStoreAlphabet > ( ).add ( std::move ( symbols ) );
}
void setPushdownStoreAlphabet ( std::set < alphabet::Symbol > symbols ) {
accessComponent < PushdownStoreAlphabet > ( ).set ( std::move ( symbols ) );
}
void removePushdownStoreSymbol ( const alphabet::Symbol & symbol ) {
accessComponent < PushdownStoreAlphabet > ( ).remove ( symbol );
}
const alphabet::Symbol & getInitialSymbol ( ) const {
return accessElement < InitialSymbol > ( ).get ( );
}
bool setInitialSymbol ( alphabet::Symbol symbol ) {
return accessElement < InitialSymbol > ( ).set ( std::move ( symbol ) );
}
const std::set < alphabet::Symbol > & getInputAlphabet ( ) const {
return accessComponent < InputAlphabet > ( ).get ( );
}
bool addInputSymbol ( alphabet::Symbol symbol ) {
return accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) );
}
void addInputSymbols ( std::set < alphabet::Symbol > symbols ) {
accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) );
}
void setInputAlphabet ( std::set < alphabet::Symbol > symbols ) {
accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) );
}
void removeInputSymbol ( const alphabet::Symbol & symbol ) {
accessComponent < InputAlphabet > ( ).remove ( symbol );
}
 
/**
* Adds transition to the DPDA.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment