Skip to content

Commit

Permalink
fix: fixes #19
Browse files Browse the repository at this point in the history
  • Loading branch information
Viva-Lambda committed Nov 10, 2023
1 parent 76bb8f0 commit 4984de5
Show file tree
Hide file tree
Showing 7 changed files with 1,331 additions and 222 deletions.
205 changes: 7 additions & 198 deletions pygmodels/graph/graphops/graphalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,183 +20,6 @@
from pygmodels.utils import is_type, type_check


class BaseGraphSetOps:
"""!"""

@staticmethod
def set_op_node_edge(
g: AbstractGraph,
obj: Union[Set[AbstractNode], Set[AbstractEdge]],
op: Callable[
[Union[Set[AbstractNode], Set[AbstractEdge]]],
Union[Set[AbstractNode], Set[AbstractEdge]],
],
):
"""!"""
is_type(val=g, originType=AbstractGraph, shouldRaiseError=True)
is_eset = all(isinstance(o, AbstractEdge) for o in obj)
if is_eset:
edges = g.E
return op(edges, obj)
is_nset = all(isinstance(o, AbstractNode) for o in obj)
if is_nset is False:
raise TypeError(
"argument type is not supported: " + type(obj).__name__
)
#
nodes = g.V
return op(nodes, obj)

@staticmethod
def set_op(
g: AbstractGraph,
obj: Union[
Set[AbstractNode],
Set[AbstractEdge],
AbstractGraph,
AbstractNode,
AbstractEdge,
],
op: Callable[
[Union[Set[AbstractNode], Set[AbstractEdge]]],
Union[Set[AbstractNode], Set[AbstractEdge], AbstractGraph],
],
) -> Optional[Union[Set[AbstractNode], Set[AbstractEdge], bool]]:
"""!
\brief generic set operation for graph
\param obj the hooked object to operation. We deduce its corresponding
argument from its type.
\param op operation that is going to be applied to obj and its
corresponding object.
The idea is to give a single interface for generic set operation
functions. For example if object is a set of nodes we provide
the target for the operation as the nodes of this graph, if it is an
edge we provide a set of edges of this graph
"""
is_type(val=g, originType=AbstractGraph, shouldRaiseError=True)
is_node = isinstance(obj, AbstractNode)
if is_node:
return BaseGraphSetOps.set_op_node_edge(g=g, obj=set([obj]), op=op)
is_edge = isinstance(obj, AbstractEdge)
if is_edge:
return BaseGraphSetOps.set_op_node_edge(g=g, obj=set([obj]), op=op)
is_set = isinstance(obj, (set, frozenset))
if is_set:
return BaseGraphSetOps.set_op_node_edge(g=g, obj=obj, op=op)
is_graph = isinstance(obj, AbstractGraph)
if is_graph:
oeset = BaseGraphOps.edges(obj)
onset = BaseGraphOps.nodes(obj)
oedge_set = BaseGraphSetOps.set_op(g, obj=oeset, op=op)
onode_set = BaseGraphSetOps.set_op(g, obj=onset, op=op)
gdata = g.data()
gdata.update(obj.data())
return BaseGraph(
gid=str(uuid4()), nodes=onode_set, edges=oedge_set, data=gdata
)
else:
raise TypeError(
"argument type is not supported: " + type(obj).__name__
)

@staticmethod
def intersection(
g: AbstractGraph,
aset: Union[
Set[AbstractNode],
Set[AbstractEdge],
AbstractGraph,
AbstractNode,
AbstractEdge,
],
) -> Union[Set[AbstractNode], Set[AbstractEdge], AbstractGraph]:
"""!
\brief obtain intersection of either node or edge set
"""
is_type(val=g, originType=AbstractGraph, shouldRaiseError=True)
return BaseGraphSetOps.set_op(
g, obj=aset, op=lambda gset, y: gset.intersection(y)
)

@staticmethod
def union(
g: AbstractGraph,
aset: Union[
Set[AbstractNode],
Set[AbstractEdge],
AbstractGraph,
AbstractEdge,
AbstractNode,
],
) -> Union[Set[AbstractNode], Set[AbstractEdge], AbstractGraph]:
"""!
\brief obtain union of either node or edge set
"""
is_type(val=g, originType=AbstractGraph, shouldRaiseError=True)
return BaseGraphSetOps.set_op(
g, obj=aset, op=lambda gset, y: gset.union(y)
)

