Ticket #10788: trac_10788_return_words-sl.patch

File trac_10788_return_words-sl.patch, 10.4 KB (added by slabbe, 10 years ago)

Applies over sage-4.6.1

• sage/combinat/words/abstract_word.py

```# HG changeset patch
# User Sebastien Labbe <slabqc at gmail.com>
# Date 1297867867 18000
# Node ID 3abf635b88a8ac08e04593faf3f591341db96ccf
# Parent  60a38feccb260ab8c9bbef73e841fc68343c5dfd
#10788: Maximum recursion depth exceeded in the computation of return words

diff --git a/sage/combinat/words/abstract_word.py b/sage/combinat/words/abstract_word.py```
 a class Word_class(SageObject): """ return self._len def is_finite(self): r""" Returns whether this word is known to be finite. .. WARNING:: A word defined by an iterator such that its end has never been reached will returns False. EXAMPLES:: sage: Word([]).is_finite() True sage: Word('a').is_finite() True sage: TM = words.ThueMorseWord() sage: TM.is_finite() False :: sage: w = Word(iter('a'*100)) sage: w.is_finite() False """ return False def __len__(self): r""" Returns the length of self (as a python integer). class Word_class(SageObject): return Word(it, alphabet=alphabet, length=length, datatype='iter') def factor_occurrences_iterator(self, fact): r""" Returns an iterator over all occurrences (including overlapping ones) of fact in self in their order of appearance. INPUT: - ``fact`` - a non empty finite word OUTPUT: iterator EXAMPLES:: sage: TM = words.ThueMorseWord() sage: fact = Word([0,1,1,0,1]) sage: it = TM.factor_occurrences_iterator(fact) sage: it.next() 0 sage: it.next() 12 sage: it.next() 24 """ if fact.is_empty(): raise NotImplementedError, "The factor must be non empty" if not fact.is_finite(): raise ValueError, "The factor must be finite" p = fact._pos_in(self, 0) while p is not None: yield p p = fact._pos_in(self, p+1) def return_words_iterator(self, fact): r""" Returns an iterator over all the return words of fact in self (without unicity). INPUT: - ``fact`` - a non empty finite word OUTPUT: iterator EXAMPLES:: sage: w = Word('baccabccbacbca') sage: b = Word('b') sage: list(w.return_words_iterator(b)) [word: bacca, word: bcc, word: bac] :: sage: TM = words.ThueMorseWord() sage: fact = Word([0,1,1,0,1]) sage: it = TM.return_words_iterator(fact) sage: it.next() word: 011010011001 sage: it.next() word: 011010010110 sage: it.next() word: 0110100110010110 sage: it.next() word: 01101001 sage: it.next() word: 011010011001 sage: it.next() word: 011010010110 """ it = self.factor_occurrences_iterator(fact) i = it.next() while True: j = it.next() yield self[i:j] i = j def complete_return_words_iterator(self, fact): r""" Returns an iterator over all the complete return words of fact in self (without unicity). A complete return words `u` of a factor `v`  is a factor starting by the given factor `v` and ending just after the next occurrence of this factor `v`. See for instance [1]. INPUT: - ``fact`` - a non empty finite word OUTPUT: iterator EXAMPLES:: sage: TM = words.ThueMorseWord() sage: fact = Word([0,1,1,0,1]) sage: it = TM.complete_return_words_iterator(fact) sage: it.next() word: 01101001100101101 sage: it.next() word: 01101001011001101 sage: it.next() word: 011010011001011001101 sage: it.next() word: 0110100101101 sage: it.next() word: 01101001100101101 sage: it.next() word: 01101001011001101 REFERENCES: -   [1] J. Justin, L. Vuillon, Return words in Sturmian and episturmian words, Theor. Inform. Appl. 34 (2000) 343--356. """ it = self.factor_occurrences_iterator(fact) L = fact.length() i = it.next() while True: j = it.next() yield self[i:j+L] i = j
• sage/combinat/words/finite_word.py

