Macaulay2 Engine
Loading...
Searching...
No Matches
WordTable.cpp
Go to the documentation of this file.
2#include "NCAlgebras/Word.hpp" // for Word, WordWithData, operator<<
3
4std::ostream& operator<<(std::ostream& o, const WordTable& wordTable)
5{
6 if (wordTable.mMonomials.size() == 0) return o;
7
8 int j = 0;
9 for (; j < wordTable.mMonomials.size() - 1; ++j)
10 {
11 o << wordTable.mMonomials[j] << ",";
12 }
13 o << wordTable.mMonomials[j];
14 return o;
15}
16
18{
19 // we are making a copy of the word, since the pointers
20 // to the GB elements may change during autoreduction.
21 auto newW = mMonomialSpace.allocateArray<int>(w.size());
22 std::copy(w.begin(),w.end(),newW.first);
23 mMonomials.push_back(Word(newW.first,newW.second));
24 return mMonomials.size();
25}
26
27size_t WordTable::insert(Word w, std::vector<Overlap>& newRightOverlaps)
28{
29 // we are making a copy of the word, since the pointers
30 // to the GB elements may change during autoreduction.
31 auto newW = mMonomialSpace.allocateArray<int>(w.size());
32 std::copy(w.begin(),w.end(),newW.first);
33 mMonomials.push_back(Word(newW.first,newW.second));
34 rightOverlaps(newRightOverlaps); // find (right) overlaps with most recent added word 'w'.
35 return mMonomials.size();
36}
37
39 Word word2,
40 std::vector<int>& result_start_indices)
41// if there exists monomials p, q, such that p*word1*q == word2, then
42// the position of word1 in word2 is added (there may be several
43// matches)
44{
45 if (word2.size() < word1.size()) return;
46 for (auto j = 0; j <= word2.size() - word1.size(); ++j)
47 {
48 bool match = true;
49 for (auto k = 0; k < word1.size(); ++k)
50 if (word1.begin()[k] != word2.begin()[j+k])
51 {
52 match = false;
53 break;
54 }
55 if (match) result_start_indices.push_back(j);
56 }
57}
58
60 Word word2,
61 int& result_start_index)
62// if there exists monomials p, q, such that p*word1*q == word2, then
63// the first position of word1 in word2 is returned in result_start_index
64// and true is returned. If no match, then false is returned,
65// and result_start_index is not touched.
66{
67 if (word2.size() < word1.size()) return false;
68 for (auto j = 0; j <= word2.size() - word1.size(); ++j)
69 {
70 bool match = true;
71 for (auto k = 0; k < word1.size(); ++k)
72 if (word1.begin()[k] != word2.begin()[j+k])
73 {
74 match = false;
75 break;
76 }
77 if (match)
78 {
79 result_start_index = j;
80 return true;
81 }
82 }
83 return false;
84}
85
87// true is returned if there exists monomial q, such that word1*q == word2
88{
89 if (word2.size() < word1.size()) return false;
90 bool match = true;
91 for (auto k = 0; k < word1.size(); ++k)
92 if (word1.begin()[k] != word2.begin()[k])
93 {
94 match = false;
95 break;
96 }
97 return match;
98}
99
101// true is returned if there exists monomial p, such that p*word1 == word2
102{
103 auto word1size = word1.size();
104 auto word2size = word2.size();
105 if (word2size < word1size) return false;
106 // at this point if word2.size() == 0, then word2 (and hence word1) are both empty
107 if (word2size == 0) return false;
108 bool match = true;
109 for (auto k = 0; k < word1size; ++k)
110 if (word1.begin()[word1size-1-k] != word2.begin()[word2size-1-k])
111 {
112 match = false;
113 break;
114 }
115 return match;
116}
117
119 std::vector<std::pair<int,int>>& output) const
120{
121 // this command returns a pair (i,j) where word i in the table appears
122 // in position j of word.
123 std::vector<int> start_indices;
124 for (auto i = 0; i < mMonomials.size(); ++i)
125 {
126 start_indices.clear();
127 subwordPositions(mMonomials[i], word, start_indices);
128 for (auto j : start_indices)
129 output.push_back(std::make_pair(i,j));
130 }
131}
132
134 int& output) const
135{
136 for (auto i = 0; i < mMonomials.size(); ++i)
137 {
138 if (isPrefixOf(mMonomials[i], word))
139 {
140 output = i;
141 return true;
142 }
143 }
144 return false;
145}
146
148 int& output) const
149{
150 for (auto i = 0; i < mMonomials.size(); ++i)
151 {
152 if (isSuffixOf(mMonomials[i], word))
153 {
154 output = i;
155 return true;
156 }
157 }
158 return false;
159}
160
162 std::pair<int,int>& output) const
163{
164 int start_index = -1; // return value
165 for (auto i = 0; i < mMonomials.size(); ++i)
166 {
167 if (subwordPosition(mMonomials[i], word, start_index))
168 {
169 output = std::make_pair(i, start_index);
170 return true;
171 }
172 }
173 return false;
174}
175
177 std::vector<std::pair<int,int>>& output) const
178{
179 // this command returns a list of pairs (i,j) where word appears
180 // appears in monomial i in position j
181 std::vector<int> start_indices;
182 for (auto i = 0; i < mMonomials.size(); ++i)
183 {
184 start_indices.clear();
185 subwordPositions(word, mMonomials[i], start_indices);
186 for (auto j : start_indices)
187 output.push_back(std::make_pair(i,j));
188 }
189}
190
191auto WordTable::isNontrivialSuperword(Word word, int index1, int index2) const -> bool
192{
193 // this command is only called on an overlap between the words mMonomials[index1]
194 // and mMonomials[index2].
195 std::vector<int> start_indices;
196 for (auto i = 0; i < mMonomials.size(); ++i)
197 {
198 start_indices.clear();
199 subwordPositions(mMonomials[i], word, start_indices);
200 for (auto j : start_indices)
202 if (i != index1 && i != index2) return true;
203 // these commands handle when the overlap is *trivially* a multiple of one of
204 // the monomials in index1 or index2
205 if (j == 0 && i != index1) return true;
206 if (j == word.size() - mMonomials[index2].size() && i != index2) return true;
207 }
208 }
209 return false;
210}
211
212// This function finds overlap where suffix of word at lindex == prefix of word at rindex
214 Word word2,
215 std::vector<int>& result_overlaps)
216{
217 if (word1.size() <= 1) return;
218 for (int i = word1.size() - 1; i > 0 and i + word2.size() > word1.size(); --i)
219 {
220 Word suffix(word1.begin() + i, word1.end());
221 Word prefix(word2.begin(), word2.begin() + word1.size() - i); // indices should be in range.
222 if (suffix == prefix)
223 result_overlaps.push_back(i);
224 }
225}
226
227void WordTable::leftOverlaps(std::vector<Overlap>& newLeftOverlaps) const
228{
229 // word here is the last word in the dictionary.
230 // For left overlap: dictword is a word in the dictionary NOT word.
231 // For right overlap: dictword is any word in the dictionary.
232 // A left overlap: suffix(dictword) == prefix(word)
233 // A right overlap: prefix(dictword) == suffix(word).
234 // if dictword == word, a match will be a right overlap, NOT a left overlap.
235 // A returned triple:
236 // (left overlap):
237
238 int word_index = mMonomials.size()-1;
239 std::vector<int> overlap_indices;
240 for (int i=0; i<word_index; ++i)
241 {
242 overlap_indices.clear();
243 overlaps(mMonomials[i], mMonomials[word_index], overlap_indices);
244 for (auto j : overlap_indices)
245 newLeftOverlaps.push_back(std::make_tuple(i, j, word_index,true));
246 }
247 // triples will be <dict word index, index into dict word where suffix starts, word_index>.
248}
249
250void WordTable::rightOverlaps(std::vector<Overlap>& newRightOverlaps) const
251// find (right) overlaps with most recent added word 'w'.
252{
253 int word_index = mMonomials.size()-1;
254 std::vector<int> overlap_indices;
255 for (int i=0; i<=word_index; ++i)
256 {
257 overlap_indices.clear();
258 overlaps(mMonomials[word_index], mMonomials[i], overlap_indices);
259 for (auto j : overlap_indices)
260 newRightOverlaps.push_back(std::make_tuple(word_index, j, i,true));
261 }
262}
263
264std::ostream& operator<<(std::ostream& o, const WordWithDataTable& wordTable)
265{
266 if (wordTable.mMonomials.size() == 0) return o;
267
268 int j = 0;
269 for (; j < wordTable.mMonomials.size() - 1; ++j)
270 {
271 o << wordTable.mMonomials[j] << ",";
272 }
273 o << wordTable.mMonomials[j];
274 return o;
275}
276
278{
279 size_t retval = mMonomials.size();
280 mMonomials.push_back(w);
281 mIndices.push_back(retval);
282 return retval;
283}
284
285size_t WordWithDataTable::insert(WordWithData w, std::vector<Overlap>& newRightOverlaps)
286{
287 size_t retval = mMonomials.size();
288 mMonomials.push_back(w);
289 mIndices.push_back(retval);
290 rightOverlaps(newRightOverlaps); // find (right) overlaps with most recent added word 'w'.
291 return retval;
292}
293
295 WordWithData word2,
296 std::vector<int>& result_start_indices)
297// if there exists monomials p, q, such that p*word1*q == word2, then
298// the position of word1 in word2 is added (there may be several
299// matches)
300{
301 if (word2.size() < word1.size()) return;
302 if (word2.ecartDegree() < word1.ecartDegree()) return;
303 for (auto j = 0; j <= word2.size() - word1.size(); ++j)
304 {
305 bool match = true;
306 for (auto k = 0; k < word1.size(); ++k)
307 if (word1.begin()[k] != word2.begin()[j+k])
308 {
309 match = false;
310 break;
311 }
312 if (match) result_start_indices.push_back(j);
313 }
314}
315
317 WordWithData word2,
318 int& result_start_index)
319// if there exists monomials p, q, such that p*word1*q == word2, then
320// the first position of word1 in word2 is returned in result_start_index
321// and true is returned. If no match, then false is returned,
322// and result_start_index is not touched.
323{
324 if (word2.size() < word1.size()) return false;
325 if (word2.ecartDegree() < word1.ecartDegree()) return false;
326 for (auto j = 0; j <= word2.size() - word1.size(); ++j)
327 {
328 bool match = true;
329 for (auto k = 0; k < word1.size(); ++k)
330 if (word1.begin()[k] != word2.begin()[j+k])
331 {
332 match = false;
333 break;
334 }
335 if (match)
336 {
337 result_start_index = j;
338 return true;
339 }
340 }
341 return false;
342}
343
345// true is returned if there exists monomial q, such that word1*q == word2
346{
347 if (word2.size() < word1.size()) return false;
348 bool match = true;
349 for (auto k = 0; k < word1.size(); ++k)
350 if (word1.begin()[k] != word2.begin()[k])
351 {
352 match = false;
353 break;
354 }
355 return match;
356}
357
359// true is returned if there exists monomial p, such that p*word1 == word2
360{
361 auto word1size = word1.size();
362 auto word2size = word2.size();
363 if (word2size < word1size) return false;
364 // at this point if word2.size() == 0, then word2 (and hence word1) are both empty
365 if (word2size == 0) return false;
366 bool match = true;
367 for (auto k = 0; k < word1size; ++k)
368 if (word1.begin()[word1size-1-k] != word2.begin()[word2size-1-k])
369 {
370 match = false;
371 break;
372 }
373 return match;
374}
375
377 std::vector<std::pair<int,int>>& output) const
378{
379 // this command returns a pair (i,j) where word i in the table appears
380 // in position j of word.
381 std::vector<int> start_indices;
382 for (auto i = 0; i < mMonomials.size(); ++i)
383 {
384 if (mIndices[i] == -1) continue;
385 start_indices.clear();
386 subwordPositions(mMonomials[i], word, start_indices);
387 for (auto j : start_indices)
388 output.push_back(std::make_pair(i,j));
389 }
390}
391
393 int& output) const
394{
395 for (auto i = 0; i < mMonomials.size(); ++i)
396 {
397 if (mIndices[i] == -1) continue;
398 if (isPrefixOf(mMonomials[i], word))
399 {
400 output = i;
401 return true;
402 }
403 }
404 return false;
405}
406
408 int& output) const
409{
410 for (auto i = 0; i < mMonomials.size(); ++i)
411 {
412 if (mIndices[i] == -1) continue;
413 if (isSuffixOf(mMonomials[i], word))
414 {
415 output = i;
416 return true;
417 }
418 }
419 return false;
420}
421
423 std::pair<int,int>& output) const
424{
425 int start_index = -1;
426 for (auto i = 0; i < mMonomials.size(); ++i)
427 {
428 if (mIndices[i] == -1) continue;
429 if (subwordPosition(mMonomials[i], word, start_index))
430 {
431 output = std::make_pair(i, start_index);
432 return true;
433 }
434 }
435 return false;
436}
437
439 std::vector<std::pair<int,int>>& output) const
440{
441 // this command returns a list of pairs (i,j) where word appears
442 // appears in monomial i in position j
443 std::vector<int> start_indices;
444 for (auto i = 0; i < mMonomials.size(); ++i)
445 {
446 if (mIndices[i] == -1) continue;
447 start_indices.clear();
448 subwordPositions(word, mMonomials[i], start_indices);
449 for (auto j : start_indices)
450 output.push_back(std::make_pair(i,j));
451 }
452}
453
454auto WordWithDataTable::isNontrivialSuperword(WordWithData word, int index1, int index2) const -> bool
455{
456 // this command is only called on an overlap between the words mMonomials[index1]
457 // and mMonomials[index2].
458 std::vector<int> start_indices;
459 for (auto i = 0; i < mMonomials.size(); ++i)
460 {
461 if (mIndices[i] == -1) continue;
462 start_indices.clear();
463 subwordPositions(mMonomials[i], word, start_indices);
464 for (auto j : start_indices)
465 {
466 if (i != index1 && i != index2) return true;
467 // these commands handle when the overlap is trivially a multiple of one of
468 // the monomials in index1 or index2
469 if (j == 0 && i != index1) return true;
470 if (j == word.size() - mMonomials[index2].size() && i != index2) return true;
471 }
472 }
473 return false;
474}
475
476// This function finds overlap where suffix of word at lindex == prefix of word at rindex
478 WordWithData word2,
479 std::vector<int>& result_overlaps)
480{
481 if (word1.size() <= 1) return;
482 for (int i = word1.size() - 1; i > 0 and i + word2.size() > word1.size(); --i)
483 {
484 // below, we are disregarding ecart degree for overlap detection/generation
485 Word suffix(word1.begin() + i, word1.end());
486 Word prefix(word2.begin(), word2.begin() + word1.size() - i); // indices should be in range.
487 if (suffix == prefix)
488 result_overlaps.push_back(i);
489 }
490}
491
492void WordWithDataTable::leftOverlaps(std::vector<Overlap>& newLeftOverlaps) const
493{
494 // word here is the last word in the dictionary.
495 // For left overlap: dictword is a word in the dictionary NOT word.
496 // For right overlap: dictword is any word in the dictionary.
497 // A left overlap: suffix(dictword) == prefix(word)
498 // A right overlap: prefix(dictword) == suffix(word).
499 // if dictword == word, a match will be a right overlap, NOT a left overlap.
500 // A returned triple:
501 // (left overlap):
502
503 int word_index = mMonomials.size()-1;
504 std::vector<int> overlap_indices;
505 for (int i=0; i<word_index; ++i)
506 {
507 if (mIndices[i] == -1) continue;
508 overlap_indices.clear();
509 overlaps(mMonomials[i], mMonomials[word_index], overlap_indices);
510 for (auto j : overlap_indices)
511 newLeftOverlaps.push_back(std::make_tuple(i, j, word_index,true));
512 }
513 // triples will be <dict word index, index into dict word where suffix starts, word_index>.
514}
515
516void WordWithDataTable::rightOverlaps(std::vector<Overlap>& newRightOverlaps) const
517// find (right) overlaps with most recent added word 'w'.
518{
519 int word_index = mMonomials.size()-1;
520 std::vector<int> overlap_indices;
521 for (int i=0; i<=word_index; ++i)
522 {
523 if (mIndices[i] == -1) continue;
524 overlap_indices.clear();
525 overlaps(mMonomials[word_index], mMonomials[i], overlap_indices);
526 for (auto j : overlap_indices)
527 newRightOverlaps.push_back(std::make_tuple(word_index, j, i,true));
528 }
529}
530
531// Local Variables:
532// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
533// indent-tabs-mode: nil
534// End:
std::vector< int > word
Word prefix(const Word vec, int lengthOfPrefix)
Word suffix(const Word vec, int indexOfSuffix)
Word and WordWithData — non-owning views over the flat-int encoding of a non-commutative word.
std::ostream & operator<<(std::ostream &o, const WordTable &wordTable)
Definition WordTable.cpp:4
WordTable / WordWithDataTable — leading-word indices for non-commutative Gröbner basis lookup.
const int * begin() const
Definition Word.hpp:72
const int * end() const
Definition Word.hpp:73
int size() const
Definition Word.hpp:74
Non-owning view of a non-commutative word: [begin, end) of int variable indices.
Definition Word.hpp:56
void superwords(Word word, std::vector< std::pair< int, int > > &output) const
void rightOverlaps(std::vector< Overlap > &newRightOverlaps) const
static void subwordPositions(Word word1, Word word2, std::vector< int > &result_start_indices)
Definition WordTable.cpp:38
bool isPrefix(Word word, int &output) const
bool isSuffix(Word word, int &output) const
void subwords(Word word, std::vector< std::pair< int, int > > &output) const
std::vector< Word > mMonomials
static void overlaps(Word word1, Word word2, std::vector< int > &result_overlaps)
auto isNontrivialSuperword(Word word, int index1, int index2) const -> bool
void leftOverlaps(std::vector< Overlap > &newLeftOverlaps) const
static bool isPrefixOf(Word word1, Word word2)
Definition WordTable.cpp:86
static bool subwordPosition(Word word1, Word word2, int &result_start_index)
Definition WordTable.cpp:59
bool subword(Word word, std::pair< int, int > &output) const
MemoryBlock mMonomialSpace
size_t insert(Word w)
Definition WordTable.cpp:17
static bool isSuffixOf(Word word1, Word word2)
const int * end() const
Definition Word.hpp:141
size_t size() const
Definition Word.hpp:148
const int * begin() const
Definition Word.hpp:140
int ecartDegree() const
Definition Word.hpp:145
Word plus its ecart degree and heft degree — the value type WordWithDataTable stores.
Definition Word.hpp:116
static void overlaps(WordWithData word1, WordWithData word2, std::vector< int > &result_overlaps)
bool subword(WordWithData word, std::pair< int, int > &output) const
static void subwordPositions(WordWithData word1, WordWithData word2, std::vector< int > &result_start_indices)
bool isSuffix(WordWithData word, int &output) const
std::vector< int > mIndices
void superwords(WordWithData word, std::vector< std::pair< int, int > > &output) const
static bool subwordPosition(WordWithData word1, WordWithData word2, int &result_start_index)
bool isPrefix(WordWithData word, int &output) const
auto isNontrivialSuperword(WordWithData word, int index1, int index2) const -> bool
size_t insert(WordWithData w)
static bool isPrefixOf(WordWithData word1, WordWithData word2)
void leftOverlaps(std::vector< Overlap > &newLeftOverlaps) const
static bool isSuffixOf(WordWithData word1, WordWithData word2)
void subwords(WordWithData word, std::vector< std::pair< int, int > > &output) const
void rightOverlaps(std::vector< Overlap > &newRightOverlaps) const
std::vector< WordWithData > mMonomials