Is UndirectedEdge[a,b] the same edge as UndirectedEdge[b,a]?

Is UndirectedEdge[a,b] the same edge as UndirectedEdge[b,a]? Then please consider this.

g = CompleteGraph[4, VertexLabels -> "Name", ImagePadding -> 10]


If we ask to delete UndirectedEdge[1,4] or UndirectedEdge[4,1] gives the same result:

EdgeDelete[g, {1 \[UndirectedEdge] 4}]
EdgeDelete[g, {4 \[UndirectedEdge] 1}]


MemberQ[EdgeList[g], 1 \[UndirectedEdge] 4]
(* True *)

MemberQ[EdgeList[g], 4 \[UndirectedEdge] 1]
(* False *)


This strikes me as inconsistent.

Postscript: Should UndirectedEdge be orderless?

@R.M 's response makes a lot of sense:

MemberQ[EdgeList[g], b \[UndirectedEdge] a] answers True if and only if b \[UndirectedEdge] a, is literally in EdgeList[g]. It will not respond True if that edge is listed in EdgeList[g] as a \[UndirectedEdge] b. However, EdgeQ[g, b \[UndirectedEdge] a] will respond True whether that edge is stored in EdgeList[g] either as a \[UndirectedEdge] b or b \[UndirectedEdge] a.

Even so, it seems to me that UndirectedEdge ought to be Orderless. Wouldn't it be preferable to behave like Plus?

Compare Plus and UndirectedEdge:

ClearAll[x, y]
Plus[x, y]
Plus[y, x]
Attributes[Plus]
Plus[x, y] == Plus[y, x]
Plus[x, y] === Plus[y, x]


ClearAll[x, y]
x \[UndirectedEdge] y
y \[UndirectedEdge] x
Attributes[UndirectedEdge]
UndirectedEdge[x, y] == UndirectedEdge[y, x]
UndirectedEdge[x, y] === UndirectedEdge[y, x]


-
Also: MemberQ[{a+b,b+c}, b+a] gives True. –  celtschk Apr 5 '12 at 16:14
@celtschk Yes, b+a is read as Plus[a,b], apparently because or the Orderless attribute of Plus. –  David Carraher Apr 5 '12 at 16:27

This is not inconsistent at all. You're using MemberQ, which only looks at the structural form and UndirectedEdge[1, 4] and UndirectedEdge[4, 1] are not the same, even though you know they mean the same thing. To check if an edge is in a graph, use EdgeQ

EdgeQ[g, 1 \[UndirectedEdge] 4]
EdgeQ[g, 4 \[UndirectedEdge] 1]
(* True, True *)


I think it's probably just an oversight on WRI's part to not include the Orderless attribute and such oversights are not uncommon. I can't think of a reason why it shouldn't be Orderless. One can always add this to the definition as follows:

Unprotect[UndirectedEdge];
SetAttributes[UndirectedEdge, Orderless];
Protect[UndirectedEdge];


Now using MemberQ as in the question will yield True in both cases. However, I would not recommend doing this, because I think it is worth it to understand the structural and semantic differences between the two and one should always use the one appropriate for the task (and in this case, also has a more meaningful name).

-
+1 for pointing out structural/semantic difference between MemberQ and EdgeQ. –  István Zachar Apr 5 '12 at 14:45
Nice answer. I had forgotten about EdgeQ and only after reading your answer do I understand why EdgeQ was created. –  David Carraher Apr 5 '12 at 14:50