aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFederico Igne <federico.igne@cs.ox.ac.uk>2020-08-19 14:21:25 +0100
committerFederico Igne <federico.igne@cs.ox.ac.uk>2020-08-19 14:21:25 +0100
commitfce66bdc060fe3ec6bd07fd17eca68ea45f119fa (patch)
tree2645225f369e90bc1059d85b3b8a955ed9c39f5a /src
parent50f5cd42f73b655d7d349eef70e5c269826429f9 (diff)
downloadRSAComb-fce66bdc060fe3ec6bd07fd17eca68ea45f119fa.tar.gz
RSAComb-fce66bdc060fe3ec6bd07fd17eca68ea45f119fa.zip
Add check for RSA graph acyclicity
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/rsacomb/RSAOntology.scala84
1 files changed, 44 insertions, 40 deletions
diff --git a/src/main/scala/rsacomb/RSAOntology.scala b/src/main/scala/rsacomb/RSAOntology.scala
index 10f2fa4..3d9210e 100644
--- a/src/main/scala/rsacomb/RSAOntology.scala
+++ b/src/main/scala/rsacomb/RSAOntology.scala
@@ -9,16 +9,16 @@ import org.semanticweb.owlapi.model.OWLObjectPropertyExpression
9import org.semanticweb.owlapi.model.parameters.Imports 9import org.semanticweb.owlapi.model.parameters.Imports
10import org.semanticweb.owlapi.reasoner.structural.StructuralReasonerFactory 10import org.semanticweb.owlapi.reasoner.structural.StructuralReasonerFactory
11 11
12import tech.oxfordsemantic.jrdfox.logic.Variable 12import tech.oxfordsemantic.jrdfox.client.{UpdateType, DataStoreConnection}
13import tech.oxfordsemantic.jrdfox.client.UpdateType 13import tech.oxfordsemantic.jrdfox.logic.{Resource, Rule, Atom, Variable, IRI}
14import tech.oxfordsemantic.jrdfox.logic.{Rule, Atom, Variable, IRI}
15 14
16/* Scala imports */ 15/* Scala imports */
17import scala.collection.JavaConverters._ 16import scala.collection.JavaConverters._
17import scalax.collection.immutable.Graph
18import scalax.collection.GraphEdge.UnDiEdge
18 19
19/* Debug only */ 20/* Debug only */
20import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer 21import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer
21import java.io.OutputStream
22 22
23/* Wrapper trait for the implicit class `RSAOntology`. 23/* Wrapper trait for the implicit class `RSAOntology`.
24 */ 24 */
@@ -29,24 +29,22 @@ trait RSAOntology {
29 */ 29 */
30 implicit class RSAOntology(ontology: OWLOntology) extends RSAAxiom { 30 implicit class RSAOntology(ontology: OWLOntology) extends RSAAxiom {
31 31
32 /* Steps for RSA check
33 * 1) convert ontology axioms into LP rules
34 * 2) call RDFox on the onto and compute materialization
35 * 3) build graph from E(x,y) facts
36 * 4) check if the graph is tree-like
37 * ideally this annotates the graph with info about the reasons
38 * why the ontology might not be RSA. This could help a second
39 * step of approximation of an Horn-ALCHOIQ to RSA
40 */
32 def isRSA: Boolean = { 41 def isRSA: Boolean = {
33 42
34 /* TODO: Steps for RSA check 43 val tbox = ontology.tboxAxioms(Imports.INCLUDED)
35 * 1) convert ontology axioms into LP rules 44 val rbox = ontology.rboxAxioms(Imports.INCLUDED)
36 * 2) call RDFox on the onto and compute materialization 45 val axioms =
37 * 3) build graph from E(x,y) facts
38 * 4) check if the graph is tree-like
39 * ideally this annotates the graph with info about the reasons
40 * why the ontology might not be RSA. This could help a second
41 * step of approximation of an Horn-ALCHOIQ to RSA
42 */
43
44 val tbox =
45 Stream 46 Stream
46 .concat( 47 .concat(tbox, rbox)
47 ontology.tboxAxioms(Imports.INCLUDED),
48 ontology.rboxAxioms(Imports.INCLUDED)
49 )
50 .collect(Collectors.toList()) 48 .collect(Collectors.toList())
51 .asScala 49 .asScala
52 val unsafe = ontology.getUnsafeRoles 50 val unsafe = ontology.getUnsafeRoles
@@ -54,13 +52,13 @@ trait RSAOntology {
54 /* DEBUG: print rules in DL syntax and unsafe roles */ 52 /* DEBUG: print rules in DL syntax and unsafe roles */
55 val renderer = new DLSyntaxObjectRenderer() 53 val renderer = new DLSyntaxObjectRenderer()
56 println("\nDL rules:") 54 println("\nDL rules:")
57 tbox.foreach(x => println(renderer.render(x))) 55 axioms.foreach(x => println(renderer.render(x)))
58 println("\nUnsafe roles:") 56 println("\nUnsafe roles:")
59 println(unsafe) 57 println(unsafe)
60 58
61 /* Ontology convertion into LP rules */ 59 /* Ontology convertion into LP rules */
62 val datalog = for { 60 val datalog = for {
63 axiom <- tbox 61 axiom <- axioms
64 visitor = new RDFoxAxiomConverter( 62 visitor = new RDFoxAxiomConverter(
65 Variable.create("x"), 63 Variable.create("x"),
66 SkolemStrategy.ConstantRSA(axiom.toString), 64 SkolemStrategy.ConstantRSA(axiom.toString),
@@ -90,29 +88,20 @@ trait RSAOntology {
90 */ 88 */
91 data.addRules(datalog.asJava) 89 data.addRules(datalog.asJava)
92 90
93 // Retrieve all instances of PE 91 /* Build graph
94 println("\nQueries:") 92 */
95 RDFoxUtil.query( 93 val graph = getRSAGraph(data);
96 data, 94 println(graph)
97 RSA.Prefixes,
98 "SELECT ?X ?Y WHERE { ?X internal:PE ?Y }"
99 )
100 RDFoxUtil.query(
101 data,
102 RSA.Prefixes,
103 "SELECT ?X ?Y WHERE { ?X internal:E ?Y }"
104 )
105 RDFoxUtil.query(
106 data,
107 RSA.Prefixes,
108 "SELECT ?X WHERE { ?X rdf:type owl:Thing }"
109 )
110 95
111 // Close connection to RDFox 96 // Close connection to RDFox
112 RDFoxUtil.closeConnection(server, data) 97 RDFoxUtil.closeConnection(server, data)
113 98
114 /* DEBUG */ 99 /* To check if the graph is tree-like we check for acyclicity in a
115 true 100 * undirected graph.
101 *
102 * TODO: Implement additional checks (taking into account equality)
103 */
104 graph.isAcyclic
116 } 105 }
117 106
118 def getUnsafeRoles: List[OWLObjectPropertyExpression] = { 107 def getUnsafeRoles: List[OWLObjectPropertyExpression] = {
@@ -180,6 +169,21 @@ trait RSAOntology {
180 (unsafe1 ++ unsafe2).toList 169 (unsafe1 ++ unsafe2).toList
181 } 170 }
182 171
172 def getRSAGraph(
173 data: DataStoreConnection
174 ): Graph[Resource, UnDiEdge] = {
175 val query = "SELECT ?X ?Y WHERE { ?X internal:E ?Y }"
176 val cursor =
177 data.createCursor(RSA.Prefixes, query, new HashMap[String, String]());
178 var mul = cursor.open()
179 var edges: List[UnDiEdge[Resource]] = List()
180 while (mul > 0) {
181 edges = UnDiEdge(cursor.getResource(0), cursor.getResource(1)) :: edges
182 mul = cursor.advance()
183 }
184 Graph(edges: _*)
185 }
186
183 } // implicit class RSAOntology 187 } // implicit class RSAOntology
184 188
185} // trait RSAOntology 189} // trait RSAOntology