automaton_fwd.h

Back to Finite-state automaton

pastel/sys/automaton/

#ifndef PASTELSYS_AUTOMATON_FWD_H
#define PASTELSYS_AUTOMATON_FWD_H

#include "pastel/sys/mytypes.h"
#include "pastel/sys/incidence_graph/incidence_graph_fwd.h"
#include "pastel/sys/generic/class.h"
#include "pastel/sys/optional/optional.h"
#include "pastel/sys/iterator/second_iterator.h"
#include "pastel/sys/hashing/iteratoraddress_hash.h"
#include "pastel/sys/hashing.h"

#include <unordered_map>

namespace Pastel
{

    template <
        typename Symbol, 
        typename StateData, 
        typename TransitionData,
        typename Customization>
    class Automaton;

    namespace Automaton_
    {

        template <
            typename Symbol,
            typename StateData,
            typename TransitionData>
        class StateLabel;

        template <
            typename Symbol, 
            typename StateData, 
            typename TransitionData>
        class TransitionLabel;

    }

    template <
        typename Symbol, 
        typename StateData, 
        typename TransitionData>
    class Automaton_Fwd
    {
    public:
        //! The start/final-labeling of the state.
        using StateLabel = 
            Automaton_::StateLabel<Symbol, StateData, TransitionData>;

        //! The symbol-labeling of the transition.
        using TransitionLabel = 
            Automaton_::TransitionLabel<Symbol, StateData, TransitionData>;

        //! The underlying graph.
        using Graph_Settings = IncidenceGraph_Settings<
            GraphType::Directed, 
            StateLabel, 
            TransitionLabel>;
        typedef IncidenceGraph_Fwd<Graph_Settings> 
            Graph_Fwd;
        typedef IncidenceGraph<Graph_Settings> 
            Graph;

        //! The states.
        /*!
       The states are the vertices of the graph.
       */
        typedef typename Graph_Fwd::Vertex_Iterator
            State_Iterator;
        typedef typename Graph_Fwd::Vertex_ConstIterator
            State_ConstIterator;

        //! The user-data for the states.
        struct State_Tag;
        using StateData_Class = 
            Class<StateData, State_Tag>;
;
        //! The transitions.
        /*!
       The transitions are the edges of the graph, 
       labeled with symbols.
       */
        typedef typename Graph_Fwd::Edge_Iterator
            Transition_Iterator;
        typedef typename Graph_Fwd::Edge_ConstIterator
            Transition_ConstIterator;

        //! The user-data for the transitions.
        struct TransitionData_Tag;
        using TransitionData_Class = 
            Class<TransitionData, TransitionData_Tag>;

        typedef typename Graph_Fwd::Incidence_Iterator
            Incidence_Iterator;
        typedef typename Graph_Fwd::Incidence_ConstIterator
            Incidence_ConstIterator;

        //! The set of final states.
        using FinalSet = std::list<State_ConstIterator>;

        typedef typename FinalSet::iterator
            Final_Iterator;
    #ifdef __GNUC__
        /*
       Since even gcc 4.7 does not implement the C++11 
       container support for const_iterators properly,
       we will have to use mutable iterators as a hack.
       */
        using Final_ConstIterator = Final_Iterator;
    #else
        typedef typename FinalSet::const_iterator
            Final_ConstIterator;
    #endif

        //! The set of start states.
        using StartSet = std::list<State_ConstIterator>;
        typedef typename StartSet::iterator
            Start_Iterator;
    #ifdef __GNUC__
        using Start_ConstIterator = Start_Iterator;
    #else
        typedef typename StartSet::const_iterator
            Start_ConstIterator;
    #endif

