Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
ExactPatternMatchingAutomaton.h
Go to the documentation of this file.
1
6#pragma once
7
9
11
20
23
26#include <automaton/PDA/NPDA.h>
27#include <automaton/TA/NFTA.h>
30
33
34namespace arbology {
35
36namespace exact {
37
39public:
44 template < class SymbolType >
46
47 template < class SymbolType >
49
50 template < class SymbolType >
52
53 template < class SymbolType >
55
56 template < class SymbolType >
58
59 template < class SymbolType >
61
62 template < class SymbolType >
64
65 template < class SymbolType >
67
68 template < class SymbolType >
70
71 template < class SymbolType >
73
74 template < class SymbolType >
76
77};
78
79template < class SymbolType >
80ext::vector < char > computeRHS ( const tree::PrefixRankedPattern < SymbolType > & pattern, const ext::vector < int > & patternSubtreeJumpTable, int i ) {
82
83 unsigned rank = content [ i ].getRank ( );
84
85 i++;
86
88
89 for ( unsigned ranki = 0; ranki < rank; ranki++ ) {
90 if ( content [ i ] == pattern.getSubtreeWildcard ( ) ) {
91 res.push_back ( 'R' );
92 i++;
93 } else {
94 res.push_back ( 'T' );
95
96 i = patternSubtreeJumpTable [ i ];
97 }
98 }
99
100 return res;
101}
102
103template < class SymbolType >
106
107 for ( const common::ranked_symbol < SymbolType > & symbol : pattern.getAlphabet ( ) ) {
108 if ( symbol == pattern.getSubtreeWildcard ( ) ) continue;
109
110 res.addInputSymbol ( symbol );
111 }
112
113 res.setPushdownStoreAlphabet ( { 'T', 'R' } );
114
115 for ( const common::ranked_symbol < SymbolType > & symbol : pattern.getAlphabet ( ) ) {
116 if ( symbol == pattern.getSubtreeWildcard ( ) ) continue;
117
118 res.addTransition ( 0, symbol, ext::vector < char > ( 1, 'T' ), 0, ext::vector < char > ( symbol.getRank ( ), 'T' ) );
119 }
120
121 ext::vector < int > patternSubtreeJumpTable = tree::properties::SubtreeJumpTable::compute ( pattern );
122
123 unsigned i = 1;
124
125 for ( const common::ranked_symbol < SymbolType > & symbol : pattern.getContent ( ) ) {
126 res.addState ( i );
127
128 if ( symbol == pattern.getSubtreeWildcard ( ) )
129 for ( const common::ranked_symbol < SymbolType > & alphabetSymbol : pattern.getAlphabet ( ) ) {
130 if ( alphabetSymbol == pattern.getSubtreeWildcard ( ) ) continue;
131
132 if ( alphabetSymbol.getRank ( ) == 0 ) {
133 res.addTransition ( i - 1, alphabetSymbol, ext::vector < char > ( 1, 'T' ), i - 1, ext::vector < char > { } );
134
135 res.addTransition ( i - 1, alphabetSymbol, ext::vector < char > ( 1, 'R' ), i, ext::vector < char > { } );
136 } else {
137 ext::vector < char > push ( alphabetSymbol.getRank ( ), 'T' );
138 res.addTransition ( i - 1, alphabetSymbol, ext::vector < char > ( 1, 'T' ), i - 1, push );
139
140 push [ alphabetSymbol.getRank ( ) - 1 ] = 'R';
141 res.addTransition ( i - 1, alphabetSymbol, ext::vector < char > ( 1, 'R' ), i - 1, push );
142 }
143 }
144
145 else
146 res.addTransition ( i - 1, symbol, ext::vector < char > ( 1, 'T' ), i, computeRHS ( pattern, patternSubtreeJumpTable, i - 1 ) );
147
148 i++;
149 }
150
151 res.addFinalState ( i - 1 );
152
153 return res;
154}
155
156template < class SymbolType >
159}
160
161template < class SymbolType >
163 automaton::VisiblyPushdownNPDA < common::ranked_symbol < SymbolType >, char, unsigned > res ( alphabet::BottomOfTheStackSymbol::instance < char > ( ) );
164
165 res.addState ( 0 );
166 res.addInitialState ( 0 );
167
168 for ( const common::ranked_symbol < SymbolType > & symbol : pattern.getAlphabet ( ) ) {
169 if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
170
171 if ( pattern.getBars ( ).count ( symbol ) )
172 res.addReturnInputSymbol ( symbol );
173 else
174 res.addCallInputSymbol ( symbol );
175 }
176
177 res.setPushdownStoreAlphabet ( { alphabet::BottomOfTheStackSymbol::instance < char > ( ) , 'T', 'R' } );
178
179 for ( const common::ranked_symbol < SymbolType > & symbol : pattern.getAlphabet ( ) ) {
180 if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue;
181
182 if ( pattern.getBars ( ).count ( symbol ) )
183 res.addReturnTransition ( 0, symbol, 'T', 0 );
184 else
185 res.addCallTransition ( 0, symbol, 0, 'T' );
186 }
187
188 unsigned i = 1;
189
190 for ( const common::ranked_symbol < SymbolType > & symbol : pattern.getContent ( ) ) {
191 res.addState ( i );
192
193 if ( symbol == pattern.getSubtreeWildcard ( ) ) {
194 for ( const common::ranked_symbol < SymbolType > & alphabetSymbol : pattern.getAlphabet ( ) ) {
195 if ( ( alphabetSymbol == pattern.getSubtreeWildcard ( ) ) || ( alphabetSymbol == pattern.getVariablesBar ( ) ) || ( pattern.getBars ( ).count ( alphabetSymbol ) ) ) continue;
196
197 res.addCallTransition ( i - 1, alphabetSymbol, i, 'R' );
198 }
199 } else if ( symbol == pattern.getVariablesBar ( ) ) {
200 for ( const common::ranked_symbol < SymbolType > & alphabetSymbol : pattern.getAlphabet ( ) ) {
201 if ( ( alphabetSymbol == pattern.getSubtreeWildcard ( ) ) || ( alphabetSymbol == pattern.getVariablesBar ( ) ) ) continue;
202
203 if ( pattern.getBars ( ).count ( alphabetSymbol ) )
204 res.addReturnTransition ( i - 1, alphabetSymbol, 'T', i - 1 );
205 else
206 res.addCallTransition ( i - 1, alphabetSymbol, i - 1, 'T' );
207 }
208
209 for ( const common::ranked_symbol < SymbolType > & alphabetSymbol : pattern.getAlphabet ( ) ) {
210 if ( ( alphabetSymbol == pattern.getSubtreeWildcard ( ) ) || ( alphabetSymbol == pattern.getVariablesBar ( ) ) || ( ! pattern.getBars ( ).count ( alphabetSymbol ) ) ) continue;
211
212 res.addReturnTransition ( i - 1, alphabetSymbol, 'R', i );
213 }
214 } else if ( pattern.getBars ( ).count ( symbol ) ) {
215 res.addReturnTransition ( i - 1, symbol, 'T', i );
216 } else {
217 res.addCallTransition ( i - 1, symbol, i, 'T' );
218 }
219
220 i++;
221 }
222
223 res.addFinalState ( i - 1 );
224 return res;
225}
226
227template < class SymbolType >
230}
231
232template < class SymbolType >
235}
236
237template < class SymbolType >
239 if ( node.getData ( ) == subtreeWildcard ) {
240 unsigned state = nextState++;
241 res.addState ( state );
242
243 for ( const common::ranked_symbol < SymbolType > & symbol : res.getInputAlphabet ( ) ) {
245 states.reserve ( symbol.getRank ( ) );
246
247 for ( unsigned i = 0; i < symbol.getRank ( ); i++ )
248 states.push_back ( state );
249
250 res.addTransition ( symbol, states, state );
251 }
252
253 return state;
254 } else {
256 states.reserve ( node.getData ( ).getRank ( ) );
257
258 for ( const ext::tree < common::ranked_symbol < SymbolType > > & child : node.getChildren ( ) )
259 states.push_back ( constructRecursivePattern ( child, res, subtreeWildcard, nextState ) );
260
261 unsigned state = nextState++;
262 res.addState ( state );
263 res.addTransition ( node.getData ( ), states, state );
264 return state;
265 }
266}
267
268template < class SymbolType >
271
272 alphabet.erase ( pattern.getSubtreeWildcard ( ) );
273
275 res.setInputAlphabet ( alphabet );
276
277 unsigned nextState = 0;
278
279 res.addFinalState ( constructRecursivePattern ( pattern.getContent ( ), res, pattern.getSubtreeWildcard ( ), nextState ) );
280 return res;
281}
282
283template < class SymbolType >
286}
287
288template < class SymbolType >
290 if ( node.getData ( ) == subtreeWildcard ) {
291 unsigned state = nextState++;
292 res.addState ( state );
293
294 for ( const common::ranked_symbol < SymbolType > & symbol : res.getInputAlphabet ( ) ) {
296
297 for ( unsigned i = 0; i < symbol.getRank ( ); i++ )
298 states.insert ( state );
299
300 res.addTransition ( symbol, states, state );
301 }
302
303 return state;
304 } else {
306
307 for ( const ext::tree < common::ranked_symbol < SymbolType > > & child : node.getChildren ( ) )
308 states.insert ( constructRecursivePattern ( child, res, subtreeWildcard, nextState ) );
309
310 unsigned state = nextState++;
311 res.addState ( state );
312 res.addTransition ( node.getData ( ), states, state );
313 return state;
314 }
315}
316
317template < class SymbolType >
320
321 alphabet.erase ( pattern.getSubtreeWildcard ( ) );
322
324 res.setInputAlphabet ( alphabet );
325
326 unsigned nextState = 0;
327
328 res.addFinalState ( constructRecursivePattern ( pattern.getContent ( ), res, pattern.getSubtreeWildcard ( ), nextState ) );
329 return res;
330}
331
332template < class SymbolType >
335}
336
337template < class SymbolType >
340}
341
342template < class SymbolType >
343unsigned constructRecursivePattern ( const ext::tree < SymbolType > & node, automaton::NondeterministicZAutomaton < SymbolType, unsigned > & res, const SymbolType & subtreeWildcard, const SymbolType & subtreeGap, const SymbolType & nodeWildcard, unsigned & nextState ) {
344 unsigned state = nextState ++;
345 res.addState ( state );
346 if ( node.getData ( ) == nodeWildcard ) {
347 for ( const SymbolType & symbol : res.getInputAlphabet ( ) ) {
348 res.addTransition ( symbol, { }, state );
349 }
350 } else {
351 res.addTransition ( node.getData ( ), { }, state );
352 }
353
354 for ( const ext::tree < SymbolType > & child : node.getChildren ( ) ) {
355 res.addState ( nextState );
356 unsigned target = nextState ++;
357 if ( child.getData ( ) == subtreeWildcard ) {
358 res.addTransition ( state, { 0u }, target );
359 } else if ( child.getData ( ) == subtreeGap ) {
360 res.addTransition ( state, { 0u }, state );
361
362 res.addTransition ( state, { }, target );
363 } else {
364 unsigned result = constructRecursivePattern ( child, res, subtreeWildcard, subtreeGap, nodeWildcard, nextState );
365 res.addTransition ( state, { result }, target );
366 }
367 state = target;
368 }
369
370 return state;
371}
372
373template < class SymbolType >
376
377 alphabet.erase ( pattern.getSubtreeWildcard ( ) );
378 alphabet.erase ( pattern.getSubtreeGap ( ) );
379 alphabet.erase ( pattern.getNodeWildcard ( ) );
380
382 res.setInputAlphabet ( alphabet );
383
384 res.addState ( 0 );
385
386 for ( const SymbolType & symbol : res.getInputAlphabet ( ) )
387 res.addTransition ( symbol, { }, 0 );
388
389 res.addTransition ( 0u, { 0u }, 0 );
390
391 unsigned nextState = 1;
392
393 res.addFinalState ( constructRecursivePattern ( pattern.getContent ( ), res, pattern.getSubtreeWildcard ( ), pattern.getSubtreeGap ( ), pattern.getNodeWildcard ( ), nextState ) );
394 return res;
395}
396
397} /* namespace exact */
398
399} /* namespace arbology */
400
Definition: ExactPatternMatchingAutomaton.h:38
static automaton::NPDA< common::ranked_symbol< SymbolType >, char, unsigned > construct(const tree::PrefixRankedPattern< SymbolType > &pattern)
Definition: ExactPatternMatchingAutomaton.h:104
static automaton::InputDrivenNPDA< common::ranked_symbol< SymbolType >, char, unsigned > construct(const tree::PrefixRankedTree< SymbolType > &pattern)
Definition: ExactSubtreeMatchingAutomaton.h:48
Nondeterministic input driven pushdown automaton. Accepts subset of context free languages.
Definition: InputDrivenNPDA.h:79
Nondeterministic finite tree automaton without epsilon transitions. Accepts regular tree languages.
Definition: NFTA.h:72
Definition: NPDA.h:74
Nondeterministic Z-Automaton. Computation model for unranked regular tree languages.
Definition: NondeterministicZAutomaton.h:68
Nondeterministic unordered finite tree automaton without epsilon transitions. Accepts regular tree la...
Definition: UnorderedNFTA.h:72
Nondeterministic visibly pushdown automaton. Accepts subset of context free languages.
Definition: VisiblyPushdownNPDA.h:81
Definition: ranked_symbol.hpp:20
Definition: multiset.hpp:44
Definition: set.hpp:44
Class introducing a tree with interface trying to be close to the interface of standard library conta...
Definition: tree.hpp:52
Class extending the vector class from the standard library. Original reason is to allow printing of t...
Definition: vector.hpp:45
Tree pattern represented as linear sequece as result of preorder traversal with additional bar symbol...
Definition: PrefixRankedBarPattern.h:85
const common::ranked_symbol< SymbolType > & getVariablesBar() const &
Definition: PrefixRankedBarPattern.h:220
const common::ranked_symbol< SymbolType > & getSubtreeWildcard() const &
Definition: PrefixRankedBarPattern.h:202
const ext::set< common::ranked_symbol< SymbolType > > & getAlphabet() const &
Definition: PrefixRankedBarPattern.h:148
const ext::set< common::ranked_symbol< SymbolType > > & getBars() const &
Definition: PrefixRankedBarPattern.h:175
const ext::vector< common::ranked_symbol< SymbolType > > & getContent() const &
Definition: PrefixRankedBarPattern.h:334
Tree structure represented as linear sequece as result of preorder traversal with additional bar symb...
Definition: PrefixRankedBarTree.h:78
Tree pattern represented as linear sequece as result of preorder traversal. The representation is so ...
Definition: PrefixRankedPattern.h:77
const ext::vector< common::ranked_symbol< SymbolType > > & getContent() const &
Definition: PrefixRankedPattern.h:262
const ext::set< common::ranked_symbol< SymbolType > > & getAlphabet() const &
Definition: PrefixRankedPattern.h:127
const common::ranked_symbol< SymbolType > & getSubtreeWildcard() const &
Definition: PrefixRankedPattern.h:154
Tree structure represented as linear sequece as result of preorder traversal. The representation is s...
Definition: PrefixRankedTree.h:71
Tree pattern represented in its natural representation. The representation is so called ranked,...
Definition: RankedPattern.h:72
const ext::tree< common::ranked_symbol< SymbolType > > & getContent() const &
Definition: RankedPattern.h:251
const ext::set< common::ranked_symbol< SymbolType > > & getAlphabet() const &
Definition: RankedPattern.h:126
const common::ranked_symbol< SymbolType > & getSubtreeWildcard() const &
Definition: RankedPattern.h:153
Tree structure represented in its natural representation. The representation is so called ranked,...
Definition: RankedTree.h:72
Tree pattern represented in its natural representation. The representation is so called ranked,...
Definition: UnorderedRankedPattern.h:72
const ext::tree< common::ranked_symbol< SymbolType > > & getContent() const &
Definition: UnorderedRankedPattern.h:251
const ext::set< common::ranked_symbol< SymbolType > > & getAlphabet() const &
Definition: UnorderedRankedPattern.h:126
const common::ranked_symbol< SymbolType > & getSubtreeWildcard() const &
Definition: UnorderedRankedPattern.h:153
Tree structure represented in its natural representation. The representation is so called ranked,...
Definition: UnorderedRankedTree.h:70
Extended tree pattern represented in its natural representation. The representation is so called unra...
Definition: UnrankedExtendedPattern.h:76
const SymbolType & getNodeWildcard() const &
Definition: UnrankedExtendedPattern.h:150
const ext::set< SymbolType > & getAlphabet() const &
Definition: UnrankedExtendedPattern.h:123
const SymbolType & getSubtreeGap() const &
Definition: UnrankedExtendedPattern.h:186
const SymbolType & getSubtreeWildcard() const &
Definition: UnrankedExtendedPattern.h:168
const ext::tree< SymbolType > & getContent() const &
Definition: UnrankedExtendedPattern.h:285
Tree pattern represented in its natural representation. The representation is so called unranked,...
Definition: UnrankedPattern.h:73
Tree represented in its natural representation. The representation is so called unranked,...
Definition: UnrankedTree.h:69
static ext::vector< int > compute(const tree::PrefixRankedBarTree< SymbolType > &subject)
Definition: SubtreeJumpTable.h:49
Definition: BarSymbol.cpp:12
unsigned constructRecursivePattern(const ext::tree< common::ranked_symbol< SymbolType > > &node, automaton::NFTA< SymbolType, unsigned > &res, const common::ranked_symbol< SymbolType > &subtreeWildcard, unsigned &nextState)
Definition: ExactPatternMatchingAutomaton.h:238
ext::vector< char > computeRHS(const tree::PrefixRankedPattern< SymbolType > &pattern, const ext::vector< int > &patternSubtreeJumpTable, int i)
Definition: ExactPatternMatchingAutomaton.h:80
Definition: BoyerMooreHorspool.h:22
int i
Definition: AllEpsilonClosure.h:118
typename T::SymbolType SymbolType
Definition: ReachableStates.h:176
return res
Definition: MinimizeByPartitioning.h:145
for(const StateType &state :fsm.getStates()) renamingData.insert(std Rename::RenamedAutomaton< T > result(renamingData.at(fsm.getInitialState()))
Definition: Rename.h:253
Definition: Node.cpp:11