diff --git a/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.cpp b/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.cpp index 023bf220786392865eee8086fad4d28c4b7c63d9..e2bd69b8cd42a237c4ef9b2357dbd5c21b849c5f 100644 --- a/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.cpp +++ b/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.cpp @@ -14,6 +14,8 @@ namespace exact { auto ExactTreePatternAutomatonPrefixRankedTree = registration::AbstractRegister < ExactTreePatternAutomaton, automaton::InputDrivenNPDA < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, char, unsigned >, const tree::PrefixRankedTree < > &, const common::ranked_symbol < DefaultSymbolType, DefaultRankType > & > ( ExactTreePatternAutomaton::construct ); +auto ExactTreePatternAutomatonPrefixRankedBarTree = registration::AbstractRegister < ExactTreePatternAutomaton, automaton::InputDrivenNPDA < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, char, unsigned >, const tree::PrefixRankedBarTree < > &, const common::ranked_symbol < DefaultSymbolType, DefaultRankType > &, const common::ranked_symbol < DefaultSymbolType, DefaultRankType > & > ( ExactTreePatternAutomaton::construct ); + } /* namespace exact */ } /* namespace arbology */ diff --git a/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.h b/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.h index c208a9d05b1c4220c3d4e6ace02fae27c7ccb10e..86569ee64e639066afe527282f29070dd6b92b4a 100644 --- a/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.h +++ b/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.h @@ -9,7 +9,10 @@ #define _EXACT_TREE_PATTERN_AUTOMATON_H__ #include <alphabet/SubtreeWildcardSymbol.h> + #include <tree/ranked/PrefixRankedTree.h> +#include <tree/ranked/PrefixRankedBarTree.h> + #include <automaton/PDA/InputDrivenNPDA.h> #include <alib/deque> @@ -21,13 +24,64 @@ namespace exact { class ExactTreePatternAutomaton { public: /** - * Performs conversion. - * @return left regular grammar equivalent to source automaton. + * Construct a tree pattern automaton. + * @return input driven automaton implementing an index for tree patterns. + */ + template < class SymbolType, class RankType > + static automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > construct ( const tree::PrefixRankedBarTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard, const common::ranked_symbol < SymbolType, RankType > & variablesBar ); + + /** + * Construct a tree pattern automaton. + * @return input driven automaton implementing an index for tree patterns. */ template < class SymbolType, class RankType > static automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > construct ( const tree::PrefixRankedTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard ); }; +template < class SymbolType, class RankType > +automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > ExactTreePatternAutomaton::construct ( const tree::PrefixRankedBarTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard, const common::ranked_symbol < SymbolType, RankType > & variablesBar ) { + char S = alphabet::SubtreeWildcardSymbol::instance < char > ( ); + automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > res ( 0, S ); + + for ( const common::ranked_symbol < SymbolType, RankType > & symbol : tree.getAlphabet ( ) ) { + res.addInputSymbol ( symbol ); + if ( tree.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 ) ); + } + + res.addInputSymbol ( subtreeWildcard ); + res.setPushdownStoreOperation ( subtreeWildcard, ext::vector < char > ( 1, S ), ext::vector < char > { } ); + + res.addInputSymbol ( variablesBar ); + res.setPushdownStoreOperation ( variablesBar, ext::vector < char > { }, ext::vector < char > ( 1, S ) ); + + unsigned i = 1; + ext::deque < unsigned > subtreeJumps; + + for ( const common::ranked_symbol < SymbolType, RankType > & symbol : tree.getContent ( ) ) { + res.addState ( i ); + res.addTransition ( i - 1, symbol, i ); + res.addTransition ( 0, std::move ( symbol ), i ); + + if ( tree.getBars ( ).count ( symbol ) ) { + unsigned source = subtreeJumps.back ( ); + subtreeJumps.pop_back ( ); + + res.addState ( ~0 - i ); + res.addTransition ( source, subtreeWildcard, ~0 - i ); + res.addTransition ( ~0 - i, variablesBar, i ); + } else { + subtreeJumps.push_back ( i - 1 ); + } + + i++; + } + + return res; +} + template < class SymbolType, class RankType > automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > ExactTreePatternAutomaton::construct ( const tree::PrefixRankedTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard ) { char S = alphabet::SubtreeWildcardSymbol::instance < char > ( );