diff --git a/alib2algo/src/automaton/simplify/Minimize.h b/alib2algo/src/automaton/simplify/Minimize.h index b81fd92c77e922b6b22fe5fabc86f4e94dcaff78..2ad33d66d16bdea0dd074888f8ea49737176813f 100644 --- a/alib2algo/src/automaton/simplify/Minimize.h +++ b/alib2algo/src/automaton/simplify/Minimize.h @@ -48,101 +48,77 @@ automaton::DFA < SymbolType, StateType > Minimize::minimize(const automaton::DFA std::map<StateType, std::map<SymbolType, StateType > > refactor; - for(const StateType& state : dfa.getStates()) { + for(const StateType& state : dfa.getStates()) refactor.insert(std::make_pair(state, std::map<SymbolType, StateType>())); - } - for(const std::pair<const std::pair<StateType, SymbolType>, StateType>& transition : dfa.getTransitions()) { + for(const std::pair<const std::pair<StateType, SymbolType>, StateType>& transition : dfa.getTransitions()) refactor[transition.first.first].insert(std::make_pair(transition.first.second, transition.second)); - } - - std::map<StateType, StateType> toEquivalentStates1; //original state to equivalent state - std::map<std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> > minimizedTransitionFunction1; //mapped to the original state - std::map<StateType, StateType> toEquivalentStates2; - std::map<std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> > minimizedTransitionFunction2; + std::map<StateType, StateType> toEquivalentStates; //original state to equivalent state + std::map<std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> > minimizedTransitionFunction; //mapped to the original state const StateType *firstFinal = NULL, *firstNonfinal = NULL; for(const StateType& state : dfa.getStates()) { if(dfa.getFinalStates().count(state) == 0) { // not a final state - if(!firstNonfinal) firstNonfinal = &state; - toEquivalentStates2.insert(std::pair<StateType, StateType>(state, *firstNonfinal)); + if(!firstNonfinal) + firstNonfinal = &state; + toEquivalentStates.insert(std::pair<StateType, StateType>(state, *firstNonfinal)); } else { - if(!firstFinal) firstFinal = &state; - toEquivalentStates2.insert(std::pair<StateType, StateType>(state, *firstFinal)); + if(!firstFinal) + firstFinal = &state; + toEquivalentStates.insert(std::pair<StateType, StateType>(state, *firstFinal)); } } - for(const std::pair<const StateType, std::map<SymbolType, StateType> >& transition : refactor) { - const StateType& from = toEquivalentStates2.find(transition.first)->second; - std::set<std::pair<SymbolType, StateType> > transitionFunction; - - for(const std::pair<const SymbolType, StateType> & transitionFromState : transition.second) { - transitionFunction.insert(std::make_pair(transitionFromState.first, toEquivalentStates2.find(transitionFromState.second)->second)); - } - - minimizedTransitionFunction2[std::make_pair(from, transitionFunction)].insert(transition.first); - } - size_t delta_iter = 0; - if(common::GlobalData::verbose) { - print_progress(dfa, minimizedTransitionFunction2, delta_iter++); - } - - do { - toEquivalentStates1 = toEquivalentStates2; - minimizedTransitionFunction1 = minimizedTransitionFunction2; + unsigned prevSize = 0; + while ( true ) { + for(const std::pair<const StateType, std::map<SymbolType, StateType> >& transition : refactor) { + const StateType& from = toEquivalentStates.find(transition.first)->second; + std::set<std::pair<SymbolType, StateType> > transitionFunction; - toEquivalentStates2.clear(); - minimizedTransitionFunction2.clear(); + for(const std::pair<const SymbolType, StateType> & transitionFromState : transition.second) + transitionFunction.insert(std::make_pair(transitionFromState.first, toEquivalentStates.find(transitionFromState.second)->second)); - for(const std::pair<const std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> >& transition : minimizedTransitionFunction1) { - for(const StateType& target : transition.second) { - toEquivalentStates2.insert(std::make_pair(target, *(transition.second.begin()))); - } + minimizedTransitionFunction[std::make_pair(from, transitionFunction)].insert(transition.first); } - for(const std::pair<const StateType, std::map<SymbolType, StateType> >& transition : refactor) { - const StateType& from = toEquivalentStates2.find(transition.first)->second; - std::set<std::pair<SymbolType, StateType> > transitionFunction; + if(common::GlobalData::verbose) + print_progress(dfa, minimizedTransitionFunction, delta_iter++); - for(const std::pair<const SymbolType, StateType> & transitionFromState : transition.second) { - transitionFunction.insert(std::make_pair(transitionFromState.first, toEquivalentStates2.find(transitionFromState.second)->second)); - } + if (minimizedTransitionFunction.size() == prevSize) + break; - minimizedTransitionFunction2[std::make_pair(from, transitionFunction)].insert(transition.first); - } + prevSize = minimizedTransitionFunction.size(); + toEquivalentStates.clear(); - if(common::GlobalData::verbose) { - print_progress(dfa, minimizedTransitionFunction2, delta_iter++); - } + for(const std::pair<const std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> >& transition : minimizedTransitionFunction) + for(const StateType& target : transition.second) + toEquivalentStates.insert(std::make_pair(target, *(transition.second.begin()))); - } while(minimizedTransitionFunction1.size() != minimizedTransitionFunction2.size()); + minimizedTransitionFunction.clear(); + } const StateType* initialState = NULL; - for(const std::pair<const std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> >& transition : minimizedTransitionFunction2) { + for(const std::pair<const std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> >& transition : minimizedTransitionFunction) if(transition.second.count(dfa.getInitialState())) { initialState = &(transition.first.first); break; } - } automaton::DFA < SymbolType, StateType > result(*initialState); result.setInputAlphabet(dfa.getInputAlphabet()); - for(const std::pair<const std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> >& transition : minimizedTransitionFunction2) { + for(const std::pair<const std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> >& transition : minimizedTransitionFunction) { result.addState(transition.first.first); - if(dfa.getFinalStates().count(*(transition.second.begin()))) { + if(dfa.getFinalStates().count(*(transition.second.begin()))) result.addFinalState(transition.first.first); - } } - for(const std::pair<const std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> >& transition : minimizedTransitionFunction2) { - for(const std::pair<SymbolType, StateType>& transitionFromState : transition.first.second) { + for(const std::pair<const std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> >& transition : minimizedTransitionFunction) + for(const std::pair<SymbolType, StateType>& transitionFromState : transition.first.second) result.addTransition(transition.first.first, transitionFromState.first, transitionFromState.second); - } - } return result; } @@ -153,7 +129,7 @@ template < class SymbolType, class StateType > void Minimize::print_progress(const automaton::DFA < SymbolType, StateType >& dfa, const std::map<std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> >& minimizedTransitionFunction, size_t iter) { std::clog << "delta " << iter << std::endl; - //std::map<std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> > minimizedTransitionFunction1; //mapped to the original state + //std::map<std::pair<StateType, std::set<std::pair<SymbolType, StateType> > >, std::set<StateType> > minimizedTransitionFunction; //mapped to the original state /* need to restruct this first so we have table like: orig state | new state | trans_symb_1 | trans_symb_2 | ... | trans_symb_n */ // we surely have DFA here (transition map hence)