Skip to content
This repository was archived by the owner on Oct 8, 2020. It is now read-only.

Commit 2295952

Browse files
Added cycle and loop detection for RDG.
1 parent edbdfe3 commit 2295952

2 files changed

Lines changed: 52 additions & 3 deletions

File tree

sansa-inference-common/src/main/scala/net/sansa_stack/inference/rules/RuleDependencyGraph.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.sansa_stack.inference.rules
22

3+
import scala.collection.mutable
34
import scalax.collection.Graph
45
import scalax.collection.edge.LDiEdge
56
import scalax.collection.mutable.DefaultGraphImpl
@@ -48,4 +49,25 @@ class RuleDependencyGraph(iniNodes: Iterable[Rule] = Set[Rule](),
4849
))
4950
)
5051

52+
/**
53+
* Returns all nodes that are connected by an edge to itself.
54+
*
55+
* @return
56+
*/
57+
def loopNodes(): mutable.Set[NodeBase] = {
58+
nodes.filter(n => n.outgoing.map(_.target).contains(n))
59+
}
60+
61+
/**
62+
* Returns true if there is a cycle in the graph, i.e. either
63+
*
64+
* - there is a path n1 -> n2 -> ... -> n1 or
65+
* - a loop, i.e. an edge that connects a vertex to itself.
66+
*
67+
* @return
68+
*/
69+
def hasCycle(): Boolean = {
70+
loopNodes().nonEmpty || findCycle.isDefined
71+
}
72+
5173
}

sansa-inference-common/src/main/scala/net/sansa_stack/inference/rules/RuleDependencyGraphGenerator.scala

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import scalax.collection.GraphTraversal.Parameters
77
import scalax.collection._
88
import scalax.collection.edge.Implicits._
99
import scalax.collection.edge._
10+
import scalax.collection.mutable.DefaultGraphImpl
1011

1112
import org.apache.jena.graph.Node
1213
import org.apache.jena.reasoner.TriplePattern
@@ -54,6 +55,8 @@ object RuleDependencyGraphGenerator extends Logging {
5455
g += (r2 ~+> r1) (r2r1.get)
5556
}
5657
}
58+
59+
// cycles?
5760
val r1r1 = f(r1, r1)
5861
if (r1r1.isDefined) { // r1 depends on r1, i.e. reflexive dependency
5962
g += (r1 ~+> r1) (r1r1.get)
@@ -65,7 +68,7 @@ object RuleDependencyGraphGenerator extends Logging {
6568
g = removeEdgesWithPredicateAlreadyTC(g)
6669
g = removeCyclesIfPredicateIsTC(g)
6770
g = removeEdgesWithCycleOverTCNode(g)
68-
// g = prune(g)
71+
g = prune(g)
6972
// g = prune1(g)
7073
}
7174

@@ -143,10 +146,11 @@ object RuleDependencyGraphGenerator extends Logging {
143146
ret
144147
}
145148

146-
147149
def prune(graph: RuleDependencyGraph): RuleDependencyGraph = {
148150
var redundantEdges = Seq[Graph[Rule, LDiEdge]#EdgeT]()
149151

152+
// graph.outerNodeTraverser.foreach(n => println(n))
153+
150154
// for each node n in G
151155
graph.nodes.foreach(node => {
152156
debug("#" * 20)
@@ -216,6 +220,27 @@ object RuleDependencyGraphGenerator extends Logging {
216220

217221
}
218222

223+
def removeRedundantEdges(graph: RuleDependencyGraph): RuleDependencyGraph = {
224+
debug("removeRedundantEdges")
225+
var redundantEdges = Seq[Graph[Rule, LDiEdge]#EdgeT]()
226+
227+
// for each node n in G
228+
graph.nodes.foreach(node => {
229+
debug("#" * 20)
230+
debug(s"NODE:${node.value.getName}")
231+
232+
// check for nodes that do compute the TC
233+
val outgoingEdges = node.outgoing.withFilter(e => e.target != node)
234+
235+
outgoingEdges.foreach(e => {
236+
val targetNode = e.target
237+
238+
})
239+
})
240+
241+
graph
242+
}
243+
219244
// get all nodes that depend on a TC node for a predicate p and another node for p
220245
def removeEdgesWithPredicateAlreadyTC(graph: RuleDependencyGraph): RuleDependencyGraph = {
221246
debug("removeEdgesWithPredicateAlreadyTC")
@@ -366,7 +391,7 @@ object RuleDependencyGraphGenerator extends Logging {
366391
}
367392

368393
def removeCyclesIfPredicateIsTC(graph: RuleDependencyGraph): RuleDependencyGraph = {
369-
394+
debug("removeCyclesIfPredicateIsTC")
370395
var redundantEdges = Seq[Graph[Rule, LDiEdge]#EdgeT]()
371396

372397
// for each node n in G
@@ -463,4 +488,6 @@ object RuleDependencyGraphGenerator extends Logging {
463488
val e = edge.toOuter
464489
"[" + e.source.getName + " ~> " + e.target.getName + "] '" + e.label
465490
}
491+
492+
// override def debug(msg: => String): Unit = println(msg)
466493
}

0 commit comments

Comments
 (0)