`diff --git a/sage/combinat/words/finite_word.py b/sage/combinat/words/finite_word.py`
 a exponent %s: the length of the word (%s) """ return self.length()==0 def is_finite(self): r""" Returns True. EXAMPLES:: sage: Word([]).is_finite() True sage: Word('a').is_finite() True """ return True def to_integer_word(self): r""" Returns a word defined over the integers [0,1,...,self.length()-1] exponent %s: the length of the word (%s) """ return self[::-1] @cached_method def prefix_function_table(self): r""" Returns a vector containing the length of the proper prefix-suffixes exponent %s: the length of the word (%s) res[q] = k return res @cached_method def good_suffix_table(self): r""" Returns a table of the maximum skip you can do in order not to miss exponent %s: the length of the word (%s) return [lpd.get(a,-1) for a in self.parent().alphabet()] return lpd @cached_method def last_position_dict(self): r""" Returns a dictionary that contains the last position of each letter exponent %s: the length of the word (%s) 0 """ lf = self.length() lm = len(other) lm = other.length() if lf == 0: return p elif lm == 0: exponent %s: the length of the word (%s) [0, 2, 8] """ if self.length() == 0: raise NotImplementedError, "undefined value" raise NotImplementedError, "The factor must be non empty" p = self._pos_in(other, 0) while p is not None: yield p exponent %s: the length of the word (%s) sage: Word().nb_factor_occurrences_in(Word('123')) Traceback (most recent call last): ... NotImplementedError: undefined value NotImplementedError: The factor must be non empty sage: Word('123').nb_factor_occurrences_in(Word('112332312313112332121123')) 4 sage: Word('321').nb_factor_occurrences_in(Word('11233231231311233221123')) exponent %s: the length of the word (%s) def _return_words_list(self, fact): r""" Returns the return words as a list in the order they appear in the word. INPUT: - ``fact`` - a non empty finite word OUTPUT: Python list of finite words TESTS:: sage: Word('baccabccbacbca')._return_words_list(Word('b')) [word: bacca, word: bcc, word: bac] """ i = fact.first_pos_in(self) if i is None: return [] w = self[i+1:] j = fact.first_pos_in(w) res = [] while j is not None: res.append(self[i:i+j+1]) w = w[j+1:] i += j+1 j = fact.first_pos_in(w) return res return list(self.return_words_iterator(fact)) def return_words(self, fact): r""" exponent %s: the length of the word (%s) This is the set of all factors starting by the given factor and ending just before the next occurrence of this factor. See [1] and [2]. INPUT: - ``fact`` - a non empty finite word OUTPUT: Python set of finite words EXAMPLES:: exponent %s: the length of the word (%s) set([]) sage: Word('121212').return_words(Word('1212')) set([word: 12]) :: sage: TM = words.ThueMorseWord()[:10000] sage: TM.return_words(Word([0]))     # optional long time (1.34 s) set([word: 0, word: 01, word: 011]) REFERENCES: exponent %s: the length of the word (%s) -   [2] C. Holton, L.Q. Zamboni, Descendants of primitive substitutions, Theory Comput. Syst. 32 (1999) 133-157. """ return set(self._return_words_list(fact)) return set(self.return_words_iterator(fact)) def complete_return_words(self, fact): r""" exponent %s: the length of the word (%s) This is the set of all factors starting by the given factor and ending just after the next occurrence of this factor. See for instance [1]. INPUT: - ``fact`` - a non empty finite word OUTPUT: Python set of finite words EXAMPLES:: exponent %s: the length of the word (%s) -   [1] J. Justin, L. Vuillon, Return words in Sturmian and episturmian words, Theor. Inform. Appl. 34 (2000) 343--356. """ i = fact.first_pos_in(self) if i is None: return set() w = self[i+1:] j = fact.first_pos_in(w) res = set() while j is not None: res.add(self[i:i+j+len(fact)+1]) w = w[j+1:] i += j+1 j = fact.first_pos_in(w) return res return set(self.complete_return_words_iterator(fact)) def return_words_derivate(self, fact): r"""