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

add verbose automaton minimize algo

parent 89f37da9
No related branches found
No related tags found
No related merge requests found
/*
* 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 */
/*
* 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__ */
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
   
#include <container/xml/ObjectsSet.h> #include <container/xml/ObjectsSet.h>
#include <container/xml/ObjectsMap.h> #include <container/xml/ObjectsMap.h>
#include <container/xml/ObjectsVector.h>
#include <container/xml/ObjectsVariant.h> #include <container/xml/ObjectsVariant.h>
   
#include <common/ranked_symbol.hpp> #include <common/ranked_symbol.hpp>
...@@ -32,6 +33,7 @@ public: ...@@ -32,6 +33,7 @@ public:
abstraction::XmlContainerParserRegistry::registerSet < common::ranked_symbol < object::Object, unsigned > > ( "RankedSymbol" ); abstraction::XmlContainerParserRegistry::registerSet < common::ranked_symbol < object::Object, unsigned > > ( "RankedSymbol" );
abstraction::XmlComposerRegistry::registerXmlComposer < ext::set < common::ranked_symbol < object::Object, unsigned > > > ( ); abstraction::XmlComposerRegistry::registerXmlComposer < ext::set < common::ranked_symbol < object::Object, unsigned > > > ( );
abstraction::XmlComposerRegistry::registerXmlComposer < 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 > > ( ); abstraction::XmlComposerRegistry::registerXmlComposer < ext::map < common::ranked_symbol < object::Object, unsigned >, size_t > > ( );
   
...@@ -42,6 +44,7 @@ public: ...@@ -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::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 < 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::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 > > > > ( );
} }
}; };
   
......
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