From e94d3fb7efd13fd7c34abba38d6a80ce4a1a00f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 4 Nov 2025 19:20:04 +0100 Subject: [PATCH 1/2] some typing annotations in combinat/ --- src/sage/combinat/alternating_sign_matrix.py | 2 +- src/sage/combinat/binary_tree.py | 10 +- src/sage/combinat/cartesian_product.py | 2 +- .../cluster_algebra_quiver/cluster_seed.py | 92 ++++++++++--------- .../quiver_mutation_type.py | 19 ++-- src/sage/combinat/colored_permutations.py | 2 +- src/sage/combinat/composition_tableau.py | 4 +- src/sage/combinat/constellation.py | 15 ++- src/sage/combinat/crystals/littelmann_path.py | 2 +- src/sage/combinat/crystals/pbw_datum.pyx | 5 +- src/sage/combinat/debruijn_sequence.pyx | 3 +- src/sage/combinat/diagram_algebras.py | 6 +- src/sage/combinat/k_tableau.py | 2 +- src/sage/combinat/posets/bubble_shuffle.py | 6 +- src/sage/combinat/posets/hasse_diagram.py | 2 +- .../combinat/posets/hochschild_lattice.py | 4 +- src/sage/combinat/rooted_tree.py | 2 +- src/sage/combinat/set_partition_ordered.py | 4 +- src/sage/combinat/skew_partition.py | 10 +- src/sage/combinat/tiling.py | 4 +- 20 files changed, 98 insertions(+), 98 deletions(-) diff --git a/src/sage/combinat/alternating_sign_matrix.py b/src/sage/combinat/alternating_sign_matrix.py index 60be9082232..5df9a34cc68 100644 --- a/src/sage/combinat/alternating_sign_matrix.py +++ b/src/sage/combinat/alternating_sign_matrix.py @@ -892,7 +892,7 @@ def number_of_negative_ones(self): number_negative_ones = number_of_negative_ones - def is_permutation(self): + def is_permutation(self) -> bool: """ Return ``True`` if ``self`` is a permutation matrix and ``False`` otherwise. diff --git a/src/sage/combinat/binary_tree.py b/src/sage/combinat/binary_tree.py index 7fdd5dbdadd..c01a93631db 100644 --- a/src/sage/combinat/binary_tree.py +++ b/src/sage/combinat/binary_tree.py @@ -644,7 +644,7 @@ def node_to_str(bt): t_repr._baseline = t_repr._h - 1 return t_repr - def _sort_key(self): + def _sort_key(self) -> tuple: """ Return a tuple of nonnegative integers encoding the binary tree ``self``. @@ -673,7 +673,7 @@ def _sort_key(self): resu = [l] + [u for t in self for u in t._sort_key()] return tuple(resu) - def is_empty(self): + def is_empty(self) -> bool: """ Return whether ``self`` is empty. @@ -3619,7 +3619,7 @@ def builder(i, p): for p in shuffle(W(l), W([shift + ri for ri in r])): yield builder(shift, p) - def is_full(self): + def is_full(self) -> bool: r""" Return ``True`` if ``self`` is full, else return ``False``. @@ -3789,7 +3789,7 @@ def prune(self): return BinaryTree() return BinaryTree([self[0].prune(), self[1].prune()]) - def is_perfect(self): + def is_perfect(self) -> bool: r""" Return ``True`` if ``self`` is perfect, else return ``False``. @@ -3836,7 +3836,7 @@ def is_perfect(self): """ return 2 ** self.depth() - 1 == self.node_number() - def is_complete(self): + def is_complete(self) -> bool: r""" Return ``True`` if ``self`` is complete, else return ``False``. diff --git a/src/sage/combinat/cartesian_product.py b/src/sage/combinat/cartesian_product.py index 7173a72a1c4..129840d98dc 100644 --- a/src/sage/combinat/cartesian_product.py +++ b/src/sage/combinat/cartesian_product.py @@ -271,7 +271,7 @@ def __iterate__(self): """ return iter(self._mrange) - def is_finite(self): + def is_finite(self) -> bool: """ The Cartesian product is finite if all of its inputs are finite, or if any input is empty. diff --git a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py index 21e2405ee50..918b150d373 100644 --- a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py +++ b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py @@ -4833,7 +4833,7 @@ def SetToPath(T): return ans -def is_LeeLiZel_allowable(T, n, m, b, c): +def is_LeeLiZel_allowable(T, n, m, b, c) -> bool: """ Check if the subset `T` contributes to the computation of the greedy element `x[m,n]` in the rank two `(b,c)`-cluster algebra. @@ -4848,52 +4848,54 @@ def is_LeeLiZel_allowable(T, n, m, b, c): True """ horiz = set(T).intersection(PathSubset(n, 0)) - vert = set(T).symmetric_difference(horiz) - if len(horiz) == 0 or len(vert) == 0: + if not horiz: return True - else: - Latt = SetToPath(PathSubset(n, m)) - for u in horiz: - from sage.combinat.words.word import Word - from sage.modules.free_module_element import vector - WW = Word(Latt) - LattCycled = vector(WW.conjugate(Latt.index(u))).list() - for v in vert: - uv_okay = False - for A in range(LattCycled.index(v)): - EA = [] - AF = copy(LattCycled) - for i in range(LattCycled.index(v), len(LattCycled)-1): - AF.pop() - AF.reverse() - for i in range(A+1): - EA.append(LattCycled[i]) - AF.pop() - AF.reverse() - nAF1 = 0 - for i in range(len(AF)): - if AF[i] % 2 == 1: - nAF1 += 1 - nAF2 = 0 - for i in range(len(AF)): - if AF[i] % 2 == 0 and AF[i] in vert: - nAF2 += 1 - nEA2 = 0 - for i in range(len(EA)): - if EA[i] % 2 == 0: - nEA2 += 1 - nEA1 = 0 - for i in range(len(EA)): - if EA[i] % 2 == 1 and EA[i] in horiz: - nEA1 += 1 - if nAF1 == b*nAF2 or nEA2 == c*nEA1: - uv_okay = True - if not uv_okay: - return False + vert = set(T).symmetric_difference(horiz) + if not vert: return True - -def get_green_vertices(C): + Latt = SetToPath(PathSubset(n, m)) + for u in horiz: + from sage.combinat.words.word import Word + from sage.modules.free_module_element import vector + WW = Word(Latt) + LattCycled = vector(WW.conjugate(Latt.index(u))).list() + for v in vert: + uv_okay = False + for A in range(LattCycled.index(v)): + EA = [] + AF = copy(LattCycled) + for i in range(LattCycled.index(v), len(LattCycled) - 1): + AF.pop() + AF.reverse() + for i in range(A + 1): + EA.append(LattCycled[i]) + AF.pop() + AF.reverse() + nAF1 = 0 + for i in range(len(AF)): + if AF[i] % 2 == 1: + nAF1 += 1 + nAF2 = 0 + for i in range(len(AF)): + if AF[i] % 2 == 0 and AF[i] in vert: + nAF2 += 1 + nEA2 = 0 + for i in range(len(EA)): + if EA[i] % 2 == 0: + nEA2 += 1 + nEA1 = 0 + for i in range(len(EA)): + if EA[i] % 2 == 1 and EA[i] in horiz: + nEA1 += 1 + if nAF1 == b * nAF2 or nEA2 == c * nEA1: + uv_okay = True + if not uv_okay: + return False + return True + + +def get_green_vertices(C) -> list: r""" Get the green vertices from a matrix. @@ -4914,7 +4916,7 @@ def get_green_vertices(C): return [i for i, v in enumerate(C.columns()) if any(x > 0 for x in v)] -def get_red_vertices(C): +def get_red_vertices(C) -> list: r""" Get the red vertices from a matrix. diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py index 3c3acd40e3b..5e054831b42 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py @@ -885,7 +885,7 @@ def cartan_matrix(self): # return CartanMatrix(cmat) return cmat - def is_irreducible(self): + def is_irreducible(self) -> bool: """ Return ``True`` if ``self`` is irreducible. @@ -897,7 +897,7 @@ def is_irreducible(self): """ return self._info['irreducible'] - def is_mutation_finite(self): + def is_mutation_finite(self) -> bool: """ Return ``True`` if ``self`` is of finite mutation type. @@ -912,7 +912,7 @@ def is_mutation_finite(self): """ return self._info['mutation_finite'] - def is_simply_laced(self): + def is_simply_laced(self) -> bool: """ Return ``True`` if ``self`` is simply laced. @@ -935,7 +935,7 @@ def is_simply_laced(self): """ return self._info['simply_laced'] - def is_skew_symmetric(self): + def is_skew_symmetric(self) -> bool: """ Return ``True`` if the B-matrix of ``self`` is skew-symmetric. @@ -955,7 +955,7 @@ def is_skew_symmetric(self): """ return self._info['skew_symmetric'] - def is_finite(self): + def is_finite(self) -> bool: """ Return ``True`` if ``self`` is of finite type. @@ -974,7 +974,7 @@ def is_finite(self): """ return self._info['finite'] - def is_affine(self): + def is_affine(self) -> bool: """ Return ``True`` if ``self`` is of affine type. @@ -990,10 +990,9 @@ def is_affine(self): """ if self.is_irreducible(): return self._info['affine'] - else: - return False + return False - def is_elliptic(self): + def is_elliptic(self) -> bool: """ Return ``True`` if ``self`` is of elliptic type. @@ -1012,7 +1011,7 @@ def is_elliptic(self): else: return False - def properties(self): + def properties(self) -> None: """ Print a scheme of all properties of ``self``. diff --git a/src/sage/combinat/colored_permutations.py b/src/sage/combinat/colored_permutations.py index 3c3c165c860..c3992a30bf6 100644 --- a/src/sage/combinat/colored_permutations.py +++ b/src/sage/combinat/colored_permutations.py @@ -1126,7 +1126,7 @@ def fixed_point_polynomial(self, q=None): q = PolynomialRing(ZZ, 'q').gen(0) return prod(q + d - 1 for d in self.degrees()) - def is_well_generated(self): + def is_well_generated(self) -> bool: r""" Return if ``self`` is a well-generated complex reflection group. diff --git a/src/sage/combinat/composition_tableau.py b/src/sage/combinat/composition_tableau.py index 972aabe777d..d982ab9db8f 100644 --- a/src/sage/combinat/composition_tableau.py +++ b/src/sage/combinat/composition_tableau.py @@ -199,7 +199,7 @@ def weight(self): for row in self: for i in row: w[i] += 1 - return Composition([w[i] for i in range(1, self.size()+1)]) + return Composition([w[i] for i in range(1, self.size() + 1)]) def descent_set(self): r""" @@ -253,7 +253,7 @@ def shape_partition(self): """ return Partition(sorted((len(row) for row in self), reverse=True)) - def is_standard(self): + def is_standard(self) -> bool: r""" Return ``True`` if ``self`` is a standard composition tableau and ``False`` otherwise. diff --git a/src/sage/combinat/constellation.py b/src/sage/combinat/constellation.py index 649c4b6dbc0..75153176bd8 100644 --- a/src/sage/combinat/constellation.py +++ b/src/sage/combinat/constellation.py @@ -232,7 +232,7 @@ def __hash__(self): raise ValueError("cannot hash mutable constellation") return hash(tuple(self._g)) - def set_immutable(self): + def set_immutable(self) -> None: r""" Do nothing, as ``self`` is already immutable. @@ -245,7 +245,7 @@ def set_immutable(self): """ self._mutable = False - def is_mutable(self): + def is_mutable(self) -> bool: r""" Return ``False`` as ``self`` is immutable. @@ -429,7 +429,7 @@ def mutable_copy(self): # GENERAL PROPERTIES - def is_connected(self): + def is_connected(self) -> bool: r""" Test of connectedness. @@ -444,10 +444,9 @@ def is_connected(self): """ if self._connected: return True - else: - return perms_are_connected(self._g, self.degree()) + return perms_are_connected(self._g, self.degree()) - def connected_components(self): + def connected_components(self) -> list: """ Return the connected components. @@ -946,7 +945,7 @@ def __init__(self, length, degree, sym=None, connected=True): self._connected = bool(connected) - def is_empty(self): + def is_empty(self) -> bool: r""" Return whether this set of constellations is empty. @@ -961,7 +960,7 @@ def is_empty(self): """ return self._connected and self._length == 1 and self._degree > 1 - def __contains__(self, elt): + def __contains__(self, elt) -> bool: r""" TESTS:: diff --git a/src/sage/combinat/crystals/littelmann_path.py b/src/sage/combinat/crystals/littelmann_path.py index 7e2f9fe5aca..83039877eff 100644 --- a/src/sage/combinat/crystals/littelmann_path.py +++ b/src/sage/combinat/crystals/littelmann_path.py @@ -835,7 +835,7 @@ def weight(x): return sum(q**(c[0].energy_function()) * B.sum(B(weight(b)) for b in c) for c in C) return B.sum(q**(b.energy_function()) * B(weight(b)) for b in self) - def is_perfect(self, level=1): + def is_perfect(self, level=1) -> bool: r""" Check whether the crystal ``self`` is perfect (of level ``level``). diff --git a/src/sage/combinat/crystals/pbw_datum.pyx b/src/sage/combinat/crystals/pbw_datum.pyx index 3e0c521a0f3..2a3d449083f 100644 --- a/src/sage/combinat/crystals/pbw_datum.pyx +++ b/src/sage/combinat/crystals/pbw_datum.pyx @@ -86,10 +86,11 @@ class PBWDatum(): self.long_word == other_PBWDatum.long_word and self.lusztig_datum == other_PBWDatum.lusztig_datum) - def is_equivalent_to(self, other_pbw_datum): + def is_equivalent_to(self, other_pbw_datum) -> bool: r""" Return whether ``self`` is equivalent to ``other_pbw_datum``. - modulo the tropical Plücker relations. + + Here equivalent means modulo the tropical Plücker relations. EXAMPLES:: diff --git a/src/sage/combinat/debruijn_sequence.pyx b/src/sage/combinat/debruijn_sequence.pyx index 1182abc022e..b762594b1fb 100644 --- a/src/sage/combinat/debruijn_sequence.pyx +++ b/src/sage/combinat/debruijn_sequence.pyx @@ -111,7 +111,7 @@ cdef gen(int t, int p, k, n): gen(t + 1, t, k, n) -def is_debruijn_sequence(seq, k, n): +def is_debruijn_sequence(seq, k, n) -> bool: r""" Given a sequence of integer elements in `0, \ldots, k-1`, tests whether it corresponds to a De Bruijn sequence of parameters `k` and `n`. @@ -133,7 +133,6 @@ def is_debruijn_sequence(seq, k, n): sage: is_debruijn_sequence([1] + s[1:], 2, 3) False """ - if k == 1: return seq == [0] diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index a81769c841d..813e9a849f4 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -565,7 +565,7 @@ def order(self): """ return self.parent().order - def is_planar(self): + def is_planar(self) -> bool: r""" Test if the diagram ``self`` is planar. @@ -1108,7 +1108,7 @@ def perm(self): std[short_form.index(i)] = j return std - def is_elementary_symmetric(self): + def is_elementary_symmetric(self) -> bool: r""" Check if is elementary symmetric. @@ -5575,7 +5575,7 @@ def _acted_upon_(self, scalar, self_on_left=True): ######################################################################### -def is_planar(sp): +def is_planar(sp) -> bool: r""" Return ``True`` if the diagram corresponding to the set partition ``sp`` is planar; otherwise, return ``False``. diff --git a/src/sage/combinat/k_tableau.py b/src/sage/combinat/k_tableau.py index a52d3438994..0e6d6e29597 100644 --- a/src/sage/combinat/k_tableau.py +++ b/src/sage/combinat/k_tableau.py @@ -2565,7 +2565,7 @@ def _is_valid_standard( self ): Tsizes = [Core(lam, self.k + 1).length() for lam in Tshapes] return all(Tsizes[i] == Tsizes[i+1]-1 for i in range(len(Tsizes)-1)) - def is_column_strict_with_weight( self, mu ): + def is_column_strict_with_weight(self, mu) -> bool: """ Test if ``self`` is a column strict tableau with respect to the weight ``mu``. diff --git a/src/sage/combinat/posets/bubble_shuffle.py b/src/sage/combinat/posets/bubble_shuffle.py index 92dd66c72fa..088b601147f 100644 --- a/src/sage/combinat/posets/bubble_shuffle.py +++ b/src/sage/combinat/posets/bubble_shuffle.py @@ -17,7 +17,7 @@ from collections.abc import Iterator from sage.categories.finite_lattice_posets import FiniteLatticePosets -from sage.combinat.posets.lattices import LatticePoset +from sage.combinat.posets.lattices import LatticePoset, FiniteLatticePoset from sage.combinat.subset import subsets from sage.combinat.shuffle import ShuffleProduct from sage.graphs.digraph import DiGraph @@ -142,7 +142,7 @@ def bubble_coverings(m, n, mot, transpose=True) -> Iterator[tuple[int, ...]]: yield tuple(mot2) -def BubblePoset(m, n) -> LatticePoset: +def BubblePoset(m, n) -> FiniteLatticePoset: r""" Return the Bubble lattice `B_{m,n}`. @@ -174,7 +174,7 @@ def BubblePoset(m, n) -> LatticePoset: return LatticePoset(dg, category=cat) -def ShufflePoset(m, n) -> LatticePoset: +def ShufflePoset(m, n) -> FiniteLatticePoset: r""" Return the Shuffle lattice `S_{m,n}`. diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 4dc1085fe8a..30b468cca18 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -2544,7 +2544,7 @@ def is_linear_interval(self, t_min, t_max) -> bool: return True return False - def diamonds(self) -> tuple[list[tuple[int]], bool]: + def diamonds(self) -> tuple[list[tuple[int, int, int, int]], bool]: r""" Return the list of diamonds of ``self``. diff --git a/src/sage/combinat/posets/hochschild_lattice.py b/src/sage/combinat/posets/hochschild_lattice.py index f23f76229f3..4e423e46e17 100644 --- a/src/sage/combinat/posets/hochschild_lattice.py +++ b/src/sage/combinat/posets/hochschild_lattice.py @@ -19,12 +19,12 @@ from collections.abc import Iterator from sage.categories.finite_lattice_posets import FiniteLatticePosets -from sage.combinat.posets.lattices import LatticePoset +from sage.combinat.posets.lattices import FiniteLatticePoset, LatticePoset from sage.graphs.digraph import DiGraph from sage.topology.simplicial_complex import SimplicialComplex -def hochschild_lattice(n) -> LatticePoset: +def hochschild_lattice(n) -> FiniteLatticePoset: r""" Return the Hochschild lattice `H_n`. diff --git a/src/sage/combinat/rooted_tree.py b/src/sage/combinat/rooted_tree.py index b7a9e9a9090..6c54e8f1b5d 100644 --- a/src/sage/combinat/rooted_tree.py +++ b/src/sage/combinat/rooted_tree.py @@ -300,7 +300,7 @@ def normalize(self): # ensure unique representation self.set_immutable() - def is_empty(self): + def is_empty(self) -> bool: r""" Return if ``self`` is the empty tree. diff --git a/src/sage/combinat/set_partition_ordered.py b/src/sage/combinat/set_partition_ordered.py index cb0ab305b56..0401f1041c3 100644 --- a/src/sage/combinat/set_partition_ordered.py +++ b/src/sage/combinat/set_partition_ordered.py @@ -453,7 +453,7 @@ def finer(self): return FiniteEnumeratedSet([par(sum((list(i) for i in C), [])) for C in product(*[OrderedSetPartitions(X) for X in self])]) - def is_finer(self, co2): + def is_finer(self, co2) -> bool: """ Return ``True`` if the ordered set partition ``self`` is finer than the ordered set partition ``co2``; otherwise, return ``False``. @@ -672,7 +672,7 @@ def strongly_finer(self): return FiniteEnumeratedSet([par(sum((list(P) for P in C), [])) for C in product(*[[buo(X, comp) for comp in Compositions(len(X))] for X in self])]) - def is_strongly_finer(self, co2): + def is_strongly_finer(self, co2) -> bool: r""" Return ``True`` if the ordered set partition ``self`` is strongly finer than the ordered set partition ``co2``; otherwise, return diff --git a/src/sage/combinat/skew_partition.py b/src/sage/combinat/skew_partition.py index 371bf86dd45..250dd0cbd23 100644 --- a/src/sage/combinat/skew_partition.py +++ b/src/sage/combinat/skew_partition.py @@ -589,7 +589,7 @@ def size(self): """ return sum(self.row_lengths()) - def is_connected(self): + def is_connected(self) -> bool: """ Return ``True`` if ``self`` is a connected skew partition. @@ -634,16 +634,16 @@ def overlap(self): sage: SkewPartition([[10,10],[1]]).overlap() 9 """ - p,q = self + p, q = self if len(p) <= 1: from sage.rings.infinity import PlusInfinity return PlusInfinity() if len(q) == 0: return min(p) q = [q[0]] + list(q) - return min(row_lengths_aux([p,q])) + return min(row_lengths_aux([p, q])) - def is_overlap(self, n): + def is_overlap(self, n) -> bool: r""" Return ``True`` if the overlap of ``self`` is at most ``n``. @@ -658,7 +658,7 @@ def is_overlap(self, n): """ return n <= self.overlap() - def is_ribbon(self): + def is_ribbon(self) -> bool: r""" Return ``True`` if and only if ``self`` is a ribbon. diff --git a/src/sage/combinat/tiling.py b/src/sage/combinat/tiling.py index 55f117c43e7..98ef9c6511e 100644 --- a/src/sage/combinat/tiling.py +++ b/src/sage/combinat/tiling.py @@ -1603,7 +1603,7 @@ def __init__(self, pieces, box, rotation=True, self._reusable = reusable self._outside = outside - def _repr_(self): + def _repr_(self) -> str: r""" String representation. @@ -1626,7 +1626,7 @@ def _repr_(self): s += "Reusing pieces allowed: %s" % self._reusable return s - def is_suitable(self): + def is_suitable(self) -> bool: r""" Return whether the volume of the box is equal to sum of the volume of the polyominoes and the number of rows sent to the DLX solver is From 1fae623e0396657cdbbbd16110222d8e89a36d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 4 Nov 2025 20:28:31 +0100 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Vincent Macri --- src/sage/combinat/cluster_algebra_quiver/cluster_seed.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py index 918b150d373..2efceb0abb5 100644 --- a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py +++ b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py @@ -4895,7 +4895,7 @@ def is_LeeLiZel_allowable(T, n, m, b, c) -> bool: return True -def get_green_vertices(C) -> list: +def get_green_vertices(C) -> list[int]: r""" Get the green vertices from a matrix. @@ -4916,7 +4916,7 @@ def get_green_vertices(C) -> list: return [i for i, v in enumerate(C.columns()) if any(x > 0 for x in v)] -def get_red_vertices(C) -> list: +def get_red_vertices(C) -> list[int]: r""" Get the red vertices from a matrix.