diff --git a/adeterminize.vpa3/src/VPADeterminizer3.cpp b/adeterminize.vpa3/src/VPADeterminizer3.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a4e0016072c981c01f2f548bf6cf3a070f0856b8 --- /dev/null +++ b/adeterminize.vpa3/src/VPADeterminizer3.cpp @@ -0,0 +1,277 @@ +#include "VPADeterminizer3.h" + +namespace determinization { + + +string VPADeterminizer3::buildStateName(const SComponent& s) { + string name = "{"; + for (set<StatesPair>::const_iterator statesPair = s.statesPairs.begin(); + statesPair != s.statesPairs.end(); + statesPair++) { + if (statesPair != s.statesPairs.begin()) { + name += ", "; + } + name += "('" + statesPair->state1.getName() + "', '" + statesPair->state2.getName() + "')"; + } + name += "}"; + return name; +} + + +string VPADeterminizer3::buildStackSymbolName(const SComponent& s, const Symbol& input) { + string name = "(" + buildStateName(s) + ")"; + name += ", " + input.getSymbol(); + return name; +} + + +const State& VPADeterminizer3::getOrCreateState(const SComponent& s, map<string, StateData>& states, + PDA& deterministicVPA) { + string stateName = buildStateName(s); + + map<string, StateData>::iterator statesIter = states.find(stateName); + if (statesIter != states.end()) { + return statesIter->second.state; + } + + State state(stateName); + StateData stateData(state, s); + StateData& insertedData = states.insert(pair<string, StateData>(stateName, stateData)).first->second; + deterministicVPA.addState(state); + return insertedData.state; +} + + +vector<SComponent> VPADeterminizer3::buildStackAlphabet(PDA& nondeterministicVPA, PDA& deterministicVPA, + set<Symbol>& callSymbols) { + const set<State>& states = nondeterministicVPA.getStates(); + + // Generate all possible states pairs + vector<StatesPair> possibleStatesPairs; + for (set<State>::iterator state1 = states.begin(); state1 != states.end(); state1++) { + for (set<State>::iterator state2 = states.begin(); state2 != states.end(); state2++) { + possibleStatesPairs.push_back(StatesPair(*state1, *state2)); + } + } + + // Generate all possible s components = partial stack alphabet + vector<SComponent> partialStackAlphabet; + int possibleSSize = pow(2, possibleStatesPairs.size()); + for (int i = 0; i < possibleSSize; i++) { + set<StatesPair> statesPairsSet; + int mask = 1; + for (vector<StatesPair>::iterator statesPair = possibleStatesPairs.begin(); + statesPair != possibleStatesPairs.end(); + statesPair++) { + if ((i & mask) != 0) { + statesPairsSet.insert(*statesPair); + } + mask <<= 1; + } + partialStackAlphabet.push_back(SComponent(statesPairsSet)); + } + + // Generate whole stack alphabet + set<Symbol> alphabet = nondeterministicVPA.getInputAlphabet(); + for (vector<SComponent>::iterator s = partialStackAlphabet.begin(); s != partialStackAlphabet.end(); s++) { + for (set<Symbol>::iterator callSymbol = callSymbols.begin(); callSymbol != callSymbols.end(); callSymbol++) { + string stackSymbolName = VPADeterminizer3::buildStackSymbolName(*s, *callSymbol); + deterministicVPA.addStackSymbol(Symbol(stackSymbolName)); + } + } + + // Add bottom of stack symbol + deterministicVPA.addStackSymbol(VPADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL); + + return partialStackAlphabet; +} + + +PDA VPADeterminizer3::determinize(PDA& nondeterministicVPA) { + PDA deterministicVPA; + map<string, StateData> states; + set<Symbol> internalSymbols; + set<Symbol> callSymbols; + set<Symbol> returnSymbols; + + DeterminizationUtils::copyInputAlphabet(nondeterministicVPA, deterministicVPA); + VPADeterminizationUtils::divideInputAlphabet(nondeterministicVPA, internalSymbols, callSymbols, returnSymbols); + vector<SComponent> partialStackAlphabet = VPADeterminizer3::buildStackAlphabet(nondeterministicVPA, + deterministicVPA, callSymbols); + + const SComponent& initialS = VPADeterminizationUtils::getSComponentWithStatesIdentity( + nondeterministicVPA.getInitialStates()); + const State& initialState = VPADeterminizer3::getOrCreateState(initialS, states, deterministicVPA); + deterministicVPA.addInitialState(initialState); + + set<TransitionPDA> transitions = nondeterministicVPA.getTransitions(); + + while (true) { + StateData* unmarkedStateData = VPADeterminizationUtils::getUnmarkedState(states); + if (unmarkedStateData == NULL) { + break; + } + + // Internal symbols + for (set<Symbol>::iterator internalSymbol = internalSymbols.begin(); + internalSymbol != internalSymbols.end(); + internalSymbol++) { + SComponent sPrimed; + SComponent& s = unmarkedStateData->s; + for (set<StatesPair>::iterator statesPair = s.statesPairs.begin(); + statesPair != s.statesPairs.end(); + statesPair++) { + const State& q = statesPair->state1; + const State& qDoublePrimed = statesPair->state2; + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == qDoublePrimed && transition->getInput() == *internalSymbol) { + const State& qPrimed = transition->getTo(); + sPrimed.statesPairs.insert(StatesPair(q, qPrimed)); + } + } + } + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizer3::getOrCreateState(sPrimed, states, deterministicVPA); + const TransitionPDA transition(fromState, *internalSymbol, toState); + deterministicVPA.addTransition(transition); + } + + // Call symbols + for (set<Symbol>::iterator callSymbol = callSymbols.begin(); + callSymbol != callSymbols.end(); + callSymbol++) { + RComponent rPrimed; + SComponent& s = unmarkedStateData->s; + for (set<StatesPair>::iterator statesPair = s.statesPairs.begin(); + statesPair != s.statesPairs.end(); + statesPair++) { + const State& q = statesPair->state2; + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == q && transition->getInput() == *callSymbol) { + const State& qPrimed = transition->getTo(); + rPrimed.states.insert(qPrimed); + } + } + } + const SComponent& sPrimed = VPADeterminizationUtils::getSComponentWithStatesIdentity(rPrimed.states); + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizer3::getOrCreateState(sPrimed, states, deterministicVPA); + string stackSymbolName = VPADeterminizer3::buildStackSymbolName(s, *callSymbol); + list<Symbol> pop; + list<Symbol> push(1, Symbol(stackSymbolName)); + const TransitionPDA transition(fromState, *callSymbol, toState, pop, push); + deterministicVPA.addTransition(transition); + } + + // Return symbols + for (set<Symbol>::iterator returnSymbol = returnSymbols.begin(); + returnSymbol != returnSymbols.end(); + returnSymbol++) { + SComponent& s = unmarkedStateData->s; + + // Empty stack + list<Symbol> bottomOfStack(1, VPADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL); + SComponent sPrimed; + for (set<StatesPair>::iterator statesPair = s.statesPairs.begin(); + statesPair != s.statesPairs.end(); + statesPair++) { + const State& q = statesPair->state1; + const State& qDoublePrimed = statesPair->state2; + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == qDoublePrimed && transition->getInput() == *returnSymbol && + transition->getPop() == bottomOfStack) { + const State& qPrimed = transition->getTo(); + sPrimed.statesPairs.insert(StatesPair(q, qPrimed)); + } + } + } + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizer3::getOrCreateState(sPrimed, states, deterministicVPA); + list<Symbol> pop(1, VPADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL); + list<Symbol> push; + const TransitionPDA transition(fromState, *returnSymbol, toState, pop, push); + deterministicVPA.addTransition(transition); + + // Otherwise + for (set<Symbol>::iterator callSymbol = callSymbols.begin(); callSymbol != callSymbols.end(); callSymbol++) { + set<StatesPair> update; + for (set<StatesPair>::iterator sPair = s.statesPairs.begin(); + sPair != s.statesPairs.end(); + sPair++) { + const State& q1 = sPair->state1; + const State& q2 = sPair->state2; + for (set<TransitionPDA>::iterator transitionPush = transitions.begin(); + transitionPush != transitions.end(); + transitionPush++) { + for (set<TransitionPDA>::iterator transitionPop = transitions.begin(); + transitionPop != transitions.end(); + transitionPop++) { + const State& q = transitionPush->getFrom(); + const State& qPrimed = transitionPop->getTo(); + if (transitionPush->getInput() == *callSymbol && transitionPush->getTo() == q1 && + transitionPop->getInput() == *returnSymbol && transitionPop->getFrom() == q2 && + transitionPush->getPush() == transitionPop->getPop()) { + update.insert(StatesPair(q, qPrimed)); + } + } + } + } + if (update.size() == 0) { + continue; + } + + for (vector<SComponent>::iterator partialStackSymbol = partialStackAlphabet.begin(); + partialStackSymbol != partialStackAlphabet.end(); + partialStackSymbol++) { + SComponent& sPrimed = *partialStackSymbol; + SComponent sDoublePrimed; + for (set<StatesPair>::iterator updateItem = update.begin(); + updateItem != update.end(); + updateItem++) { + const State& q3 = updateItem->state1; + const State& qPrimed = updateItem->state2; + for (set<StatesPair>::iterator sPrimedPair = sPrimed.statesPairs.begin(); + sPrimedPair != sPrimed.statesPairs.end(); + sPrimedPair++) { + if (sPrimedPair->state2 == q3) { + const State& q = sPrimedPair->state1; + sDoublePrimed.statesPairs.insert(StatesPair(q, qPrimed)); + } + } + } + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizer3::getOrCreateState(sDoublePrimed, states, deterministicVPA); + string stackSymbolName = VPADeterminizer3::buildStackSymbolName(sPrimed, *callSymbol); + list<Symbol> pop(1, Symbol(stackSymbolName)); + list<Symbol> push; + const TransitionPDA transition(fromState, *returnSymbol, toState, pop, push); + deterministicVPA.addTransition(transition); + } + } + } + } + + // Final states + for (map<string, StateData>::iterator stateIter = states.begin(); stateIter != states.end(); stateIter++) { + const StateData& stateData = stateIter->second; + set<State> secondStates; + for (set<StatesPair>::iterator sPair = stateData.s.statesPairs.begin(); + sPair != stateData.s.statesPairs.end(); + sPair++) { + secondStates.insert(sPair->state2); + } + if (DeterminizationUtils::containSomeFinalStateOfAutomaton(secondStates, nondeterministicVPA)) { + deterministicVPA.addFinalState(stateData.state); + } + } + + return deterministicVPA; +} + +} /* namespace determinization */ diff --git a/adeterminize.vpa3/src/VPADeterminizer3.h b/adeterminize.vpa3/src/VPADeterminizer3.h new file mode 100644 index 0000000000000000000000000000000000000000..f1a252f5d10e0abd97d57c2d866a3c0fc4880f84 --- /dev/null +++ b/adeterminize.vpa3/src/VPADeterminizer3.h @@ -0,0 +1,34 @@ +#ifndef VPADETERMINIZER2_H_ +#define VPADETERMINIZER2_H_ + +#include <string> +#include <set> +#include <map> +#include <vector> + +#include "automaton/PDA/PDA.h" +#include "automaton/Transition.h" +#include "alphabet/Symbol.h" +#include "DeterminizationUtils.h" +#include "VPADeterminizationUtils.h" +#include "VPADeterminizationStructs.h" + +using namespace std; +using namespace automaton; +using namespace alphabet; + +namespace determinization { + +class VPADeterminizer3 { +protected: + static string buildStateName(const SComponent& s); + static string buildStackSymbolName(const SComponent& s, const Symbol& input); + static const State& getOrCreateState(const SComponent& s, map<string, StateData>& states, PDA& deterministicVPA); + static vector<SComponent> buildStackAlphabet(PDA& nondeterministicVPA, PDA& deterministicVPA, set<Symbol>& callSymbols); + +public: + static PDA determinize(PDA& automaton); +}; + +} /* namespace determinization */ +#endif /* VPADETERMINIZER2_H_ */ \ No newline at end of file diff --git a/adeterminize.vpa3/src/adeterminize.vpa3.cpp b/adeterminize.vpa3/src/adeterminize.vpa3.cpp new file mode 100644 index 0000000000000000000000000000000000000000..364824b69ae6fbd3c488b9d26cadc3da6c541d7e --- /dev/null +++ b/adeterminize.vpa3/src/adeterminize.vpa3.cpp @@ -0,0 +1,34 @@ +#include <iostream> +#include <set> + +#include "automaton/UnknownAutomaton.h" +#include "AutomatonFactory.h" +#include "AlibException.h" +#include "VPADeterminizer3.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 VPA + PDA deterministicVPA = VPADeterminizer3::determinize(*((PDA*) knownAutomaton)); + deterministicVPA.toXML(cout); + + delete knownAutomaton; + + } catch (AlibException& e) { + cout << e.what() << endl; + return 0; + } +} \ No newline at end of file diff --git a/adeterminize/src/VPADeterminizationStructs.h b/adeterminize/src/VPADeterminizationStructs.h index 29772cdcb5b44e14dcc6fd25ac81bb473fe48d46..cdf196a15be8980975bf06980d7e6add87c26a0f 100644 --- a/adeterminize/src/VPADeterminizationStructs.h +++ b/adeterminize/src/VPADeterminizationStructs.h @@ -56,6 +56,11 @@ struct StateData { r(r), state(state), isMarked(false) {} + + StateData(const State& state, const SComponent& s) + : s(s), + state(state), + isMarked(false) {} };