Skip to content

Commit 52a74d7

Browse files
committed
implement the method "is_left_modular" for lattices
1 parent 4cdd703 commit 52a74d7

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

src/sage/combinat/posets/lattices.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
:meth:`~FiniteLatticePoset.is_planar` | Return ``True`` if the lattice has an upward planar drawing.
6363
:meth:`~FiniteLatticePoset.is_dismantlable` | Return ``True`` if the lattice is dismantlable.
6464
:meth:`~FiniteLatticePoset.is_interval_dismantlable` | Return ``True`` if the lattice is interval dismantlable.
65+
:meth:`~FiniteLatticePoset.is_left_modular` | Return ``True`` if the lattice is left_modular.
6566
:meth:`~FiniteLatticePoset.is_sublattice_dismantlable` | Return ``True`` if the lattice is sublattice dismantlable.
6667
:meth:`~FiniteLatticePoset.is_stone` | Return ``True`` if the lattice is a Stone lattice.
6768
:meth:`~FiniteLatticePoset.is_trim` | Return ``True`` if the lattice is a trim lattice.
@@ -1557,9 +1558,24 @@ def is_trim(self, certificate=False) -> bool | tuple:
15571558
sage: LatticePoset({1:[]}).is_trim(True)
15581559
(True, [1])
15591560
1561+
Testing a trim lattice ::
1562+
1563+
sage: L = LatticePoset(([1,2,3,4,5,6],
1564+
....: [[1,2],[1,3],[3,4],[4,5],[2,5],[2,6],[6,5],[2,4]]))
1565+
sage: L.is_trim(True)
1566+
(True, [1, 2, 6, 5])
1567+
1568+
Testing a lattice which is not trim ::
1569+
1570+
sage: L = LatticePoset(([1,2,3,4,5,6],
1571+
....: [[1,2],[1,3],[3,4],[4,5],[2,5],[2,6],[6,5]]))
1572+
sage: L.is_trim(True)
1573+
(False, None)
1574+
15601575
.. SEEALSO::
15611576
15621577
- Weaker properties: :meth:`is_extremal`
1578+
- Weaker properties: :meth:`is_left_modular`
15631579
- Stronger properties: :meth:`is_distributive`
15641580
15651581
REFERENCES:
@@ -1577,6 +1593,65 @@ def is_trim(self, certificate=False) -> bool | tuple:
15771593
return (True, chain) if certificate else True
15781594
return (False, None) if certificate else False
15791595

1596+
def is_left_modular(self, H=None, certificate=False) -> bool | list:
1597+
r"""
1598+
Return whether ``self`` is a left-modular lattice.
1599+
1600+
INPUT:
1601+
1602+
- ``H`` -- subset of elements; full ``self`` if no ``H`` is given
1603+
1604+
- ``certificate`` -- boolean (default: ``False``); whether to return
1605+
a list of failures
1606+
1607+
OUTPUT:
1608+
1609+
if ``certificate == True``, this outputs a list of tuples
1610+
`(y, x, z)` which fail left-modularity.
1611+
1612+
if ``certificate == False``, this outputs ``False``
1613+
if any `x \in H` fails to be left-modular and ``True`` otherwise.
1614+
1615+
ALGORITHM:
1616+
1617+
Given a lattice `L` and a subset of elements `H`,
1618+
an element `x \in H` is left-modular
1619+
if for every `y,z \in L, y \leq z`
1620+
the equality `(y \vee x) \wedge z = y \vee (x \wedge z)`.
1621+
1622+
.. SEEALSO::
1623+
1624+
- Stronger properties: :meth:`is_trim`
1625+
1626+
EXAMPLES:
1627+
1628+
A lattice that is not left-modular::
1629+
1630+
sage: L = LatticePoset(([1,2,3,4,5],
1631+
....: [[1,2],[1,3],[3,4],[4,5],[2,5]]))
1632+
sage: L.is_left_modular()
1633+
False
1634+
1635+
A left-modular lattice::
1636+
1637+
sage: L = LatticePoset(([1,2,3,4,5,6],
1638+
....: [[1,2],[1,3],[3,4],[4,5],[2,5],[2,6],[6,5],[2,4]]))
1639+
sage: L.is_left_modular()
1640+
True
1641+
"""
1642+
if H is None:
1643+
H = self
1644+
out = []
1645+
for x in H:
1646+
for z in self:
1647+
mxz = self.meet(x, z)
1648+
for y in self.principal_lower_set(z):
1649+
if self.join(y, mxz) != self.meet(self.join(y, x), z):
1650+
if not certificate:
1651+
return False
1652+
out.append((y, x, z))
1653+
return out if certificate else True
1654+
15801655
def is_complemented(self, certificate=False) -> bool | tuple:
15811656
r"""
15821657
Return ``True`` if the lattice is complemented, and

0 commit comments

Comments
 (0)