#17173: Poset: faster is_distributive_lattice
-----------------------------+---------------------------------
   Reporter:  jmantysalo     |            Owner:
       Type:  enhancement    |           Status:  new
   Priority:  major          |        Milestone:  sage-wishlist
  Component:  combinatorics  |         Keywords:
  Merged in:                 |          Authors:
  Reviewers:                 |  Report Upstream:  N/A
Work issues:                 |           Branch:
     Commit:                 |     Dependencies:
   Stopgaps:                 |
-----------------------------+---------------------------------
 After #17121 it is faster to say `P.is_lattice() and
 LatticePoset(P).is_distibutive()` than
 `P._hasse_diagram.is_distributive_lattice()`. However, there exists also
 fast algorithm to directly check if a given poset is distributive lattice,
 see http://www.lirmm.fr/~nourine/Papiers/dist-recognition.ps .

 To show that algorithm works I did a small example code, which is not
 optimized at all. I will continue with this later. If someone is going to
 implement this, please add a note to this ticket.

 {{{
 def join_irreducibles(self): return [e for e in self if
 len(self.lower_covers(e))==1]
 def meet_irreducibles(self): return [e for e in self if
 len(self.upper_covers(e))==1]

 def is_distributive_lattice(self):
     if ( not self.is_graded() or not self.is_bounded() or not
     self.rank() == len(join_irreducibles(self)) ==
 len(meet_irreducibles(self)) ):
         return False
     return _is_distributive_lattice_workhorse(self)

 def _is_distributive_lattice_workhorse(P):
     # Real workhorse, a recursive algorithm.
     # To show how the reduction goes:
     P.show()
     if not len([x for x in P if len(P.upper_covers(x))==1])==len([x for x
 in P if len(P.lower_covers(x))==1])==P.rank():
         return False
     if P.cardinality() == 2:
         if len(P.minimal_elements())==1:
             return True
         return "This should not happen!"
     M=P.subposet([x for x in P if len(P.upper_covers(x))==1])
     if len(M) == 0:
         return "This should not happen!"
     m=M.minimal_elements()[0]
     if len(P.upper_covers(m)) > 1:
         return "This should not happen!"
     m_=P.upper_covers(m)[0]
     M_=P.subposet([x for x in P if not x in P.closed_interval(P.bottom(),
 m)])
     if len(M_.minimal_elements()) > 1:
         return False
     j=M_.minimal_elements()
     j=j[0]
     # Does not really work, but counter-example must be quite big lattice.
     Z1=P.interval(P.bottom(), m)
     Z2=Set(P.interval(j, m_))
     for z in Z1:
         if len(Set(P.upper_covers(z)).difference(Z1)) != 1:
             return False
         if Set(P.upper_covers(z)).intersection(Z2).cardinality() != 1:
             return False
         Z2 = Z2.difference(P.upper_covers(z))
     if Z2.cardinality() > 0:
         return False
     P_=P.subposet(x for x in P if not x in P.interval(P.bottom(), m))
     return _is_distributive_lattice_workhorse(P_)
 }}}

--
Ticket URL: <http://trac.sagemath.org/ticket/17173>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/d/optout.

Reply via email to