Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
ExactNonlinearTreePatternAutomaton.h
Go to the documentation of this file.
1
6#pragma once
7
8#include <alib/pair>
9#include <alib/deque>
10#include <alib/vector>
11
13
16
18
19namespace arbology {
20
21namespace exact {
22
24 template < class SymbolType >
26
27 template < class SymbolType >
28 static void constructTail ( automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType >, char, ext::pair < unsigned, unsigned > > & res, const tree::PrefixRankedTree < SymbolType > & tree, const common::ranked_symbol < SymbolType > & subtreeWildcard, const common::ranked_symbol < SymbolType > & currentNonlinearVariable, const ext::set < common::ranked_symbol < SymbolType > > & nonlinearVariables, unsigned subtreeId, bool nonlinearJumps, typename ext::vector < common::ranked_symbol < SymbolType > >::const_iterator rankedSymbolsIter, unsigned i, typename ext::vector < common::ranked_symbol < unsigned > >::const_iterator subtreeRepeatsIter );
29
30 template < class SymbolType >
32
33 template < class SymbolType >
34 static void constructTail ( automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType >, char, ext::pair < unsigned, unsigned > > & res, const tree::PrefixRankedBarTree < SymbolType > & tree, const common::ranked_symbol < SymbolType > & subtreeWildcard, const common::ranked_symbol < SymbolType > & currentNonlinearVariable, const ext::set < common::ranked_symbol < SymbolType > > & nonlinearVariables, const common::ranked_symbol < SymbolType > & variablesBar, unsigned subtreeId, bool nonlinearJumps, typename ext::vector < common::ranked_symbol < SymbolType > >::const_iterator rankedSymbolsIter, unsigned i, typename ext::vector < common::ranked_symbol < unsigned > >::const_iterator subtreeRepeatsIter );
35
36public:
41 template < class SymbolType >
43
48 template < class SymbolType >
50};
51
52template < class SymbolType >
53void ExactNonlinearTreePatternAutomaton::constructTail ( automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType >, char, ext::pair < unsigned, unsigned > > & res, const tree::PrefixRankedTree < SymbolType > & tree, const common::ranked_symbol < SymbolType > & subtreeWildcard, const common::ranked_symbol < SymbolType > & currentNonlinearVariable, const ext::set < common::ranked_symbol < SymbolType > > & nonlinearVariables, unsigned subtreeId, bool nonlinearJumps, typename ext::vector < common::ranked_symbol < SymbolType > >::const_iterator rankedSymbolsIter, unsigned i, typename ext::vector < common::ranked_symbol < unsigned > >::const_iterator subtreeRepeatsIter ) {
55 ext::deque < unsigned > subtreeRepeatsStack;
56
57 for (++ rankedSymbolsIter, ++ subtreeRepeatsIter, ++i; rankedSymbolsIter != tree.getContent ( ).end ( ); ++ rankedSymbolsIter, ++ subtreeRepeatsIter, ++i ) {
58 common::ranked_symbol < SymbolType > symbol = * rankedSymbolsIter;
59 subtreeJumps.push_back ( std::make_pair ( symbol.getRank ( ), i - 1 ) );
60 subtreeRepeatsStack.push_back ( subtreeRepeatsIter->getSymbol ( ) );
61
62 ext::pair < unsigned, unsigned > currentState = ext::make_pair ( i, subtreeId + 1 );
63 ext::pair < unsigned, unsigned > previousState = ext::make_pair ( i - 1, subtreeId + 1 );
64
65 res.addState ( currentState );
66
67 res.addTransition ( previousState, std::move ( symbol ), currentState );
68
69 while ( !subtreeJumps.empty ( ) && subtreeJumps.back ( ).first == 0 ) {
70 ext::pair < unsigned, unsigned > source = ext::make_pair ( subtreeJumps.back ( ).second, subtreeId + 1 );
71 res.addTransition ( source, subtreeWildcard, currentState );
72
73 for ( const common::ranked_symbol < SymbolType > & nonlinearVariable : nonlinearVariables )
74 if ( nonlinearVariable != currentNonlinearVariable || ( subtreeId == subtreeRepeatsStack.back ( ) && nonlinearJumps ) )
75 res.addTransition ( source, nonlinearVariable, currentState );
76
77 if ( !subtreeJumps.empty ( ) ) {
78 subtreeJumps.pop_back ( );
79 subtreeRepeatsStack.pop_back ( );
80 }
81 }
82
83 if ( !subtreeJumps.empty ( ) ) subtreeJumps.back ( ).first--;
84 }
85}
86
87template < class SymbolType >
88automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType >, char, ext::pair < unsigned, unsigned > > ExactNonlinearTreePatternAutomaton::constructInternal ( const tree::PrefixRankedTree < SymbolType > & tree, const common::ranked_symbol < SymbolType > & subtreeWildcard, const common::ranked_symbol < SymbolType > & currentNonlinearVariable, const ext::set < common::ranked_symbol < SymbolType > > & nonlinearVariables ) {
89 char S = alphabet::WildcardSymbol::instance < char > ( );
91
92 tree::PrefixRankedTree < unsigned > repeats = tree::properties::ExactSubtreeRepeatsNaive::repeats ( tree );
93
94 std::vector < unsigned > repeatsFrequency ( repeats.getContent ( ).size ( ), 0 );
95 for ( const common::ranked_symbol < unsigned > & repeat : repeats.getContent ( ) )
96 ++ repeatsFrequency [ repeat.getSymbol ( ) ];
97
98 for ( const common::ranked_symbol < SymbolType > & symbol : tree.getAlphabet ( ) ) {
99 res.addInputSymbol ( symbol );
100 res.setPushdownStoreOperation ( symbol, ext::vector < char > ( 1, S ), ext::vector < char > ( symbol.getRank ( ), S ) );
101 }
102
103 res.addInputSymbol ( subtreeWildcard );
104 res.setPushdownStoreOperation ( subtreeWildcard, ext::vector < char > ( 1, S ), ext::vector < char > { } );
105
106 for ( const common::ranked_symbol < SymbolType > & nonlinearVariable : nonlinearVariables ) {
107 res.addInputSymbol ( nonlinearVariable );
108 res.setPushdownStoreOperation ( nonlinearVariable, ext::vector < char > ( 1, S ), ext::vector < char > { } );
109 }
110
111 unsigned i = 1;
113 ext::deque < unsigned > subtreeRepeatsStack;
114
115 typename ext::vector < common::ranked_symbol < SymbolType > >::const_iterator rankedSymbolsIter;
116 typename ext::vector < common::ranked_symbol < unsigned > >::const_iterator subtreeRepeatsIter;
117 for ( rankedSymbolsIter = tree.getContent ( ).begin(), subtreeRepeatsIter = repeats.getContent ( ).begin ( ); rankedSymbolsIter != tree.getContent ( ).end ( ); ++ rankedSymbolsIter, ++ subtreeRepeatsIter, ++ i ) {
118 common::ranked_symbol < SymbolType > symbol = * rankedSymbolsIter;
119 subtreeJumps.push_back ( std::make_pair ( symbol.getRank ( ), i - 1 ) );
120 subtreeRepeatsStack.push_back ( subtreeRepeatsIter->getSymbol ( ) );
121
123 ext::pair < unsigned, unsigned > previousState = ext::make_pair ( i - 1, 0u );
124
125 res.addState ( currentState );
126
127 res.addTransition ( previousState, symbol, currentState );
128 res.addTransition ( res.getInitialState ( ), std::move ( symbol ), currentState );
129
130 while ( !subtreeJumps.empty ( ) && subtreeJumps.back ( ).first == 0 ) {
131 ext::pair < unsigned, unsigned > source = ext::make_pair ( subtreeJumps.back ( ).second, 0u );
132 res.addTransition ( source, subtreeWildcard, currentState );
133
134 for ( const common::ranked_symbol < SymbolType > & nonlinearVariable : nonlinearVariables )
135 if ( nonlinearVariable != currentNonlinearVariable )
136 res.addTransition ( source, nonlinearVariable, currentState );
137 else {
138 unsigned subtreeId = subtreeRepeatsStack.back ( );
139 bool multiRepeat = repeatsFrequency [ subtreeId ] > 1;
140 if ( ! multiRepeat )
141 subtreeId = repeats.getContent ( ) [ 0 ].getSymbol ( );
142
143 ext::pair < unsigned, unsigned > targetState = ext::make_pair ( i, subtreeId + 1 );
144
145 res.addState ( targetState );
146 res.addTransition ( source, nonlinearVariable, targetState );
147
148 constructTail ( res, tree, subtreeWildcard, currentNonlinearVariable, nonlinearVariables, subtreeId, multiRepeat, rankedSymbolsIter, i, subtreeRepeatsIter );
149 }
150
151 subtreeJumps.pop_back ( );
152 subtreeRepeatsStack.pop_back ( );
153 }
154
155 if ( !subtreeJumps.empty ( ) ) subtreeJumps.back ( ).first--;
156 }
157
158 return res;
159}
160
161template < class SymbolType >
163 return constructInternal ( tree, subtreeWildcard, * nonlinearVariables.begin ( ), nonlinearVariables );
164}
165
166template < class SymbolType >
167void ExactNonlinearTreePatternAutomaton::constructTail ( automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType >, char, ext::pair < unsigned, unsigned > > & res, const tree::PrefixRankedBarTree < SymbolType > & tree, const common::ranked_symbol < SymbolType > & subtreeWildcard, const common::ranked_symbol < SymbolType > & currentNonlinearVariable, const ext::set < common::ranked_symbol < SymbolType > > & nonlinearVariables, const common::ranked_symbol < SymbolType > & variablesBar, unsigned subtreeId, bool nonlinearJumps, typename ext::vector < common::ranked_symbol < SymbolType > >::const_iterator rankedSymbolsIter, unsigned i, typename ext::vector < common::ranked_symbol < unsigned > >::const_iterator subtreeRepeatsIter ) {
168 ext::deque < unsigned > subtreeJumps;
169 ext::deque < unsigned > subtreeRepeatsStack;
170
171 for (++ rankedSymbolsIter, ++ subtreeRepeatsIter, ++i; rankedSymbolsIter != tree.getContent ( ).end ( ); ++ rankedSymbolsIter, ++ subtreeRepeatsIter, ++i ) {
172 common::ranked_symbol < SymbolType > symbol = * rankedSymbolsIter;
173
174 ext::pair < unsigned, unsigned > currentState = ext::make_pair ( i, subtreeId + 1 );
175 ext::pair < unsigned, unsigned > previousState = ext::make_pair ( i - 1, subtreeId + 1 );
176
177 res.addState ( currentState );
178
179 res.addTransition ( previousState, symbol, currentState );
180
181 if ( tree.getBars ( ).count ( symbol ) ) {
182 if ( !subtreeJumps.empty ( ) ) {
183 ext::pair < unsigned, unsigned > source = ext::make_pair ( subtreeJumps.back ( ), subtreeId + 1 );
184 ext::pair < unsigned, unsigned > middle = ext::make_pair ( ~0 - i, subtreeId + 1 );
185 res.addState ( middle );
186
187 res.addTransition ( source, subtreeWildcard, middle );
188 res.addTransition ( middle, variablesBar, currentState );
189
190 for ( const common::ranked_symbol < SymbolType > & nonlinearVariable : nonlinearVariables )
191 if ( nonlinearVariable != currentNonlinearVariable || ( subtreeId == subtreeRepeatsStack.back ( ) && nonlinearJumps ) )
192 res.addTransition ( source, nonlinearVariable, middle );
193
194 subtreeJumps.pop_back ( );
195 subtreeRepeatsStack.pop_back ( );
196 }
197 } else {
198 subtreeJumps.push_back ( i - 1 );
199 subtreeRepeatsStack.push_back ( subtreeRepeatsIter->getSymbol ( ) );
200 }
201 }
202}
203
204template < class SymbolType >
205automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType >, char, ext::pair < unsigned, unsigned > > ExactNonlinearTreePatternAutomaton::constructInternal ( const tree::PrefixRankedBarTree < SymbolType > & tree, const common::ranked_symbol < SymbolType > & subtreeWildcard, const common::ranked_symbol < SymbolType > & currentNonlinearVariable, const ext::set < common::ranked_symbol < SymbolType > > & nonlinearVariables, const common::ranked_symbol < SymbolType > & variablesBar ) {
206 char S = alphabet::WildcardSymbol::instance < char > ( );
208
209 tree::PrefixRankedBarTree < unsigned > repeats = tree::properties::ExactSubtreeRepeatsNaive::repeats ( tree );
210
211 std::vector < unsigned > repeatsFrequency ( repeats.getContent ( ).size ( ), 0 );
212 for ( const common::ranked_symbol < unsigned > & repeat : repeats.getContent ( ) )
213 if ( ! repeats.getBars ( ).count ( repeat ) )
214 ++ repeatsFrequency [ repeat.getSymbol ( ) ];
215
216 for ( const common::ranked_symbol < SymbolType > & symbol : tree.getAlphabet ( ) ) {
217 res.addInputSymbol ( symbol );
218 if ( tree.getBars ( ).count ( symbol ) )
219 res.setPushdownStoreOperation ( symbol, ext::vector < char > ( 1, S ), ext::vector < char > { } );
220 else
221 res.setPushdownStoreOperation ( symbol, ext::vector < char > { }, ext::vector < char > ( 1, S ) );
222 }
223
224 res.addInputSymbol ( subtreeWildcard );
225 res.setPushdownStoreOperation ( subtreeWildcard, ext::vector < char > { }, ext::vector < char > ( 1, S ) );
226
227 res.addInputSymbol ( variablesBar );
228 res.setPushdownStoreOperation ( variablesBar, ext::vector < char > ( 1, S ), ext::vector < char > { } );
229
230 for ( const common::ranked_symbol < SymbolType > & nonlinearVariable : nonlinearVariables ) {
231 res.addInputSymbol ( nonlinearVariable );
232 res.setPushdownStoreOperation ( nonlinearVariable, ext::vector < char > { }, ext::vector < char > ( 1, S ) );
233 }
234
235 unsigned i = 1;
236 ext::deque < unsigned > subtreeJumps;
237 ext::deque < unsigned > subtreeRepeatsStack;
238
239 typename ext::vector < common::ranked_symbol < SymbolType > >::const_iterator rankedSymbolsIter;
240 typename ext::vector < common::ranked_symbol < unsigned > >::const_iterator subtreeRepeatsIter;
241 for ( rankedSymbolsIter = tree.getContent ( ).begin(), subtreeRepeatsIter = repeats.getContent ( ).begin ( ); rankedSymbolsIter != tree.getContent ( ).end ( ); ++ rankedSymbolsIter, ++ subtreeRepeatsIter, ++ i ) {
242 common::ranked_symbol < SymbolType > symbol = * rankedSymbolsIter;
243
245 ext::pair < unsigned, unsigned > previousState = ext::make_pair ( i - 1, 0u );
246
247 res.addState ( currentState );
248
249 res.addTransition ( previousState, symbol, currentState );
250
251 if ( tree.getBars ( ).count ( symbol ) ) {
252 ext::pair < unsigned, unsigned > source = ext::make_pair ( subtreeJumps.back ( ), 0u );
254 res.addState ( middle );
255
256 res.addTransition ( source, subtreeWildcard, middle );
257 res.addTransition ( middle, variablesBar, currentState );
258
259 for ( const common::ranked_symbol < SymbolType > & nonlinearVariable : nonlinearVariables )
260 if ( nonlinearVariable != currentNonlinearVariable )
261 res.addTransition ( source, nonlinearVariable, middle );
262 else {
263 unsigned subtreeId = subtreeRepeatsStack.back ( );
264 bool multiRepeat = repeatsFrequency [ subtreeId ] > 1;
265 if ( ! multiRepeat )
266 subtreeId = repeats.getContent ( ) [ 0 ].getSymbol ( );
267
268 ext::pair < unsigned, unsigned > targetState = ext::make_pair ( i, subtreeId + 1 );
269 ext::pair < unsigned, unsigned > middleState = ext::make_pair ( ~0 - i, subtreeId + 1 );
270
271 res.addState ( targetState );
272 res.addState ( middleState );
273
274 res.addTransition ( source, nonlinearVariable, middleState );
275 res.addTransition ( middleState, variablesBar, targetState );
276
277 constructTail ( res, tree, subtreeWildcard, currentNonlinearVariable, nonlinearVariables, variablesBar, subtreeId, multiRepeat, rankedSymbolsIter, i, subtreeRepeatsIter );
278 }
279
280 subtreeJumps.pop_back ( );
281 subtreeRepeatsStack.pop_back ( );
282 } else {
283 subtreeJumps.push_back ( i - 1 );
284 subtreeRepeatsStack.push_back ( subtreeRepeatsIter->getSymbol ( ) );
285
286 res.addTransition ( res.getInitialState ( ), symbol, currentState );
287 }
288 }
289
290 return res;
291}
292
293template < class SymbolType >
295 return constructInternal ( tree, subtreeWildcard, * nonlinearVariables.begin ( ), nonlinearVariables, variablesBar );
296}
297
298} /* namespace exact */
299
300} /* namespace arbology */
301
Definition: ExactNonlinearTreePatternAutomaton.h:23
static automaton::InputDrivenNPDA< common::ranked_symbol< SymbolType >, char, ext::pair< unsigned, unsigned > > construct(const tree::PrefixRankedTree< SymbolType > &tree, const common::ranked_symbol< SymbolType > &subtreeWildcard, const ext::set< common::ranked_symbol< SymbolType > > &nonlinearVariables)
Definition: ExactNonlinearTreePatternAutomaton.h:162
Nondeterministic input driven pushdown automaton. Accepts subset of context free languages.
Definition: InputDrivenNPDA.h:79
Definition: ranked_symbol.hpp:20
const size_t & getRank() const &
Definition: ranked_symbol.hpp:83
Class extending the deque class from the standard library. Original reason is to allow printing of th...
Definition: deque.hpp:44
Class extending the pair class from the standard library. Original reason is to allow printing of the...
Definition: pair.hpp:43
Definition: set.hpp:44
Class extending the vector class from the standard library. Original reason is to allow printing of t...
Definition: vector.hpp:45
Tree structure represented as linear sequece as result of preorder traversal with additional bar symb...
Definition: PrefixRankedBarTree.h:78
const ext::vector< common::ranked_symbol< SymbolType > > & getContent() const &
Definition: PrefixRankedBarTree.h:273
const ext::set< common::ranked_symbol< SymbolType > > & getBars() const &
Definition: PrefixRankedBarTree.h:156
Tree structure represented as linear sequece as result of preorder traversal. The representation is s...
Definition: PrefixRankedTree.h:71
const ext::vector< common::ranked_symbol< SymbolType > > & getContent() const &
Definition: PrefixRankedTree.h:235
Definition: BoyerMooreHorspool.h:22
int i
Definition: AllEpsilonClosure.h:118
return res
Definition: MinimizeByPartitioning.h:145
constexpr auto make_pair(T1 &&x, T2 &&y)
Definition: pair.hpp:79
void end()
Definition: measurements.cpp:19
Definition: BackwardOccurrenceTest.h:17