        //! A set of branches.
        /*!
       A branch-set is a set of transitions with the same
       from-state and a symbol. The elements of the branch-set
       are called branches, referring to how to the computation
       in a non-deterministic automaton branches when there are 
       multiple branches to follow.
       */
        typedef std::unordered_map<
            State_ConstIterator, Transition_ConstIterator,
            IteratorAddress_Hash>
            BranchMap;
        typedef typename BranchMap::iterator
            Actual_Branch_Iterator;
    #ifdef __GNUC__
        using Actual_Branch_ConstIterator = Actual_Branch_Iterator;
    #else
        typedef typename BranchMap::const_iterator
            Actual_Branch_ConstIterator;
    #endif
        typedef Second_Iterator<Actual_Branch_Iterator, false>
            Branch_Iterator;
    #ifdef __GNUC__
        using Branch_ConstIterator = Branch_Iterator;
    #else
        typedef Second_Iterator<Actual_Branch_ConstIterator, true>
            Branch_ConstIterator;
    #endif

    private:
        template <
            typename, typename, 
            typename, typename>
        friend class Automaton;

        class StateSymbol
        {
        public:
            StateSymbol(
                State_ConstIterator state_,
                Optional<Symbol> symbol_)
                : state(std::move(state_))
                , symbol(std::move(symbol_))
            {
            }

            bool operator==(const StateSymbol& that) const
            {
                return state == that.state &&
                    symbol == that.symbol;
            }

            bool operator!=(const StateSymbol& that) const
            {
                return !(*this == that);
            }

            State_ConstIterator state;
            Optional<Symbol> symbol;
        };

        class StateSymbol_Hash
        {
        public:
            Pastel::hash_integer operator()(
                const StateSymbol& transition) const
            {
                return Pastel::combineHash(
                    Pastel::computeHash(&*transition.state),
                    Pastel::computeHash(transition.symbol));
            }
        };

        typedef std::unordered_map<StateSymbol, 
            BranchMap, StateSymbol_Hash> Symbol_BranchMap_Map;
        typedef typename Symbol_BranchMap_Map::iterator
            Symbol_BranchMap_Iterator;
        typedef typename Symbol_BranchMap_Map::const_iterator
            Symbol_BranchMap_ConstIterator;
    };

}

#include "pastel/sys/automaton/automaton_state_label.h"
#include "pastel/sys/automaton/automaton_transition_label.h"

namespace Pastel
{

    template <
        typename Symbol,
        typename StateData,
        typename TransitionData>
    class No_Automaton_Customization
    {
    private:
        using Fwd = Automaton_Fwd<Symbol, StateData, TransitionData>;

        PASTEL_FWD(State_Iterator);
        PASTEL_FWD(State_ConstIterator);
        PASTEL_FWD(Transition_Iterator);
        PASTEL_FWD(Transition_ConstIterator);

    protected:
        No_Automaton_Customization() {}
        No_Automaton_Customization(const No_Automaton_Customization& that) {}
        No_Automaton_Customization(No_Automaton_Customization&& that) {}
        No_Automaton_Customization& operator=(
            No_Automaton_Customization that) {return *this;}

        void swap(No_Automaton_Customization& that) {}

        void onClear() {}
        void onClearTransitions() {}
        void onClearStart() {}
        void onClearFinal() {}

        void onAddState(const State_Iterator& state) {}
        void onRemoveState(const State_ConstIterator& state) {}

        void onAddStart(
            const State_ConstIterator& state) {}
        void onRemoveStart(
            const State_ConstIterator& state) {}

        void onAddFinal(
            const State_ConstIterator& state) {}
        void onRemoveFinal(
            const State_ConstIterator& state) {}

        void onAddTransition(
            const Transition_ConstIterator& transition)  {}
        void onRemoveTransition(
            const Transition_ConstIterator& transition)  {}

        void onMerge(Automaton<Symbol, StateData, TransitionData,
            No_Automaton_Customization>& that) {}

        bool canAddTransition(
            const State_ConstIterator& fromState,
            const Optional<Symbol>& symbol,
            const State_ConstIterator& toState) 
        {
            return true;
        }
    };

}

#endif