passagemath-graphs 10.6.1rc1__cp310-cp310-musllinux_1_2_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. passagemath_graphs-10.6.1rc1.dist-info/METADATA +292 -0
  2. passagemath_graphs-10.6.1rc1.dist-info/RECORD +260 -0
  3. passagemath_graphs-10.6.1rc1.dist-info/WHEEL +5 -0
  4. passagemath_graphs-10.6.1rc1.dist-info/top_level.txt +2 -0
  5. passagemath_graphs.libs/libgcc_s-69c45f16.so.1 +0 -0
  6. passagemath_graphs.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
  7. passagemath_graphs.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
  8. sage/all__sagemath_graphs.py +39 -0
  9. sage/combinat/abstract_tree.py +2723 -0
  10. sage/combinat/all__sagemath_graphs.py +34 -0
  11. sage/combinat/binary_tree.py +5306 -0
  12. sage/combinat/cluster_algebra_quiver/all.py +22 -0
  13. sage/combinat/cluster_algebra_quiver/cluster_seed.py +5208 -0
  14. sage/combinat/cluster_algebra_quiver/interact.py +124 -0
  15. sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
  16. sage/combinat/cluster_algebra_quiver/mutation_type.py +1555 -0
  17. sage/combinat/cluster_algebra_quiver/quiver.py +2290 -0
  18. sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +2468 -0
  19. sage/combinat/designs/MOLS_handbook_data.py +570 -0
  20. sage/combinat/designs/all.py +58 -0
  21. sage/combinat/designs/bibd.py +1655 -0
  22. sage/combinat/designs/block_design.py +1071 -0
  23. sage/combinat/designs/covering_array.py +269 -0
  24. sage/combinat/designs/covering_design.py +530 -0
  25. sage/combinat/designs/database.py +5615 -0
  26. sage/combinat/designs/design_catalog.py +122 -0
  27. sage/combinat/designs/designs_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  28. sage/combinat/designs/designs_pyx.pxd +21 -0
  29. sage/combinat/designs/designs_pyx.pyx +993 -0
  30. sage/combinat/designs/difference_family.py +3951 -0
  31. sage/combinat/designs/difference_matrices.py +279 -0
  32. sage/combinat/designs/evenly_distributed_sets.cpython-310-aarch64-linux-gnu.so +0 -0
  33. sage/combinat/designs/evenly_distributed_sets.pyx +661 -0
  34. sage/combinat/designs/ext_rep.py +1064 -0
  35. sage/combinat/designs/gen_quadrangles_with_spread.cpython-310-aarch64-linux-gnu.so +0 -0
  36. sage/combinat/designs/gen_quadrangles_with_spread.pyx +339 -0
  37. sage/combinat/designs/group_divisible_designs.py +361 -0
  38. sage/combinat/designs/incidence_structures.py +2357 -0
  39. sage/combinat/designs/latin_squares.py +581 -0
  40. sage/combinat/designs/orthogonal_arrays.py +2244 -0
  41. sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
  42. sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-310-aarch64-linux-gnu.so +0 -0
  43. sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +967 -0
  44. sage/combinat/designs/resolvable_bibd.py +815 -0
  45. sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
  46. sage/combinat/designs/subhypergraph_search.cpython-310-aarch64-linux-gnu.so +0 -0
  47. sage/combinat/designs/subhypergraph_search.pyx +530 -0
  48. sage/combinat/designs/twographs.py +306 -0
  49. sage/combinat/finite_state_machine.py +14874 -0
  50. sage/combinat/finite_state_machine_generators.py +2006 -0
  51. sage/combinat/graph_path.py +448 -0
  52. sage/combinat/interval_posets.py +3908 -0
  53. sage/combinat/nu_tamari_lattice.py +269 -0
  54. sage/combinat/ordered_tree.py +1446 -0
  55. sage/combinat/posets/all.py +46 -0
  56. sage/combinat/posets/bubble_shuffle.py +247 -0
  57. sage/combinat/posets/cartesian_product.py +493 -0
  58. sage/combinat/posets/d_complete.py +182 -0
  59. sage/combinat/posets/elements.py +273 -0
  60. sage/combinat/posets/forest.py +30 -0
  61. sage/combinat/posets/hasse_cython.cpython-310-aarch64-linux-gnu.so +0 -0
  62. sage/combinat/posets/hasse_cython.pyx +174 -0
  63. sage/combinat/posets/hasse_diagram.py +3672 -0
  64. sage/combinat/posets/hochschild_lattice.py +158 -0
  65. sage/combinat/posets/incidence_algebras.py +794 -0
  66. sage/combinat/posets/lattices.py +5117 -0
  67. sage/combinat/posets/linear_extension_iterator.cpython-310-aarch64-linux-gnu.so +0 -0
  68. sage/combinat/posets/linear_extension_iterator.pyx +292 -0
  69. sage/combinat/posets/linear_extensions.py +1037 -0
  70. sage/combinat/posets/mobile.py +275 -0
  71. sage/combinat/posets/moebius_algebra.py +776 -0
  72. sage/combinat/posets/poset_examples.py +2178 -0
  73. sage/combinat/posets/posets.py +9360 -0
  74. sage/combinat/rooted_tree.py +1070 -0
  75. sage/combinat/shard_order.py +239 -0
  76. sage/combinat/tamari_lattices.py +384 -0
  77. sage/combinat/yang_baxter_graph.py +923 -0
  78. sage/databases/all__sagemath_graphs.py +1 -0
  79. sage/databases/knotinfo_db.py +1231 -0
  80. sage/ext_data/all__sagemath_graphs.py +1 -0
  81. sage/ext_data/graphs/graph_plot_js.html +330 -0
  82. sage/ext_data/kenzo/CP2.txt +45 -0
  83. sage/ext_data/kenzo/CP3.txt +349 -0
  84. sage/ext_data/kenzo/CP4.txt +4774 -0
  85. sage/ext_data/kenzo/README.txt +49 -0
  86. sage/ext_data/kenzo/S4.txt +20 -0
  87. sage/graphs/all.py +42 -0
  88. sage/graphs/asteroidal_triples.cpython-310-aarch64-linux-gnu.so +0 -0
  89. sage/graphs/asteroidal_triples.pyx +320 -0
  90. sage/graphs/base/all.py +1 -0
  91. sage/graphs/base/boost_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  92. sage/graphs/base/boost_graph.pxd +106 -0
  93. sage/graphs/base/boost_graph.pyx +3045 -0
  94. sage/graphs/base/c_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  95. sage/graphs/base/c_graph.pxd +106 -0
  96. sage/graphs/base/c_graph.pyx +5096 -0
  97. sage/graphs/base/dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  98. sage/graphs/base/dense_graph.pxd +28 -0
  99. sage/graphs/base/dense_graph.pyx +801 -0
  100. sage/graphs/base/graph_backends.cpython-310-aarch64-linux-gnu.so +0 -0
  101. sage/graphs/base/graph_backends.pxd +5 -0
  102. sage/graphs/base/graph_backends.pyx +797 -0
  103. sage/graphs/base/overview.py +85 -0
  104. sage/graphs/base/sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  105. sage/graphs/base/sparse_graph.pxd +90 -0
  106. sage/graphs/base/sparse_graph.pyx +1653 -0
  107. sage/graphs/base/static_dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  108. sage/graphs/base/static_dense_graph.pxd +5 -0
  109. sage/graphs/base/static_dense_graph.pyx +1032 -0
  110. sage/graphs/base/static_sparse_backend.cpython-310-aarch64-linux-gnu.so +0 -0
  111. sage/graphs/base/static_sparse_backend.pxd +27 -0
  112. sage/graphs/base/static_sparse_backend.pyx +1583 -0
  113. sage/graphs/base/static_sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  114. sage/graphs/base/static_sparse_graph.pxd +37 -0
  115. sage/graphs/base/static_sparse_graph.pyx +1375 -0
  116. sage/graphs/bipartite_graph.py +2732 -0
  117. sage/graphs/centrality.cpython-310-aarch64-linux-gnu.so +0 -0
  118. sage/graphs/centrality.pyx +1038 -0
  119. sage/graphs/cographs.py +519 -0
  120. sage/graphs/comparability.cpython-310-aarch64-linux-gnu.so +0 -0
  121. sage/graphs/comparability.pyx +851 -0
  122. sage/graphs/connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
  123. sage/graphs/connectivity.pxd +157 -0
  124. sage/graphs/connectivity.pyx +4813 -0
  125. sage/graphs/convexity_properties.cpython-310-aarch64-linux-gnu.so +0 -0
  126. sage/graphs/convexity_properties.pxd +16 -0
  127. sage/graphs/convexity_properties.pyx +870 -0
  128. sage/graphs/digraph.py +4754 -0
  129. sage/graphs/digraph_generators.py +1993 -0
  130. sage/graphs/distances_all_pairs.cpython-310-aarch64-linux-gnu.so +0 -0
  131. sage/graphs/distances_all_pairs.pxd +12 -0
  132. sage/graphs/distances_all_pairs.pyx +2938 -0
  133. sage/graphs/domination.py +1363 -0
  134. sage/graphs/dot2tex_utils.py +100 -0
  135. sage/graphs/edge_connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
  136. sage/graphs/edge_connectivity.pyx +1215 -0
  137. sage/graphs/generators/all.py +1 -0
  138. sage/graphs/generators/basic.py +1769 -0
  139. sage/graphs/generators/chessboard.py +538 -0
  140. sage/graphs/generators/classical_geometries.py +1611 -0
  141. sage/graphs/generators/degree_sequence.py +235 -0
  142. sage/graphs/generators/distance_regular.cpython-310-aarch64-linux-gnu.so +0 -0
  143. sage/graphs/generators/distance_regular.pyx +2846 -0
  144. sage/graphs/generators/families.py +4759 -0
  145. sage/graphs/generators/intersection.py +565 -0
  146. sage/graphs/generators/platonic_solids.py +262 -0
  147. sage/graphs/generators/random.py +2623 -0
  148. sage/graphs/generators/smallgraphs.py +5741 -0
  149. sage/graphs/generators/world_map.py +724 -0
  150. sage/graphs/generic_graph.py +26867 -0
  151. sage/graphs/generic_graph_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  152. sage/graphs/generic_graph_pyx.pxd +34 -0
  153. sage/graphs/generic_graph_pyx.pyx +1673 -0
  154. sage/graphs/genus.cpython-310-aarch64-linux-gnu.so +0 -0
  155. sage/graphs/genus.pyx +622 -0
  156. sage/graphs/graph.py +9645 -0
  157. sage/graphs/graph_coloring.cpython-310-aarch64-linux-gnu.so +0 -0
  158. sage/graphs/graph_coloring.pyx +2284 -0
  159. sage/graphs/graph_database.py +1177 -0
  160. sage/graphs/graph_decompositions/all.py +1 -0
  161. sage/graphs/graph_decompositions/bandwidth.cpython-310-aarch64-linux-gnu.so +0 -0
  162. sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
  163. sage/graphs/graph_decompositions/clique_separators.cpython-310-aarch64-linux-gnu.so +0 -0
  164. sage/graphs/graph_decompositions/clique_separators.pyx +616 -0
  165. sage/graphs/graph_decompositions/cutwidth.cpython-310-aarch64-linux-gnu.so +0 -0
  166. sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
  167. sage/graphs/graph_decompositions/fast_digraph.cpython-310-aarch64-linux-gnu.so +0 -0
  168. sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
  169. sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
  170. sage/graphs/graph_decompositions/graph_products.cpython-310-aarch64-linux-gnu.so +0 -0
  171. sage/graphs/graph_decompositions/graph_products.pyx +508 -0
  172. sage/graphs/graph_decompositions/modular_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  173. sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
  174. sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
  175. sage/graphs/graph_decompositions/slice_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  176. sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
  177. sage/graphs/graph_decompositions/slice_decomposition.pyx +1106 -0
  178. sage/graphs/graph_decompositions/tree_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  179. sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
  180. sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
  181. sage/graphs/graph_decompositions/vertex_separation.cpython-310-aarch64-linux-gnu.so +0 -0
  182. sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
  183. sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
  184. sage/graphs/graph_editor.py +82 -0
  185. sage/graphs/graph_generators.py +3314 -0
  186. sage/graphs/graph_generators_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  187. sage/graphs/graph_generators_pyx.pyx +95 -0
  188. sage/graphs/graph_input.py +812 -0
  189. sage/graphs/graph_latex.py +2064 -0
  190. sage/graphs/graph_list.py +410 -0
  191. sage/graphs/graph_plot.py +1756 -0
  192. sage/graphs/graph_plot_js.py +338 -0
  193. sage/graphs/hyperbolicity.cpython-310-aarch64-linux-gnu.so +0 -0
  194. sage/graphs/hyperbolicity.pyx +1704 -0
  195. sage/graphs/hypergraph_generators.py +364 -0
  196. sage/graphs/independent_sets.cpython-310-aarch64-linux-gnu.so +0 -0
  197. sage/graphs/independent_sets.pxd +13 -0
  198. sage/graphs/independent_sets.pyx +402 -0
  199. sage/graphs/isgci.py +1033 -0
  200. sage/graphs/isoperimetric_inequalities.cpython-310-aarch64-linux-gnu.so +0 -0
  201. sage/graphs/isoperimetric_inequalities.pyx +489 -0
  202. sage/graphs/line_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  203. sage/graphs/line_graph.pyx +743 -0
  204. sage/graphs/lovasz_theta.py +77 -0
  205. sage/graphs/matching.py +1633 -0
  206. sage/graphs/matching_covered_graph.py +3590 -0
  207. sage/graphs/orientations.py +1489 -0
  208. sage/graphs/partial_cube.py +459 -0
  209. sage/graphs/path_enumeration.cpython-310-aarch64-linux-gnu.so +0 -0
  210. sage/graphs/path_enumeration.pyx +2040 -0
  211. sage/graphs/pq_trees.py +1129 -0
  212. sage/graphs/print_graphs.py +201 -0
  213. sage/graphs/schnyder.py +865 -0
  214. sage/graphs/spanning_tree.cpython-310-aarch64-linux-gnu.so +0 -0
  215. sage/graphs/spanning_tree.pyx +1457 -0
  216. sage/graphs/strongly_regular_db.cpython-310-aarch64-linux-gnu.so +0 -0
  217. sage/graphs/strongly_regular_db.pyx +3340 -0
  218. sage/graphs/traversals.cpython-310-aarch64-linux-gnu.so +0 -0
  219. sage/graphs/traversals.pxd +9 -0
  220. sage/graphs/traversals.pyx +1872 -0
  221. sage/graphs/trees.cpython-310-aarch64-linux-gnu.so +0 -0
  222. sage/graphs/trees.pxd +15 -0
  223. sage/graphs/trees.pyx +310 -0
  224. sage/graphs/tutte_polynomial.py +713 -0
  225. sage/graphs/views.cpython-310-aarch64-linux-gnu.so +0 -0
  226. sage/graphs/views.pyx +794 -0
  227. sage/graphs/weakly_chordal.cpython-310-aarch64-linux-gnu.so +0 -0
  228. sage/graphs/weakly_chordal.pyx +604 -0
  229. sage/groups/all__sagemath_graphs.py +1 -0
  230. sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
  231. sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
  232. sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-310-aarch64-linux-gnu.so +0 -0
  233. sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
  234. sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
  235. sage/knots/all.py +6 -0
  236. sage/knots/free_knotinfo_monoid.py +507 -0
  237. sage/knots/gauss_code.py +291 -0
  238. sage/knots/knot.py +682 -0
  239. sage/knots/knot_table.py +284 -0
  240. sage/knots/knotinfo.py +2900 -0
  241. sage/knots/link.py +4715 -0
  242. sage/sandpiles/all.py +13 -0
  243. sage/sandpiles/examples.py +225 -0
  244. sage/sandpiles/sandpile.py +6365 -0
  245. sage/topology/all.py +22 -0
  246. sage/topology/cell_complex.py +1214 -0
  247. sage/topology/cubical_complex.py +1976 -0
  248. sage/topology/delta_complex.py +1806 -0
  249. sage/topology/filtered_simplicial_complex.py +744 -0
  250. sage/topology/moment_angle_complex.py +823 -0
  251. sage/topology/simplicial_complex.py +5160 -0
  252. sage/topology/simplicial_complex_catalog.py +92 -0
  253. sage/topology/simplicial_complex_examples.py +1680 -0
  254. sage/topology/simplicial_complex_homset.py +205 -0
  255. sage/topology/simplicial_complex_morphism.py +836 -0
  256. sage/topology/simplicial_set.py +4102 -0
  257. sage/topology/simplicial_set_catalog.py +55 -0
  258. sage/topology/simplicial_set_constructions.py +2954 -0
  259. sage/topology/simplicial_set_examples.py +865 -0
  260. sage/topology/simplicial_set_morphism.py +1464 -0
