# HG changeset patch
# User Nathann Cohen
# Date 1354446887 3600
# Node ID da8fa0c9ccce5243ef949479e81358dbdd192c60
# Parent ffa112def1286bbce6d47eb6fb0b8a8d7f20c3e7
Bug in GenericGraph.line_graph() when the vertices cannot be compared
diff git a/sage/graphs/generic_graph.py b/sage/graphs/generic_graph.py
 a/sage/graphs/generic_graph.py
+++ b/sage/graphs/generic_graph.py
@@ 12901,24 +12901,39 @@
if not self.has_edge(u,v):
G.add_edge(u,v)
return G

+
def line_graph(self, labels=True):
"""
Returns the line graph of the (di)graph.

+
+ INPUT:
+
+  ``labels`` (boolean)  whether edge labels should be taken in
+ consideration. If ``labels=True``, the vertices of the line graph will
+ be triples ``(u,v,label)``, and pairs of vertices otherwise.
+
+ This is set to ``True`` by default.
+
The line graph of an undirected graph G is an undirected graph H
such that the vertices of H are the edges of G and two vertices e
and f of H are adjacent if e and f share a common vertex in G. In
other words, an edge in H represents a path of length 2 in G.

+
The line graph of a directed graph G is a directed graph H such
that the vertices of H are the edges of G and two vertices e and f
of H are adjacent if e and f share a common vertex in G and the
terminal vertex of e is the initial vertex of f. In other words, an
edge in H represents a (directed) path of length 2 in G.

 EXAMPLES::

+
+ .. NOTE::
+
+ As a :class:`Graph` object only accepts hashable objects as vertices
+ (and as the vertices of the line graph are the edges of the graph),
+ this code will fail if edge labels are not hashable. You can also
+ set the argument ``labels=False`` to ignore labels.
+
+ EXAMPLES::
+
sage: g=graphs.CompleteGraph(4)
sage: h=g.line_graph()
sage: h.vertices()
@@ 12954,6 +12969,17 @@
((1, 2, None), (2, 4, None), None),
((1, 3, None), (3, 4, None), None),
((2, 3, None), (3, 4, None), None)]
+
+ Tests:
+
+ :trac:`13787`::
+
+ sage: g=graphs.KneserGraph(7,1)
+ sage: C = graphs.CompleteGraph(7)
+ sage: C.is_isomorphic(g)
+ True
+ sage: C.line_graph().is_isomorphic(g.line_graph())
+ True
"""
if self._directed:
from sage.graphs.digraph import DiGraph
@@ 12967,32 +12993,61 @@
else:
from sage.graphs.all import Graph
G=Graph()
 # We must sort the edges' endpoints so that (1,2,None) is
 # seen as the same edge as (2,1,None).
 if labels:
 elist=[(min(i[0:2]),max(i[0:2]),i[2] if i[2] != {} else None)
 for i in self.edge_iterator()]
 else:
 elist=[(min(i),max(i))
 for i in self.edge_iterator(labels=False)]
+
+ # We must sort the edges' endpoints so that (1,2,None) is seen as
+ # the same edge as (2,1,None).
+ #
+ # We do so by comparing hashes, just in case all the natural order
+ # (<) on vertices would not be a total order (for instance when
+ # vertices are sets). If two adjacent vertices have the same hash,
+ # then we store the pair in the dictionary of conflicts
+
+ conflicts = {}
+
+ # 1) List of vertices in the line graph
+ elist = []
+ for e in self.edge_iterator(labels = labels):
+ if hash(e[0]) < hash(e[1]):
+ elist.append(e)
+ elif hash(e[0]) > hash(e[1]):
+ elist.append((e[1],e[0])+e[2:])
+ else:
+ # Settle the conflict arbitrarily
+ conflicts[e] = e
+ conflicts[(e[1],e[0])+e[2:]] = e
+ elist.append(e)
+
G.add_vertices(elist)
+
+ # 2) adjacencies in the line graph
for v in self:
 if labels:
 elist=[(min(i[0:2]),max(i[0:2]),i[2] if i[2] != {} else None)
 for i in self.edge_iterator(v)]
 else:
 elist=[(min(i),max(i))
 for i in self.edge_iterator(v, labels=False)]
 G.add_edges([(e, f) for e in elist for f in elist])
+ elist = []
+
+ # Add the edge to the list, according to hashes, as previously
+ for e in self.edge_iterator(v, labels=labels):
+ if hash(e[0]) < hash(e[1]):
+ elist.append(e)
+ elif hash(e[0]) > hash(e[1]):
+ elist.append((e[1],e[0])+e[2:])
+ else:
+ elist.append(conflicts[e])
+
+ # Alls pairs of elements in elist are pairs of the
+ # graph
+ while elist:
+ x = elist.pop()
+ for y in elist:
+ G.add_edge(x,y)
+
return G
def to_simple(self):
"""
Returns a simple version of itself (i.e., undirected and loops and
multiple edges are removed).

 EXAMPLES::

+
+ EXAMPLES::
+
sage: G = DiGraph(loops=True,multiedges=True,sparse=True)
sage: G.add_edges( [ (0,0), (1,1), (2,2), (2,3,1), (2,3,2), (3,2) ] )
sage: G.edges(labels=False)