aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala')
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala230
1 files changed, 129 insertions, 101 deletions
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala
index 52d4905..87a2312 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala
@@ -54,6 +54,7 @@ import uk.ac.ox.cs.rsacomb.converter._
54import uk.ac.ox.cs.rsacomb.suffix._ 54import uk.ac.ox.cs.rsacomb.suffix._
55import uk.ac.ox.cs.rsacomb.sparql._ 55import uk.ac.ox.cs.rsacomb.sparql._
56import uk.ac.ox.cs.rsacomb.util.{RDFoxUtil, RSA} 56import uk.ac.ox.cs.rsacomb.util.{RDFoxUtil, RSA}
57import uk.ac.ox.cs.rsacomb.util.Logger
57 58
58object RSAOntology { 59object RSAOntology {
59 60
@@ -141,87 +142,91 @@ class RSAOntology(val ontology: OWLOntology) {
141 * why the ontology might not be RSA. This could help a second 142 * why the ontology might not be RSA. This could help a second
142 * step of approximation of an Horn-ALCHOIQ to RSA 143 * step of approximation of an Horn-ALCHOIQ to RSA
143 */ 144 */
144 lazy val isRSA: Boolean = { 145 lazy val isRSA: Boolean = Logger.timed(
145 146 {
146 val unsafe = this.unsafeRoles 147 val unsafe = this.unsafeRoles
147 148
148 /* DEBUG: print rules in DL syntax and unsafe roles */ 149 // val renderer = new DLSyntaxObjectRenderer()
149 //val renderer = new DLSyntaxObjectRenderer() 150 // println()
150 //println("\nDL rules:") 151 // println("Unsafe roles:")
151 //axioms.foreach(x => println(renderer.render(x))) 152 // println(unsafe)
152 //println("\nUnsafe roles:") 153 // println()
153 //println(unsafe) 154 // println("DL rules:")
154 155 // tbox.foreach(x => println(renderer.render(x)))
155 object RSAConverter extends RDFoxConverter { 156
156 157 object RSAConverter extends RDFoxConverter {
157 override def convert( 158
158 expr: OWLClassExpression, 159 override def convert(
159 term: Term, 160 expr: OWLClassExpression,
160 unsafe: List[OWLObjectPropertyExpression], 161 term: Term,
161 skolem: SkolemStrategy, 162 unsafe: List[OWLObjectPropertyExpression],
162 suffix: RSASuffix 163 skolem: SkolemStrategy,
163 ): Shards = 164 suffix: RSASuffix
164 (expr, skolem) match { 165 ): Shards =
165 166 (expr, skolem) match {
166 case (e: OWLObjectSomeValuesFrom, c: Constant) 167
167 if unsafe contains e.getProperty => { 168 case (e: OWLObjectSomeValuesFrom, c: Constant)
168 val (res, ext) = super.convert(e, term, unsafe, skolem, suffix) 169 if unsafe contains e.getProperty => {
169 (RSA.PE(term, c.iri) :: RSA.U(c.iri) :: res, ext) 170 val (res, ext) = super.convert(e, term, unsafe, skolem, suffix)
170 } 171 (RSA.PE(term, c.iri) :: RSA.U(c.iri) :: res, ext)
171 172 }
172 case (e: OWLDataSomeValuesFrom, c: Constant) 173
173 if unsafe contains e.getProperty => { 174 case (e: OWLDataSomeValuesFrom, c: Constant)
174 val (res, ext) = super.convert(e, term, unsafe, skolem, suffix) 175 if unsafe contains e.getProperty => {
175 (RSA.PE(term, c.iri) :: RSA.U(c.iri) :: res, ext) 176 val (res, ext) = super.convert(e, term, unsafe, skolem, suffix)
177 (RSA.PE(term, c.iri) :: RSA.U(c.iri) :: res, ext)
178 }
179
180 case _ => super.convert(expr, term, unsafe, skolem, suffix)
176 } 181 }
177 182
178 case _ => super.convert(expr, term, unsafe, skolem, suffix) 183 }
179 } 184
180 185 /* Ontology convertion into LP rules */
181 } 186 val term = RSAOntology.genFreshVariable()
182 187 val datalog = axioms
183 /* Ontology convertion into LP rules */ 188 .map(a => RSAConverter.convert(a, term, unsafe, new Constant(a), Empty))
184 val term = RSAOntology.genFreshVariable() 189 .unzip
185 val datalog = axioms 190 val facts = datalog._1.flatten
186 .map(a => RSAConverter.convert(a, term, unsafe, new Constant(a), Empty)) 191 val rules = datalog._2.flatten
187 .unzip 192
188 val facts = datalog._1.flatten 193 //println("Datalog rules:")
189 val rules = datalog._2.flatten 194 //rules foreach println
190 195
191 /* DEBUG: print datalog rules */ 196 // Open connection with RDFox
192 //println("\nDatalog rules:") 197 val (server, data) = RDFoxUtil.openConnection("RSACheck")
193 //rules.foreach(println) 198
194 199 /* Add built-in rules
195 // Open connection with RDFox 200 * TODO: substitute with RDFoxUtil.addRules
196 val (server, data) = RDFoxUtil.openConnection("RSACheck") 201 */
197 202 data.importData(
198 /* Add built-in rules 203 UpdateType.ADDITION,
199 * TODO: substitute with RDFoxUtil.addRules 204 RSA.Prefixes,
200 */ 205 "rsa:E[?X,?Y] :- rsa:PE[?X,?Y], rsa:U[?X], rsa:U[?Y] ."
201 data.importData( 206 )
202 UpdateType.ADDITION,
203 RSA.Prefixes,
204 "rsa:E[?X,?Y] :- rsa:PE[?X,?Y], rsa:U[?X], rsa:U[?Y] ."
205 )
206
207 /* Add ontology facts and rules */
208 RDFoxUtil.addFacts(data, facts)
209 RDFoxUtil.addRules(data, rules)
210
211 /* Build graph */
212 val graph = this.rsaGraph(data);
213 //println(graph)
214
215 // Close connection to RDFox
216 RDFoxUtil.closeConnection(server, data)
217 207
218 /* To check if the graph is tree-like we check for acyclicity in a 208 /* Add ontology facts and rules */
219 * undirected graph. 209 RDFoxUtil.addFacts(data, facts)
220 * 210 RDFoxUtil.addRules(data, rules)
221 * TODO: Implement additional checks (taking into account equality) 211
222 */ 212 /* Build graph */
223 graph.isAcyclic 213 val graph = this.rsaGraph(data);
224 } 214 //println("Graph:")
215 //println(graph)
216
217 // Close connection to RDFox
218 RDFoxUtil.closeConnection(server, data)
219
220 /* To check if the graph is tree-like we check for acyclicity in a
221 * undirected graph.
222 *
223 * TODO: Implement additional checks (taking into account equality)
224 */
225 graph.isAcyclic
226 },
227 "RSA check",
228 Logger.DEBUG
229 )
225 230
226 lazy val unsafeRoles: List[OWLObjectPropertyExpression] = { 231 lazy val unsafeRoles: List[OWLObjectPropertyExpression] = {
227 232
@@ -288,9 +293,17 @@ class RSAOntology(val ontology: OWLOntology) {
288 } 293 }
289 294
290 def filteringProgram(query: ConjunctiveQuery): FilteringProgram = 295 def filteringProgram(query: ConjunctiveQuery): FilteringProgram =
291 new FilteringProgram(query, individuals) 296 Logger.timed(
297 new FilteringProgram(query, individuals),
298 "Generating filtering program",
299 Logger.DEBUG
300 )
292 301
293 lazy val canonicalModel = new CanonicalModel(this) 302 lazy val canonicalModel = Logger.timed(
303 new CanonicalModel(this),
304 "Generating canonical model program",
305 Logger.DEBUG
306 )
294 307
295 // TODO: the following functions needs testing 308 // TODO: the following functions needs testing
296 def confl( 309 def confl(
@@ -321,27 +334,42 @@ class RSAOntology(val ontology: OWLOntology) {
321 * @param query query to execute 334 * @param query query to execute
322 * @return a collection of answers 335 * @return a collection of answers
323 */ 336 */
324 def ask(query: ConjunctiveQuery): ConjunctiveQueryAnswers = { 337 def ask(query: ConjunctiveQuery): ConjunctiveQueryAnswers = Logger.timed(
325 import implicits.JavaCollections._ 338 {
326 val (server, data) = RDFoxUtil.openConnection(RSAOntology.DataStore) 339 import implicits.JavaCollections._
327 val filter = this.filteringProgram(query) 340 val (server, data) = RDFoxUtil.openConnection(RSAOntology.DataStore)
328 RDFoxUtil.addRules(data, this.canonicalModel.rules) 341 val canon = this.canonicalModel
329 RDFoxUtil.addFacts(data, this.canonicalModel.facts) 342 val filter = this.filteringProgram(query)
330 RDFoxUtil.addRules(data, filter.rules) 343
331 RDFoxUtil.addFacts(data, filter.facts) 344 Logger print s"Canonical model: ${canon.rules.length} rules"
332 val answers = RDFoxUtil 345 RDFoxUtil.addRules(data, this.canonicalModel.rules)
333 .submitQuery( 346
334 data, 347 Logger print s"Canonical model: ${canon.facts.length} facts"
335 RDFoxUtil.buildDescriptionQuery("Ans", query.answer.size), 348 RDFoxUtil.addFacts(data, this.canonicalModel.facts)
336 RSA.Prefixes 349
337 ) 350 RDFoxUtil printStatisticsFor data
338 .map( 351
339 new ConjunctiveQueryAnswers(query.bcq, _) 352 Logger print s"Filtering program: ${filter.rules.length} rules"
340 ) 353 RDFoxUtil.addRules(data, filter.rules)
341 .get 354
342 RDFoxUtil.closeConnection(server, data) 355 Logger print s"Filtering program: ${filter.facts.length} facts"
343 answers 356 RDFoxUtil.addFacts(data, filter.facts)
344 } 357
358 RDFoxUtil printStatistics data
359
360 val answers = {
361 val ans = RDFoxUtil.buildDescriptionQuery("Ans", query.answer.size)
362 RDFoxUtil
363 .submitQuery(data, ans, RSA.Prefixes)
364 .map(new ConjunctiveQueryAnswers(query.bcq, query.variables, _))
365 .get
366 }
367 RDFoxUtil.closeConnection(server, data)
368 answers
369 },
370 "Answers computation",
371 Logger.DEBUG
372 )
345 373
346 /** Query the RDFox data store used for query answering. 374 /** Query the RDFox data store used for query answering.
347 * 375 *