Skip to content

Commit

Permalink
refactor poset examples for better code coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
fchapoton committed Apr 9, 2023
1 parent 27b077e commit 67e7cf9
Showing 1 changed file with 73 additions and 127 deletions.
200 changes: 73 additions & 127 deletions src/sage/combinat/posets/poset_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,51 @@
from sage.categories.finite_lattice_posets import FiniteLatticePosets
from sage.graphs.digraph import DiGraph
from sage.rings.integer import Integer
from sage.sets.non_negative_integers import NonNegativeIntegers


def check_int(n, minimum=0):
"""
Check that ``n`` is an integer at least equal to ``minimum``.
This is a boilerplate function ensuring input safety.
INPUT:
- ``n`` -- anything
- ``minimum`` -- an optional integer (default: 0)
EXAMPLES::
sage: from sage.combinat.posets.poset_examples import check_int
sage: check_int(6, 3)
6
sage: check_int(6)
6
sage: check_int(-1)
Traceback (most recent call last):
...
ValueError: number of elements must be a non-negative integer, not -1
sage: check_int(1, 3)
Traceback (most recent call last):
...
ValueError: number of elements must be an integer at least 3, not 1
sage: check_int('junk')
Traceback (most recent call last):
...
ValueError: number of elements must be a non-negative integer, not junk
"""
if minimum == 0:
msg = "a non-negative integer"
else:
msg = f"an integer at least {minimum}"
if n not in NonNegativeIntegers() or n < minimum:
raise ValueError("number of elements must be " + msg + f", not {n}")
return Integer(n)


class Posets(metaclass=ClasscallMetaclass):
Expand Down Expand Up @@ -155,12 +200,7 @@ def __classcall__(cls, n=None):
"""
if n is None:
return sage.categories.posets.Posets()
try:
n = Integer(n)
except TypeError:
raise TypeError("number of elements must be an integer, not {0}".format(n))
if n < 0:
raise ValueError("number of elements must be non-negative, not {0}".format(n))
n = check_int(n)
return FinitePosets_n(n)

@staticmethod
Expand Down Expand Up @@ -203,12 +243,7 @@ def BooleanLattice(n, facade=None, use_subsets=False):
sage: list(posets.BooleanLattice(1, use_subsets=True))
[{}, {1}]
"""
try:
n = Integer(n)
except TypeError:
raise TypeError("number of elements must be an integer, not {0}".format(n))
if n < 0:
raise ValueError("number of elements must be non-negative, not {0}".format(n))
n = check_int(n)
if n == 0:
if use_subsets:
from sage.sets.set import Set
Expand Down Expand Up @@ -282,12 +317,7 @@ def ChainPoset(n, facade=None):
sage: C.cover_relations()
[[0, 1]]
"""
try:
n = Integer(n)
except TypeError:
raise TypeError("number of elements must be an integer, not {0}".format(n))
if n < 0:
raise ValueError("number of elements must be non-negative, not {0}".format(n))
n = check_int(n)
D = DiGraph([range(n), [[x, x + 1] for x in range(n - 1)]],
format='vertices_and_edges')
return FiniteLatticePoset(hasse_diagram=D,
Expand Down Expand Up @@ -335,12 +365,7 @@ def AntichainPoset(n, facade=None):
sage: C.cover_relations()
[]
"""
try:
n = Integer(n)
except TypeError:
raise TypeError("number of elements must be an integer, not {0}".format(n))
if n < 0:
raise ValueError("number of elements must be non-negative, not {0}".format(n))
n = check_int(n)
return Poset((range(n), []), facade=facade)

