From 160d8a5cdd251d13619e1291542cdd35a3f57ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jori=20M=C3=A4ntysalo?= Date: Fri, 5 Sep 2014 12:27:13 +0300 Subject: [PATCH] Added two simple wrapper functions. --- src/sage/combinat/posets/hasse_diagram.py | 19 ------------ src/sage/combinat/posets/posets.py | 37 ++++++++++++++++++++--- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index e8d3d5add62..085abbae54e 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -357,25 +357,6 @@ def has_bottom(self): if self.bottom() is not None: return True return False - def has_isomorphic_subposet(self, other): - """ - Return ``True`` if the poset contains a subposet isomorphic to ``other``. - - EXAMPLES:: - - sage: D = Poset({1:[2,3], 2:[4], 3:[4]}) - sage: T = Poset({1:[2,3], 2:[4,5], 3:[6,7]}) - sage: N5 = Posets.PentagonPoset() - - sage: T.has_isomorphic_subposet(D) - False - sage: N5.has_isomorphic_subposet(D) - True - """ - if DiGraph(self).transitive_closure().subgraph_search(DiGraph(other._hasse_diagram).transitive_closure(), induced=True) is None: - return False - return True - def top(self): """ Returns the top element of the poset, if it exists. diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 7e38ad99ed1..6cb8be44626 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -62,6 +62,7 @@ :meth:`~FinitePoset.is_less_than` | Returns ``True`` if `x` is less than but not equal to `y` in the poset, and ``False`` otherwise. :meth:`~FinitePoset.is_linear_extension` | Returns whether ``l`` is a linear extension of ``self`` :meth:`~FinitePoset.is_meet_semilattice` | Returns True if self has a meet operation, and False otherwise. + :meth:`~FinitePoset.isomorphic_subposets` | Return all subposets isomorphic to other poset. :meth:`~FinitePoset.join_matrix` | Returns a matrix whose ``(i,j)`` entry is ``k``, where ``self.linear_extension()[k]`` is the join (least upper bound) of ``self.linear_extension()[i]`` and ``self.linear_extension()[j]``. :meth:`~FinitePoset.is_incomparable_chain_free` | Returns whether the poset is `(m+n)`-free. :meth:`~FinitePoset.is_ranked` | Returns whether this poset is ranked. @@ -145,7 +146,7 @@ from sage.combinat.posets.hasse_diagram import HasseDiagram from sage.combinat.posets.elements import PosetElement from sage.combinat.combinatorial_map import combinatorial_map - +from sage.misc.misc import uniq def Poset(data=None, element_labels=None, cover_relations=False, linear_extension=False, category = None, facade = None, key = None): r""" @@ -1953,21 +1954,24 @@ def has_isomorphic_subposet(self, other): Return ``True`` if the poset contains a subposet isomorphic to ``other``. EXAMPLES:: - + sage: D = Poset({1:[2,3], 2:[4], 3:[4]}) sage: T = Poset({1:[2,3], 2:[4,5], 3:[6,7]}) sage: N5 = Posets.PentagonPoset() - sage: T.has_isomorphic_subposet(D) + sage: N5.has_isomorphic_subposet(T) False sage: N5.has_isomorphic_subposet(D) True sage: len([P for P in Posets(5) if P.has_isomorphic_subposet(D)]) 11 - """ - return self._hasse_diagram.has_isomorphic_subposet(other) + if not hasattr(other, 'hasse_diagram'): + raise ValueError('The input is not a finite poset.') + if self._hasse_diagram.transitive_closure().subgraph_search(other._hasse_diagram.transitive_closure(), induced=True) is None: + return False + return True def is_bounded(self): """ @@ -2653,6 +2657,29 @@ def is_isomorphic(self,other): else: raise ValueError('The input is not a finite poset.') + def isomorphic_subposets(self, other): + """ + Return a list of subposets of `self` isomorphic to `other`. + + EXAMPLES:: + + sage: C2=Poset({0:[1]}) + sage: C3=Poset({'a':['b'], 'b':['c']}) + sage: for x in C3.isomorphic_subposets(C2): print x.cover_relations() + [['a', 'b']] + [['a', 'c']] + [['b', 'c']] + sage: D = Poset({1:[2,3], 2:[4], 3:[4]}) + sage: N5 = Posets.PentagonPoset() + sage: len(N5.isomorphic_subposets(D)) + 2 + """ + if not hasattr(other, 'hasse_diagram'): + raise ValueError('The input is not a finite poset.') + L=self.hasse_diagram().transitive_closure().subgraph_search_iterator(other.hasse_diagram().transitive_closure(), induced=True) + # Since subgraph_search_iterator returns labelled copies, we remove duplicates. + return [self.subposet(x) for x in uniq([frozenset(y) for y in L])] + import __builtin__ # Caveat: list is overridden by the method list above!!! def antichains(self, element_constructor = __builtin__.list): """