diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp index d07cc9d01a5615a88c66a2ab178577a6b524ea91..dcb3c015bfd712178f64a93da096aadbb166b0c6 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp @@ -6,104 +6,17 @@ */ #include "ExactSubtreeMatchingAutomaton.h" -#include <tree/ranked/PrefixRankedBarTree.h> -#include <tree/ranked/PrefixRankedTree.h> -#include <tree/ranked/RankedTree.h> - -#include <automaton/PDA/InputDrivenNPDA.h> -#include <automaton/TA/NFTA.h> - -#include <alphabet/BottomOfTheStackSymbol.h> - -#include <alib/deque> #include <registration/AlgoRegistration.hpp> namespace arbology { namespace exact { -automaton::InputDrivenNPDA < > ExactSubtreeMatchingAutomaton::construct ( const tree::PrefixRankedTree < > & pattern ) { - automaton::InputDrivenNPDA < > res ( DefaultStateType ( 0 ), DefaultSymbolType ( 'S' ) ); - - for ( const common::ranked_symbol < > & symbol : pattern.getAlphabet ( ) ) { - res.addInputSymbol ( DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ) ); - res.setPushdownStoreOperation ( DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ), ext::vector < DefaultSymbolType > ( 1, DefaultSymbolType ( 'S' ) ), ext::vector < DefaultSymbolType > ( ( size_t ) symbol.getRank ( ), DefaultSymbolType ( 'S' ) ) ); - } - - for ( const common::ranked_symbol < > & symbol : pattern.getAlphabet ( ) ) { - res.addTransition ( DefaultStateType ( 0 ), DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ), DefaultStateType ( 0 ) ); - } - - int i = 1; - - for ( const common::ranked_symbol < > & symbol : pattern.getContent ( ) ) { - res.addState ( DefaultStateType ( i ) ); - res.addTransition ( DefaultStateType ( i - 1 ), DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ), DefaultStateType ( i ) ); - i++; - } - - res.addFinalState ( DefaultStateType ( i - 1 ) ); - return res; -} - -auto ExactSubtreeMatchingAutomatonPrefixRankedTree = registration::AbstractRegister < ExactSubtreeMatchingAutomaton, automaton::InputDrivenNPDA < >, const tree::PrefixRankedTree < > & > ( ExactSubtreeMatchingAutomaton::construct ); - -automaton::InputDrivenNPDA < > ExactSubtreeMatchingAutomaton::construct ( const tree::PrefixRankedBarTree < > & pattern ) { - automaton::InputDrivenNPDA < > res ( DefaultStateType ( 0 ), alphabet::BottomOfTheStackSymbol::instance < DefaultSymbolType > ( ) ); - - res.setPushdownStoreAlphabet ( { alphabet::BottomOfTheStackSymbol::instance < DefaultSymbolType > ( ), DefaultSymbolType ( 'S' ) } ); - - for ( const common::ranked_symbol < > & symbol : pattern.getAlphabet ( ) ) { - res.addInputSymbol ( DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ) ); - - if ( pattern.getBars ( ).count ( symbol ) ) - res.setPushdownStoreOperation ( DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ), ext::vector < DefaultSymbolType > ( 1, DefaultSymbolType ( 'S' ) ), ext::vector < DefaultSymbolType > { } ); - else - res.setPushdownStoreOperation ( DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ), ext::vector < DefaultSymbolType > { }, ext::vector < DefaultSymbolType > ( 1, DefaultSymbolType ( 'S' ) ) ); - } - - for ( const common::ranked_symbol < > & symbol : pattern.getAlphabet ( ) ) { - res.addTransition ( DefaultStateType ( 0 ), DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ), DefaultStateType ( 0 ) ); - } - - int i = 1; - - for ( const common::ranked_symbol < > & symbol : pattern.getContent ( ) ) { - res.addState ( DefaultStateType ( i ) ); - res.addTransition ( DefaultStateType ( i - 1 ), DefaultSymbolType ( alphabet::RankedSymbol < > { symbol } ), DefaultStateType ( i ) ); - i++; - } - - res.addFinalState ( DefaultStateType ( i - 1 ) ); - return res; -} - -auto ExactSubtreeMatchingAutomatonPrefixRankedBarTree = registration::AbstractRegister < ExactSubtreeMatchingAutomaton, automaton::InputDrivenNPDA < >, const tree::PrefixRankedBarTree < > & > ( ExactSubtreeMatchingAutomaton::construct ); - -DefaultStateType constructRecursive ( const ext::tree < common::ranked_symbol < > > & node, automaton::NFTA < > & res, int & nextState ) { - ext::vector < DefaultStateType > states; - - states.reserve ( ( size_t ) node.getData ( ).getRank ( ) ); - - for ( const ext::tree < common::ranked_symbol < > > & child : node.getChildren ( ) ) - states.push_back ( constructRecursive ( child, res, nextState ) ); - - DefaultStateType state = DefaultStateType ( nextState++ ); - res.addState ( state ); - res.addTransition ( node.getData ( ), states, state ); - return state; -} - -automaton::NFTA < > ExactSubtreeMatchingAutomaton::construct ( const tree::RankedTree < > & pattern ) { - automaton::NFTA < > res; +auto ExactSubtreeMatchingAutomatonPrefixRankedTree = registration::AbstractRegister < ExactSubtreeMatchingAutomaton, automaton::InputDrivenNPDA < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, char, unsigned >, const tree::PrefixRankedTree < > & > ( ExactSubtreeMatchingAutomaton::construct ); - res.setInputAlphabet ( pattern.getAlphabet ( ) ); - int nextState = 0; - res.addFinalState ( constructRecursive ( pattern.getContent ( ), res, nextState ) ); - return res; -} +auto ExactSubtreeMatchingAutomatonPrefixRankedBarTree = registration::AbstractRegister < ExactSubtreeMatchingAutomaton, automaton::InputDrivenNPDA < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, char, unsigned >, const tree::PrefixRankedBarTree < > & > ( ExactSubtreeMatchingAutomaton::construct ); -auto ExactSubtreeMatchingAutomatonRankedTree = registration::AbstractRegister < ExactSubtreeMatchingAutomaton, automaton::NFTA < >, const tree::RankedTree < > & > ( ExactSubtreeMatchingAutomaton::construct ); +auto ExactSubtreeMatchingAutomatonRankedTree = registration::AbstractRegister < ExactSubtreeMatchingAutomaton, automaton::NFTA < DefaultSymbolType, DefaultRankType, unsigned >, const tree::RankedTree < > & > ( ExactSubtreeMatchingAutomaton::construct ); } /* namespace exact */ diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h index 7ca9f9e0370c0b3cb735b9defe0b20c6f335d0d1..dcca618e0b8a9c6272b605a153c7f332385865a5 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h @@ -8,8 +8,14 @@ #ifndef _EXACT_SUBTREE_MATCHING_AUTOMATON_H__ #define _EXACT_SUBTREE_MATCHING_AUTOMATON_H__ -#include <automaton/AutomatonFeatures.h> -#include <tree/TreeFeatures.h> +#include <tree/ranked/PrefixRankedBarTree.h> +#include <tree/ranked/PrefixRankedTree.h> +#include <tree/ranked/RankedTree.h> + +#include <automaton/PDA/InputDrivenNPDA.h> +#include <automaton/TA/NFTA.h> + +#include <alphabet/BottomOfTheStackSymbol.h> namespace arbology { @@ -21,12 +27,98 @@ public: * Performs conversion. * @return left regular grammar equivalent to source automaton. */ - static automaton::InputDrivenNPDA < > construct ( const tree::PrefixRankedTree < > & pattern ); - static automaton::InputDrivenNPDA < > construct ( const tree::PrefixRankedBarTree < > & pattern ); - static automaton::NFTA < > construct ( const tree::RankedTree < > & pattern ); + template < class SymbolType, class RankType > + static automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > construct ( const tree::PrefixRankedTree < SymbolType, RankType > & pattern ); + + template < class SymbolType, class RankType > + static automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > construct ( const tree::PrefixRankedBarTree < SymbolType, RankType > & pattern ); + + template < class SymbolType, class RankType > + static automaton::NFTA < SymbolType, RankType, unsigned > construct ( const tree::RankedTree < SymbolType, RankType > & pattern ); }; +template < class SymbolType, class RankType > +automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > ExactSubtreeMatchingAutomaton::construct ( const tree::PrefixRankedTree < SymbolType, RankType > & pattern ) { + automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > res ( 0, 'S' ); + + for ( const common::ranked_symbol < SymbolType, RankType > & symbol : pattern.getAlphabet ( ) ) { + res.addInputSymbol ( symbol ); + res.setPushdownStoreOperation ( symbol, ext::vector < char > ( 1, 'S' ), ext::vector < char > ( ( size_t ) symbol.getRank ( ), 'S' ) ); + } + + for ( const common::ranked_symbol < SymbolType, RankType > & symbol : pattern.getAlphabet ( ) ) { + res.addTransition ( 0, symbol, 0 ); + } + + unsigned i = 1; + + for ( const common::ranked_symbol < SymbolType, RankType > & symbol : pattern.getContent ( ) ) { + res.addState ( i ); + res.addTransition ( i - 1, symbol, i ); + i++; + } + + res.addFinalState ( i - 1 ); + return res; +} + +template < class SymbolType, class RankType > +automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > ExactSubtreeMatchingAutomaton::construct ( const tree::PrefixRankedBarTree < SymbolType, RankType > & pattern ) { + automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > res ( 0, alphabet::BottomOfTheStackSymbol::instance < char > ( ) ); + + res.setPushdownStoreAlphabet ( { alphabet::BottomOfTheStackSymbol::instance < char > ( ), 'S' } ); + + for ( const common::ranked_symbol < SymbolType, RankType > & symbol : pattern.getAlphabet ( ) ) { + res.addInputSymbol ( symbol ); + + if ( pattern.getBars ( ).count ( symbol ) ) + res.setPushdownStoreOperation ( symbol, ext::vector < char > ( 1, 'S' ), ext::vector < char > { } ); + else + res.setPushdownStoreOperation ( symbol, ext::vector < char > { }, ext::vector < char > ( 1, 'S' ) ); + } + + for ( const common::ranked_symbol < SymbolType, RankType > & symbol : pattern.getAlphabet ( ) ) { + res.addTransition ( 0, symbol, 0 ); + } + + unsigned i = 1; + + for ( const common::ranked_symbol < SymbolType, RankType > & symbol : pattern.getContent ( ) ) { + res.addState ( i ); + res.addTransition ( i - 1, symbol, i ); + i++; + } + + res.addFinalState ( i - 1 ); + return res; +} + +template < class SymbolType, class RankType > +unsigned constructRecursive ( const ext::tree < common::ranked_symbol < SymbolType, RankType > > & node, automaton::NFTA < SymbolType, RankType, unsigned > & res, unsigned & nextState ) { + ext::vector < unsigned > states; + + states.reserve ( ( size_t ) node.getData ( ).getRank ( ) ); + + for ( const ext::tree < common::ranked_symbol < SymbolType, RankType > > & child : node.getChildren ( ) ) + states.push_back ( constructRecursive ( child, res, nextState ) ); + + unsigned state = nextState++; + res.addState ( state ); + res.addTransition ( node.getData ( ), states, state ); + return state; +} + +template < class SymbolType, class RankType > +automaton::NFTA < SymbolType, RankType, unsigned > ExactSubtreeMatchingAutomaton::construct ( const tree::RankedTree < SymbolType, RankType > & pattern ) { + automaton::NFTA < SymbolType, RankType, unsigned > res; + + res.setInputAlphabet ( pattern.getAlphabet ( ) ); + unsigned nextState = 0; + res.addFinalState ( constructRecursive ( pattern.getContent ( ), res, nextState ) ); + return res; +} + } /* namespace exact */ } /* namespace arbology */