From 86176ae04b02adbc63ccc1f9704a61cc6b7b10c3 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Fri, 20 Nov 2020 17:55:02 +0000 Subject: Update RSAOntology interface for query answering --- .../scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | 64 ++++++++++++---------- .../uk/ac/ox/cs/rsacomb/util/RDFoxHelpers.scala | 25 +++++++++ 2 files changed, 61 insertions(+), 28 deletions(-) (limited to 'src/main/scala') 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} import uk.ac.manchester.cs.owl.owlapi.OWLObjectPropertyImpl import tech.oxfordsemantic.jrdfox.client.{UpdateType, DataStoreConnection} +import tech.oxfordsemantic.jrdfox.Prefixes import tech.oxfordsemantic.jrdfox.logic.datalog.{ Rule, TupleTableAtom, @@ -302,40 +303,47 @@ class RSAOntology(val ontology: OWLOntology) extends RSAAxiom { val (server, data) = RDFoxHelpers.openConnection("AnswerComputation") data.addRules(this.canonicalModel.rules) data.addRules(this.filteringProgram(query).rules) - new ConjunctiveQueryAnswers( - query.boolean, - queryInternalPredicate(data, "Ans", query.answer.size) - ) + val answers = RDFoxHelpers + .submitQuery( + data, + RDFoxHelpers.buildDescriptionQuery("Ans", query.answer.size), + RSA.Prefixes + ) + .map( + new ConjunctiveQueryAnswers(query.boolean, _) + ) + .get + RDFoxHelpers.closeConnection(server, data) + answers } - /** Returns instances of a reified predicate + /** Query the logic program used to compute answers to a given CQ. + * + * This method has been introduced mostly for debugging purposes. * - * Predicated with arity higher than 2 are internally reified to be - * compatible with RDFox engine. This helper queries for predicate - * instances and returns a set of un-reified answers. + * @param cq a CQ used to compute the environment. + * @param query query to be executed against the environment + * @param prefixes additional prefixes for the query. It defaults to + * an empty set. + * @param opts additional options to RDFox. + * @return a collection of answers to the input query. * - * @param data open datastore connection to RDFox - * @param pred name of the predicate - * @param arity arity of the predicate - * @param opts additional options to RDFox - * @return a collection of instances of the given predicate + * @todo this function currently fails because RDFox reports a + * datastore duplication. */ - private def queryInternalPredicate( - data: DataStoreConnection, - pred: String, - arity: Int, + def queryEnvironment( + cq: ConjunctiveQuery, + query: String, + prefixes: Prefixes = new Prefixes(), opts: ju.Map[String, String] = new ju.HashMap[String, String]() - ): Seq[Seq[Resource]] = { - val query = - if (arity > 0) { - (0 until arity).mkString("SELECT ?X", " ?X", "\n") + - (0 until arity) - .map(i => s"?S rsa:${pred :: Nth(i)} ?X$i .") - .mkString("WHERE {\n", "\n", "\n}") - } else { - s"ASK { ?X a rsa:$pred }" - } - RDFoxHelpers.submitQuery(data, query, RSA.Prefixes).get + ): Option[Seq[Seq[Resource]]] = { + import implicits.JavaCollections._ + val (server, data) = RDFoxHelpers.openConnection("AnswerComputation") + data.addRules(this.canonicalModel.rules) + data.addRules(this.filteringProgram(cq).rules) + val answers = RDFoxHelpers.submitQuery(data, query, prefixes, opts) + RDFoxHelpers.closeConnection(server, data) + answers } 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.{ import tech.oxfordsemantic.jrdfox.formats.SPARQLParser import tech.oxfordsemantic.jrdfox.logic.expression.Resource import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery +import uk.ac.ox.cs.rsacomb.suffix.Nth /** A collection of helper methods for RDFox */ object RDFoxHelpers { @@ -116,6 +117,30 @@ object RDFoxHelpers { ): Option[QueryAnswers] = parseSelectQuery(query, prefixes).map(submitSelectQuery(data, _, opts)) + /** Returns a query describing an internal predicate. + * + * In the RSA combined approach internal predicates are reified to be + * compatible with RDFox engine. This helper allows to build a query + * to gather all instances of an internal predicate + * + * @param pred name of the predicate to describe. + * @param arity arity of the predicate. + * @return a string containing a SPARQL query. + */ + def buildDescriptionQuery( + pred: String, + arity: Int + ): String = { + if (arity > 0) { + (0 until arity).mkString("SELECT ?X", " ?X", "\n") + + (0 until arity) + .map(i => s"?S rsa:${pred :: Nth(i)} ?X$i .") + .mkString("WHERE {\n", "\n", "\n}") + } else { + s"ASK { ?X a rsa:$pred }" + } + } + /** Close an open connection to RDFox. * * @param server server connection -- cgit v1.2.3