-type Subgraph = [([Resource], [Resource])]
-data Subgraphs = Subgraphs Resource Subgraph
+import "Simantics/Model"
+import "http://www.simantics.org/DistrictNetwork-1.0" as DN
+
+import "Comparator"
+@private
+importJava "org.simantics.utils.strings.AlphanumComparator" where
+ @JavaName CASE_INSENSITIVE_COMPARATOR
+ alphanumericComparator :: Comparator String
+
+type Subgraph = ([Resource], [Resource])
+type Subgraphs = (Resource, [Subgraph])
+type ElementFilter = (Resource -> <ReadGraph> Boolean)
@private
-floodFill :: Resource -> <ReadGraph, Proc> Subgraph
-floodFill fromVertex = do
+floodFill :: ElementFilter -> Resource -> <ReadGraph, Proc> Subgraph
+floodFill edgeFilter fromVertex = do
processVertex fromVertex
(MSet.toList vertices, MSet.toList edges)
where
for starts processEdgeStart
for ends processEdgeEnd
else ()
- processEdgeStart edge = if MSet.add edges edge then for (edge # DN.HasEndVertex) processVertex else ()
- processEdgeEnd edge = if MSet.add edges edge then for (edge # DN.HasStartVertex) processVertex else ()
+ processEdgeStart edge = if MSet.add edges edge && edgeFilter edge then
+ for (edge # DN.HasEndVertex) processVertex
+ else ()
+ processEdgeEnd edge = if MSet.add edges edge && edgeFilter edge then
+ for (edge # DN.HasStartVertex) processVertex
+ else ()
@private
-findDisconnectedSubnetworksFromDiagram :: Resource -> <ReadGraph, Proc> Subgraphs
-findDisconnectedSubnetworksFromDiagram networkDiagram = let
+findDisconnectedSubnetworksFromDiagram :: ElementFilter -> Resource -> <ReadGraph, Proc> Subgraphs
+findDisconnectedSubnetworksFromDiagram edgeFilter networkDiagram = let
all = networkDiagram # L0.ConsistsOf
vertices = filter (flip isInstanceOf DN.Vertex) all
edges = filter (flip isInstanceOf DN.Edge) all
loop Nothing = ()
loop (Just vertex) = do
- subgraph = floodFill vertex
+ subgraph = floodFill edgeFilter vertex
MList.add result subgraph
(vs, es) = subgraph
MSet.removeAll vertexSet vs
loop (take1 vertexSet)
else ()
in do
- print "Total number of vertices: \(length vertices)"
- print "Total number of edges: \(length edges)"
+ //print "Total number of vertices: \(length vertices)"
+ //print "Total number of edges: \(length edges)"
loop (take1 vertexSet)
if MSet.size edgeSet > 0 then
MList.add result ([], MSet.toList edgeSet)
else ()
- print "Found \(MList.size result) disconnected sub-networks"
- Subgraphs networkDiagram (MList.freeze result)
+ //print "Found \(MList.size result) disconnected sub-networks"
+ (networkDiagram, (MList.freeze result))
"""
Finds disconnected district subnetworks from the provided district network diagram.
The input can be either the network diagram resource or the configuration composite
resource of the network diagram.
-See [reportDisconnectedSubnetworks](#reportDisconnectedSubnetworks) for reporting
+See [reportDisconnectedSubnetworks](#reportDisconnectedSubnetworks) for reporting the
+result by printing.
"""
-findDisconnectedSubnetworks :: Resource -> <ReadGraph, Proc> Subgraphs
-findDisconnectedSubnetworks networkDiagramOrComposite = findDisconnectedSubnetworksFromDiagram (toDiagram networkDiagramOrComposite)
+findDisconnectedSubnetworks :: ElementFilter -> Resource -> <ReadGraph, Proc> Subgraphs
+findDisconnectedSubnetworks edgeFilter networkDiagramOrComposite = findDisconnectedSubnetworksFromDiagram edgeFilter (toDiagram networkDiagramOrComposite)
where
toDiagram d = if isInstanceOf d DN.Diagram then d
else match (possibleObject d MOD.CompositeToDiagram) with
Just dia -> toDiagram dia
Nothing -> fail "Provided diagram is not a district network diagram or configuration composite: \(possibleUriOf d)"
-import "Comparator"
-@private
-importJava "org.simantics.utils.strings.AlphanumComparator" where
- @JavaName CASE_INSENSITIVE_COMPARATOR
- alphanumericComparator :: Comparator String
-
reportDisconnectedSubnetworks :: Integer -> Subgraphs -> <ReadGraph, Proc> ()
-reportDisconnectedSubnetworks vertexThreshold (Subgraphs diagram subgraphs) = do
+reportDisconnectedSubnetworks vertexThreshold (diagram, subgraphs) = do
print "## Disconnected sub-network analysis of district network \(relativeUri diagram)"
print "* Detailed reporting vertex count threshold is <= \(vertexThreshold)"
for subgraphs reportGraph
reportShort vs es = do
reportSubgraphTitle vs es
print "* Details not reported because vertex count exceeds threshold"
+ mapFirst (\s -> do print "* v0: \(s)"; Just s)
+ (sortStrings (map showVertex vs))
+ print "* ..."
reportFull vs es = do
reportSubgraphTitle vs es
forI (sortStrings (map showVertex vs)) (\i s -> print "* v\(i): \(s)")