@@ -5270,19 +5270,24 @@ def factor(self):
52705270 sage: P.factor()
52715271 Traceback (most recent call last):
52725272 ...
5273- NotImplementedError: the poset is not connected
5273+ NotImplementedError: the poset is empty or not connected
52745274
52755275 sage: P = posets.Crown(2)
52765276 sage: P.factor()
52775277 [Finite poset containing 4 elements]
52785278
52795279 sage: Poset().factor()
5280- [Finite poset containing 0 elements]
5280+ Traceback (most recent call last):
5281+ ...
5282+ NotImplementedError: the poset is empty or not connected
52815283
52825284 sage: factor(posets.BooleanLattice(2))
52835285 [Finite poset containing 2 elements,
52845286 Finite poset containing 2 elements]
52855287
5288+ sage: factor(Poset(DiGraph([[0,1],[1,2],[0,3]])))
5289+ [Finite poset containing 4 elements]
5290+
52865291 REFERENCES:
52875292
52885293 .. [Feig1986] Joan Feigenbaum, *Directed Cartesian-Product Graphs
@@ -5293,10 +5298,13 @@ def factor(self):
52935298 from sage .graphs .graph import Graph
52945299 from sage .misc .flatten import flatten
52955300 dg = self ._hasse_diagram
5296- if not dg .is_connected ():
5297- raise NotImplementedError ('the poset is not connected' )
5301+ if not dg .is_connected () or not dg . order () :
5302+ raise NotImplementedError ('the poset is empty or not connected' )
52985303 if Integer (dg .num_verts ()).is_prime ():
52995304 return [self ]
5305+ if sum (e for _ , e in self .degree_polynomial ().factor ()) == 1 :
5306+ return [self ]
5307+
53005308 G = dg .to_undirected ()
53015309 is_product , dic = G .is_cartesian_product (relabeling = True )
53025310 if not is_product :
@@ -5307,34 +5315,39 @@ def factor(self):
53075315 v0 = next (iter (dic .values ()))
53085316 n = len (v0 )
53095317 factors_range = range (n )
5310- fusion = Graph (n )
53115318
53125319 def edge_color (va , vb ):
53135320 for i in range (n ):
53145321 if va [i ] != vb [i ]:
53155322 return i
53165323
5324+ neighbors_table = {x : [[y for y in prod_dg .neighbor_iterator (x )
5325+ if edge_color (x , y ) == i ]
5326+ for i in factors_range ]
5327+ for x in prod_dg }
5328+
5329+ fusion_edges = []
53175330 for i0 , i1 in Subsets (factors_range , 2 ):
53185331 for x in prod_dg :
5319- neigh0 = [y for y in prod_dg .neighbor_iterator (x )
5320- if edge_color (x , y ) == i0 ]
5321- neigh1 = [z for z in prod_dg .neighbor_iterator (x )
5322- if edge_color (x , z ) == i1 ]
5332+ neigh0 = neighbors_table [x ][i0 ]
5333+ neigh1 = neighbors_table [x ][i1 ]
53235334 for x0 , x1 in product (neigh0 , neigh1 ):
53245335 _x2 = list (x0 )
53255336 _x2 [i1 ] = x1 [i1 ]
53265337 x2 = tuple (_x2 )
53275338 A0 = prod_dg .has_edge (x , x0 )
53285339 B0 = prod_dg .has_edge (x1 , x2 )
53295340 if A0 != B0 :
5330- fusion . add_edge ([i0 , i1 ])
5341+ fusion_edges . append ([i0 , i1 ])
53315342 break
53325343 A1 = prod_dg .has_edge (x , x1 )
53335344 B1 = prod_dg .has_edge (x0 , x2 )
53345345 if A1 != B1 :
5335- fusion . add_edge ([i0 , i1 ])
5346+ fusion_edges . append ([i0 , i1 ])
53365347 break
53375348
5349+ fusion = Graph ([list (range (n )), fusion_edges ],
5350+ format = "vertices_and_edges" )
53385351 resu = []
53395352 for s in fusion .connected_components (sort = False ):
53405353 subg = [x for x in prod_dg if all (x [i ] == v0 [i ] for i in factors_range
0 commit comments