diff options
| author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-11-20 17:55:02 +0000 |
|---|---|---|
| committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-11-20 17:55:02 +0000 |
| commit | 86176ae04b02adbc63ccc1f9704a61cc6b7b10c3 (patch) | |
| tree | 581364ba4432ac4ff4f61e28e9581c6219b00e0f | |
| parent | 0ac35ab057257eadc297d430666d0c1da41756f6 (diff) | |
| download | RSAComb-86176ae04b02adbc63ccc1f9704a61cc6b7b10c3.tar.gz RSAComb-86176ae04b02adbc63ccc1f9704a61cc6b7b10c3.zip | |
Update RSAOntology interface for query answering
| -rw-r--r-- | src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | 64 | ||||
| -rw-r--r-- | src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxHelpers.scala | 25 |
2 files changed, 61 insertions, 28 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 56fbac3..9ef8986 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | |||
| @@ -22,6 +22,7 @@ import org.semanticweb.owlapi.model.{IRI => OWLIRI} | |||
| 22 | import uk.ac.manchester.cs.owl.owlapi.OWLObjectPropertyImpl | 22 | import uk.ac.manchester.cs.owl.owlapi.OWLObjectPropertyImpl |
| 23 | 23 | ||
| 24 | import tech.oxfordsemantic.jrdfox.client.{UpdateType, DataStoreConnection} | 24 | import tech.oxfordsemantic.jrdfox.client.{UpdateType, DataStoreConnection} |
| 25 | import tech.oxfordsemantic.jrdfox.Prefixes | ||
| 25 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ | 26 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ |
| 26 | Rule, | 27 | Rule, |
| 27 | TupleTableAtom, | 28 | TupleTableAtom, |
| @@ -302,40 +303,47 @@ class RSAOntology(val ontology: OWLOntology) extends RSAAxiom { | |||
| 302 | val (server, data) = RDFoxHelpers.openConnection("AnswerComputation") | 303 | val (server, data) = RDFoxHelpers.openConnection("AnswerComputation") |
| 303 | data.addRules(this.canonicalModel.rules) | 304 | data.addRules(this.canonicalModel.rules) |
| 304 | data.addRules(this.filteringProgram(query).rules) | 305 | data.addRules(this.filteringProgram(query).rules) |
| 305 | new ConjunctiveQueryAnswers( | 306 | val answers = RDFoxHelpers |
| 306 | query.boolean, | 307 | .submitQuery( |
| 307 | queryInternalPredicate(data, "Ans", query.answer.size) | 308 | data, |
| 308 | ) | 309 | RDFoxHelpers.buildDescriptionQuery("Ans", query.answer.size), |
| 310 | RSA.Prefixes | ||
| 311 | ) | ||
| 312 | .map( | ||
| 313 | new ConjunctiveQueryAnswers(query.boolean, _) | ||
| 314 | ) | ||
| 315 | .get | ||
| 316 | RDFoxHelpers.closeConnection(server, data) | ||
| 317 | answers | ||
| 309 | } | 318 | } |
| 310 | 319 | ||
| 311 | /** Returns instances of a reified predicate | 320 | /** Query the logic program used to compute answers to a given CQ. |
| 321 | * | ||
| 322 | * This method has been introduced mostly for debugging purposes. | ||
| 312 | * | 323 | * |
| 313 | * Predicated with arity higher than 2 are internally reified to be | 324 | * @param cq a CQ used to compute the environment. |
| 314 | * compatible with RDFox engine. This helper queries for predicate | 325 | * @param query query to be executed against the environment |
| 315 | * instances and returns a set of un-reified answers. | 326 | * @param prefixes additional prefixes for the query. It defaults to |
| 327 | * an empty set. | ||
| 328 | * @param opts additional options to RDFox. | ||
| 329 | * @return a collection of answers to the input query. | ||
| 316 | * | 330 | * |
| 317 | * @param data open datastore connection to RDFox | 331 | * @todo this function currently fails because RDFox reports a |
| 318 | * @param pred name of the predicate | 332 | * datastore duplication. |
| 319 | * @param arity arity of the predicate | ||
| 320 | * @param opts additional options to RDFox | ||
| 321 | * @return a collection of instances of the given predicate | ||
| 322 | */ | 333 | */ |
| 323 | private def queryInternalPredicate( | 334 | def queryEnvironment( |
| 324 | data: DataStoreConnection, | 335 | cq: ConjunctiveQuery, |
| 325 | pred: String, | 336 | query: String, |
| 326 | arity: Int, | 337 | prefixes: Prefixes = new Prefixes(), |
| 327 | opts: ju.Map[String, String] = new ju.HashMap[String, String]() | 338 | opts: ju.Map[String, String] = new ju.HashMap[String, String]() |
| 328 | ): Seq[Seq[Resource]] = { | 339 | ): Option[Seq[Seq[Resource]]] = { |
| 329 | val query = | 340 | import implicits.JavaCollections._ |
| 330 | if (arity > 0) { | 341 | val (server, data) = RDFoxHelpers.openConnection("AnswerComputation") |
| 331 | (0 until arity).mkString("SELECT ?X", " ?X", "\n") + | 342 | data.addRules(this.canonicalModel.rules) |
| 332 | (0 until arity) | 343 | data.addRules(this.filteringProgram(cq).rules) |
| 333 | .map(i => s"?S rsa:${pred :: Nth(i)} ?X$i .") | 344 | val answers = RDFoxHelpers.submitQuery(data, query, prefixes, opts) |
| 334 | .mkString("WHERE {\n", "\n", "\n}") | 345 | RDFoxHelpers.closeConnection(server, data) |
| 335 | } else { | 346 | answers |
| 336 | s"ASK { ?X a rsa:$pred }" | ||
| 337 | } | ||
| 338 | RDFoxHelpers.submitQuery(data, query, RSA.Prefixes).get | ||
| 339 | } | 347 | } |
| 340 | 348 | ||
| 341 | def self(axiom: OWLSubClassOfAxiom): Set[Term] = { | 349 | def self(axiom: OWLSubClassOfAxiom): Set[Term] = { |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxHelpers.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxHelpers.scala index 43e5d28..369da7f 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxHelpers.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxHelpers.scala | |||
| @@ -10,6 +10,7 @@ import tech.oxfordsemantic.jrdfox.client.{ | |||
| 10 | import tech.oxfordsemantic.jrdfox.formats.SPARQLParser | 10 | import tech.oxfordsemantic.jrdfox.formats.SPARQLParser |
| 11 | import tech.oxfordsemantic.jrdfox.logic.expression.Resource | 11 | import tech.oxfordsemantic.jrdfox.logic.expression.Resource |
| 12 | import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery | 12 | import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery |
| 13 | import uk.ac.ox.cs.rsacomb.suffix.Nth | ||
| 13 | 14 | ||
| 14 | /** A collection of helper methods for RDFox */ | 15 | /** A collection of helper methods for RDFox */ |
| 15 | object RDFoxHelpers { | 16 | object RDFoxHelpers { |
| @@ -116,6 +117,30 @@ object RDFoxHelpers { | |||
| 116 | ): Option[QueryAnswers] = | 117 | ): Option[QueryAnswers] = |
| 117 | parseSelectQuery(query, prefixes).map(submitSelectQuery(data, _, opts)) | 118 | parseSelectQuery(query, prefixes).map(submitSelectQuery(data, _, opts)) |
| 118 | 119 | ||
| 120 | /** Returns a query describing an internal predicate. | ||
| 121 | * | ||
| 122 | * In the RSA combined approach internal predicates are reified to be | ||
| 123 | * compatible with RDFox engine. This helper allows to build a query | ||
| 124 | * to gather all instances of an internal predicate | ||
| 125 | * | ||
| 126 | * @param pred name of the predicate to describe. | ||
| 127 | * @param arity arity of the predicate. | ||
| 128 | * @return a string containing a SPARQL query. | ||
| 129 | */ | ||
| 130 | def buildDescriptionQuery( | ||
| 131 | pred: String, | ||
| 132 | arity: Int | ||
| 133 | ): String = { | ||
| 134 | if (arity > 0) { | ||
| 135 | (0 until arity).mkString("SELECT ?X", " ?X", "\n") + | ||
| 136 | (0 until arity) | ||
| 137 | .map(i => s"?S rsa:${pred :: Nth(i)} ?X$i .") | ||
| 138 | .mkString("WHERE {\n", "\n", "\n}") | ||
| 139 | } else { | ||
| 140 | s"ASK { ?X a rsa:$pred }" | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 119 | /** Close an open connection to RDFox. | 144 | /** Close an open connection to RDFox. |
| 120 | * | 145 | * |
| 121 | * @param server server connection | 146 | * @param server server connection |
