diff --git a/adeterminize.rhdpda2/makefile b/adeterminize.rhdpda2/makefile new file mode 100644 index 0000000000000000000000000000000000000000..043ec4d1e675caf5c49150e529e130c7f7f3191e --- /dev/null +++ b/adeterminize.rhdpda2/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=adeterminize.rhdpda2 +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src -I../adeterminize/src +LDFLAGS= -L../alib/lib -L../adeterminize/lib -lxml2 -lalib -ladeterminize -Wl,-rpath,. + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(OBJECTS) -o $@ $(LDFLAGS) + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/adeterminize.rhdpda2/src/RHDPDADeterminizer2.cpp b/adeterminize.rhdpda2/src/RHDPDADeterminizer2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..076da5ccc459c23b4b4f3cfa5a1d9e129c228b7d --- /dev/null +++ b/adeterminize.rhdpda2/src/RHDPDADeterminizer2.cpp @@ -0,0 +1,226 @@ +#include "RHDPDADeterminizer2.h" + +namespace determinization { + + +void RHDPDADeterminizer2::divideTransitions(const set<TransitionPDA>& transitions, set<TransitionPDA>& internalTransitions, + set<TransitionPDA>& pushTransitions, set<TransitionPDA>& popTransitions) { + for (set<TransitionPDA>::iterator transition = transitions.begin(); transition != transitions.end(); transition++) { + if (transition->getPush().size() == 1) { + pushTransitions.insert(*transition); + } else if (transition->getPop().size() == 1) { + popTransitions.insert(*transition); + } else { + internalTransitions.insert(*transition); + } + } +} + + +PDA RHDPDADeterminizer2::determinize(PDA& rhdpda) { + PDA rdpda; + map<string, StateData> states; + const set<TransitionPDA>& transitions = rhdpda.getTransitions(); + set<TransitionPDA> internalTransitions; + set<TransitionPDA> pushTransitions; + set<TransitionPDA> popTransitions; + set<StateSymbolPair> allStateSymbolPairs = RHDPDADeterminizationUtils::buildAllStateSymbolPairs(rhdpda); + vector<SComponent> allScomponents = RHDPDADeterminizationUtils::generateAllPossibleSComponents(allStateSymbolPairs); + vector<RComponent> allRcomponents = RHDPDADeterminizationUtils::generateAllPossibleRComponents(allStateSymbolPairs); + const set<Symbol>& inputAlphabet = rhdpda.getInputAlphabet(); + + DeterminizationUtils::copyInputAlphabet(rhdpda, rdpda); + divideTransitions(transitions, internalTransitions, pushTransitions, popTransitions); + + set<StateSymbolPair> initialSPairs = RHDPDADeterminizationUtils::combineStatesWithSymbol(rhdpda.getStates(), + RHDPDADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL); + set<StateSymbolPair> initialRPairs = RHDPDADeterminizationUtils::combineStatesWithSymbol(rhdpda.getInitialStates(), + RHDPDADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL); + const SComponent& initialS = RHDPDADeterminizationUtils::getSComponentWithPairsIdentity(initialSPairs); + const RComponent& initialR(initialRPairs); + const State& initialState = RHDPDADeterminizationUtils::getOrCreateState(initialS, initialR, states, rdpda); + rdpda.addInitialState(initialState); + + while (true) { + StateData* unmarkedStateData = RHDPDADeterminizationUtils::getUnmarkedState(states); + if (unmarkedStateData == NULL) { + break; + } + + // Internal + for (set<Symbol>::iterator a = inputAlphabet.begin(); a != inputAlphabet.end(); a++) { + SComponent sPrimed; + SComponent& s = unmarkedStateData->s; + for (set<PairOfPairs>::iterator pairOfPairs = s.pairsOfPairs.begin(); + pairOfPairs != s.pairsOfPairs.end(); + pairOfPairs++) { + const StateSymbolPair& x = pairOfPairs->pair1; + const State& r = pairOfPairs->pair2.state; + const Symbol& Y = pairOfPairs->pair2.symbol; + for (set<TransitionPDA>::iterator transition = internalTransitions.begin(); + transition != internalTransitions.end(); + transition++) { + if (transition->getFrom() == r && transition->getInput() == *a) { + const State& q = transition->getTo(); + sPrimed.pairsOfPairs.insert(PairOfPairs(x, StateSymbolPair(q, Y))); + } + } + } + RComponent rPrimed; + RComponent& r = unmarkedStateData->r; + for (set<StateSymbolPair>::iterator pair = r.pairs.begin(); pair != r.pairs.end(); pair++) { + const State& p = pair->state; + const Symbol& Y = pair->symbol; + for (set<TransitionPDA>::iterator transition = internalTransitions.begin(); + transition != internalTransitions.end(); + transition++) { + if (transition->getFrom() == p && transition->getInput() == *a) { + const State& q = transition->getTo(); + rPrimed.pairs.insert(StateSymbolPair(q, Y)); + } + } + } + if (sPrimed.pairsOfPairs.size() > 0 && rPrimed.pairs.size() > 0) { + const State& fromState = unmarkedStateData->state; + const State& toState = RHDPDADeterminizationUtils::getOrCreateState(sPrimed, rPrimed, states, rdpda); + const TransitionPDA transition(fromState, *a, toState); + rdpda.addTransition(transition); + } + } + + // Push + for (set<Symbol>::iterator a = inputAlphabet.begin(); a != inputAlphabet.end(); a++) { + SComponent sDoublePrimed = RHDPDADeterminizationUtils::getSComponentWithPairsIdentity(allStateSymbolPairs); + SComponent& s = unmarkedStateData->s; + RComponent rDoublePrimed; + RComponent& r = unmarkedStateData->r; + for (set<StateSymbolPair>::iterator pair = r.pairs.begin(); pair != r.pairs.end(); pair++) { + const State& p = pair->state; + for (set<TransitionPDA>::iterator transition = pushTransitions.begin(); + transition != pushTransitions.end(); + transition++) { + if (transition->getFrom() == p && transition->getInput() == *a) { + const State& q = transition->getTo(); + const Symbol& Z = transition->getPush().front(); + rDoublePrimed.pairs.insert(StateSymbolPair(q, Z)); + } + } + } + if (rDoublePrimed.pairs.size() > 0) { + const State& fromState = unmarkedStateData->state; + const State& toState = + RHDPDADeterminizationUtils::getOrCreateState(sDoublePrimed, rDoublePrimed, states, rdpda); + string stackSymbolName = RHDPDADeterminizationUtils::buildStackSymbolName(s, r, *a, rdpda); + list<Symbol> pop; + list<Symbol> push(1, Symbol(stackSymbolName)); + const TransitionPDA transition(fromState, *a, toState, pop, push); + rdpda.addTransition(transition); + } + } + + // Pop + for (set<Symbol>::iterator a = inputAlphabet.begin(); a != inputAlphabet.end(); a++) { + for (set<Symbol>::iterator b = inputAlphabet.begin(); b != inputAlphabet.end(); b++) { + SComponent& s = unmarkedStateData->s; + + set<PairOfPairs> update; + for (set<PairOfPairs>::iterator pairOfPairs = s.pairsOfPairs.begin(); + pairOfPairs != s.pairsOfPairs.end(); + pairOfPairs++) { + const State& r = pairOfPairs->pair1.state; + const Symbol& Z = pairOfPairs->pair1.symbol; + const State& rPrimed = pairOfPairs->pair2.state; + if (pairOfPairs->pair2.symbol == Z) { + for (set<TransitionPDA>::iterator pushTransition = pushTransitions.begin(); + pushTransition != pushTransitions.end(); + pushTransition++) { + for (set<TransitionPDA>::iterator popTransition = popTransitions.begin(); + popTransition != popTransitions.end(); + popTransition++) { + const State& p = pushTransition->getFrom(); + const State& q = popTransition->getTo(); + if (pushTransition->getInput() == *a && pushTransition->getTo() == r && + popTransition->getInput() == *b && popTransition->getFrom() == rPrimed && + pushTransition->getPush().front() == Z && popTransition->getPop().front() == Z) { + StateSymbolPair pair1(p, Z); + StateSymbolPair pair2(q, Z); + update.insert(PairOfPairs(pair1, pair2)); + } + } + } + } + } + if (update.size() == 0) { + continue; + } + + for (vector<SComponent>::iterator sPrimed = allScomponents.begin(); + sPrimed != allScomponents.end(); + sPrimed++) { + for (vector<RComponent>::iterator rPrimed = allRcomponents.begin(); + rPrimed != allRcomponents.end(); + rPrimed++) { + RComponent rDoublePrimed; + for (set<PairOfPairs>::iterator updateItem = update.begin(); + updateItem != update.end(); + updateItem++) { + const StateSymbolPair& y = updateItem->pair1; + const StateSymbolPair& x = updateItem->pair2; + if (rPrimed->pairs.find(y) != rPrimed->pairs.end()) { + rDoublePrimed.pairs.insert(x); + } + } + SComponent sDoublePrimed; + for (set<PairOfPairs>::iterator updateItem = update.begin(); + updateItem != update.end(); + updateItem++) { + const StateSymbolPair& z = updateItem->pair1; + const StateSymbolPair& y = updateItem->pair2; + for (set<PairOfPairs>::iterator sPrimedPair = sPrimed->pairsOfPairs.begin(); + sPrimedPair != sPrimed->pairsOfPairs.end(); + sPrimedPair++) { + if (sPrimedPair->pair2 == z) { + const StateSymbolPair& x = sPrimedPair->pair1; + sDoublePrimed.pairsOfPairs.insert(PairOfPairs(x, y)); + } + } + } + if (sDoublePrimed.pairsOfPairs.size() > 0 && rDoublePrimed.pairs.size() > 0) { + const State& fromState = unmarkedStateData->state; + const State& toState = + RHDPDADeterminizationUtils::getOrCreateState(sDoublePrimed, rDoublePrimed, states, rdpda); + string stackSymbolName = + RHDPDADeterminizationUtils::buildStackSymbolName(*sPrimed, *rPrimed, *a, rdpda); + list<Symbol> pop(1, Symbol(stackSymbolName)); + list<Symbol> push; + const TransitionPDA transition(fromState, *b, toState, pop, push); + rdpda.addTransition(transition); + } + } + } + } + } + } + + const set<State>& rhdpdaFinalState = rhdpda.getFinalStates(); + for (map<string, StateData>::iterator state = states.begin(); + state != states.end(); + state++) { + bool isFinalState = false; + RComponent& r = state->second.r; + for (set<StateSymbolPair>::iterator pair = r.pairs.begin(); + pair != r.pairs.end(); + pair++) { + if (rhdpdaFinalState.find(pair->state) != rhdpdaFinalState.end()) { + isFinalState = true; + } + } + if (isFinalState) { + rdpda.addFinalState(state->second.state); + } + } + + return rdpda; +} + +} /* namespace determinization */ diff --git a/adeterminize.rhdpda2/src/RHDPDADeterminizer2.h b/adeterminize.rhdpda2/src/RHDPDADeterminizer2.h new file mode 100644 index 0000000000000000000000000000000000000000..05afe45dbe19a0327ac3ac3351984ecbc74a3dec --- /dev/null +++ b/adeterminize.rhdpda2/src/RHDPDADeterminizer2.h @@ -0,0 +1,33 @@ +#ifndef RHDPDADETERMINZER2_H_ +#define RHDPDADETERMINZER2_H_ + +#include <string> +#include <set> +#include <map> +#include <vector> + +#include "automaton/PDA/PDA.h" +#include "automaton/Transition.h" +#include "automaton/exception/AutomatonException.h" +#include "alphabet/Symbol.h" +#include "DeterminizationUtils.h" +#include "RHDPDADeterminizationUtils.h" +#include "RHDPDADeterminizationStructs.h" + +using namespace std; +using namespace automaton; +using namespace alphabet; + +namespace determinization { + +class RHDPDADeterminizer2 { +protected: + static void divideTransitions(const set<TransitionPDA>& transitions, set<TransitionPDA>& internalTransitions, + set<TransitionPDA>& pushTransitions, set<TransitionPDA>& popTransitions); + +public: + static PDA determinize(PDA& automaton); +}; + +} /* namespace determinization */ +#endif /* RHDPDADETERMINZER2_H_ */ \ No newline at end of file diff --git a/adeterminize.rhdpda2/src/adeterminize.rhdpda2.cpp b/adeterminize.rhdpda2/src/adeterminize.rhdpda2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..700b2bad75c94d8f4bbd89f6d2d4a3853583821d --- /dev/null +++ b/adeterminize.rhdpda2/src/adeterminize.rhdpda2.cpp @@ -0,0 +1,34 @@ +#include <iostream> +#include <set> + +#include "automaton/UnknownAutomaton.h" +#include "AutomatonFactory.h" +#include "AlibException.h" +#include "RHDPDADeterminizer2.h" + + +using namespace std; +using namespace automaton; +using namespace determinization; +using namespace alib; + + +int main(int argc, char** argv) { + UnknownAutomaton automaton; + + try { + string input(istreambuf_iterator<char>(cin), (istreambuf_iterator<char>())); + automaton = AutomatonFactory::fromString(input); + + Automaton* knownAutomaton = AutomatonFactory::buildAutomaton(automaton); + // TODO check that automaton is RHDPDA + PDA deterministicPDA = RHDPDADeterminizer2::determinize(*((PDA*) knownAutomaton)); + deterministicPDA.toXML(cout); + + delete knownAutomaton; + + } catch (AlibException& e) { + cout << e.what() << endl; + return 0; + } +} diff --git a/examples/RHDPDA3.xml b/examples/RHDPDA3.xml new file mode 100644 index 0000000000000000000000000000000000000000..772fa5879085e209e8251b2968d3e9a173e815f5 --- /dev/null +++ b/examples/RHDPDA3.xml @@ -0,0 +1,114 @@ +<automaton> + <states> + <state>0</state> + <state>1</state> + <state>2</state> + <state>3</state> + <state>ERR</state> + </states> + <inputAlphabet> + <symbol>a</symbol> + <symbol>b</symbol> + </inputAlphabet> + <stackAlphabet> + <symbol>a</symbol> + <symbol>x</symbol> + <symbol>_</symbol> + </stackAlphabet> + <transitions> + <transition> + <from>0</from> + <input>a</input> + <to>1</to> + <pop></pop> + <push> + <symbol>x</symbol> + </push> + </transition> + <transition> + <from>0</from> + <input>b</input> + <to>3</to> + <pop></pop> + <push></push> + </transition> + <transition> + <from>1</from> + <input>a</input> + <to>1</to> + <pop></pop> + <push> + <symbol>a</symbol> + </push> + </transition> + <transition> + <from>1</from> + <input>b</input> + <to>2</to> + <pop></pop> + <push></push> + </transition> + <transition> + <from>2</from> + <input>a</input> + <to>2</to> + <pop> + <symbol>a</symbol> + </pop> + <push></push> + </transition> + <transition> + <from>2</from> + <input>a</input> + <to>3</to> + <pop> + <symbol>x</symbol> + </pop> + <push></push> + </transition> + <transition> + <from>2</from> + <input>b</input> + <to>ERR</to> + <pop></pop> + <push></push> + </transition> + <transition> + <from>3</from> + <input>a</input> + <to>ERR</to> + <pop></pop> + <push></push> + </transition> + <transition> + <from>3</from> + <input>b</input> + <to>ERR</to> + <pop></pop> + <push></push> + </transition> + <transition> + <from>ERR</from> + <input>a</input> + <to>ERR</to> + <pop></pop> + <push></push> + </transition> + <transition> + <from>ERR</from> + <input>b</input> + <to>ERR</to> + <pop></pop> + <push></push> + </transition> + </transitions> + <initialStates> + <state>0</state> + </initialStates> + <startSymbols> + <symbol>_</symbol> + </startSymbols> + <finalStates> + <state>3</state> + </finalStates> +</automaton> diff --git a/examples/RHDPDA5.xml b/examples/RHDPDA5.xml new file mode 100644 index 0000000000000000000000000000000000000000..91a822d4ee09a5a21ca9ae1d6eb799a0b99d2b04 --- /dev/null +++ b/examples/RHDPDA5.xml @@ -0,0 +1,42 @@ +<automaton> + <states> + <state>0</state> + <state>1</state> + </states> + <inputAlphabet> + <symbol>a</symbol> + </inputAlphabet> + <stackAlphabet> + <symbol>a</symbol> + <symbol>_</symbol> + </stackAlphabet> + <transitions> + <transition> + <from>0</from> + <input>a</input> + <to>1</to> + <pop></pop> + <push> + <symbol>a</symbol> + </push> + </transition> + <transition> + <from>1</from> + <input>a</input> + <to>0</to> + <pop> + <symbol>a</symbol> + </pop> + <push></push> + </transition> + </transitions> + <initialStates> + <state>0</state> + </initialStates> + <startSymbols> + <symbol>_</symbol> + </startSymbols> + <finalStates> + <state>0</state> + </finalStates> +</automaton> diff --git a/makefile b/makefile index 3958ffa67c0195d0ced76f40241dc8a4ec161665..44ef8fbcef539a11dfc0d6664274efb6bd7b763d 100644 --- a/makefile +++ b/makefile @@ -6,7 +6,7 @@ SUBDIRS_LIBS = alib adeterminize SUBDIRS_BINS = acat \ aconvert aconvert.dot aconvert.gastex aconvert.regexp aconvert.automaton aconvert.grammar \ aminimize \ - adeterminize.fsm adeterminize.idpda adeterminize.vpa adeterminize.vpa2 adeterminize.vpa3 adeterminize.rhdpda \ + adeterminize.fsm adeterminize.idpda adeterminize.vpa adeterminize.vpa2 adeterminize.vpa3 adeterminize.rhdpda adeterminize.rhdpda2 \ adiff adiff.automaton adiff.grammar \ aepsilon \ atrim \