@staticmethod
def difference(
g: AbstractGraph,
aset: Union[
Set[AbstractNode],
Set[AbstractEdge],
AbstractGraph,
AbstractEdge,
AbstractNode,
],
) -> Union[Set[AbstractNode], Set[AbstractEdge], AbstractGraph]:
"""!
\brief obtain set difference of either node or edge set
"""
is_type(val=g, originType=AbstractGraph, shouldRaiseError=True)
return BaseGraphSetOps.set_op(
g, obj=aset, op=lambda gset, y: gset.difference(y)
)

@staticmethod
def symmetric_difference(
g: AbstractGraph,
aset: Union[
Set[AbstractNode],
Set[AbstractEdge],
AbstractGraph,
AbstractNode,
AbstractEdge,
],
) -> Union[Set[AbstractNode], Set[AbstractEdge], AbstractGraph]:
"""!
\brief obtain symmetric set difference of either node or edge set.
"""
is_type(val=g, originType=AbstractGraph, shouldRaiseError=True)
return BaseGraphSetOps.set_op(
g, obj=aset, op=lambda gset, y: gset.symmetric_difference(y)
)

@staticmethod
def contains(
g: AbstractGraph,
a: Union[
Set[AbstractEdge],
Set[AbstractNode],
AbstractGraph,
AbstractNode,
AbstractEdge,
],
) -> bool:
"""!
\brief check if argument set of nodes or edges is contained by graph
"""
is_type(val=g, originType=AbstractGraph, shouldRaiseError=True)
return BaseGraphSetOps.set_op(
g, obj=a, op=lambda gset, y: y.issubset(gset) is True
)


class BaseGraphAlgOps:
""""""

Expand Down Expand Up @@ -270,14 +93,10 @@ def plus_minus(
)
#
if isinstance(el, (set, frozenset)):
return BaseGraphAlgOps.plus_minus_node_edge(
g=g, el=el, is_plus=is_plus
)
return BaseGraphAlgOps.plus_minus_node_edge(g=g, el=el, is_plus=is_plus)
#
if isinstance(el, AbstractGraph):
return BaseGraphAlgOps.plus_minus_node_edge(
g=g, el=el, is_plus=is_plus
)
return BaseGraphAlgOps.plus_minus_node_edge(g=g, el=el, is_plus=is_plus)
raise TypeError("argument type is not compatible with operation")

@staticmethod
Expand Down Expand Up @@ -309,9 +128,7 @@ def added_edge_between_if_none(
The flag is_directed specifies if the edge is directed or not
"""
is_type(val=g, originType=AbstractGraph, shouldRaiseError=True)
if not BaseGraphBoolOps.is_in(g, n1) or not BaseGraphBoolOps.is_in(
g, n2
):
if not BaseGraphBoolOps.is_in(g, n1) or not BaseGraphBoolOps.is_in(g, n2):
raise ValueError("one of the nodes is not present in graph")
n1id = n1.id()
n2id = n2.id()
Expand All @@ -322,24 +139,16 @@ def added_edge_between_if_none(
if len(common_edge_ids) == 0:
# there are no edges between the nodes
if isinstance(g, AbstractUndiGraph):
edge = Edge.undirected(
eid=str(uuid4()), start_node=n1, end_node=n2
)
edge = Edge.undirected(eid=str(uuid4()), start_node=n1, end_node=n2)
return BaseGraphAlgOps.add(g, edge)
elif isinstance(g, AbstractDiGraph):
edge = Edge.directed(
eid=str(uuid4()), start_node=n1, end_node=n2
)
edge = Edge.directed(eid=str(uuid4()), start_node=n1, end_node=n2)
return BaseGraphAlgOps.add(g, edge)
elif is_directed is True:
edge = Edge.directed(
eid=str(uuid4()), start_node=n1, end_node=n2
)
edge = Edge.directed(eid=str(uuid4()), start_node=n1, end_node=n2)
return BaseGraphAlgOps.add(g, edge)
elif is_directed is False:
edge = Edge.undirected(
eid=str(uuid4()), start_node=n1, end_node=n2
)
edge = Edge.undirected(eid=str(uuid4()), start_node=n1, end_node=n2)
return BaseGraphAlgOps.add(g, edge)
else:
raise ValueError("Must specify an edge type to be added")
Expand Down
Loading

0 comments on commit 4984de5

Please sign in to comment.