diff --git a/src/sage/combinat/posets/lattices.py b/src/sage/combinat/posets/lattices.py index 72e242f80ea..1acf7f39dfe 100644 --- a/src/sage/combinat/posets/lattices.py +++ b/src/sage/combinat/posets/lattices.py @@ -803,7 +803,7 @@ def is_complemented(self): """ return self._hasse_diagram.is_complemented_lattice() - def is_relatively_complemented(self): + def is_relatively_complemented(self, certificate=False): """ Return ``True`` if the lattice is relatively complemented, and ``False`` otherwise. @@ -811,6 +811,18 @@ def is_relatively_complemented(self): A lattice is relatively complemented if every interval of it is a complemented lattice. + INPUT: + + - ``certificate`` -- (default: ``False``) Whether to return + a certificate if the lattice is not relatively complemented. + + OUTPUT: + + - If ``certificate=True`` return either ``(True, None)`` or + ``(False, (a, b, c))``, where `b` is the only element that + covers `a` and is covered by `c`. If ``certificate=False`` + return ``True`` or ``False``. + EXAMPLES:: sage: L = LatticePoset({1: [2, 3, 4, 8], 2: [5, 6], 3: [5, 7], @@ -834,6 +846,11 @@ def is_relatively_complemented(self): sage: L.is_relatively_complemented() False + We can also get a non-complemented 3-element interval:: + + sage: L.is_relatively_complemented(certificate=True) + (False, (1, 6, 11)) + TESTS:: sage: [Posets.ChainPoset(i).is_relatively_complemented() for @@ -864,19 +881,27 @@ def is_relatively_complemented(self): H = self._hasse_diagram n = H.order() if n < 3: - return True + return (True, None) if certificate else True # Quick check: the lattice must be atomic and coatomic. - if H.out_degree(0) != H.in_degree().count(1): - return False - if H.in_degree(n-1) != H.out_degree().count(1): - return False + if not certificate: + if H.out_degree(0) != H.in_degree().count(1): + return False + if H.in_degree(n-1) != H.out_degree().count(1): + return False for e1 in range(n-1): C = Counter(flatten([H.neighbors_out(e2) for e2 in H.neighbors_out(e1)])) - if any(c == 1 and len(H.closed_interval(e1, e3)) == 3 for e3, c in C.iteritems()): - return False - return True + for e3, c in C.iteritems(): + if c == 1 and len(H.closed_interval(e1, e3)) == 3: + if not certificate: + return False + e2 = H.neighbors_in(e3)[0] + e1 = H.neighbors_in(e2)[0] + return (False, (self._vertex_to_element(e1), + self._vertex_to_element(e2), + self._vertex_to_element(e3))) + return (True, None) if certificate else True def breadth(self, certificate=False): r"""