Пример #1
0
    def __setstate__(self, d):
        """
        TESTS::

            sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2])
            sage: d = f.__getstate__()
            sage: f = Family([4,5,6], lambda i: 2*i, hidden_keys=[2])
            sage: f.__setstate__(d)
            sage: f.keys()
            [3, 4, 7]
            sage: f[3]
            6
        """
        hidden_function = d['hidden_function']
        if isinstance(hidden_function, str):
            # Let's assume that hidden_function is an unpickled function.
            from sage.misc.fpickle import unpickle_function
            hidden_function = unpickle_function(hidden_function)
        self.__init__(d['dictionary'], d['hidden_keys'], hidden_function)
        self.hidden_dictionary = d['hidden_dictionary']
        # Old pickles from before trac #22955 may not have a 'keys'
        if 'keys' in d:
            self._keys = d['keys']
        else:
            self._keys = None
Пример #2
0
    def __setstate__(self, d):
        """
        TESTS::

            sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2])
            sage: d = f.__getstate__()
            sage: f = Family([4,5,6], lambda i: 2*i, hidden_keys=[2])
            sage: f.__setstate__(d)
            sage: f.keys()
            [3, 4, 7]
            sage: f[3]
            6
        """
        hidden_function = d['hidden_function']
        if isinstance(hidden_function, str):
        # Let's assume that hidden_function is an unpickled function.
            from sage.misc.fpickle import unpickle_function
            hidden_function = unpickle_function(hidden_function)
        self.__init__(d['dictionary'], d['hidden_keys'], hidden_function)
        self.hidden_dictionary = d['hidden_dictionary']
        # Old pickles from before trac #22955 may not have a 'keys'
        if 'keys' in d:
            self._keys = d['keys']
        else:
            self._keys = None
Пример #3
0
def _make_lazy_string(ftype, fpickle, args, kwargs):
    """
    Used for pickling.

    EXAMPLES::

        sage: from sage.misc.lazy_string import _make_lazy_string
        sage: s = _make_lazy_string(None, lambda: "laziness", (), {})
        sage: s
        l'laziness'
    """
    if ftype == 'func':
        from sage.misc.fpickle import unpickle_function
        f = unpickle_function(fpickle)
    else:
        f = fpickle
    return _LazyString(f, args, kwargs)
Пример #4
0
def _make_lazy_string(ftype, fpickle, args, kwargs):
    """
    Used for pickling.

    EXAMPLES::

        sage: from sage.misc.lazy_string import _make_lazy_string
        sage: s = _make_lazy_string(None, lambda: "laziness", (), {})
        sage: s
        l'laziness'
    """
    if ftype == 'func':
        from sage.misc.fpickle import unpickle_function
        f = unpickle_function(fpickle)
    else:
        f = fpickle
    return _LazyString(f, args, kwargs)
Пример #5
0
    def __setstate__(self, d):
        """
        EXAMPLES::

            sage: from sage.sets.family import LazyFamily
            sage: f = LazyFamily([3,4,7], lambda i: 2*i)
            sage: d = f.__getstate__()
            sage: f = LazyFamily([4,5,6], lambda i: 2*i)
            sage: f.__setstate__(d)
            sage: f.keys()
            [3, 4, 7]
            sage: f[3]
            6
        """
        function = d['function']
        if isinstance(function, str):
        # Let's assume that function is an unpickled function.
            from sage.misc.fpickle import unpickle_function
            function = unpickle_function(function)

        self.__init__(d['set'], function)
Пример #6
0
    def __setstate__(self, d):
        """
        EXAMPLES::

            sage: from sage.sets.family import LazyFamily
            sage: f = LazyFamily([3,4,7], lambda i: 2*i)
            sage: d = f.__getstate__()
            sage: f = LazyFamily([4,5,6], lambda i: 2*i)
            sage: f.__setstate__(d)
            sage: f.keys()
            [3, 4, 7]
            sage: f[3]
            6
        """
        function = d['function']
        if isinstance(function, str):
            # Let's assume that function is an unpickled function.
            from sage.misc.fpickle import unpickle_function
            function = unpickle_function(function)

        self.__init__(d['set'], function)
