| 1536 | def is_incomparable_chain_free(self, m, n = None): |
| 1537 | r""" |
| 1538 | Returns ``True`` if the poset is `(m+n)`-free (that is, there is no pair |
| 1539 | of incomparable chains of lengths `m` and `n`), and ``False`` if not. |
| 1540 | |
| 1541 | If ``m`` is a tuple of pairs of chain lengths, returns ``True`` if the poset |
| 1542 | does not contain a pair of incomparable chains whose lengths comprise |
| 1543 | one of the chain pairs, and ``False`` if not. |
| 1544 | |
| 1545 | A poset is `(m+n)`-free if it contains no induced subposet that is |
| 1546 | isomorphic to the poset consisting of two disjoint chains of lengths |
| 1547 | `m` and `n`. See, for example, Exercise 15 in Chapter 3 of |
| 1548 | Stanley, *Enumerative Combinatorics, Volume 1*, 2nd edition. |
| 1549 | |
| 1550 | INPUT: |
| 1551 | |
| 1552 | - ``m`` - tuple of pairs of nonnegative integers |
| 1553 | - ``m``, ``n`` - nonnegative integers |
| 1554 | |
| 1555 | EXAMPLES:: |
| 1556 | |
| 1557 | sage: P = Poset({0:[2], 1:[2], 2:[3], 3:[4], 4:[]}) |
| 1558 | sage: P.is_incomparable_chain_free(1, 1) |
| 1559 | False |
| 1560 | sage: P.is_incomparable_chain_free(2, 1) |
| 1561 | True |
| 1562 | |
| 1563 | :: |
| 1564 | |
| 1565 | sage: P = Poset(((0, 1, 2, 3, 4), ((0, 1), (1, 2), (0, 3), (4, 2)))) |
| 1566 | sage: P.is_incomparable_chain_free(((3, 1), (2, 2))) |
| 1567 | True |
| 1568 | |
| 1569 | :: |
| 1570 | |
| 1571 | 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")))) |
| 1572 | sage: P.is_incomparable_chain_free(3, 1) |
| 1573 | True |
| 1574 | sage: P.is_incomparable_chain_free(2, 2) |
| 1575 | False |
| 1576 | |
| 1577 | :: |
| 1578 | |
| 1579 | sage: [len([p for p in Posets(n) if p.is_incomparable_chain_free(((3, 1), (2, 2)))]) for n in range(6)] |
| 1580 | [1, 1, 2, 5, 14, 42] |
| 1581 | |
| 1582 | TESTS:: |
| 1583 | |
| 1584 | sage: Q = Poset({0:[2], 1:[2], 2:[3], 3:[4], 4:[]}) |
| 1585 | sage: Q.is_incomparable_chain_free(2, 20/10) |
| 1586 | True |
| 1587 | sage: Q.is_incomparable_chain_free(2, pi) |
| 1588 | Traceback (most recent call last): |
| 1589 | ... |
| 1590 | TypeError: 2 and pi must be integers. |
| 1591 | sage: Q.is_incomparable_chain_free(2, -1) |
| 1592 | Traceback (most recent call last): |
| 1593 | ... |
| 1594 | ValueError: 2 and -1 must be nonnegative integers. |
| 1595 | sage: P = Poset(((0, 1, 2, 3, 4), ((0, 1), (1, 2), (0, 3), (4, 2)))) |
| 1596 | sage: P.is_incomparable_chain_free((3, 1)) |
| 1597 | Traceback (most recent call last): |
| 1598 | ... |
| 1599 | TypeError: (3, 1) is not a tuple of tuples. |
| 1600 | sage: P.is_incomparable_chain_free([3, 1], [2, 2]) |
| 1601 | Traceback (most recent call last): |
| 1602 | ... |
| 1603 | TypeError: [3, 1] and [2, 2] must be integers. |
| 1604 | sage: P.is_incomparable_chain_free([[3, 1], [2, 2]]) |
| 1605 | True |
| 1606 | sage: P.is_incomparable_chain_free(([3, 1], [2, 2])) |
| 1607 | True |
| 1608 | sage: P.is_incomparable_chain_free([3, 1], 2) |
| 1609 | Traceback (most recent call last): |
| 1610 | ... |
| 1611 | TypeError: [3, 1] and 2 must be integers. |
| 1612 | sage: P.is_incomparable_chain_free(([3, 1], [2, 2, 2])) |
| 1613 | Traceback (most recent call last): |
| 1614 | ... |
| 1615 | ValueError: '([3, 1], [2, 2, 2])' is not a tuple of length-2 tuples. |
| 1616 | |
| 1617 | AUTHOR: |
| 1618 | |
| 1619 | - Eric Rowland (2013-05-28) |
| 1620 | """ |
| 1621 | if n is None: |
| 1622 | try: |
| 1623 | chain_pairs = [tuple(chain_pair) for chain_pair in m] |
| 1624 | except TypeError: |
| 1625 | raise TypeError('%s is not a tuple of tuples.' % str(tuple(m))) |
| 1626 | if not all(len(chain_pair) is 2 for chain_pair in chain_pairs): |
| 1627 | raise ValueError('%r is not a tuple of length-2 tuples.' % str(tuple(m))) |
| 1628 | return all(self.is_incomparable_chain_free(*chain_pair) for chain_pair in chain_pairs) |
| 1629 | try: |
| 1630 | m, n = Integer(m), Integer(n) |
| 1631 | except TypeError: |
| 1632 | raise TypeError('%s and %s must be integers.' % (m, n)) |
| 1633 | if m < 0 or n < 0: |
| 1634 | raise ValueError("%s and %s must be nonnegative integers." % (m, n)) |
| 1635 | twochains = digraphs.TransitiveTournament(m) + digraphs.TransitiveTournament(n) |
| 1636 | return self.hasse_diagram().transitive_closure().subgraph_search(twochains, induced = True) is None |
| 1637 | |