# Ticket #14099: poset_functionality_14099_er.patch

File poset_functionality_14099_er.patch, 5.8 KB (added by rowland, 8 years ago)
• ## sage/combinat/posets/posets.py

```# HG changeset patch
# User Eric Rowland <rowland at lacim.ca>
# Date 1360638503 18000
# Node ID 1ab2e5736a9e5a7a3fc023ffb29c12fc1269f055
# Parent  ec1fb07db6e23f9fbd4c34f0d48198d08ec76473
#14099: Method for testing (m+n)-freeness in poset

diff --git a/sage/combinat/posets/posets.py b/sage/combinat/posets/posets.py```
 a from sage.structure.parent import Parent from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.graphs.digraph import DiGraph from sage.graphs.digraph_generators import digraphs from sage.combinat.posets.hasse_diagram import HasseDiagram from sage.combinat.posets.elements import PosetElement class FinitePoset(UniqueRepresentation, if leq_mat[i,j]: yield [elements[i], elements[j]] def _is_m_plus_n_free(self, m, n): r""" Returns ``True`` if the poset is (m+n)-free (that is, there is no pair of incomparable chains of lengths m and n), and ``False`` if not. INPUT: - ``m``, ``n`` - nonnegative integers EXAMPLES:: sage: Q = Poset({0:[2], 1:[2], 2:[3], 3:[4], 4:[]}) sage: Q._is_m_plus_n_free(1, 1) False sage: Q._is_m_plus_n_free(2, 1) True TESTS:: sage: Q = Poset({0:[2], 1:[2], 2:[3], 3:[4], 4:[]}) sage: Q._is_m_plus_n_free(2, 20/10) True sage: Q._is_m_plus_n_free(2, pi) Traceback (most recent call last): ... TypeError: pi is not an integer. sage: Q._is_m_plus_n_free(2, -1) Traceback (most recent call last): ... ValueError: -1 is not a nonnegative integer. """ try: m = Integer(m) except TypeError: raise TypeError('%s is not an integer.' % m) try: n = Integer(n) except TypeError: raise TypeError('%s is not an integer.' % n) if m < 0: raise ValueError('%s is not a nonnegative integer.' % m) if n < 0: raise ValueError('%s is not a nonnegative integer.' % n) relations = self.relations() g = DiGraph([rel for rel in relations if rel[0] != rel[1]]) g.add_vertices([rel[0] for rel in relations if rel[0] == rel[1]]) mchain = digraphs.Circuit(m+1) mchain.delete_vertex(m) nchain = digraphs.Circuit(n+1) nchain.delete_vertex(n) return g.transitive_closure().subgraph_search((mchain + nchain).transitive_closure(), induced = True) is None def is_incomparable_chain_free(self, *chain_pairs): r""" Returns ``True`` if the poset does not contain a pair of incomparable chains whose lengths comprise one of the ``chain_pairs``, and ``False`` if not. A poset is *``(m+n)``-free* if it contains no induced subposet that is isomorphic to the poset consisting of two disjoint chains of lengths ``m`` and ``n``.  See, for example, Exercise 15 in Chapter 3 of [Stanley, Enumerative Combinatorics Volume 1, 2nd edition]. INPUT: - ``*chain_pairs`` - sequence of pairs ``(m, n)`` of nonnegative integers EXAMPLES:: sage: P = Poset(((0, 1, 2, 3, 4), ((0, 1), (1, 2), (0, 3), (4, 2)))) sage: P.is_incomparable_chain_free((3, 1), (2, 2)) True :: sage: P = Poset((("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"), (("d", "a"), ("e", "a"), ("f", "a"), ("g", "a"), ("h", "b"), ("f", "b"), ("h", "c"), ("g", "c"), ("h", "d"), ("i", "d"), ("h", "e"), ("i", "e"), ("j", "f"), ("i", "f"), ("j", "g"), ("i", "g"), ("j", "h")))) sage: P.is_incomparable_chain_free((3, 1)) True sage: P.is_incomparable_chain_free((2, 2)) False :: sage: [len([p for p in Posets(n) if p.is_incomparable_chain_free((3, 1), (2, 2))]) for n in range(6)] [1, 1, 2, 5, 14, 42] TESTS:: sage: P = Poset(((0, 1, 2, 3, 4), ((0, 1), (1, 2), (0, 3), (4, 2)))) sage: P.is_incomparable_chain_free([3, 1], [2, 2]) True sage: P.is_incomparable_chain_free([[3, 1], [2, 2]]) True sage: P.is_incomparable_chain_free(([3, 1], [2, 2])) True sage: P.is_incomparable_chain_free([3, 1]) True sage: P.is_incomparable_chain_free((3, 1)) True sage: P.is_incomparable_chain_free([3, 1], 2) Traceback (most recent call last): ... TypeError: ([3, 1], 2) is not a tuple of tuples. sage: P.is_incomparable_chain_free([3, 1], [2, 2, 2]) Traceback (most recent call last): ... ValueError: '((3, 1), (2, 2, 2))' is not a tuple of length-2 tuples. """ try: if len(chain_pairs) is 1 and all(isinstance(tuple(chain_pair), tuple) for chain_pair in chain_pairs[0]): chain_pairs = chain_pairs[0] except: None try: chain_pairs = [tuple(chain_pair) for chain_pair in chain_pairs] except TypeError: raise TypeError('%s is not a tuple of tuples.' % str(tuple(chain_pairs))) if not all(len(chain_pair) is 2 for chain_pair in chain_pairs): raise ValueError('%r is not a tuple of length-2 tuples.' % str(tuple(chain_pairs))) return all(self._is_m_plus_n_free(chain_pair[0], chain_pair[1]) for chain_pair in chain_pairs) def is_lequal(self, x, y): """ Returns ``True`` if `x` is less than or equal to `y` in the poset, and