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 b class Word_class(SageObject): 
    147147        """
    148148        return self._len
    149149
     150    def is_finite(self):
     151        r"""
     152        Returns whether this word is known to be finite.
     153
     154        .. WARNING::
     155
     156            A word defined by an iterator such that its end has
     157            never been reached will returns False.
     158       
     159        EXAMPLES::
     160
     161            sage: Word([]).is_finite()
     162            True
     163            sage: Word('a').is_finite()
     164            True
     165            sage: TM = words.ThueMorseWord()
     166            sage: TM.is_finite()
     167            False
     168
     169        ::
     170
     171            sage: w = Word(iter('a'*100))
     172            sage: w.is_finite()
     173            False
     174
     175        """
     176        return False
     177
    150178    def __len__(self):
    151179        r"""
    152180        Returns the length of self (as a python integer).
    class Word_class(SageObject): 
    15541582
    15551583        return Word(it, alphabet=alphabet, length=length, datatype='iter')
    15561584
     1585    def factor_occurrences_iterator(self, fact):
     1586        r"""
     1587        Returns an iterator over all occurrences (including overlapping ones)
     1588        of fact in self in their order of appearance.
     1589       
     1590        INPUT:
     1591
     1592        - ``fact`` - a non empty finite word
     1593
     1594        OUTPUT:
     1595
     1596        iterator
     1597       
     1598        EXAMPLES::
     1599
     1600            sage: TM = words.ThueMorseWord()
     1601            sage: fact = Word([0,1,1,0,1])
     1602            sage: it = TM.factor_occurrences_iterator(fact)
     1603            sage: it.next()
     1604            0
     1605            sage: it.next()
     1606            12
     1607            sage: it.next()
     1608            24
     1609        """
     1610        if fact.is_empty():
     1611            raise NotImplementedError, "The factor must be non empty"
     1612        if not fact.is_finite():
     1613            raise ValueError, "The factor must be finite"
     1614        p = fact._pos_in(self, 0)
     1615        while p is not None:
     1616            yield p
     1617            p = fact._pos_in(self, p+1)
     1618
     1619    def return_words_iterator(self, fact):
     1620        r"""
     1621        Returns an iterator over all the return words of fact in self
     1622        (without unicity).
     1623
     1624        INPUT:
     1625
     1626        - ``fact`` - a non empty finite word
     1627
     1628        OUTPUT:
     1629
     1630        iterator
     1631
     1632        EXAMPLES::
     1633
     1634            sage: w = Word('baccabccbacbca')
     1635            sage: b = Word('b')
     1636            sage: list(w.return_words_iterator(b))
     1637            [word: bacca, word: bcc, word: bac]
     1638
     1639        ::
     1640
     1641            sage: TM = words.ThueMorseWord()
     1642            sage: fact = Word([0,1,1,0,1])
     1643            sage: it = TM.return_words_iterator(fact)
     1644            sage: it.next()
     1645            word: 011010011001
     1646            sage: it.next()
     1647            word: 011010010110
     1648            sage: it.next()
     1649            word: 0110100110010110
     1650            sage: it.next()
     1651            word: 01101001
     1652            sage: it.next()
     1653            word: 011010011001
     1654            sage: it.next()
     1655            word: 011010010110
     1656        """
     1657        it = self.factor_occurrences_iterator(fact)
     1658        i = it.next()
     1659        while True:
     1660            j = it.next()
     1661            yield self[i:j]
     1662            i = j
     1663
     1664    def complete_return_words_iterator(self, fact):
     1665        r"""
     1666        Returns an iterator over all the complete return words of fact in
     1667        self (without unicity).
     1668
     1669        A complete return words `u` of a factor `v`  is a factor starting
     1670        by the given factor `v` and ending just after the next occurrence
     1671        of this factor `v`. See for instance [1].
     1672
     1673        INPUT:
     1674
     1675        - ``fact`` - a non empty finite word
     1676
     1677        OUTPUT:
     1678
     1679        iterator
     1680
     1681        EXAMPLES::
     1682
     1683            sage: TM = words.ThueMorseWord()
     1684            sage: fact = Word([0,1,1,0,1])
     1685            sage: it = TM.complete_return_words_iterator(fact)
     1686            sage: it.next()
     1687            word: 01101001100101101
     1688            sage: it.next()
     1689            word: 01101001011001101
     1690            sage: it.next()
     1691            word: 011010011001011001101
     1692            sage: it.next()
     1693            word: 0110100101101
     1694            sage: it.next()
     1695            word: 01101001100101101
     1696            sage: it.next()
     1697            word: 01101001011001101
     1698
     1699        REFERENCES:
     1700
     1701        -   [1] J. Justin, L. Vuillon, Return words in Sturmian and
     1702            episturmian words, Theor. Inform. Appl. 34 (2000) 343--356.
     1703        """
     1704        it = self.factor_occurrences_iterator(fact)
     1705        L = fact.length()
     1706        i = it.next()
     1707        while True:
     1708            j = it.next()
     1709            yield self[i:j+L]
     1710            i = j
     1711
  • sage/combinat/words/finite_word.py

    diff --git a/sage/combinat/words/finite_word.py b/sage/combinat/words/finite_word.py
    a b exponent %s: the length of the word (%s) 
    440440        """
    441441        return self.length()==0
    442442
     443    def is_finite(self):
     444        r"""
     445        Returns True.
     446       
     447        EXAMPLES::
     448
     449            sage: Word([]).is_finite()
     450            True
     451            sage: Word('a').is_finite()
     452            True
     453        """
     454        return True
     455
    443456    def to_integer_word(self):
    444457        r"""
    445458        Returns a word defined over the integers [0,1,...,self.length()-1]
    exponent %s: the length of the word (%s) 
    774787        """
    775788        return self[::-1]
    776789
     790    @cached_method
    777791    def prefix_function_table(self):
    778792        r"""
    779793        Returns a vector containing the length of the proper prefix-suffixes
    exponent %s: the length of the word (%s) 
    798812            res[q] = k
    799813        return res
    800814
     815    @cached_method
    801816    def good_suffix_table(self):
    802817        r"""
    803818        Returns a table of the maximum skip you can do in order not to miss
    exponent %s: the length of the word (%s) 
    26202635            return [lpd.get(a,-1) for a in self.parent().alphabet()]
    26212636        return lpd
    26222637
     2638    @cached_method
    26232639    def last_position_dict(self):
    26242640        r"""
    26252641        Returns a dictionary that contains the last position of each letter
    exponent %s: the length of the word (%s) 
    26572673            0
    26582674        """
    26592675        lf = self.length()
    2660         lm = len(other)
     2676        lm = other.length()
    26612677        if lf == 0:
    26622678            return p
    26632679        elif lm == 0:
    exponent %s: the length of the word (%s) 
    28642880            [0, 2, 8]
    28652881        """
    28662882        if self.length() == 0:
    2867             raise NotImplementedError, "undefined value"
     2883            raise NotImplementedError, "The factor must be non empty"
    28682884        p = self._pos_in(other, 0)
    28692885        while p is not None:
    28702886            yield p
    exponent %s: the length of the word (%s) 
    28802896            sage: Word().nb_factor_occurrences_in(Word('123'))
    28812897            Traceback (most recent call last):
    28822898            ...
    2883             NotImplementedError: undefined value
     2899            NotImplementedError: The factor must be non empty
    28842900            sage: Word('123').nb_factor_occurrences_in(Word('112332312313112332121123'))
    28852901            4
    28862902            sage: Word('321').nb_factor_occurrences_in(Word('11233231231311233221123'))
    exponent %s: the length of the word (%s) 
    29322948    def _return_words_list(self, fact):
    29332949        r"""
    29342950        Returns the return words as a list in the order they appear in the word.
     2951
     2952        INPUT:
     2953
     2954        - ``fact`` - a non empty finite word
     2955
     2956        OUTPUT:
     2957
     2958        Python list of finite words
    29352959       
    29362960        TESTS::
    29372961
    29382962            sage: Word('baccabccbacbca')._return_words_list(Word('b'))
    29392963            [word: bacca, word: bcc, word: bac]
    29402964        """
    2941         i = fact.first_pos_in(self)
    2942         if i is None:
    2943             return []
    2944         w = self[i+1:]
    2945         j = fact.first_pos_in(w)
    2946         res = []
    2947         while j is not None:
    2948             res.append(self[i:i+j+1])
    2949             w = w[j+1:]
    2950             i += j+1
    2951             j = fact.first_pos_in(w)
    2952         return res
     2965        return list(self.return_words_iterator(fact))
    29532966
    29542967    def return_words(self, fact):
    29552968        r"""
    exponent %s: the length of the word (%s) 
    29572970       
    29582971        This is the set of all factors starting by the given factor and ending
    29592972        just before the next occurrence of this factor. See [1] and [2].
     2973
     2974        INPUT:
     2975
     2976        - ``fact`` - a non empty finite word
     2977
     2978        OUTPUT:
     2979
     2980        Python set of finite words
    29602981       
    29612982        EXAMPLES::
    29622983
    exponent %s: the length of the word (%s) 
    29662987            set([])
    29672988            sage: Word('121212').return_words(Word('1212'))
    29682989            set([word: 12])
     2990
     2991        ::
     2992
     2993            sage: TM = words.ThueMorseWord()[:10000]
     2994            sage: TM.return_words(Word([0]))     # optional long time (1.34 s)
     2995            set([word: 0, word: 01, word: 011])
    29692996       
    29702997        REFERENCES:
    29712998
    exponent %s: the length of the word (%s) 
    29743001        -   [2] C. Holton, L.Q. Zamboni, Descendants of primitive substitutions,
    29753002            Theory Comput. Syst. 32 (1999) 133-157.
    29763003        """
    2977         return set(self._return_words_list(fact))
     3004        return set(self.return_words_iterator(fact))
    29783005
    29793006    def complete_return_words(self, fact):
    29803007        r"""
    exponent %s: the length of the word (%s) 
    29823009       
    29833010        This is the set of all factors starting by the given factor and ending
    29843011        just after the next occurrence of this factor. See for instance [1].
     3012
     3013        INPUT:
     3014
     3015        - ``fact`` - a non empty finite word
     3016
     3017        OUTPUT:
     3018
     3019        Python set of finite words
    29853020       
    29863021        EXAMPLES::
    29873022
    exponent %s: the length of the word (%s) 
    29983033        -   [1] J. Justin, L. Vuillon, Return words in Sturmian and
    29993034            episturmian words, Theor. Inform. Appl. 34 (2000) 343--356.
    30003035        """
    3001         i = fact.first_pos_in(self)
    3002         if i is None:
    3003             return set()
    3004         w = self[i+1:]
    3005         j = fact.first_pos_in(w)
    3006         res = set()
    3007         while j is not None:
    3008             res.add(self[i:i+j+len(fact)+1])
    3009             w = w[j+1:]
    3010             i += j+1
    3011             j = fact.first_pos_in(w)
    3012         return res
     3036        return set(self.complete_return_words_iterator(fact))
    30133037
    30143038    def return_words_derivate(self, fact):
    30153039        r"""