Пример #7
0
    def _construct_word(self, data=None, length=None, datatype=None, caching=True):
        r"""
        Construct a word.

        INPUT:

        -  ``data`` - (default: None) list, string, tuple, iterator, None
           (shorthand for []), or a callable defined on [0,1,...,length].

        -  ``length`` - (default: None) This is dependent on the type of data. 
           It is ignored for words defined by lists, strings, tuples,
           etc., because they have a naturally defined length.
           For callables, this defines the domain of definition,
           which is assumed to be [0, 1, 2, ..., length-1].
           For iterators: Infinity if you know the iterator will not
           terminate (default); "unknown" if you do not know whether the
           iterator terminates; "finite" if you know that the iterator
           terminates, but do know know the length.

        -  ``datatype`` - (default: None) None, "list", "str", "tuple", "iter",
           "callable". If None, then the function
           tries to guess this from the data.
        -  ``caching`` - (default: True) True or False. Whether to keep a cache
           of the letters computed by an iterator or callable.

        .. note::

           Be careful when defining words using callables and iterators. It
           appears that islice does not pickle correctly causing various errors
           when reloading. Also, most iterators do not support copying and
           should not support pickling by extension.

        EXAMPLES:

        Empty word::

            sage: Words()._construct_word()
            word:

        Word with string::

            sage: Words()._construct_word("abbabaab")
            word: abbabaab

        Word with string constructed from other types::

            sage: Words()._construct_word([0,1,1,0,1,0,0,1], datatype="str")
            word: 01101001
            sage: Words()._construct_word((0,1,1,0,1,0,0,1), datatype="str")
            word: 01101001

        Word with list::

            sage: Words()._construct_word([0,1,1,0,1,0,0,1])
            word: 01101001

        Word with list constructed from other types::

            sage: Words()._construct_word("01101001", datatype="list")
            word: 01101001
            sage: Words()._construct_word((0,1,1,0,1,0,0,1), datatype="list")
            word: 01101001

        Word with tuple::

            sage: Words()._construct_word((0,1,1,0,1,0,0,1))
            word: 01101001

        Word with tuple constructed from other types::

            sage: Words()._construct_word([0,1,1,0,1,0,0,1], datatype="tuple")
            word: 01101001
            sage: Words()._construct_word("01101001", datatype="str")
            word: 01101001

        Word with iterator::

            sage: from itertools import count
            sage: Words()._construct_word(count())
            word: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,...
            sage: Words()._construct_word(iter("abbabaab")) # iterators default to infinite words
            word: abbabaab
            sage: Words()._construct_word(iter("abbabaab"), length="unknown")
            word: abbabaab
            sage: Words()._construct_word(iter("abbabaab"), length="finite")
            word: abbabaab

        Word with function (a 'callable')::

            sage: f = lambda n : add(Integer(n).digits(2)) % 2
            sage: Words()._construct_word(f)
            word: 0110100110010110100101100110100110010110...
            sage: Words()._construct_word(f, length=8)
            word: 01101001

        Word over a string with a parent::

            sage: w = Words('abc')._construct_word("abbabaab"); w
            word: abbabaab
            sage: w.parent()
            Words over {'a', 'b', 'c'}

        The default parent is the combinatorial class of all words::

            sage: w = Words()._construct_word("abbabaab"); w
            word: abbabaab
            sage: w.parent()
            Words

        Creation of a word from a word::

            sage: Words([0,1,2,3])(Words([2,3])([2,2,2,3,3,2]))
            word: 222332
            sage: _.parent()
            Words over {0, 1, 2, 3}

        ::

            sage: Words([3,2,1])(Words([2,3])([2,2,2,3,3,2]))
            word: 222332
            sage: _.parent()
            Words over {3, 2, 1}

        Construction of a word from a word when the parents are the same::

            sage: W = Words()
            sage: w = W(range(8))
            sage: z = W(w)
            sage: w is z
            True

        Construction of a word path from a finite word::

            sage: W = Words('abcd')
            sage: P = WordPaths('abcd')
            sage: w = W('aaab')
            sage: P(w)
            Path: aaab

        Construction of a word path from a Christoffel word::

            sage: w = words.ChristoffelWord(5,8)
            sage: w
            word: 0010010100101
            sage: P = WordPaths([0,1,2,3])
            sage: P(w)
            Path: 0010010100101

        Construction of a word represented by a list from a word
        represented by a str ::

            sage: w = Word('ababbbabab')
            sage: type(w)
            <class 'sage.combinat.words.word.FiniteWord_str'>
            sage: z = Word(w, datatype='list')
            sage: type(z)
            <class 'sage.combinat.words.word.FiniteWord_list'>
            sage: y = Word(w, alphabet='abc', datatype='list')
            sage: type(y)
            <class 'sage.combinat.words.word.FiniteWord_list'>

        Creation of a word from a concatenation of words::

            sage: W = Words()
            sage: w = W() * W('a')
            sage: Z = Words('ab')
            sage: Z(w)
            word: a

        Creation of a word path from a FiniteWord_iter::

            sage: w = words.FibonacciWord()
            sage: f = w[:100]
            sage: P = WordPaths([0,1,2,3])
            sage: p = P(f); p
            Path: 0100101001001010010100100101001001010010...
            sage: p.length()
            100

        Creation of a word path from a FiniteWord_callable::

            sage: g = Word(lambda n:n%2, length = 100)
            sage: P = WordPaths([0,1,2,3])
            sage: p = P(g); p
            Path: 0101010101010101010101010101010101010101...
            sage: p.length()
            100

        Creation of a word from a pickled function::

            sage: f = lambda n : n % 10
            sage: from sage.misc.fpickle import pickle_function
            sage: s = pickle_function(f)
            sage: Word(s, datatype='pickled_function')
            word: 0123456789012345678901234567890123456789...

        """
        from sage.combinat.words.abstract_word import Word_class
        from sage.combinat.words.word_infinite_datatypes import WordDatatype_callable, WordDatatype_iter
        from sage.combinat.words.word_datatypes import WordDatatype
        if isinstance(data, Word_class):
            ####################
            # If `data` is already a word and if its parent is self, 
            # then return `data` (no matter what the parameter length,
            # datatype and length are).
            ###########################
            if data.parent() is self:
                return data
            ###########################
            # Otherwise, if self is not the parent of `data`, then we 
            # try to recover the data, the length and the datatype of the
            # input `data`
            ###########################
            if isinstance(data,  WordDatatype_callable):
                from sage.combinat.words.finite_word import CallableFromListOfWords
                if isinstance(data._func, CallableFromListOfWords):
                    # The following line is important because, in this case,
                    # data._func is also a tuple (indeed
                    # CallableFromListOfWords inherits from tuple)
                    datatype = "callable" 
                if length is None:
                    length = data._len
                data = data._func
            elif isinstance(data,  WordDatatype_iter):
                if length is None:
                    length = data._len
                data = iter(data)
            elif isinstance(data, WordDatatype):
                data = data._data
            else:
                raise TypeError, "Any instance of Word_class must be an instance of WordDatatype."

        if data is None:
            data = []

        # Guess the datatype if it is not given.
        if datatype is None:
            if isinstance(data, (list, CombinatorialObject)):
                datatype = "list"
            elif isinstance(data, (str)):
                datatype = "str"
            elif isinstance(data, tuple):
                datatype = "tuple"
            elif callable(data):
                datatype = "callable"
            elif hasattr(data,"__iter__"):
                datatype = "iter"
            else:
                raise ValueError, "Cannot guess a datatype from data (=%s); please specify one"%data
        else:
            # type check the datatypes
            if datatype == "iter" and not hasattr(data, "__iter__"):
                raise ValueError, "Your data is not iterable"
            elif datatype == "callable" and not callable(data):
                raise ValueError, "Your data is not callable"
            elif datatype not in ("list", "tuple", "str",
                                "callable", "iter", "pickled_function"):
                raise ValueError, "Unknown datatype (=%s)" % datatype

        # If `data` is a pickled_function, restore the function
        if datatype == 'pickled_function':
            from sage.misc.fpickle import unpickle_function
            data = unpickle_function(data)
            datatype = 'callable'

        # Construct the word class and keywords
        if datatype in ('list','str','tuple'):
            cls_str = 'FiniteWord_%s'%datatype
            kwds = dict(parent=self,data=data)
        elif datatype == 'callable':
            if length in (None, Infinity, 'infinite'):
                cls_str = 'InfiniteWord_callable'
            else:
                cls_str = 'FiniteWord_callable'
            if caching: 
                cls_str += '_with_caching'
            kwds = dict(parent=self,callable=data,length=length)
        elif datatype == 'iter':
            if length in (None, Infinity, 'infinite'):
                cls_str = 'InfiniteWord_iter'
            elif length == 'finite':
                cls_str = 'FiniteWord_iter'
            elif length == 'unknown':
                cls_str = 'Word_iter'
            elif length in ZZ and length >= 0:
                cls_str = 'FiniteWord_iter'
            else:
                raise ValueError, "not a correct value for length (%s)" % length
            if caching: 
                cls_str += '_with_caching'
            kwds = dict(parent=self,iter=data,length=length)
        else:
            raise ValueError, "Not known datatype"

        wordclass = self._element_classes
        cls = wordclass[cls_str]
        w = cls(**kwds)
        return w