@staticmethod
Expand Down Expand Up @@ -398,12 +423,7 @@ def DiamondPoset(n, facade=None):
sage: posets.DiamondPoset(7)
Finite lattice containing 7 elements
"""
try:
n = Integer(n)
except TypeError:
raise TypeError("number of elements must be an integer, not {0}".format(n))
if n <= 2:
raise ValueError("n must be an integer at least 3")
n = check_int(n, 3)
c = [[n - 1] for x in range(n)]
c[0] = [x for x in range(1, n - 1)]
c[n - 1] = []
Expand Down Expand Up @@ -435,12 +455,7 @@ def Crown(n, facade=None):
sage: posets.Crown(3)
Finite poset containing 6 elements
"""
try:
n = Integer(n)
except TypeError:
raise TypeError("number of elements must be an integer, not {0}".format(n))
if n < 2:
raise ValueError("n must be an integer at least 2")
n = check_int(n, 2)
D = {i: [i + n, i + n + 1] for i in range(n - 1)}
D[n - 1] = [n, n + n - 1]
return FinitePoset(hasse_diagram=DiGraph(D), category=FinitePosets(),
Expand Down Expand Up @@ -478,12 +493,7 @@ def DivisorLattice(n, facade=None):
Finite lattice containing 1 elements with distinguished linear extension
"""
from sage.arith.misc import divisors, is_prime
try:
n = Integer(n)
except TypeError:
raise TypeError("number of elements must be an integer, not {0}".format(n))
if n <= 0:
raise ValueError("n must be a positive integer")
n = check_int(n, 1)
Div_n = divisors(n)
hasse = DiGraph([Div_n, lambda a, b: b % a == 0 and is_prime(b // a)])
return FiniteLatticePoset(hasse, elements=Div_n, facade=facade,
Expand Down Expand Up @@ -623,9 +633,7 @@ def IntegerPartitionsDominanceOrder(n):
[[4, 2], [5, 1]],
[[5, 1], [6]]]
"""
from sage.rings.semirings.non_negative_integer_semiring import NN
if n not in NN:
raise ValueError('n must be an integer')
n = check_int(n)
from sage.combinat.partition import Partitions, Partition
return LatticePoset((Partitions(n), Partition.dominates)).dual()

Expand Down Expand Up @@ -663,14 +671,7 @@ def PowerPoset(n):
0
"""
# Todo: Make this faster.

try:
n = Integer(n)
except TypeError:
raise TypeError("parameter n must be an integer, not {0}".format(n))
if n < 0:
raise ValueError("parameter n must be non-negative, not {0}".format(n))

n = check_int(n)
all_pos_n = set()
Pn = list(Posets(n))
for P in Pn:
Expand Down Expand Up @@ -759,16 +760,6 @@ def RandomPoset(n, p):
TESTS::
sage: posets.RandomPoset('junk', 0.5)
Traceback (most recent call last):
...
TypeError: number of elements must be an integer, not junk
sage: posets.RandomPoset(-6, 0.5)
Traceback (most recent call last):
...
ValueError: number of elements must be non-negative, not -6
sage: posets.RandomPoset(6, 'garbage')
Traceback (most recent call last):
...
Expand All @@ -783,13 +774,7 @@ def RandomPoset(n, p):
Finite poset containing 0 elements
"""
from sage.misc.prandom import random

try:
n = Integer(n)
except (TypeError, ValueError):
raise TypeError("number of elements must be an integer, not {0}".format(n))
if n < 0:
raise ValueError("number of elements must be non-negative, not {0}".format(n))
n = check_int(n)
try:
p = float(p)
except (TypeError, ValueError):
Expand Down Expand Up @@ -856,16 +841,6 @@ def RandomLattice(n, p, properties=None):
TESTS::
sage: posets.RandomLattice('junk', 0.5)
Traceback (most recent call last):
...
TypeError: number of elements must be an integer, not junk
sage: posets.RandomLattice(-6, 0.5)
Traceback (most recent call last):
...
ValueError: number of elements must be non-negative, not -6
sage: posets.RandomLattice(6, 'garbage')
Traceback (most recent call last):
...
Expand All @@ -885,13 +860,7 @@ def RandomLattice(n, p, properties=None):
Finite lattice containing 0 elements
"""
from copy import copy

try:
n = Integer(n)
except TypeError:
raise TypeError("number of elements must be an integer, not {0}".format(n))
if n < 0:
raise ValueError("number of elements must be non-negative, not {0}".format(n))
n = check_int(n)
try:
p = float(p)
except Exception:
Expand Down Expand Up @@ -973,10 +942,8 @@ def SetPartitions(n):
sage: posets.SetPartitions(4)
Finite lattice containing 15 elements
"""
from sage.rings.semirings.non_negative_integer_semiring import NN
if n not in NN:
raise ValueError('n must be an integer')
from sage.combinat.set_partition import SetPartitions
n = check_int(n)
S = SetPartitions(n)

def covers(x):
Expand Down Expand Up @@ -1083,12 +1050,7 @@ def StandardExample(n, facade=None):
sage: P(4) < P(3), P(4) > P(3)
(False, False)
"""
try:
n = Integer(n)
except TypeError:
raise TypeError("dimension must be an integer, not {0}".format(n))
if n < 2:
raise ValueError("dimension must be at least 2, not {0}".format(n))
n = check_int(n, 2)
return Poset((range(2*n), [[i, j+n] for i in range(n)
for j in range(n) if i != j]),
facade=facade)
Expand Down Expand Up @@ -1244,17 +1206,20 @@ def TetrahedralPoset(n, *colors, **labels):
sage: tet = posets.TetrahedralPoset(3, 'green','yellow','blue','orange')
sage: ji.is_isomorphic(tet)
True
TESTS::
sage: posets.TetrahedralPoset(4,'scarlet')
Traceback (most recent call last):
...
ValueError: color input must be among: 'green', 'red', 'yellow',
'orange', 'silver', and 'blue'
"""
n = check_int(n, 2)
n = n - 1
try:
n = Integer(n)
except TypeError:
raise TypeError("n must be an integer")
if n < 2:
raise ValueError("n must be greater than 2")
for c in colors:
if c not in ('green', 'red', 'yellow', 'orange', 'silver', 'blue'):
raise ValueError("color input must be from the following: 'green', 'red', 'yellow', 'orange', 'silver', and 'blue'")
raise ValueError("color input must be among: 'green', 'red', 'yellow', 'orange', 'silver', and 'blue'")
elem = [(i, j, k) for i in range(n)
for j in range(n - i) for k in range(n - i - j)]
rels = []
Expand Down Expand Up @@ -1421,12 +1386,7 @@ def UpDownPoset(n, m=1):
sage: P = posets.UpDownPoset(0); P
Finite poset containing 0 elements
"""
try:
n = Integer(n)
except TypeError:
raise TypeError("number of elements must be an integer, not {0}".format(n))
if n < 0:
raise ValueError("number of elements must be non-negative, not {0}".format(n))
n = check_int(n)
try:
m = Integer(m)
except TypeError:
Expand Down Expand Up @@ -1581,12 +1541,7 @@ def YoungFibonacci(n):
from sage.categories.finite_posets import FinitePosets
from sage.combinat.words.word import Word

try:
n = Integer(n)
except TypeError:
raise TypeError("number of elements must be an integer, not {0}".format(n))
if n < 0:
raise ValueError("number of elements must be non-negative, not {0}".format(n))
n = check_int(n)

if n == 0:
return MeetSemilattice({'': []})
Expand Down Expand Up @@ -1632,12 +1587,7 @@ def DoubleTailedDiamond(n):
sage: P.cover_relations()
[[1, 2], [2, 3], [2, 4], [3, 5], [4, 5], [5, 6]]
"""
try:
n = Integer(n)
except TypeError:
raise TypeError("number of elements must be an integer, not {}".format(n))
if n <= 0:
raise ValueError("number of elements must be nonnegative, not {}".format(n))
n = check_int(n, 1)

edges = [(i, i+1) for i in range(1, n)]
edges.extend([(n, n+1), (n, n+2), (n+1, n+3), (n+2, n+3)])
Expand Down Expand Up @@ -1680,12 +1630,7 @@ def PermutationPattern(n):
sage: posets.PermutationPattern(2)
Finite poset containing 3 elements
"""
try:
n = Integer(n)
except TypeError:
raise TypeError("number of elements must be an integer, not {}".format(n))
if n <= 0:
raise ValueError("number of elements must be nonnegative, not {}".format(n))
n = check_int(n, 1)
elem = []
for i in range(1, n + 1):
elem += Permutations(i)
Expand Down Expand Up @@ -1841,6 +1786,7 @@ def RibbonPoset(n, descents):
sage: sorted(R.cover_relations())
[[0, 1], [2, 1], [3, 2], [3, 4]]
"""
n = check_int(n)
return Mobile(DiGraph([list(range(n)),
[(i + 1, i) if i in descents else (i, i + 1)
for i in range(n - 1)]]))
Expand Down

0 comments on commit 67e7cf9

Please sign in to comment.