Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/doc/en/reference/references/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5881,6 +5881,10 @@ REFERENCES:
Journal of Algorithms, Volume 26, Issue 2, Pages 275 - 290, 1998.
(https://doi.org/10.1006/jagm.1997.0891)

.. [Sq2002] Matthew B. Squire.
*Enumerating the Ideals of a Poset*.
(https://citeseer.ist.psu.edu/465417.html)

.. [SS1983] Shorey and Stewart. "On the Diophantine equation a
x^{2t} + b x^t y + c y^2 = d and pure powers in recurrence
sequences." Mathematica Scandinavica, 1983.
Expand Down
50 changes: 50 additions & 0 deletions src/sage/categories/posets.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,56 @@ def order_filter(self, elements):
[3, 7, 8, 9, 10, 11, 12, 13, 14, 15]
"""

def generate_upsets(U, Y, Poset):
r"""
Enumerates the ideals (upsets) of a given poset.

ALGORITHM:

The algorithm is based on [Sq2002]_.
Current algorithms for genertating ideals require an amortized
time of `O(n)` per ideal in the worst case, where `n` is the number
of elements in the poset. This algorithm generates ideals in an
amortized time of `O(log n)` per ideal.

The function recursively generates all possible upsets (subsets) of
a given set `Y` based on a partially ordered set (Poset), ensuring that
if `Xi < Xm < Xj`, then Xi must also be less than `Xj`. It iterates through
`Y`, partitioning it into two subsets based on the relationship between
elements and yields the resulting upsets.

INPUT:

- ``U`` -- a list of the current upset being constructed.
- ``Y`` -- a list of remaining elements to be considered for inclusion.
- ``Poset`` -- a dictionary representing the partial order.

OUTPUT:

- A subset of `Y` that satisfies the upset condition.

EXAMPLES::

"""
if not Y:
yield U
else:
Xm = Y[len(Y) // 2]
Y1 = []
Y2 = []
for i, Xi in enumerate(Y):
if Poset[(Xi, Xm)] == 1:
U[i] = 0
else:
Y1.append(Xi)
yield from Posets.generate_upsets(U.copy(), Y1, Poset)
for j, Xj in enumerate(Y):
if Poset[(Xm, Xj)] == 1:
U[j] = 1
else:
Y2.append(Xj)
yield from Posets.generate_upsets(U.copy(), Y2, Poset)

def directed_subset(self, elements, direction):
r"""
Return the order filter or the order ideal generated by a
Expand Down