Пример #8
0
    def _construct_word(self,
                        data=None,
                        length=None,
                        datatype=None,
                        caching=True):
        r"""
        Construct a word.

        INPUT:

        -  ``data`` - (default: None) list, string, tuple, iterator, None
           (shorthand for []), or a callable defined on [0,1,...,length].

        -  ``length`` - (default: None) This is dependent on the type of data. 
           It is ignored for words defined by lists, strings, tuples,
           etc., because they have a naturally defined length.
           For callables, this defines the domain of definition,
           which is assumed to be [0, 1, 2, ..., length-1].
           For iterators: Infinity if you know the iterator will not
           terminate (default); "unknown" if you do not know whether the
           iterator terminates; "finite" if you know that the iterator
           terminates, but do know know the length.

        -  ``datatype`` - (default: None) None, "list", "str", "tuple", "iter",
           "callable". If None, then the function
           tries to guess this from the data.
        -  ``caching`` - (default: True) True or False. Whether to keep a cache
           of the letters computed by an iterator or callable.

        .. note::

           Be careful when defining words using callables and iterators. It
           appears that islice does not pickle correctly causing various errors
           when reloading. Also, most iterators do not support copying and
           should not support pickling by extension.

        EXAMPLES:

        Empty word::

            sage: Words()._construct_word()
            word:

        Word with string::

            sage: Words()._construct_word("abbabaab")
            word: abbabaab

        Word with string constructed from other types::

            sage: Words()._construct_word([0,1,1,0,1,0,0,1], datatype="str")
            word: 01101001
            sage: Words()._construct_word((0,1,1,0,1,0,0,1), datatype="str")
            word: 01101001

        Word with list::

            sage: Words()._construct_word([0,1,1,0,1,0,0,1])
            word: 01101001

        Word with list constructed from other types::

            sage: Words()._construct_word("01101001", datatype="list")
            word: 01101001
            sage: Words()._construct_word((0,1,1,0,1,0,0,1), datatype="list")
            word: 01101001

        Word with tuple::

            sage: Words()._construct_word((0,1,1,0,1,0,0,1))
            word: 01101001

        Word with tuple constructed from other types::

            sage: Words()._construct_word([0,1,1,0,1,0,0,1], datatype="tuple")
            word: 01101001
            sage: Words()._construct_word("01101001", datatype="str")
            word: 01101001

        Word with iterator::

            sage: from itertools import count
            sage: Words()._construct_word(count())
            word: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,...
            sage: Words()._construct_word(iter("abbabaab")) # iterators default to infinite words
            word: abbabaab
            sage: Words()._construct_word(iter("abbabaab"), length="unknown")
            word: abbabaab
            sage: Words()._construct_word(iter("abbabaab"), length="finite")
            word: abbabaab

        Word with function (a 'callable')::

            sage: f = lambda n : add(Integer(n).digits(2)) % 2
            sage: Words()._construct_word(f)
            word: 0110100110010110100101100110100110010110...
            sage: Words()._construct_word(f, length=8)
            word: 01101001

        Word over a string with a parent::

            sage: w = Words('abc')._construct_word("abbabaab"); w
            word: abbabaab
            sage: w.parent()
            Words over {'a', 'b', 'c'}

        The default parent is the combinatorial class of all words::

            sage: w = Words()._construct_word("abbabaab"); w
            word: abbabaab
            sage: w.parent()
            Words

        Creation of a word from a word::

            sage: Words([0,1,2,3])(Words([2,3])([2,2,2,3,3,2]))
            word: 222332
            sage: _.parent()
            Words over {0, 1, 2, 3}

        ::

            sage: Words([3,2,1])(Words([2,3])([2,2,2,3,3,2]))
            word: 222332
            sage: _.parent()
            Words over {3, 2, 1}

        Construction of a word from a word when the parents are the same::

            sage: W = Words()
            sage: w = W(range(8))
            sage: z = W(w)
            sage: w is z
            True

        Construction of a word path from a finite word::

            sage: W = Words('abcd')
            sage: P = WordPaths('abcd')
            sage: w = W('aaab')
            sage: P(w)
            Path: aaab

        Construction of a word path from a Christoffel word::

            sage: w = words.ChristoffelWord(5,8)
            sage: w
            word: 0010010100101
            sage: P = WordPaths([0,1,2,3])
            sage: P(w)
            Path: 0010010100101

        Construction of a word represented by a list from a word
        represented by a str ::

            sage: w = Word('ababbbabab')
            sage: type(w)
            <class 'sage.combinat.words.word.FiniteWord_str'>
            sage: z = Word(w, datatype='list')
            sage: type(z)
            <class 'sage.combinat.words.word.FiniteWord_list'>
            sage: y = Word(w, alphabet='abc', datatype='list')
            sage: type(y)
            <class 'sage.combinat.words.word.FiniteWord_list'>

        Creation of a word from a concatenation of words::

            sage: W = Words()
            sage: w = W() * W('a')
            sage: Z = Words('ab')
            sage: Z(w)
            word: a

        Creation of a word path from a FiniteWord_iter::

            sage: w = words.FibonacciWord()
            sage: f = w[:100]
            sage: P = WordPaths([0,1,2,3])
            sage: p = P(f); p
            Path: 0100101001001010010100100101001001010010...
            sage: p.length()
            100

        Creation of a word path from a FiniteWord_callable::

            sage: g = Word(lambda n:n%2, length = 100)
            sage: P = WordPaths([0,1,2,3])
            sage: p = P(g); p
            Path: 0101010101010101010101010101010101010101...
            sage: p.length()
            100

        Creation of a word from a pickled function::

            sage: f = lambda n : n % 10
            sage: from sage.misc.fpickle import pickle_function
            sage: s = pickle_function(f)
            sage: Word(s, datatype='pickled_function')
            word: 0123456789012345678901234567890123456789...

        """
        from sage.combinat.words.abstract_word import Word_class
        from sage.combinat.words.word_infinite_datatypes import WordDatatype_callable, WordDatatype_iter
        from sage.combinat.words.word_datatypes import WordDatatype
        if isinstance(data, Word_class):
            ####################
            # If `data` is already a word and if its parent is self,
            # then return `data` (no matter what the parameter length,
            # datatype and length are).
            ###########################
            if data.parent() is self:
                return data
            ###########################
            # Otherwise, if self is not the parent of `data`, then we
            # try to recover the data, the length and the datatype of the
            # input `data`
            ###########################
            if isinstance(data, WordDatatype_callable):
                from sage.combinat.words.finite_word import CallableFromListOfWords
                if isinstance(data._func, CallableFromListOfWords):
                    # The following line is important because, in this case,
                    # data._func is also a tuple (indeed
                    # CallableFromListOfWords inherits from tuple)
                    datatype = "callable"
                if length is None:
                    length = data._len
                data = data._func
            elif isinstance(data, WordDatatype_iter):
                if length is None:
                    length = data._len
                data = iter(data)
            elif isinstance(data, WordDatatype):
                data = data._data
            else:
                raise TypeError, "Any instance of Word_class must be an instance of WordDatatype."

        if data is None:
            data = []

        # Guess the datatype if it is not given.
        if datatype is None:
            if isinstance(data, (list, CombinatorialObject)):
                datatype = "list"
            elif isinstance(data, (str)):
                datatype = "str"
            elif isinstance(data, tuple):
                datatype = "tuple"
            elif callable(data):
                datatype = "callable"
            elif hasattr(data, "__iter__"):
                datatype = "iter"
            else:
                raise ValueError, "Cannot guess a datatype from data (=%s); please specify one" % data
        else:
            # type check the datatypes
            if datatype == "iter" and not hasattr(data, "__iter__"):
                raise ValueError, "Your data is not iterable"
            elif datatype == "callable" and not callable(data):
                raise ValueError, "Your data is not callable"
            elif datatype not in ("list", "tuple", "str", "callable", "iter",
                                  "pickled_function"):
                raise ValueError, "Unknown datatype (=%s)" % datatype

        # If `data` is a pickled_function, restore the function
        if datatype == 'pickled_function':
            from sage.misc.fpickle import unpickle_function
            data = unpickle_function(data)
            datatype = 'callable'

        # Construct the word class and keywords
        if datatype in ('list', 'str', 'tuple'):
            cls_str = 'FiniteWord_%s' % datatype
            kwds = dict(parent=self, data=data)
        elif datatype == 'callable':
            if length in (None, Infinity, 'infinite'):
                cls_str = 'InfiniteWord_callable'
            else:
                cls_str = 'FiniteWord_callable'
            if caching:
                cls_str += '_with_caching'
            kwds = dict(parent=self, callable=data, length=length)
        elif datatype == 'iter':
            if length in (None, Infinity, 'infinite'):
                cls_str = 'InfiniteWord_iter'
            elif length == 'finite':
                cls_str = 'FiniteWord_iter'
            elif length == 'unknown':
                cls_str = 'Word_iter'
            elif length in ZZ and length >= 0:
                cls_str = 'FiniteWord_iter'
            else:
                raise ValueError, "not a correct value for length (%s)" % length
            if caching:
                cls_str += '_with_caching'
            kwds = dict(parent=self, iter=data, length=length)
        else:
            raise ValueError, "Not known datatype"

        wordclass = self._element_classes
        cls = wordclass[cls_str]
        w = cls(**kwds)
        return w