Ticket #8703: trac_8703-trees_addition-dg-v2.patch

File trac_8703-trees_addition-dg-v2.patch, 23.4 KB (added by chapoton, 6 years ago)
  • sage/combinat/abstract_tree.py

    # HG changeset patch
    # User darij grinberg <darijgrinberg@gmail.com>
    # Date 1362209209 28800
    # Node ID b80acf19629092f84fa6e075de752561a342651d
    # Parent  f170c8e4be2d04eff3d085b3aa6865d511b73332
    trac #8703 minor details (review patch by dg)
    
    diff --git a/sage/combinat/abstract_tree.py b/sage/combinat/abstract_tree.py
    a b class AbstractTree(object): 
    247247        The actual canonical labelling is currently unspecified. However, it
    248248        is guaranteed to have labels in `1...n` where `n` is the number of
    249249        nodes of the tree. Moreover, two (unlabelled) trees compare as equal if
    250         and only if they canonical labelled trees compare as equal.
     250        and only if their canonical labelled trees compare as equal.
    251251
    252252        EXAMPLES::
    253253
    class AbstractTree(object): 
    266266            .
    267267        """
    268268        LTR = self.parent().labelled_trees()
    269         liste=[]
    270         deca=1
     269        liste = []
     270        deca = 1
    271271        for subtree in self:
    272             liste=liste+[subtree.canonical_labelling(shift+deca)]
    273             deca=deca+subtree.node_number()
     272            liste += [subtree.canonical_labelling(shift+deca)]
     273            deca += subtree.node_number()
    274274        return LTR._element_constructor_(liste,label=shift)
    275275
    276276    def tree_factorial(self):
    class AbstractTree(object): 
    284284
    285285        EXAMPLES::
    286286
    287             sage: LT=LabelledOrderedTrees()
    288             sage: t=LT([LT([],label=6),LT([],label=1)],label=9)
     287            sage: LT = LabelledOrderedTrees()
     288            sage: t = LT([LT([],label=6),LT([],label=1)],label=9)
    289289            sage: t.tree_factorial()
    290290            3
    291291
    class AbstractClonableTree(AbstractTree) 
    394394    :class:`~sage.structure.list_clone.ClonableList` depending wether one
    395395    wants to build trees where adding a child is allowed.
    396396
    397     .. note:: Due to the limitation of Cython inheritance, one cannot inherit
     397    .. NOTE:: Due to the limitation of Cython inheritance, one cannot inherit
    398398       here from :class:`~sage.structure.list_clone.ClonableElement`, because
    399399       it would prevent us to inherit later from
    400400       :class:`~sage.structure.list_clone.ClonableArray` or
    class AbstractClonableTree(AbstractTree) 
    511511            sage: x
    512512            [[[], [[], []]], [[[], []], [[], []]]]
    513513        """
    514         assert isinstance(value, self.__class__)
    515 
     514        if not isinstance(value, self.__class__):
     515            raise TypeError('the given value is not a tree')
    516516        if isinstance(idx, tuple):
    517517            self.__setitem_rec__(idx, 0, value)
    518518        else:
    class AbstractLabelledTree(AbstractTree) 
    663663
    664664        EXAMPLES::
    665665
    666             sage: t=LabelledOrderedTree([[],[]], label = 3)
     666            sage: t = LabelledOrderedTree([[],[]], label = 3)
    667667            sage: t.label()
    668668            3
    669669            sage: t[0].label()
    670             sage: t=LabelledOrderedTree([LabelledOrderedTree([], 5),[]], label = 3)
     670            sage: t = LabelledOrderedTree([LabelledOrderedTree([], 5),[]], label = 3)
    671671            sage: t.label()
    672672            3
    673673            sage: t[0].label()
    class AbstractLabelledTree(AbstractTree) 
    810810
    811811    def as_digraph(self):
    812812        """
    813         Returns a directed graph version of ``self``
     813        Returns a directed graph version of ``self``.
     814
     815        .. WARNING::
     816
     817            At this time, the output makes sense only if ``self`` is a
     818            labelled binary tree with no repeated labels and no "None"
     819            labels.
    814820
    815821        EXAMPLES::
    816822
    817            sage: LT=LabelledOrderedTrees()
    818            sage: ko=LT([LT([],label=6),LT([],label=1)],label=9)
    819            sage: ko.as_digraph()
     823           sage: LT = LabelledOrderedTrees()
     824           sage: t1 = LT([LT([],label=6),LT([],label=1)],label=9)
     825           sage: t1.as_digraph()
    820826           Digraph on 3 vertices
    821827
    822828           sage: t = BinaryTree([[None, None],[[],None]]);
    class AbstractLabelledTree(AbstractTree) 
    825831           Digraph on 4 vertices
    826832        """
    827833        from sage.graphs.digraph import DiGraph
    828         resu=dict([[self.label(),
     834        resu = dict([[self.label(),
    829835                    [t.label() for t in self if not t.is_empty()]]])
    830         resu=DiGraph(resu)
     836        resu = DiGraph(resu)
    831837        for t in self:
    832838            if not t.is_empty():
    833                 resu=resu.union(t.as_digraph())
     839                resu = resu.union(t.as_digraph())
    834840        return resu
    835841
    836842
    class AbstractLabelledClonableTree(Abstr 
    841847
    842848    This class take care of modification for the label by the clone protocol.
    843849
    844     .. note:: Due to the limitation of Cython inheritance, one cannot inherit
     850    .. NOTE:: Due to the limitation of Cython inheritance, one cannot inherit
    845851       here from :class:`ClonableArray`, because it would prevent us to
    846852       inherit later from :class:`~sage.structure.list_clone.ClonableList`.
    847853    """
    class AbstractLabelledClonableTree(Abstr 
    853859
    854860        OUPUT: ``None``, ``self`` is modified in place
    855861
    856         .. note::
     862        .. NOTE::
    857863
    858864            ``self`` must be in a mutable state. See
    859865            :mod:`sage.structure.list_clone` for more details about
    class AbstractLabelledClonableTree(Abstr 
    861867
    862868        EXAMPLES::
    863869
    864             sage: t=LabelledOrderedTree([[],[[],[]]])
     870            sage: t = LabelledOrderedTree([[],[[],[]]])
    865871            sage: t.set_root_label(3)
    866872            Traceback (most recent call last):
    867873            ...
    class AbstractLabelledClonableTree(Abstr 
    875881
    876882        This also work for binary trees::
    877883
    878             sage: bt=LabelledBinaryTree([[],[]])
     884            sage: bt = LabelledBinaryTree([[],[]])
    879885            sage: bt.set_root_label(3)
    880886            Traceback (most recent call last):
    881887            ...
    class AbstractLabelledClonableTree(Abstr 
    914920
    915921        OUPUT: Nothing, ``self`` is modified in place
    916922
    917         .. note::
     923        .. NOTE::
    918924
    919925            ``self`` must be in a mutable state. See
    920926            :mod:`sage.structure.list_clone` for more details about
    class AbstractLabelledClonableTree(Abstr 
    922928
    923929        EXAMPLES::
    924930
    925             sage: t=LabelledOrderedTree([[],[[],[]]])
     931            sage: t = LabelledOrderedTree([[],[[],[]]])
    926932            sage: t.set_label((0,), 4)
    927933            Traceback (most recent call last):
    928934            ...
    class AbstractLabelledClonableTree(Abstr 
    936942            sage: t
    937943            None[4[], None[42[], None[]]]
    938944
    939         .. todo::
     945        .. TODO::
    940946
    941947            Do we want to implement the following syntactic sugar::
    942948
  • sage/combinat/binary_tree.py

    diff --git a/sage/combinat/binary_tree.py b/sage/combinat/binary_tree.py
    a b  
    22Binary trees
    33
    44This module deals with binary trees as mathematical (in particular immmutable)
    5 objects. 
     5objects.
    66
    7 .. note :: If you need the data-structure for example to represent sets or hash
     7.. NOTE :: If you need the data-structure for example to represent sets or hash
    88           tables with AVL trees, you should have a look at
    99           :mod:`sage.misc.sagex_ds`.
    1010
    11 On the use of Factories to query a database of counting algorithms
    12 ------------------------------------------------------------------
    13 
    14 **The problem we try to solve**
    15 
    16 A common problem in combinatorics is to enumerate or count some standard
    17 mathematical objects satisfying a set of constraints. For instance, one can be
    18 interested in the :mod:`partitions <sage.combinat.partition>` of an integer `n`
    19 of length `7` and parts of size at least `3` and at most `8`, [...]
    20 
    21 For partitions, the number of different parameters available is actually quite
    22 large :
    23 
    24 - The length of the partition (i.e. partitions in `k` parts, or in "at least"
    25   `k_1` parts "at most" `k_2` parts).
    26 
    27 - The sum of the partition (i.e. the integer `n`).
    28 
    29 - The min/max size of a part, or even a set of integers such that the partition
    30   should only use integers from the given set.
    31 
    32 - The min/max slope of the partition.
    33 
    34 - An inner and outer profile.
    35 
    36 - A min/max value for the lexicographical ordering of the partition.
    37 
    38 One may in particular be interested in enumerating/counting the partitions
    39 satisfying *some arbitrary combination* of constraints using the parameters
    40 listed above.
    41 
    42 This all means that there is a real need of unifying a large family of
    43 algorithms, so that users do not have to find their way through a library
    44 of 50 different counting/enumeration algorithms *all* dealing with partitions
    45 with different set of parameters.
    46 
    47 **How we solve it**
    48 
    49 We try to build a *database* of algorithms that the user can query easily in
    50 order to use the best implementation for his needs.
    51 
    52 Namely, in the case of :mod:`partitions <sage.combinat.partition>`, we want to
    53 define a class factory named ``Partitions`` and accepting any combination of
    54 constraints as an input. The role of the ``Partitions`` class factory is in this
    55 situation to identify the counting/enumeration algorithm corresponding to this
    56 set of constraint, and to return a hand-made object with the best set of
    57 methods.
    58 
    59 **The design**
    60 
    61 For each combination of constraints that has specific enumeration/counting
    62 algorithms in Sage, we want to create a corresponding class. The result will be
    63 -- if we stick with the example of partitions -- a brand new Zoo with weird things
    64 inside :
    65 
    66 - ``PartitionsWithFixedSlopeAndOuterProfile(slope, outer_profile)`` --
    67   representing the partitions with slope ``slope`` and outer profile
    68   ``outer_profile``
    69 
    70 - ``PartitionsWithRestrictedPartsAndBoundedLength(part_set, length)`` --
    71   represeting the partitions with a set of allowed parts and given length.
    72 
    73 - ...
    74 
    75 Each of these classes should define methods like ``__iter__`` (so that we can
    76 iterate on its elements) or ``cardinality``.
    77 
    78 The main class ``Partitions`` will then take as arguments *all of the*
    79 *combinations of parameters the user may like*, and query the database for the
    80 best secialized class implemented. The user then receives an instance of this
    81 specialized class that he can use with the best algorithms implemented.
    82 
    83 Of course, it may happen that there is actually no algorithm able to enumerate
    84 partitions with the set of constraints specified. In this case, the best way is
    85 to build a class enumerating a larger set of partitions, and to check for each
    86 of them whether is also satisfies the more restrictive set of constraints. This
    87 is costly, but it is the best way available, and the library should also be able
    88 to answer the question *"what is the best implementation available to list the
    89 partitions asked by the user ?"*. We then need to make sure we enumerate as few
    90 unnecessary elements as possible.
    91 
    9211**AUTHORS:**
    9312
    9413- Florent Hivert (2010-2011): initial implementation.
    unnecessary elements as possible. 
    10120#  the License, or (at your option) any later version.
    10221#                  http://www.gnu.org/licenses/
    10322#*****************************************************************************
    104 from sage.structure.list_clone import ClonableArray, ClonableList
     23from sage.structure.list_clone import ClonableArray
    10524from sage.combinat.abstract_tree import (AbstractClonableTree,
    10625                                         AbstractLabelledClonableTree)
    10726from sage.combinat.ordered_tree import LabelledOrderedTrees
    class BinaryTree(AbstractClonableTree, C 
    11332    """
    11433    The class of binary trees
    11534
     35    Binary trees here mean ordered (a.k.a. plane) binary trees,
     36    meaning that the children of each node are ordered.
     37
    11638    INPUT:
    11739
    11840    - ``children`` -- ``None`` (default) or a list, tuple or iterable of
    119       length 2 of binary trees or convertible objects. Alternatively a string
    120       is also accepted. The syntax is the same as for printing: empty trees
    121       are denoted by `.` and children are grouped by square brackets.
     41      length 2 of binary trees or convertible objects. This corresponds to
     42      the standard recursive definition of a binary tree as either a leaf
     43      or a pair of binary trees. Syntactic sugar allows leaving out all
     44      but the outermost calls of the ``BinaryTree()`` constructor, so that,
     45      e. g., ``BinaryTree([BinaryTree(None),BinaryTree(None)])`` can be
     46      simplified to ``BinaryTree([None,None])``. It is also allowed to
     47      abbreviate ``[None, None]`` by ``[]``.
    12248
    12349    - ``check`` -- (default to ``True``) whether check for binary should be
    12450      performed or not.
    12551
    126     .. warning:: despite what the HTML documentation may say, ``BinaryTree``
    127                  does not have any ``parent`` argument, as the examples below
    128                  show.
    129 
    13052    EXAMPLES::
    13153
    13254        sage: BinaryTree()
    13355        .
     56        sage: BinaryTree(None)
     57        .
     58        sage: BinaryTree([])
     59        [., .]
    13460        sage: BinaryTree([None, None])
    13561        [., .]
    13662        sage: BinaryTree([None, []])
    class BinaryTree(AbstractClonableTree, C 
    14369        sage: BinaryTree([[], None, []])
    14470        Traceback (most recent call last):
    14571        ...
    146         AssertionError: This is not a binary tree
     72        ValueError: this is not a binary tree
    14773
    14874    TESTS::
    14975
    class BinaryTree(AbstractClonableTree, C 
    204130         """
    205131        return BinaryTrees_all()
    206132
    207     def __init__(self, parent, children = None, check=True):
     133    def __init__(self, parent, children = None, check = True):
    208134        """
    209135        TESTS::
    210136
    class BinaryTree(AbstractClonableTree, C 
    215141            sage: BinaryTree("[.,.,.]")
    216142            Traceback (most recent call last):
    217143            ...
    218             AssertionError: This is not a binary tree
     144            ValueError: this is not a binary tree
    219145            sage: all(BinaryTree(repr(bt)) == bt for i in range(6) for bt in BinaryTrees(i))
    220146            True
    221147        """
    222         if(type(children) is str):
     148        if (type(children) is str):  # if the input is the repr of a binary tree
    223149            children = children.replace(".","None")
    224             import ast
    225             children = ast.literal_eval(children)
     150            from ast import literal_eval
     151            children = literal_eval(children)
    226152        if children is None:
    227153            children = []
    228         elif children == [] or isinstance(children, (Integer, int)):
     154        elif (children == [] or children == ()
     155              or isinstance(children, (Integer, int))):
    229156            children = [None, None]
    230157        if (children.__class__ is self.__class__ and
    231158            children.parent() == parent):
    class BinaryTree(AbstractClonableTree, C 
    245172            sage: BinaryTree([[], [], []]) # indirect doctest
    246173            Traceback (most recent call last):
    247174            ...
    248             AssertionError: This is not a binary tree
     175            ValueError: this is not a binary tree
    249176            sage: BinaryTree([[]])         # indirect doctest
    250177            Traceback (most recent call last):
    251178            ...
    252             AssertionError: This is not a binary tree
     179            ValueError: this is not a binary tree
    253180        """
    254         assert (not self or len(self) == 2), "This is not a binary tree"
     181        if not (not self or len(self) == 2):
     182            raise ValueError("this is not a binary tree")
    255183
    256184    def _repr_(self):
    257185        """
    class BinaryTree(AbstractClonableTree, C 
    355283
    356284        - ``child_list`` -- a pair of binary trees (or objects convertible to)
    357285
    358         .. note:: ``self`` must be in a mutable state.
     286        .. NOTE:: ``self`` must be in a mutable state.
    359287
    360         .. seealso::
     288        .. SEEALSO::
    361289            :meth:`make_leaf <sage.combinat.binary_tree.BinaryTree.make_leaf>`
    362290
    363291        EXAMPLES::
    class BinaryTree(AbstractClonableTree, C 
    374302            sage: with t.clone() as t:
    375303            ...    t.make_node([BinaryTree(), BinaryTree(), BinaryTree([])])
    376304            Traceback (most recent call last):
    377             AssertionError: the list must have length 2
     305            ...
     306            ValueError: the list must have length 2
    378307            sage: with t1.clone() as t2:
    379308            ...    t2.make_node([t1, t1])
    380309            sage: with t2.clone() as t3:
    class BinaryTree(AbstractClonableTree, C 
    384313        """
    385314        self._require_mutable()
    386315        child_lst = [self.__class__(self.parent(), x) for x in child_list]
    387         assert(len(child_lst) == 2), "the list must have length 2"
     316        if not(len(child_lst) == 2):
     317            raise ValueError("the list must have length 2")
    388318        self.__init__(self.parent(), child_lst, check=False)
    389319
    390320    def make_leaf(self):
    391321        """
    392322        Modify ``self`` so that it became a leaf
    393323
    394         .. note:: ``self`` must be in a mutable state.
     324        .. NOTE:: ``self`` must be in a mutable state.
    395325
    396326        .. seealso::
    397327            :meth:`make_node <sage.combinat.binary_tree.BinaryTree.make_node>`
    class BinaryTree(AbstractClonableTree, C 
    437367        - a leaf is associated to the empty Dyck Word
    438368
    439369        - a tree with chidren `l,r` is associated to the Dyck word
    440           `1 T(l) 0 T(r)` where `T(l)` and `T(r)` are the trees
     370          `1 T(l) 0 T(r)` where `T(l)` and `T(r)` are the Dyck words
    441371          associated to `l` and `r`.
    442372
    443373        EXAMPLES::
    class BinaryTree(AbstractClonableTree, C 
    459389        The *canopee* of a non empty binary tree `T` with `n` internal nodes is
    460390        the list `l` of `0` and `1` of length `n-1` obtained by going along the
    461391        leaves of `T` from left to right except the two extremal ones, writing
    462         `0` if the leaf is a right leaf and `1` is a left leaf.
     392        `0` if the leaf is a right leaf and `1` if the leaf is a left leaf.
    463393
    464394        EXAMPLES::
    465395
    class BinaryTree(AbstractClonableTree, C 
    510440               Formal Power Series and Algebraic Combinatorics, 1994.
    511441        """
    512442        if not self:
    513             raise ValueError, "canopee is only defined for non empty binary trees"
     443            raise ValueError("canopee is only defined for non empty binary trees")
    514444        res = []
    515445        def add_leaf_rec(tr):
    516446            for i in range(2):
    class BinaryTrees(UniqueRepresentation,  
    553483        sage: BinaryTrees(2)
    554484        Binary trees of size 2
    555485
    556     .. note:: this in a factory class whose constructor returns instances of
     486    .. NOTE:: this in a factory class whose constructor returns instances of
    557487              subclasses.
    558488
    559     .. note:: the fact that OrderedTrees is a class instead a simple callable
     489    .. NOTE:: the fact that OrderedTrees is a class instead a simple callable
    560490              is an implementation detail. It could be changed in the future
    561491              and one should not rely on it.
    562492    """
    class BinaryTrees(UniqueRepresentation,  
    580510        if n is None:
    581511            return BinaryTrees_all()
    582512        else:
    583             assert (isinstance(n, (Integer, int)) and n >= 0), "n must be a non negative integer"
     513            if not (isinstance(n, (Integer, int)) and n >= 0):
     514                raise ValueError("n must be a non negative integer")
    584515            return BinaryTrees_size(Integer(n))
    585516
    586517    @cached_method
    class BinaryTrees_all(DisjointUnionEnume 
    702633
    703634    Element = BinaryTree
    704635
    705 from sage.misc.lazy_attribute import lazy_attribute
    706636from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
    707637from combinat import catalan_number
    708638#################################################################
    class BinaryTrees_size(BinaryTrees): 
    780710        """
    781711        A basic generator.
    782712
    783         .. todo:: could be optimized.
     713        .. TODO:: could be optimized.
    784714
    785715        TESTS::
    786716
    class BinaryTrees_size(BinaryTrees): 
    833763            sage: S([])   # indirect doctest
    834764            Traceback (most recent call last):
    835765            ...
    836             ValueError: Wrong number of nodes
     766            ValueError: wrong number of nodes
    837767            sage: S(None)   # indirect doctest
    838768            .
    839769
    class BinaryTrees_size(BinaryTrees): 
    843773        """
    844774        res = self.element_class(self._parent_for, *args, **keywords)
    845775        if res.node_number() != self._size:
    846             raise ValueError, "Wrong number of nodes"
     776            raise ValueError("wrong number of nodes")
    847777        return res
    848778
    849779
    class LabelledBinaryTree(AbstractLabelle 
    921851
    922852        - ``letter`` -- any object comparable with the label of ``self``
    923853
    924         .. note:: ``self`` is supposed to be a binary search tree. No check is
     854        .. NOTE:: ``self`` is supposed to be a binary search tree. No check is
    925855                  performed.
    926856
    927857        EXAMPLES::
  • sage/combinat/ordered_tree.py

    diff --git a/sage/combinat/ordered_tree.py b/sage/combinat/ordered_tree.py
    a b class OrderedTree(AbstractClonableTree,  
    2626    """
    2727    The class for (ordered rooted) Trees
    2828
    29     An ordered tree is a constructed from a node called the root on which one
     29    An ordered tree is constructed from a node called the root on which one
    3030    has grafted a possibly empty list of trees. There is a total order on the
    31     children of a node which is given by the the order of the element in the
     31    children of a node which is given by the order of the element in the
    3232    list. Note that there is no empty ordered tree.
    3333
    3434    INPUT:
    class OrderedTree(AbstractClonableTree,  
    209209            sage: OrderedTree([[],[[]]]).parent()
    210210            Ordered trees
    211211
    212         .. note::
     212        .. NOTE::
    213213
    214214            It is possible to bypass the automatic parent mechanism using:
    215215
    class OrderedTree(AbstractClonableTree,  
    248248
    249249        For ordered trees, returns always ``False``
    250250
    251         .. note:: this is different from ``bool(t)`` which returns whether
     251        .. NOTE:: this is different from ``bool(t)`` which returns whether
    252252                  ``t`` has some child or not.
    253253
    254254        EXAMPLES::
    class OrderedTrees(UniqueRepresentation, 
    289289        sage: OrderedTrees(2)
    290290        Ordered trees of size 2
    291291
    292     .. note:: this in a factory class whose constructor returns instances of
     292    .. NOTE:: this in a factory class whose constructor returns instances of
    293293              subclasses.
    294294
    295     .. note:: the fact that OrderedTrees is a class instead a simple callable
     295    .. NOTE:: the fact that OrderedTrees is a class instead a simple callable
    296296              is an implementation detail. It could be changed in the future
    297297              and one should not rely on it.
    298298    """
    class OrderedTrees(UniqueRepresentation, 
    316316        if n is None:
    317317            return OrderedTrees_all()
    318318        else:
    319             assert (isinstance(n, (Integer, int)) and n >= 0), "n must be a non negative integer"
     319            if not (isinstance(n, (Integer, int)) and n >= 0):
     320                raise ValueError("n must be a non negative integer")
    320321            return OrderedTrees_size(Integer(n))
    321322
    322323    @cached_method
    class OrderedTrees_size(OrderedTrees): 
    519520        """
    520521        A basic generator
    521522
    522         .. todo:: could be optimized.
     523        .. TODO:: could be optimized.
    523524
    524525        TESTS::
    525526
    class LabelledOrderedTree(AbstractLabell 
    593594    """
    594595    Labelled ordered trees
    595596
    596     A labellel ordered tree is an ordered tree with a label attached at each
     597    A labelled ordered tree is an ordered tree with a label attached at each
    597598    node
    598599
    599600    INPUT:
    class LabelledOrderedTrees(UniqueReprese 
    755756        return self
    756757
    757758    Element = LabelledOrderedTree
    758