@@ -0,0 +1,1446 @@
1
+ # sage_setup: distribution = sagemath-graphs
2
+ """
3
+ Ordered rooted trees
4
+
5
+ AUTHORS:
6
+
7
+ - Florent Hivert (2010-2011): initial revision
8
+ - Frédéric Chapoton (2010): contributed some methods
9
+ """
10
+ # ****************************************************************************
11
+ # Copyright (C) 2010 Florent Hivert <Florent.Hivert@univ-rouen.fr>,
12
+ #
13
+ # Distributed under the terms of the GNU General Public License (GPL)
14
+ # as published by the Free Software Foundation; either version 2 of
15
+ # the License, or (at your option) any later version.
16
+ # https://www.gnu.org/licenses/
17
+ # ****************************************************************************
18
+
19
+ import itertools
20
+
21
+ from sage.structure.list_clone import ClonableArray, ClonableList
22
+ from sage.structure.parent import Parent
23
+ from sage.structure.unique_representation import UniqueRepresentation
24
+ from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass
25
+ from sage.misc.lazy_attribute import lazy_class_attribute
26
+ from sage.misc.lazy_import import lazy_import
27
+ from sage.combinat.abstract_tree import (AbstractClonableTree,
28
+ AbstractLabelledClonableTree)
29
+ from sage.combinat.combinatorial_map import combinatorial_map
30
+ from sage.misc.cachefunc import cached_method
31
+ from sage.categories.sets_cat import Sets, EmptySetError
32
+ from sage.rings.integer import Integer
33
+ from sage.sets.non_negative_integers import NonNegativeIntegers
34
+ from sage.sets.disjoint_union_enumerated_sets import DisjointUnionEnumeratedSets
35
+ from sage.sets.family import Family
36
+ from sage.rings.infinity import Infinity
37
+
38
+ lazy_import('sage.combinat.dyck_word', 'CompleteDyckWords_size')
39
+
40
+
41
+ class OrderedTree(AbstractClonableTree, ClonableList,
42
+ metaclass=InheritComparisonClasscallMetaclass):
43
+ """
44
+ The class of (ordered rooted) trees.
45
+
46
+ An ordered tree is constructed from a node, called the root, on which one
47
+ has grafted a possibly empty list of trees. There is a total order on the
48
+ children of a node which is given by the order of the elements in the
49
+ list. Note that there is no empty ordered tree (so the smallest ordered
50
+ tree consists of just one node).
51
+
52
+ INPUT:
53
+
54
+ One can create a tree from any list (or more generally iterable) of trees
55
+ or objects convertible to a tree. Alternatively a string is also
56
+ accepted. The syntax is the same as for printing: children are grouped by
57
+ square brackets.
58
+
59
+ EXAMPLES::
60
+
61
+ sage: x = OrderedTree([])
62
+ sage: x1 = OrderedTree([x,x])
63
+ sage: x2 = OrderedTree([[],[]])
64
+ sage: x1 == x2
65
+ True
66
+ sage: tt1 = OrderedTree([x,x1,x2])
67
+ sage: tt2 = OrderedTree([[], [[], []], x2])
68
+ sage: tt1 == tt2
69
+ True
70
+
71
+ sage: OrderedTree([]) == OrderedTree()
72
+ True
73
+
74
+ TESTS::
75
+
76
+ sage: x1.__hash__() == x2.__hash__()
77
+ True
78
+ sage: tt1.__hash__() == tt2.__hash__()
79
+ True
80
+
81
+ Trees are usually immutable. However they inherit from
82
+ :class:`sage.structure.list_clone.ClonableList`, so that they can be
83
+ modified using the clone protocol. Let us now see what this means.
84
+
85
+ Trying to modify a non-mutable tree raises an error::
86
+
87
+ sage: tt1[1] = tt2
88
+ Traceback (most recent call last):
89
+ ...
90
+ ValueError: object is immutable; please change a copy instead.
91
+
92
+ Here is the correct way to do it::
93
+
94
+ sage: with tt2.clone() as tt2:
95
+ ....: tt2[1] = tt1
96
+ sage: tt2
97
+ [[], [[], [[], []], [[], []]], [[], []]]
98
+
99
+ It is also possible to append a child to a tree::
100
+
101
+ sage: with tt2.clone() as tt3:
102
+ ....: tt3.append(OrderedTree([]))
103
+ sage: tt3
104
+ [[], [[], [[], []], [[], []]], [[], []], []]
105
+
106
+ Or to insert a child in a tree::
107
+
108
+ sage: with tt2.clone() as tt3:
109
+ ....: tt3.insert(2, OrderedTree([]))
110
+ sage: tt3
111
+ [[], [[], [[], []], [[], []]], [], [[], []]]
112
+
113
+ We check that ``tt1`` is not modified and that everything is correct with
114
+ respect to equality::
115
+
116
+ sage: tt1
117
+ [[], [[], []], [[], []]]
118
+ sage: tt1 == tt2
119
+ False
120
+ sage: tt1.__hash__() == tt2.__hash__()
121
+ False
122
+
123
+ TESTS::
124
+
125
+ sage: tt1bis = OrderedTree(tt1)
126
+ sage: with tt1.clone() as tt1:
127
+ ....: tt1[1] = tt1bis
128
+ sage: tt1
129
+ [[], [[], [[], []], [[], []]], [[], []]]
130
+ sage: tt1 == tt2
131
+ True
132
+ sage: tt1.__hash__() == tt2.__hash__()
133
+ True
134
+ sage: len(tt1)
135
+ 3
136
+ sage: tt1[2]
137
+ [[], []]
138
+ sage: tt1[3]
139
+ Traceback (most recent call last):
140
+ ...
141
+ IndexError: list index out of range
142
+ sage: tt1[1:2]
143
+ [[[], [[], []], [[], []]]]
144
+
145
+ Various tests involving construction, equality and hashing::
146
+
147
+ sage: OrderedTree() == OrderedTree()
148
+ True
149
+ sage: t1 = OrderedTree([[],[[]]])
150
+ sage: t2 = OrderedTree([[],[[]]])
151
+ sage: t1 == t2
152
+ True
153
+ sage: t2 = OrderedTree(t1)
154
+ sage: t1 == t2
155
+ True
156
+ sage: t1 = OrderedTree([[],[[]]])
157
+ sage: t2 = OrderedTree([[[]],[]])
158
+ sage: t1 == t2
159
+ False
160
+
161
+ sage: t1 = OrderedTree([[],[[]]])
162
+ sage: t2 = OrderedTree([[],[[]]])
163
+ sage: t1.__hash__() == t2.__hash__()
164
+ True
165
+ sage: t2 = OrderedTree([[[]],[]])
166
+ sage: t1.__hash__() == t2.__hash__()
167
+ False
168
+ sage: OrderedTree().__hash__() == OrderedTree([]).__hash__()
169
+ True
170
+ sage: tt1 = OrderedTree([t1,t2,t1])
171
+ sage: tt2 = OrderedTree([t1, [[[]],[]], t1])
172
+ sage: tt1.__hash__() == tt2.__hash__()
173
+ True
174
+
175
+ Check that the hash value is correctly updated after modification::
176
+
177
+ sage: with tt2.clone() as tt2:
178
+ ....: tt2[1,1] = tt1
179
+ sage: tt1.__hash__() == tt2.__hash__()
180
+ False
181
+ """
182
+ @staticmethod
183
+ def __classcall_private__(cls, *args, **opts):
184
+ """
185
+ Ensure that trees created by the enumerated sets and directly
186
+ are the same and that they are instances of :class:`OrderedTree`
187
+
188
+ TESTS::
189
+
190
+ sage: issubclass(OrderedTrees().element_class, OrderedTree)
191
+ True
192
+ sage: t0 = OrderedTree([[],[[], []]])
193
+ sage: t0.parent()
194
+ Ordered trees
195
+ sage: type(t0)
196
+ <class 'sage.combinat.ordered_tree.OrderedTrees_all_with_category.element_class'>
197
+
198
+ sage: t1 = OrderedTrees()([[],[[], []]])
199
+ sage: t1.parent() is t0.parent()
200
+ True
201
+ sage: type(t1) is type(t0)
202
+ True
203
+
204
+ sage: t1 = OrderedTrees(4)([[],[[]]])
205
+ sage: t1.parent() is t0.parent()
206
+ True
207
+ sage: type(t1) is type(t0)
208
+ True
209
+ """
210
+ return cls._auto_parent.element_class(cls._auto_parent, *args, **opts)
211
+
212
+ @lazy_class_attribute
213
+ def _auto_parent(cls):
214
+ """
215
+ The automatic parent of the elements of this class.
216
+
217
+ When calling the constructor of an element of this class, one needs a
218
+ parent. This class attribute specifies which parent is used.
219
+
220
+ EXAMPLES::
221
+
222
+ sage: OrderedTree([[],[[]]])._auto_parent
223
+ Ordered trees
224
+ sage: OrderedTree([[],[[]]]).parent()
225
+ Ordered trees
226
+
227
+ .. NOTE::
228
+
229
+ It is possible to bypass the automatic parent mechanism using::
230
+
231
+ sage: t1 = OrderedTree.__new__(OrderedTree, Parent(), [])
232
+ sage: t1.__init__(Parent(), [])
233
+ sage: t1
234
+ []
235
+ sage: t1.parent()
236
+ <sage.structure.parent.Parent object at ...>
237
+ """
238
+ return OrderedTrees_all()
239
+
240
+ def __init__(self, parent=None, children=None, check=True):
241
+ """
242
+ TESTS::
243
+
244
+ sage: t1 = OrderedTrees(4)([[],[[]]])
245
+ sage: TestSuite(t1).run()
246
+ sage: OrderedTrees()("[]") # indirect doctest
247
+ []
248
+ sage: all(OrderedTree(repr(tr)) == tr for i in range(6) for tr in OrderedTrees(i))
249
+ True
250
+ """
251
+ if children is None:
252
+ children = []
253
+ if isinstance(children, str):
254
+ children = eval(children)
255
+ if (children.__class__ is self.__class__ and
256
+ children.parent() == parent):
257
+ children = list(children)
258
+ else:
259
+ children = [self.__class__(parent, x) for x in children]
260
+ ClonableArray.__init__(self, parent, children, check=check)
261
+
262
+ def is_empty(self):
263
+ """
264
+ Return if ``self`` is the empty tree.
265
+
266
+ For ordered trees, this always returns ``False``.
267
+
268
+ .. NOTE:: this is different from ``bool(t)`` which returns whether
269
+ ``t`` has some child or not.
270
+
271
+ EXAMPLES::
272
+
273
+ sage: t = OrderedTrees(4)([[],[[]]])
274
+ sage: t.is_empty()
275
+ False
276
+ sage: bool(t)
277
+ True
278
+ """
279
+ return False
280
+
281
+ def _to_binary_tree_rec(self, bijection='left'):
282
+ r"""
283
+ Internal recursive method to obtain a binary tree from an ordered
284
+ tree.
285
+
286
+ See :meth:`to_binary_tree_left_branch` and
287
+ :meth:`to_binary_tree_right_branch` for what it does.
288
+
289
+ EXAMPLES::
290
+
291
+ sage: T = OrderedTree([[],[]])
292
+ sage: T._to_binary_tree_rec()
293
+ [[., .], .]
294
+ sage: T._to_binary_tree_rec(bijection='right')
295
+ [., [., .]]
296
+ sage: T = OrderedTree([[], [[], []], [[], [[]]]])
297
+ sage: T._to_binary_tree_rec()
298
+ [[[., .], [[., .], .]], [[., .], [., .]]]
299
+ sage: T._to_binary_tree_rec(bijection='right')
300
+ [., [[., [., .]], [[., [[., .], .]], .]]]
301
+ """
302
+ from sage.combinat.binary_tree import BinaryTree
303
+ root = BinaryTree()
304
+ if bijection == "left":
305
+ for child in self:
306
+ root = BinaryTree([root, child._to_binary_tree_rec(bijection)])
307
+ elif bijection == "right":
308
+ children = list(self)
309
+ children.reverse()
310
+ for child in children:
311
+ root = BinaryTree([child._to_binary_tree_rec(bijection), root])
312
+ else:
313
+ raise ValueError("the bijection argument should be either "
314
+ "left or right")
315
+ return root
316
+
317
+ @combinatorial_map(name="To binary tree, left brother = left child")
318
+ def to_binary_tree_left_branch(self):
319
+ r"""
320
+ Return a binary tree of size `n-1` (where `n` is the size of `t`,
321
+ and where `t` is ``self``) obtained from `t` by the following
322
+ recursive rule:
323
+
324
+ - if `x` is the left brother of `y` in `t`, then `x` becomes the
325
+ left child of `y`;
326
+ - if `x` is the last child of `y` in `t`, then `x` becomes the
327
+ right child of `y`,
328
+
329
+ and removing the root of `t`.
330
+
331
+ EXAMPLES::
332
+
333
+ sage: T = OrderedTree([[],[]])
334
+ sage: T.to_binary_tree_left_branch()
335
+ [[., .], .]
336
+ sage: T = OrderedTree([[], [[], []], [[], [[]]]])
337
+ sage: T.to_binary_tree_left_branch()
338
+ [[[., .], [[., .], .]], [[., .], [., .]]]
339
+
340
+ TESTS::
341
+
342
+ sage: T = OrderedTree([[],[]])
343
+ sage: T == T.to_binary_tree_left_branch().to_ordered_tree_left_branch()
344
+ True
345
+ sage: T = OrderedTree([[], [[], []], [[], [[]]]])
346
+ sage: T == T.to_binary_tree_left_branch().to_ordered_tree_left_branch()
347
+ True
348
+ """
349
+ return self._to_binary_tree_rec()
350
+
351
+ @combinatorial_map(name="To parallelogram polyomino")
352
+ def to_parallelogram_polyomino(self, bijection=None):
353
+ r"""
354
+ Return a polyomino parallelogram.
355
+
356
+ INPUT:
357
+
358
+ - ``bijection`` -- (default: ``'Boussicault-Socci'``) is the name of the
359
+ bijection to use. Possible values are ``'Boussicault-Socci'``,
360
+ ``'via dyck and Delest-Viennot'``.
361
+
362
+ EXAMPLES::
363
+
364
+ sage: # needs sage.combinat sage.modules
365
+ sage: T = OrderedTree([[[], [[], [[]]]], [], [[[],[]]], [], []])
366
+ sage: T.to_parallelogram_polyomino(bijection='Boussicault-Socci')
367
+ [[0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1],
368
+ [1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0]]
369
+ sage: T = OrderedTree( [] )
370
+ sage: T.to_parallelogram_polyomino()
371
+ [[1], [1]]
372
+ sage: T = OrderedTree( [[]] )
373
+ sage: T.to_parallelogram_polyomino()
374
+ [[0, 1], [1, 0]]
375
+ sage: T = OrderedTree( [[],[]] )
376
+ sage: T.to_parallelogram_polyomino()
377
+ [[0, 1, 1], [1, 1, 0]]
378
+ sage: T = OrderedTree( [[[]]] )
379
+ sage: T.to_parallelogram_polyomino()
380
+ [[0, 0, 1], [1, 0, 0]]
381
+ """
382
+ if (bijection is None) or (bijection == 'Boussicault-Socci'):
383
+ return self._to_parallelogram_polyomino_Boussicault_Socci()
384
+ if bijection == 'via dyck and Delest-Viennot':
385
+ raise NotImplementedError
386
+ raise ValueError('unknown bijection')
387
+
388
+ def _to_parallelogram_polyomino_Boussicault_Socci(self):
389
+ r"""
390
+ Return the polyomino parallelogram using the Boussicault-Socci
391
+ bijection.
392
+
393
+ EXAMPLES::
394
+
395
+ sage: # needs sage.combinat sage.modules
396
+ sage: T = OrderedTree(
397
+ ....: [[[], [[], [[]]]], [], [[[],[]]], [], []]
398
+ ....: )
399
+ sage: T._to_parallelogram_polyomino_Boussicault_Socci()
400
+ [[0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1], [1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0]]
401
+ sage: T = OrderedTree( [] )
402
+ sage: T._to_parallelogram_polyomino_Boussicault_Socci()
403
+ [[1], [1]]
404
+ sage: T = OrderedTree( [[]] )
405
+ sage: T._to_parallelogram_polyomino_Boussicault_Socci()
406
+ [[0, 1], [1, 0]]
407
+ sage: T = OrderedTree( [[],[]] )
408
+ sage: T._to_parallelogram_polyomino_Boussicault_Socci()
409
+ [[0, 1, 1], [1, 1, 0]]
410
+ sage: T = OrderedTree( [[[]]] )
411
+ sage: T._to_parallelogram_polyomino_Boussicault_Socci()
412
+ [[0, 0, 1], [1, 0, 0]]
413
+ """
414
+ from sage.combinat.parallelogram_polyomino import ParallelogramPolyomino
415
+ if self.node_number() == 1:
416
+ return ParallelogramPolyomino([[1], [1]])
417
+ upper_nodes = []
418
+ lower_nodes = []
419
+ w_coordinate = {}
420
+ w_coordinate[()] = 0
421
+ h_coordinate = {}
422
+
423
+ cpt = 0
424
+ for h in range(0, self.depth(), 2):
425
+ for node in self.paths_at_depth(h):
426
+ h_coordinate[node] = cpt
427
+ lower_nodes.append(node)
428
+ cpt += 1
429
+
430
+ cpt = 0
431
+ for h in range(1, self.depth(), 2):
432
+ for node in self.paths_at_depth(h):
433
+ w_coordinate[node] = cpt
434
+ upper_nodes.append(node)
435
+ cpt += 1
436
+
437
+ def W(path):
438
+ if path in w_coordinate:
439
+ return w_coordinate[path]
440
+ else:
441
+ return w_coordinate[path[:-1]]
442
+
443
+ def H(path):
444
+ if path in h_coordinate:
445
+ return h_coordinate[path]
446
+ else:
447
+ return h_coordinate[path[:-1]]
448
+
449
+ lower_path = []
450
+ for i in range(1, len(lower_nodes)):
451
+ lower_path.append(0)
452
+ lower_path += [1] * (W(lower_nodes[i]) - W(lower_nodes[i - 1]))
453
+ lower_path.append(0)
454
+ lower_path += [1] * (self.node_number() - len(lower_path))
455
+
456
+ upper_path = []
457
+ for i in range(1, len(upper_nodes)):
458
+ upper_path.append(1)
459
+ upper_path += [0] * (H(upper_nodes[i]) - H(upper_nodes[i - 1]))
460
+ upper_path.append(1)
461
+ upper_path += [0] * (self.node_number() - len(upper_path))
462
+
463
+ return ParallelogramPolyomino([lower_path, upper_path])
464
+
465
+ @combinatorial_map(name="To binary tree, right brother = right child")
466
+ def to_binary_tree_right_branch(self):
467
+ r"""
468
+ Return a binary tree of size `n-1` (where `n` is the size of `t`,
469
+ and where `t` is ``self``) obtained from `t` by the following
470
+ recursive rule:
471
+
472
+ - if `x` is the right brother of `y` in `t`, then`x` becomes the
473
+ right child of `y`;
474
+ - if `x` is the first child of `y` in `t`, then `x` becomes the
475
+ left child of `y`,
476
+
477
+ and removing the root of `t`.
478
+
479
+ EXAMPLES::
480
+
481
+ sage: T = OrderedTree([[],[]])
482
+ sage: T.to_binary_tree_right_branch()
483
+ [., [., .]]
484
+ sage: T = OrderedTree([[], [[], []], [[], [[]]]])
485
+ sage: T.to_binary_tree_right_branch()
486
+ [., [[., [., .]], [[., [[., .], .]], .]]]
487
+
488
+ TESTS::
489
+
490
+ sage: T = OrderedTree([[],[]])
491
+ sage: T == T.to_binary_tree_right_branch().to_ordered_tree_right_branch()
492
+ True
493
+ sage: T = OrderedTree([[], [[], []], [[], [[]]]])
494
+ sage: T == T.to_binary_tree_right_branch().to_ordered_tree_right_branch()
495
+ True
496
+ """
497
+ return self._to_binary_tree_rec(bijection='right')
498
+
499
+ @combinatorial_map(name="To Dyck path")
500
+ def to_dyck_word(self):
501
+ r"""
502
+ Return the Dyck path corresponding to ``self`` where the maximal
503
+ height of the Dyck path is the depth of ``self`` .
504
+
505
+ EXAMPLES::
506
+
507
+ sage: T = OrderedTree([[],[]])
508
+ sage: T.to_dyck_word() # needs sage.combinat
509
+ [1, 0, 1, 0]
510
+ sage: T = OrderedTree([[],[[]]])
511
+ sage: T.to_dyck_word() # needs sage.combinat
512
+ [1, 0, 1, 1, 0, 0]
513
+ sage: T = OrderedTree([[], [[], []], [[], [[]]]])
514
+ sage: T.to_dyck_word() # needs sage.combinat
515
+ [1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0]
516
+ """
517
+ word = []
518
+ for child in self:
519
+ word.append(1)
520
+ word.extend(child.to_dyck_word())
521
+ word.append(0)
522
+ from sage.combinat.dyck_word import DyckWord
523
+ return DyckWord(word)
524
+
525
+ @combinatorial_map(name="To graph")
526
+ def to_undirected_graph(self):
527
+ r"""
528
+ Return the undirected graph obtained from the tree nodes and edges.
529
+
530
+ The graph is endowed with an embedding, so that it will be displayed
531
+ correctly.
532
+
533
+ EXAMPLES::
534
+
535
+ sage: t = OrderedTree([])
536
+ sage: t.to_undirected_graph()
537
+ Graph on 1 vertex
538
+ sage: t = OrderedTree([[[]],[],[]])
539
+ sage: t.to_undirected_graph()
540
+ Graph on 5 vertices
541
+
542
+ If the tree is labelled, we use its labelling to label the graph. This
543
+ will fail if the labels are not all distinct.
544
+ Otherwise, we use the graph canonical labelling which means that
545
+ two different trees can have the same graph.
546
+
547
+ EXAMPLES::
548
+
549
+ sage: t = OrderedTree([[[]],[],[]])
550
+ sage: t.canonical_labelling().to_undirected_graph()
551
+ Graph on 5 vertices
552
+
553
+ TESTS::
554
+
555
+ sage: t.canonical_labelling().to_undirected_graph() == t.to_undirected_graph()
556
+ False
557
+ sage: OrderedTree([[],[]]).to_undirected_graph() == OrderedTree([[[]]]).to_undirected_graph()
558
+ True
559
+ sage: OrderedTree([[],[],[]]).to_undirected_graph() == OrderedTree([[[[]]]]).to_undirected_graph()
560
+ False
561
+ """
562
+ from sage.graphs.graph import Graph
563
+ g = Graph()
564
+ if self in LabelledOrderedTrees():
565
+ relabel = False
566
+ else:
567
+ self = self.canonical_labelling()
568
+ relabel = True
569
+ roots = [self]
570
+ g.add_vertex(name=self.label())
571
+ emb = {self.label(): []}
572
+ while roots:
573
+ node = roots.pop()
574
+ children = reversed([child.label() for child in node])
575
+ emb[node.label()].extend(children)
576
+ for child in node:
577
+ g.add_vertex(name=child.label())
578
+ emb[child.label()] = [node.label()]
579
+ g.add_edge(child.label(), node.label())
580
+ roots.append(child)
581
+ g.set_embedding(emb)
582
+ if relabel:
583
+ g = g.canonical_label()
584
+ return g
585
+
586
+ @combinatorial_map(name="To poset")
587
+ def to_poset(self, root_to_leaf=False):
588
+ r"""
589
+ Return the poset obtained by interpreting the tree as a Hasse
590
+ diagram. The default orientation is from leaves to root but you can
591
+ pass ``root_to_leaf=True`` to obtain the inverse orientation.
592
+
593
+ INPUT:
594
+
595
+ - ``root_to_leaf`` -- boolean (default: ``False``); ``True`` if the
596
+ poset orientation should be from root to leaves
597
+
598
+ EXAMPLES::
599
+
600
+ sage: t = OrderedTree([])
601
+ sage: t.to_poset()
602
+ Finite poset containing 1 elements
603
+ sage: p = OrderedTree([[[]],[],[]]).to_poset()
604
+ sage: p.height(), p.width() # needs networkx
605
+ (3, 3)
606
+
607
+ If the tree is labelled, we use its labelling to label the poset.
608
+ Otherwise, we use the poset canonical labelling::
609
+
610
+ sage: t = OrderedTree([[[]],[],[]]).canonical_labelling().to_poset()
611
+ sage: t.height(), t.width() # needs networkx
612
+ (3, 3)
613
+ """
614
+ if self in LabelledOrderedTrees():
615
+ relabel = False
616
+ else:
617
+ self = self.canonical_labelling()
618
+ relabel = True
619
+ relations = []
620
+ elements = [self.label()]
621
+ roots = [self]
622
+ while roots:
623
+ node = roots.pop()
624
+ for child in node:
625
+ elements.append(child.label())
626
+ relations.append((node.label(), child.label())
627
+ if root_to_leaf else (child.label(),
628
+ node.label()))
629
+ roots.append(child)
630
+ from sage.combinat.posets.posets import Poset
631
+ p = Poset([elements, relations])
632
+ if relabel:
633
+ p = p.canonical_label()
634
+ return p
635
+
636
+ @combinatorial_map(order=2, name="Left-right symmetry")
637
+ def left_right_symmetry(self):
638
+ r"""
639
+ Return the symmetric tree of ``self``.
640
+
641
+ The symmetric tree `s(T)` of an ordered tree `T` is
642
+ defined as follows:
643
+ If `T` is an ordered tree with children `C_1, C_2, \ldots, C_k`
644
+ (listed from left to right), then the symmetric tree `s(T)` of
645
+ `T` is the ordered tree with children
646
+ `s(C_k), s(C_{k-1}), \ldots, s(C_1)` (from left to right).
647
+
648
+ EXAMPLES::
649
+
650
+ sage: T = OrderedTree([[],[[]]])
651
+ sage: T.left_right_symmetry()
652
+ [[[]], []]
653
+ sage: T = OrderedTree([[], [[], []], [[], [[]]]])
654
+ sage: T.left_right_symmetry()
655
+ [[[[]], []], [[], []], []]
656
+ """
657
+ children = [c.left_right_symmetry() for c in self]
658
+ children.reverse()
659
+ return OrderedTree(children)
660
+
661
+ def plot(self):
662
+ r"""
663
+ Plot the tree ``self``.
664
+
665
+ .. WARNING::
666
+
667
+ For a labelled tree, this will fail unless all labels are
668
+ distinct. For unlabelled trees, some arbitrary labels are chosen.
669
+ Use :meth:`_latex_`, ``view``,
670
+ :meth:`_ascii_art_` or ``pretty_print`` for more
671
+ faithful representations of the data of the tree.
672
+
673
+ EXAMPLES::
674
+
675
+ sage: p = OrderedTree([[[]],[],[]])
676
+ sage: ascii_art(p)
677
+ _o__
678
+ / / /
679
+ o o o
680
+ |
681
+ o
682
+ sage: p.plot() # needs sage.plot
683
+ Graphics object consisting of 10 graphics primitives
684
+
685
+ .. PLOT::
686
+
687
+ P = OrderedTree([[[]],[],[]]).plot()
688
+ sphinx_plot(P)
689
+
690
+ Now a labelled example::
691
+
692
+ sage: g = OrderedTree([[],[[]],[]]).canonical_labelling()
693
+ sage: ascii_art(g)
694
+ _1__
695
+ / / /
696
+ 2 3 5
697
+ |
698
+ 4
699
+ sage: g.plot() # needs sage.plot
700
+ Graphics object consisting of 10 graphics primitives
701
+
702
+ .. PLOT::
703
+
704
+ P = OrderedTree([[],[[]],[]]).canonical_labelling().plot()
705
+ sphinx_plot(P)
706
+ """
707
+ try:
708
+ root = self.label()
709
+ g = self.to_undirected_graph()
710
+ except AttributeError:
711
+ root = 1
712
+ g = self.canonical_labelling().to_undirected_graph()
713
+ return g.plot(layout='tree', tree_root=root, tree_orientation='down')
714
+
715
+ def sort_key(self):
716
+ """
717
+ Return a tuple of nonnegative integers encoding the ordered
718
+ tree ``self``.
719
+
720
+ The first entry of the tuple is the number of children of the
721
+ root. Then the rest of the tuple is the concatenation of the
722
+ tuples associated to these children (we view the children of
723
+ a tree as trees themselves) from left to right.
724
+
725
+ This tuple characterizes the tree uniquely, and can be used to
726
+ sort the ordered trees.
727
+
728
+ .. NOTE::
729
+
730
+ By default, this method does not encode any extra
731
+ structure that ``self`` might have -- e.g., if you were
732
+ to define a class ``EdgeColoredOrderedTree`` which
733
+ implements edge-colored trees and which inherits from
734
+ :class:`OrderedTree`, then the :meth:`sort_key` method
735
+ it would inherit would forget about the colors of the
736
+ edges (and thus would not characterize edge-colored
737
+ trees uniquely). If you want to preserve extra data,
738
+ you need to override this method or use a new method.
739
+ For instance, on the :class:`LabelledOrderedTree`
740
+ subclass, this method is overridden by a slightly
741
+ different method, which encodes not only the numbers
742
+ of children of the nodes of ``self``, but also their
743
+ labels.
744
+ Be careful with using overridden methods, however:
745
+ If you have (say) a class ``BalancedTree`` which
746
+ inherits from :class:`OrderedTree` and which encodes
747
+ balanced trees, and if you have another class
748
+ ``BalancedLabelledOrderedTree`` which inherits both
749
+ from ``BalancedOrderedTree`` and from
750
+ :class:`LabelledOrderedTree`, then (depending on the MRO)
751
+ the default :meth:`sort_key` method on
752
+ ``BalancedLabelledOrderedTree`` (unless manually
753
+ overridden) will be taken either from ``BalancedTree``
754
+ or from :class:`LabelledOrderedTree`, and in the former
755
+ case will ignore the labelling!
756
+
757
+ EXAMPLES::
758
+
759
+ sage: RT = OrderedTree
760
+ sage: RT([[],[[]]]).sort_key()
761
+ (2, 0, 1, 0)
762
+ sage: RT([[[]],[]]).sort_key()
763
+ (2, 1, 0, 0)
764
+ """
765
+ l = len(self)
766
+ if l == 0:
767
+ return (0,)
768
+ resu = [l] + [u for t in self for u in t.sort_key()]
769
+ return tuple(resu)
770
+
771
+ @cached_method
772
+ def normalize(self, inplace=False):
773
+ r"""
774
+ Return the normalized tree of ``self``.
775
+
776
+ INPUT:
777
+
778
+ - ``inplace`` -- boolean (default: ``False``); if ``True``,
779
+ then ``self`` is modified and nothing returned. Otherwise
780
+ the normalized tree is returned.
781
+
782
+ The normalization of an ordered tree `t` is an ordered tree `s`
783
+ which has the property that `t` and `s` are isomorphic as
784
+ *unordered* rooted trees, and that if two ordered trees `t` and
785
+ `t'` are isomorphic as *unordered* rooted trees, then the
786
+ normalizations of `t` and `t'` are identical. In other words,
787
+ normalization is a map from the set of ordered trees to itself
788
+ which picks a representative from every equivalence class with
789
+ respect to the relation of "being isomorphic as unordered
790
+ trees", and maps every ordered tree to the representative
791
+ chosen from its class.
792
+
793
+ This map proceeds recursively by first normalizing every
794
+ subtree, and then sorting the subtrees according to the value
795
+ of the :meth:`sort_key` method.
796
+
797
+ Consider the quotient map `\pi` that sends a planar rooted tree to
798
+ the associated unordered rooted tree. Normalization is the
799
+ composite `s \circ \pi`, where `s` is a section of `\pi`.
800
+
801
+ EXAMPLES::
802
+
803
+ sage: OT = OrderedTree
804
+ sage: ta = OT([[],[[]]])
805
+ sage: tb = OT([[[]],[]])
806
+ sage: ta.normalize() == tb.normalize()
807
+ True
808
+ sage: ta == tb
809
+ False
810
+
811
+ An example with inplace normalization::
812
+
813
+ sage: OT = OrderedTree
814
+ sage: ta = OT([[],[[]]])
815
+ sage: tb = OT([[[]],[]])
816
+ sage: ta.normalize(inplace=True); ta
817
+ [[], [[]]]
818
+ sage: tb.normalize(inplace=True); tb
819
+ [[], [[]]]
820
+ """
821
+ if not inplace:
822
+ with self.clone() as res:
823
+ resl = res._get_list()
824
+ for i in range(len(resl)):
825
+ resl[i] = resl[i].normalize()
826
+ resl.sort(key=lambda t: t.sort_key())
827
+ return res
828
+ else:
829
+ resl = self._get_list()
830
+ for i in range(len(resl)):
831
+ resl[i] = resl[i].normalize()
832
+ resl.sort(key=lambda t: t.sort_key())
833
+
834
+
835
+ # Abstract class to serve as a Factory no instance are created.
836
+ class OrderedTrees(UniqueRepresentation, Parent):
837
+ """
838
+ Factory for ordered trees.
839
+
840
+ INPUT:
841
+
842
+ - ``size`` -- integer (optional)
843
+
844
+ OUTPUT:
845
+
846
+ - the set of all ordered trees (of the given ``size`` if specified)
847
+
848
+ EXAMPLES::
849
+
850
+ sage: OrderedTrees()
851
+ Ordered trees
852
+
853
+ sage: OrderedTrees(2)
854
+ Ordered trees of size 2
855
+
856
+ .. NOTE:: this is a factory class whose constructor returns instances of
857
+ subclasses.
858
+
859
+ .. NOTE:: the fact that OrderedTrees is a class instead of a simple callable
860
+ is an implementation detail. It could be changed in the future
861
+ and one should not rely on it.
862
+ """
863
+ @staticmethod
864
+ def __classcall_private__(cls, n=None):
865
+ """
866
+ TESTS::
867
+
868
+ sage: from sage.combinat.ordered_tree import OrderedTrees_all, OrderedTrees_size
869
+ sage: isinstance(OrderedTrees(2), OrderedTrees)
870
+ True
871
+ sage: isinstance(OrderedTrees(), OrderedTrees)
872
+ True
873
+ sage: OrderedTrees(2) is OrderedTrees_size(2)
874
+ True
875
+ sage: OrderedTrees(5).cardinality()
876
+ 14
877
+ sage: OrderedTrees() is OrderedTrees_all()
878
+ True
879
+ """
880
+ if n is None:
881
+ return OrderedTrees_all()
882
+ else:
883
+ if not (isinstance(n, (Integer, int)) and n >= 0):
884
+ raise ValueError("n must be a nonnegative integer")
885
+ return OrderedTrees_size(Integer(n))
886
+
887
+ @cached_method
888
+ def leaf(self):
889
+ """
890
+ Return a leaf tree with ``self`` as parent.
891
+
892
+ EXAMPLES::
893
+
894
+ sage: OrderedTrees().leaf()
895
+ []
896
+
897
+ TESTS::
898
+
899
+ sage: (OrderedTrees().leaf() is
900
+ ....: sage.combinat.ordered_tree.OrderedTrees_all().leaf())
901
+ True
902
+ """
903
+ return self([])
904
+
905
+
906
+ class OrderedTrees_all(DisjointUnionEnumeratedSets, OrderedTrees):
907
+ """
908
+ The set of all ordered trees.
909
+
910
+ EXAMPLES::
911
+
912
+ sage: OT = OrderedTrees(); OT
913
+ Ordered trees
914
+ sage: OT.cardinality()
915
+ +Infinity
916
+ """
917
+
918
+ def __init__(self):
919
+ """
920
+ TESTS::
921
+
922
+ sage: from sage.combinat.ordered_tree import OrderedTrees_all
923
+ sage: B = OrderedTrees_all()
924
+ sage: B.cardinality()
925
+ +Infinity
926
+
927
+ sage: it = iter(B)
928
+ sage: (next(it), next(it), next(it), next(it), next(it))
929
+ ([], [[]], [[], []], [[[]]], [[], [], []])
930
+ sage: next(it).parent()
931
+ Ordered trees
932
+ sage: B([])
933
+ []
934
+
935
+ sage: B is OrderedTrees_all()
936
+ True
937
+ sage: TestSuite(B).run() # long time
938
+ """
939
+ DisjointUnionEnumeratedSets.__init__(
940
+ self, Family(NonNegativeIntegers(), OrderedTrees_size),
941
+ facade=True, keepkey=False)
942
+
943
+ def _repr_(self):
944
+ """
945
+ TESTS::
946
+
947
+ sage: OrderedTrees() # indirect doctest
948
+ Ordered trees
949
+ """
950
+ return "Ordered trees"
951
+
952
+ def __contains__(self, x):
953
+ """
954
+ TESTS::
955
+
956
+ sage: T = OrderedTrees()
957
+ sage: 1 in T
958
+ False
959
+ sage: T([]) in T
960
+ True
961
+ """
962
+ return isinstance(x, self.element_class)
963
+
964
+ def unlabelled_trees(self):
965
+ """
966
+ Return the set of unlabelled trees associated to ``self``.
967
+
968
+ EXAMPLES::
969
+
970
+ sage: OrderedTrees().unlabelled_trees()
971
+ Ordered trees
972
+ """
973
+ return self
974
+
975
+ def labelled_trees(self):
976
+ """
977
+ Return the set of labelled trees associated to ``self``.
978
+
979
+ EXAMPLES::
980
+
981
+ sage: OrderedTrees().labelled_trees()
982
+ Labelled ordered trees
983
+ """
984
+ return LabelledOrderedTrees()
985
+
986
+ def _element_constructor_(self, *args, **keywords):
987
+ """
988
+ EXAMPLES::
989
+
990
+ sage: T = OrderedTrees()
991
+ sage: T([]) # indirect doctest
992
+ []
993
+ """
994
+ return self.element_class(self, *args, **keywords)
995
+
996
+ Element = OrderedTree
997
+
998
+
999
+ from sage.misc.lazy_attribute import lazy_attribute
1000
+ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
1001
+ from sage.combinat.composition import Compositions
1002
+ #################################################################
1003
+ # Enumerated set of binary trees of a given size
1004
+ #################################################################
1005
+
1006
+
1007
+ class OrderedTrees_size(OrderedTrees):
1008
+ """
1009
+ The enumerated sets of binary trees of a given size.
1010
+
1011
+ EXAMPLES::
1012
+
1013
+ sage: S = OrderedTrees(3); S
1014
+ Ordered trees of size 3
1015
+ sage: S.cardinality()
1016
+ 2
1017
+ sage: S.list()
1018
+ [[[], []], [[[]]]]
1019
+ """
1020
+
1021
+ def __init__(self, size):
1022
+ """
1023
+ TESTS::
1024
+
1025
+ sage: from sage.combinat.ordered_tree import OrderedTrees_size
1026
+ sage: TestSuite(OrderedTrees_size(0)).run()
1027
+ sage: for i in range(6): TestSuite(OrderedTrees_size(i)).run()
1028
+ """
1029
+ super().__init__(category=FiniteEnumeratedSets())
1030
+ self._size = size
1031
+
1032
+ def _repr_(self):
1033
+ """
1034
+ TESTS::
1035
+
1036
+ sage: OrderedTrees(3) # indirect doctest
1037
+ Ordered trees of size 3
1038
+ """
1039
+ return "Ordered trees of size {}".format(self._size)
1040
+
1041
+ def __contains__(self, x):
1042
+ """
1043
+ TESTS::
1044
+
1045
+ sage: T = OrderedTrees(3)
1046
+ sage: 1 in T
1047
+ False
1048
+ sage: T([[],[]]) in T
1049
+ True
1050
+ """
1051
+ return isinstance(x, self.element_class) and x.node_number() == self._size
1052
+
1053
+ def _an_element_(self):
1054
+ """
1055
+ TESTS::
1056
+
1057
+ sage: OrderedTrees(3).an_element() # indirect doctest
1058
+ [[], []]
1059
+ """
1060
+ if self._size == 0:
1061
+ raise EmptySetError
1062
+ return self.first()
1063
+
1064
+ def cardinality(self):
1065
+ """
1066
+ The cardinality of ``self``.
1067
+
1068
+ This is a Catalan number.
1069
+
1070
+ TESTS::
1071
+
1072
+ sage: OrderedTrees(0).cardinality()
1073
+ 0
1074
+ sage: OrderedTrees(1).cardinality()
1075
+ 1
1076
+ sage: OrderedTrees(6).cardinality()
1077
+ 42
1078
+ """
1079
+ if self._size == 0:
1080
+ return Integer(0)
1081
+ else:
1082
+ from .combinat import catalan_number
1083
+ return catalan_number(self._size - 1)
1084
+
1085
+ def random_element(self):
1086
+ """
1087
+ Return a random ``OrderedTree`` with uniform probability.
1088
+
1089
+ This method generates a random ``DyckWord`` and then uses a
1090
+ bijection between Dyck words and ordered trees.
1091
+
1092
+ EXAMPLES::
1093
+
1094
+ sage: OrderedTrees(5).random_element() # random # needs sage.combinat
1095
+ [[[], []], []]
1096
+ sage: OrderedTrees(0).random_element()
1097
+ Traceback (most recent call last):
1098
+ ...
1099
+ EmptySetError: there are no ordered trees of size 0
1100
+ sage: OrderedTrees(1).random_element() # needs sage.combinat
1101
+ []
1102
+
1103
+ TESTS::
1104
+
1105
+ sage: all(OrderedTrees(10).random_element() in OrderedTrees(10) # needs sage.combinat
1106
+ ....: for i in range(20))
1107
+ True
1108
+ """
1109
+ if self._size == 0:
1110
+ raise EmptySetError("there are no ordered trees of size 0")
1111
+ return CompleteDyckWords_size(self._size - 1).random_element().to_ordered_tree()
1112
+
1113
+ def __iter__(self):
1114
+ """
1115
+ A basic generator.
1116
+
1117
+ .. TODO:: could be optimized.
1118
+
1119
+ TESTS::
1120
+
1121
+ sage: OrderedTrees(0).list()
1122
+ []
1123
+ sage: OrderedTrees(1).list()
1124
+ [[]]
1125
+ sage: OrderedTrees(2).list()
1126
+ [[[]]]
1127
+ sage: OrderedTrees(3).list()
1128
+ [[[], []], [[[]]]]
1129
+ sage: OrderedTrees(4).list()
1130
+ [[[], [], []], [[], [[]]], [[[]], []], [[[], []]], [[[[]]]]]
1131
+ """
1132
+ if self._size == 0:
1133
+ return
1134
+ for c in Compositions(self._size - 1):
1135
+ for lst in itertools.product(*[self.__class__(i) for i in c]):
1136
+ yield self._element_constructor_(lst)
1137
+
1138
+ @lazy_attribute
1139
+ def _parent_for(self):
1140
+ """
1141
+ Return the parent of the element generated by ``self``.
1142
+
1143
+ TESTS::
1144
+
1145
+ sage: OrderedTrees(3)._parent_for
1146
+ Ordered trees
1147
+ """
1148
+ return OrderedTrees_all()
1149
+
1150
+ @lazy_attribute
1151
+ def element_class(self):
1152
+ """
1153
+ The class of the element of ``self``.
1154
+
1155
+ EXAMPLES::
1156
+
1157
+ sage: from sage.combinat.ordered_tree import OrderedTrees_size, OrderedTrees_all
1158
+ sage: S = OrderedTrees_size(3)
1159
+ sage: S.element_class is OrderedTrees().element_class
1160
+ True
1161
+ sage: S.first().__class__ == OrderedTrees_all().first().__class__
1162
+ True
1163
+ """
1164
+ return self._parent_for.element_class
1165
+
1166
+ def _element_constructor_(self, *args, **keywords):
1167
+ """
1168
+ EXAMPLES::
1169
+
1170
+ sage: S = OrderedTrees(0)
1171
+ sage: S([]) # indirect doctest
1172
+ Traceback (most recent call last):
1173
+ ...
1174
+ ValueError: wrong number of nodes
1175
+
1176
+ sage: S = OrderedTrees(1) # indirect doctest
1177
+ sage: S([])
1178
+ []
1179
+ """
1180
+ res = self.element_class(self._parent_for, *args, **keywords)
1181
+ if res.node_number() != self._size:
1182
+ raise ValueError("wrong number of nodes")
1183
+ return res
1184
+
1185
+
1186
+ class LabelledOrderedTree(AbstractLabelledClonableTree, OrderedTree):
1187
+ """
1188
+ Labelled ordered trees.
1189
+
1190
+ A labelled ordered tree is an ordered tree with a label attached at each
1191
+ node.
1192
+
1193
+ INPUT:
1194
+
1195
+ - ``children`` -- list or tuple or more generally any iterable
1196
+ of trees or object convertible to trees
1197
+ - ``label`` -- any Sage object (default: ``None``)
1198
+
1199
+ EXAMPLES::
1200
+
1201
+ sage: x = LabelledOrderedTree([], label = 3); x
1202
+ 3[]
1203
+ sage: LabelledOrderedTree([x, x, x], label = 2)
1204
+ 2[3[], 3[], 3[]]
1205
+ sage: LabelledOrderedTree((x, x, x), label = 2)
1206
+ 2[3[], 3[], 3[]]
1207
+ sage: LabelledOrderedTree([[],[[], []]], label = 3)
1208
+ 3[None[], None[None[], None[]]]
1209
+ """
1210
+ @staticmethod
1211
+ def __classcall_private__(cls, *args, **opts):
1212
+ """
1213
+ Ensure that trees created by the sets and directly are the same and
1214
+ that they are instances of :class:`LabelledOrderedTree`
1215
+
1216
+ TESTS::
1217
+
1218
+ sage: issubclass(LabelledOrderedTrees().element_class, LabelledOrderedTree)
1219
+ True
1220
+ sage: t0 = LabelledOrderedTree([[],[[], []]], label = 3)
1221
+ sage: t0.parent()
1222
+ Labelled ordered trees
1223
+ sage: type(t0)
1224
+ <class 'sage.combinat.ordered_tree.LabelledOrderedTrees_with_category.element_class'>
1225
+ """
1226
+ return cls._auto_parent.element_class(cls._auto_parent, *args, **opts)
1227
+
1228
+ @lazy_class_attribute
1229
+ def _auto_parent(cls):
1230
+ """
1231
+ The automatic parent of the elements of this class.
1232
+
1233
+ When calling the constructor of an element of this class, one needs a
1234
+ parent. This class attribute specifies which parent is used.
1235
+
1236
+ EXAMPLES::
1237
+
1238
+ sage: LabelledOrderedTree._auto_parent
1239
+ Labelled ordered trees
1240
+ sage: LabelledOrderedTree([], label = 3).parent()
1241
+ Labelled ordered trees
1242
+ """
1243
+ return LabelledOrderedTrees()
1244
+
1245
+ _UnLabelled = OrderedTree
1246
+
1247
+ __hash__ = ClonableArray.__hash__
1248
+
1249
+ @combinatorial_map(order=2, name="Left-right symmetry")
1250
+ def left_right_symmetry(self):
1251
+ r"""
1252
+ Return the symmetric tree of ``self``.
1253
+
1254
+ The symmetric tree `s(T)` of a labelled ordered tree `T` is
1255
+ defined as follows:
1256
+ If `T` is a labelled ordered tree with children
1257
+ `C_1, C_2, \ldots, C_k` (listed from left to right), then the
1258
+ symmetric tree `s(T)` of `T` is a labelled ordered tree with
1259
+ children `s(C_k), s(C_{k-1}), \ldots, s(C_1)` (from left to
1260
+ right), and with the same root label as `T`.
1261
+
1262
+ .. NOTE::
1263
+
1264
+ If you have a subclass of :meth:`LabelledOrderedTree`
1265
+ which also inherits from another subclass of
1266
+ :meth:`OrderedTree` which does not come with a labelling,
1267
+ then (depending on the method resolution order) it might
1268
+ happen that this method gets overridden by an
1269
+ implementation from that other subclass, and thus forgets
1270
+ about the labels. In this case you need to manually
1271
+ override this method on your subclass.
1272
+
1273
+ EXAMPLES::
1274
+
1275
+ sage: L2 = LabelledOrderedTree([], label=2)
1276
+ sage: L3 = LabelledOrderedTree([], label=3)
1277
+ sage: T23 = LabelledOrderedTree([L2, L3], label=4)
1278
+ sage: T23.left_right_symmetry()
1279
+ 4[3[], 2[]]
1280
+ sage: T223 = LabelledOrderedTree([L2, T23], label=17)
1281
+ sage: T223.left_right_symmetry()
1282
+ 17[4[3[], 2[]], 2[]]
1283
+ sage: T223.left_right_symmetry().left_right_symmetry() == T223
1284
+ True
1285
+ """
1286
+ children = [c.left_right_symmetry() for c in self]
1287
+ children.reverse()
1288
+ return LabelledOrderedTree(children, label=self.label())
1289
+
1290
+ def sort_key(self):
1291
+ """
1292
+ Return a tuple of nonnegative integers encoding the labelled
1293
+ tree ``self``.
1294
+
1295
+ The first entry of the tuple is a pair consisting of the
1296
+ number of children of the root and the label of the root. Then
1297
+ the rest of the tuple is the concatenation of the tuples
1298
+ associated to these children (we view the children of
1299
+ a tree as trees themselves) from left to right.
1300
+
1301
+ This tuple characterizes the labelled tree uniquely, and can
1302
+ be used to sort the labelled ordered trees provided that the
1303
+ labels belong to a type which is totally ordered.
1304
+
1305
+ .. WARNING::
1306
+
1307
+ This method overrides :meth:`OrderedTree.sort_key`
1308
+ and returns a result different from what the latter
1309
+ would return, as it wants to encode the whole labelled
1310
+ tree including its labelling rather than just the
1311
+ unlabelled tree. Therefore, be careful with using this
1312
+ method on subclasses of :class:`LabelledOrderedTree`;
1313
+ under some circumstances they could inherit it from
1314
+ another superclass instead of from :class:`OrderedTree`,
1315
+ which would cause the method to forget the labelling.
1316
+ See the docstring of :meth:`OrderedTree.sort_key`.
1317
+
1318
+ EXAMPLES::
1319
+
1320
+ sage: L2 = LabelledOrderedTree([], label=2)
1321
+ sage: L3 = LabelledOrderedTree([], label=3)
1322
+ sage: T23 = LabelledOrderedTree([L2, L3], label=4)
1323
+ sage: T23.sort_key()
1324
+ ((2, 4), (0, 2), (0, 3))
1325
+ sage: T32 = LabelledOrderedTree([L3, L2], label=5)
1326
+ sage: T32.sort_key()
1327
+ ((2, 5), (0, 3), (0, 2))
1328
+ sage: T23322 = LabelledOrderedTree([T23, T32, L2], label=14)
1329
+ sage: T23322.sort_key()
1330
+ ((3, 14), (2, 4), (0, 2), (0, 3), (2, 5), (0, 3), (0, 2), (0, 2))
1331
+ """
1332
+ l = len(self)
1333
+ if l == 0:
1334
+ return ((0, self.label()),)
1335
+ resu = [(l, self.label())] + [u for t in self for u in t.sort_key()]
1336
+ return tuple(resu)
1337
+
1338
+
1339
+ class LabelledOrderedTrees(UniqueRepresentation, Parent):
1340
+ """
1341
+ This is a parent stub to serve as a factory class for trees with various
1342
+ label constraints.
1343
+
1344
+ EXAMPLES::
1345
+
1346
+ sage: LOT = LabelledOrderedTrees(); LOT
1347
+ Labelled ordered trees
1348
+ sage: x = LOT([], label = 3); x
1349
+ 3[]
1350
+ sage: x.parent() is LOT
1351
+ True
1352
+ sage: y = LOT([x, x, x], label = 2); y
1353
+ 2[3[], 3[], 3[]]
1354
+ sage: y.parent() is LOT
1355
+ True
1356
+ """
1357
+
1358
+ def __init__(self, category=None):
1359
+ """
1360
+ TESTS::
1361
+
1362
+ sage: TestSuite(LabelledOrderedTrees()).run()
1363
+ """
1364
+ if category is None:
1365
+ category = Sets()
1366
+ Parent.__init__(self, category=category)
1367
+
1368
+ def _repr_(self):
1369
+ """
1370
+ TESTS::
1371
+
1372
+ sage: LabelledOrderedTrees() # indirect doctest
1373
+ Labelled ordered trees
1374
+ """
1375
+ return "Labelled ordered trees"
1376
+
1377
+ def cardinality(self):
1378
+ """
1379
+ Return the cardinality of ``self``.
1380
+
1381
+ EXAMPLES::
1382
+
1383
+ sage: LabelledOrderedTrees().cardinality()
1384
+ +Infinity
1385
+ """
1386
+ return Infinity
1387
+
1388
+ def _an_element_(self):
1389
+ """
1390
+ Return a labelled ordered tree.
1391
+
1392
+ EXAMPLES::
1393
+
1394
+ sage: LabelledOrderedTrees().an_element() # indirect doctest
1395
+ toto[3[], 42[3[], 3[]], 5[None[]]]
1396
+ """
1397
+ LT = self._element_constructor_
1398
+ t = LT([], label=3)
1399
+ t1 = LT([t, t], label=42)
1400
+ t2 = LT([[]], label=5)
1401
+ return LT([t, t1, t2], label='toto')
1402
+
1403
+ def _element_constructor_(self, *args, **keywords):
1404
+ """
1405
+ EXAMPLES::
1406
+
1407
+ sage: T = LabelledOrderedTrees()
1408
+ sage: T([], label=2) # indirect doctest
1409
+ 2[]
1410
+ """
1411
+ return self.element_class(self, *args, **keywords)
1412
+
1413
+ def unlabelled_trees(self):
1414
+ """
1415
+ Return the set of unlabelled trees associated to ``self``.
1416
+
1417
+ This is the set of ordered trees, since ``self`` is the set of
1418
+ labelled ordered trees.
1419
+
1420
+ EXAMPLES::
1421
+
1422
+ sage: LabelledOrderedTrees().unlabelled_trees()
1423
+ Ordered trees
1424
+ """
1425
+ return OrderedTrees_all()
1426
+
1427
+ def labelled_trees(self):
1428
+ """
1429
+ Return the set of labelled trees associated to ``self``.
1430
+
1431
+ This is precisely ``self``, because ``self`` already is the set
1432
+ of labelled ordered trees.
1433
+
1434
+ EXAMPLES::
1435
+
1436
+ sage: LabelledOrderedTrees().labelled_trees()
1437
+ Labelled ordered trees
1438
+ sage: LOT = LabelledOrderedTrees()
1439
+ sage: x = LOT([], label = 3)
1440
+ sage: y = LOT([x, x, x], label = 2)
1441
+ sage: y.canonical_labelling()
1442
+ 1[2[], 3[], 4[]]
1443
+ """
1444
+ return self
1445
+
1446
+ Element = LabelledOrderedTree