diff --git a/alib2algo/src/automaton/simplify/MinimizeVerbose.cpp b/alib2algo/src/automaton/simplify/MinimizeVerbose.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b69f1dc015974c8b60644082a5172d2e934f452c --- /dev/null +++ b/alib2algo/src/automaton/simplify/MinimizeVerbose.cpp @@ -0,0 +1,19 @@ +/* + * MinimizeVerbose.cpp + * + * Created on: Dec 9, 2013 + * Author: honza + */ + +#include "MinimizeVerbose.h" +#include <registration/AlgoRegistration.hpp> + +namespace automaton { + +namespace simplify { + +auto MinimizeVerboseNFA = registration::AbstractRegister < MinimizeVerbose, ext::vector < ext::map < std::pair < DefaultStateType, DefaultStateType >, ext::map < DefaultSymbolType, DefaultStateType > > >, const automaton::DFA < > & > ( MinimizeVerbose::minimize ); + +} /* namespace simplify */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/simplify/MinimizeVerbose.h b/alib2algo/src/automaton/simplify/MinimizeVerbose.h new file mode 100644 index 0000000000000000000000000000000000000000..7409640efb38bb1af656db32bb16cd9cb93c8b78 --- /dev/null +++ b/alib2algo/src/automaton/simplify/MinimizeVerbose.h @@ -0,0 +1,148 @@ +/* + * MinimizeVerbose.h + * + * This file is part of Algorithms library toolkit. + * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz) + + * Algorithms library toolkit is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * Algorithms library toolkit is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>. + * + * Created on: Dec 9, 2013 + * Author: Jan Travnicek + */ + +#ifndef _MINIMIZE_VERBOSE_H__ +#define _MINIMIZE_VERBOSE_H__ + +#include <automaton/FSM/DFA.h> +#include <automaton/TA/DFTA.h> + +#include <alib/map> +#include <alib/set> +#include <iomanip> +#include <sstream> + +#include <global/GlobalData.h> + +namespace automaton { + +namespace simplify { + +/** + * Minimization of automata. + * + * For finite automata, we implement Hopcroft's subset minimization. + * For finite tree automata, we implement ???. + * + * @sa automaton::simplify::MinimizeBrzozowski + */ +class MinimizeVerbose { +public: + /** + * Minimizes deterministic finite autmaton, also reports number of iterations it took. + * + * @tparam SymbolType Type for input symbols. + * @tparam StateType Type for states. + * @param dfa deterministic finite automaton to minimize. + * @return trace of minimisation of the automaton + */ + template < class SymbolType, class StateType > + static ext::vector < ext::map < std::pair < StateType, StateType >, ext::map < SymbolType, StateType > > > minimize(const automaton::DFA < SymbolType, StateType >& dfa ); + +private: + template < class SymbolType, class StateType > + static ext::map < std::pair < StateType, StateType >, ext::map < SymbolType, StateType > > print_progress ( const ext::map<std::pair<StateType, ext::set<std::pair<SymbolType, StateType> > >, ext::set<StateType> >& minimizedTransitionFunction); +}; + +template < class SymbolType, class StateType > +ext::vector < ext::map < std::pair < StateType, StateType >, ext::map < SymbolType, StateType > > > MinimizeVerbose::minimize(const automaton::DFA < SymbolType, StateType >& dfa ) { + ext::vector < ext::map < std::pair < StateType, StateType >, ext::map < SymbolType, StateType > > > res; + + ext::map<StateType, ext::map<SymbolType, StateType > > refactor; + + for(const StateType& state : dfa.getStates()) + refactor.insert(std::make_pair(state, ext::map<SymbolType, StateType>())); + + 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)); + + ext::map<StateType, StateType> toEquivalentStates; //original state to equivalent state + ext::map<std::pair<StateType, ext::set<std::pair<SymbolType, StateType> > >, ext::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; + toEquivalentStates.insert(std::pair<StateType, StateType>(state, *firstNonfinal)); + } else { + if(!firstFinal) + firstFinal = &state; + toEquivalentStates.insert(std::pair<StateType, StateType>(state, *firstFinal)); + } + } + + unsigned prevSize = 0; + while ( true ) { + for(const std::pair<const StateType, ext::map<SymbolType, StateType> >& transition : refactor) { + const StateType& from = toEquivalentStates.find(transition.first)->second; + ext::set<std::pair<SymbolType, StateType> > transitionFunction; + + for(const std::pair<const SymbolType, StateType> & transitionFromState : transition.second) + transitionFunction.insert(std::make_pair(transitionFromState.first, toEquivalentStates.find(transitionFromState.second)->second)); + + minimizedTransitionFunction[std::make_pair(from, transitionFunction)].insert(transition.first); + } + + res.push_back ( print_progress ( minimizedTransitionFunction) ); + + if (minimizedTransitionFunction.size() == prevSize) + break; + + prevSize = minimizedTransitionFunction.size(); + toEquivalentStates.clear(); + + for(const std::pair<const std::pair<StateType, ext::set<std::pair<SymbolType, StateType> > >, ext::set<StateType> >& transition : minimizedTransitionFunction) + for(const StateType& target : transition.second) + toEquivalentStates.insert(std::make_pair(target, *(transition.second.begin()))); + + minimizedTransitionFunction.clear(); + } + + return res; +} + +#define RESETSS(x) {(x).clear(); (x).str("");} + +template < class SymbolType, class StateType > +ext::map<std::pair<StateType, StateType>, ext::map<SymbolType, StateType>> MinimizeVerbose::print_progress ( const ext::map<std::pair<StateType, ext::set<std::pair<SymbolType, StateType> > >, ext::set<StateType> >& minimizedTransitionFunction) { + /* 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) + ext::map<std::pair<StateType, StateType>, ext::map<SymbolType, StateType>> printMap; + for(const auto& kv: minimizedTransitionFunction) { + for(const auto& state : kv.second) { + ext::map<SymbolType, StateType> stateTransMap; + for(const auto& transition : kv.first.second) { + stateTransMap.insert(std::make_pair(transition.first, transition.second)); + } + printMap.insert(std::make_pair(std::make_pair(state, kv.first.first), stateTransMap)); + } + } + return printMap; +} + +} /* namespace simplify */ + +} /* namespace automaton */ + +#endif /* _MINIMIZE_VERBOSE_H__ */ diff --git a/alib2data/src/PrimitiveRegistrator.cpp b/alib2data/src/PrimitiveRegistrator.cpp index 97e3c565526276124e3bf153ab0b4e98e5f3acd5..652471f4c70be7df5e3b23f8528656df34e1ae49 100644 --- a/alib2data/src/PrimitiveRegistrator.cpp +++ b/alib2data/src/PrimitiveRegistrator.cpp @@ -15,6 +15,7 @@ #include <container/xml/ObjectsSet.h> #include <container/xml/ObjectsMap.h> +#include <container/xml/ObjectsVector.h> #include <container/xml/ObjectsVariant.h> #include <common/ranked_symbol.hpp> @@ -32,6 +33,7 @@ public: abstraction::XmlContainerParserRegistry::registerSet < common::ranked_symbol < object::Object, unsigned > > ( "RankedSymbol" ); abstraction::XmlComposerRegistry::registerXmlComposer < ext::set < common::ranked_symbol < object::Object, unsigned > > > ( ); abstraction::XmlComposerRegistry::registerXmlComposer < common::ranked_symbol < object::Object, unsigned > > ( ); + abstraction::XmlComposerRegistry::registerXmlComposer < ext::vector < ext::map < std::pair < object::Object, object::Object >, ext::map < object::Object, object::Object > > > > ( ); abstraction::XmlComposerRegistry::registerXmlComposer < ext::map < common::ranked_symbol < object::Object, unsigned >, size_t > > ( ); @@ -42,6 +44,7 @@ public: core::xmlApi < object::Object >::template registerXmlWriter < ext::set < common::ranked_symbol < object::Object, unsigned > > > ( ); core::xmlApi < object::Object >::template registerXmlWriter < ext::pair < ext::set < ext::pair < object::Object, object::Object > >, ext::variant < string::Epsilon < object::Object >, object::Object > > > ( ); core::xmlApi < object::Object >::template registerXmlWriter < ext::pair < object::Object, ext::variant < string::Epsilon < object::Object >, object::Object > > > ( ); + core::xmlApi < object::Object >::template registerXmlWriter < ext::vector < ext::map < std::pair < object::Object, object::Object >, ext::map < object::Object, object::Object > > > > ( ); } };