Skip to content

Commit

Permalink
sagemathgh-37781: SetPartition return empty iterator instead of err…
Browse files Browse the repository at this point in the history
…oring out in degenerate cases

    
<!-- ^ Please provide a concise and informative title. -->
<!-- ^ Don't put issue numbers in the title, do this in the PR
description below. -->
<!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method
to calculate 1 + 2". -->
<!-- v Describe your changes below in detail. -->
<!-- v Why is this change required? What problem does it solve? -->
<!-- v If this PR resolves an open issue, please link to it here. For
example, "Fixes sagemath#12345". -->

Replaced the error raised by `SetPartition` in a degenerate case (see
below) by an empty iterator, to match the behaviour of similar functions
such as `Partitions` and `OrderedSetPartitions`. Old behaviour:
```Python
sage: list( Partitions(3,length=4) )
[]
sage: list( OrderedSetPartitions(range(3),4) )
[]
sage: list( SetPartitions(range(3),4) )
...
ValueError: part must be <= len(set)
```
New behaviour
```Python
sage: list( SetPartitions(range(3),4) )
[]
```
This solves issue sagemath#37643.

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation accordingly.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->
    
URL: sagemath#37781
Reported by: Nolord
Reviewer(s): Travis Scrimshaw
  • Loading branch information
Release Manager committed Apr 20, 2024
2 parents 9474570 + 6683de7 commit e5758a0
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 5 deletions.
16 changes: 11 additions & 5 deletions src/sage/combinat/set_partition.py
Original file line number Diff line number Diff line change
Expand Up @@ -2034,6 +2034,14 @@ class SetPartitions(UniqueRepresentation, Parent):
sage: SetPartitions('aabcd').cardinality() # needs sage.libs.flint
15
If the number of parts exceeds the length of the set,
an empty iterator is returned (:issue:`37643`)::
sage: SetPartitions(range(3), 4).list()
[]
sage: SetPartitions('abcd', 6).list()
[]
REFERENCES:
- :wikipedia:`Partition_of_a_set`
Expand Down Expand Up @@ -2062,18 +2070,16 @@ def __classcall_private__(cls, s=None, part=None):
pass
s = frozenset(s)

if part is not None:
if part is None:
return SetPartitions_set(s)
else:
if isinstance(part, (int, Integer)):
if len(s) < part:
raise ValueError("part must be <= len(set)")
return SetPartitions_setn(s, part)
else:
part = sorted(part, reverse=True)
if part not in Partitions(len(s)):
raise ValueError("part must be an integer partition of %s" % len(s))
return SetPartitions_setparts(s, Partition(part))
else:
return SetPartitions_set(s)

def __contains__(self, x):
"""
Expand Down
2 changes: 2 additions & 0 deletions src/sage/combinat/set_partition_iterator.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,7 @@ def set_partition_iterator_blocks(base_set, Py_ssize_t k):
cdef Py_ssize_t n = len(base)
cdef list a = list(range(n))
# TODO: implement _set_partition_block_gen as an iterative algorithm
if n < k:
return
for P in _set_partition_block_gen(n, k, a):
yield from_word(<list> P, base)

0 comments on commit e5758a0

Please sign in to comment.