88
99from collections import defaultdict
1010from inspect import isgenerator
11- from typing import Callable , Optional
11+ from typing import Callable , Optional , Union
1212
1313from mathics .builtin .base import AtomBuiltin , Builtin
1414from mathics .core .atoms import Atom , Integer , Integer0 , Integer1 , Integer2 , String
15- from mathics .core .convert .expression import ListExpression , from_python
15+ from mathics .core .convert .expression import ListExpression , from_python , to_mathics_list
1616from mathics .core .element import BaseElement
1717from mathics .core .expression import Expression
1818from mathics .core .symbols import Symbol , SymbolList , SymbolTrue
@@ -283,7 +283,14 @@ def _not_a_vertex(self, expression, pos, evaluation):
283283 def _not_an_edge (self , expression , pos , evaluation ):
284284 evaluation .message (self .get_name (), "inv" , "edge" , pos , expression )
285285
286- def _build_graph (self , graph , evaluation , options , expr , quiet = False ):
286+ def _build_graph (
287+ self ,
288+ graph : Union ["Graph" , Expression ],
289+ evaluation ,
290+ options : dict ,
291+ expr ,
292+ quiet = False ,
293+ ) -> Optional ["Graph" ]:
287294 head = graph .get_head ()
288295 if head is SymbolGraph and isinstance (graph , Atom ) and hasattr (graph , "G" ):
289296 return graph
@@ -384,9 +391,6 @@ def __init__(self, Gr, **kwargs):
384391 self .G = Gr
385392 self .mixed = kwargs .get ("mixed" , False )
386393
387- # Number of nodes
388- self .n : Optional [int ] = None
389-
390394 # Here we define types that appear on some, but not all
391395 # graphs. So these are optional, which we given an initial
392396 # value of None
@@ -441,14 +445,13 @@ def coalesced_graph(self, evaluation):
441445
442446 return new_graph , "WEIGHT"
443447
444- def delete_edges (self , edges_to_delete ):
448+ def delete_edges (self , edges_to_delete ) -> "Graph" :
445449 G = self .G .copy ()
446450 directed = G .is_directed ()
447451
448- edges_to_delete = list (_normalize_edges (edges_to_delete ))
449- edges_to_delete = self .edges .filter (edges_to_delete )
452+ normalized_edges_to_delete = list (_normalize_edges (edges_to_delete ))
450453
451- for edge in edges_to_delete :
454+ for edge in normalized_edges_to_delete :
452455 if edge .has_form ("DirectedEdge" , 2 ):
453456 if directed :
454457 u , v = edge .elements
@@ -461,12 +464,7 @@ def delete_edges(self, edges_to_delete):
461464 else :
462465 G .remove_edge (u , v )
463466
464- edges = self .edges .clone ()
465- edges .delete (edges_to_delete )
466-
467- return Graph (
468- self .vertices , edges , G , self .layout , self .options , self .highlights
469- )
467+ return Graph (G )
470468
471469 def delete_vertices (self , vertices_to_delete ):
472470 G = self .G .copy ()
@@ -817,8 +815,7 @@ class AdjacencyList(_NetworkXBuiltin):
817815 :Adjacency list:
818816 https://en.wikipedia.org/wiki/Adjacency_list</url> (<url>
819817 :NetworkX:
820- https://networkx.org/documentation/networkx-2.8.8/reference/readwrite/adjlist.html</url>,
821- <url>
818+ https://networkx.org/documentation/networkx-2.8.8/reference/readwrite/adjlist.html</url>, <url>
822819 :WMA:
823820 https://reference.wolfram.com/language/ref/AdjacencyList.html</url>)
824821
@@ -1418,8 +1415,8 @@ class VertexDelete(_NetworkXBuiltin):
14181415
14191416 summary_text = "remove a vertex"
14201417
1421- def eval (self , graph , what , expression , evaluation , options ):
1422- "%(name)s [graph_, what_, OptionsPattern[%(name)s ]]"
1418+ def eval (self , graph , what , expression , evaluation , options ) -> Optional [ Graph ] :
1419+ "VertexDelete [graph_, what_, OptionsPattern[VertexDelete ]]"
14231420 graph = self ._build_graph (graph , evaluation , options , expression )
14241421 if graph :
14251422 from mathics .builtin import pattern_objects
@@ -1533,41 +1530,46 @@ class UndirectedEdge(Builtin):
15331530# return mathics_graph.add_edges(*zip(*[_parse_item(what)]))
15341531
15351532
1536- # class EdgeDelete(_NetworkXBuiltin):
1537- # """
1538- # >> Length[EdgeList[EdgeDelete[{a -> b, b -> c, c -> d}, b -> c]]]
1539- # = 2
1533+ class EdgeDelete (_NetworkXBuiltin ):
1534+ """
1535+ <url>
1536+ :WMA:
1537+ https://reference.wolfram.com/language/ref/EdgeDelete.html</url>
15401538
1541- # >> Length[EdgeList[EdgeDelete[{a -> b, b -> c, c -> b, c -> d}, b <-> c]]]
1542- # = 4
1539+ <dl>
1540+ <dt>'EdgeDelete'[$g$, $edge$]
1541+ <dd>remove the edge $edge$.
1542+ </dl>
15431543
1544- # >> Length[EdgeList[EdgeDelete[{a -> b, b < -> c, c -> d }, b -> c]] ]
1545- # = 3
1544+ >> g = Graph[{1 -> 2, 2 -> 3, 3 -> 1 }, VertexLabels->True ]
1545+ = -Graph-
15461546
1547- # >> Length[ EdgeList[EdgeDelete[{a -> b, b < -> c, c -> d}, c -> b] ]]
1548- # = 3
1547+ >> EdgeList[EdgeDelete[g, 2 -> 3 ]]
1548+ = {{1, 2}, {3, 1}}
15491549
1550- # >> Length[EdgeList[EdgeDelete[{a -> b, b <-> c, c -> d}, b <-> c]] ]
1551- # = 2
1550+ ## >> g = Graph[{4<->5,5 <->7,7<->9,9 <->5,2->4,4->6,6->2}, VertexLabels->True ]
1551+ ## = -Graph-
15521552
1553- # >> EdgeDelete[{4<->5,5<->7,7<->9,9<->5,2->4,4->6,6->2} , _UndirectedEdge]
1554- # = -Graph-
1555- # """
1553+ ## >> EdgeDelete[g , _UndirectedEdge]
1554+ ## = -Graph-
1555+ """
15561556
1557- # def eval(self, graph, what, expression, evaluation, options):
1558- # "%(name)s[graph_, what_, OptionsPattern[%(name)s]]"
1559- # graph = self._build_graph(graph, evaluation, options, expression)
1560- # if graph:
1561- # from mathics.builtin import pattern_objects
1562-
1563- # head_name = what.get_head_name()
1564- # if head_name in pattern_objects:
1565- # cases = Expression(
1566- # SymbolCases, ListExpression(*graph.edges), what
1567- # ).evaluate(evaluation)
1568- # if cases.get_head_name() == "System`List":
1569- # return graph.delete_edges(cases.elements)
1570- # elif head_name == "System`List":
1571- # return graph.delete_edges(what.elements)
1572- # else:
1573- # return graph.delete_edges([what])
1557+ summary_text = "remove an edge"
1558+
1559+ def eval (self , graph , what , expression , evaluation , options ) -> Optional [Graph ]:
1560+ "EdgeDelete[graph_, what_, OptionsPattern[EdgeDelete]]"
1561+ graph = self ._build_graph (graph , evaluation , options , expression )
1562+ if graph :
1563+ from mathics .builtin import pattern_objects
1564+
1565+ head_name = what .get_head_name ()
1566+ if head_name in pattern_objects :
1567+ cases = Expression (
1568+ SymbolCases , to_mathics_list (* graph .edges ), what
1569+ ).evaluate (evaluation )
1570+ if cases .get_head_name () == "System`List" :
1571+ return graph .delete_edges (cases .elements )
1572+ elif head_name == "System`List" :
1573+ return graph .delete_edges (what .elements )
1574+ else :
1575+ return graph .delete_edges ([what ])
0 commit comments