From b241f9b23b225dec5ffc3f8ddd6c81771091f599 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Mon, 7 Dec 2020 18:08:33 +0000 Subject: Add diagnostics for (un)filtered answer ratio --- src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala | 26 +++++++++++++++++----- .../scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | 14 ++++++++++++ .../rsacomb/sparql/ConjunctiveQueryAnswers.scala | 3 +++ 3 files changed, 38 insertions(+), 5 deletions(-) (limited to 'src/main') diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala index 60511af..6891c8c 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala @@ -57,13 +57,29 @@ object RSAComb extends App { Logger print "Ontology is RSA!" /** Read SPARQL query from file */ - val query = RDFoxUtil.loadQueryFromFile(queryPath.getAbsoluteFile) - - /* Compute answers to query */ - ConjunctiveQuery.parse(query).map(ontology ask _) match { - case Some(answers) => Logger print answers + val strQuery = RDFoxUtil.loadQueryFromFile(queryPath.getAbsoluteFile) + val query = ConjunctiveQuery parse strQuery + + query match { + case Some(query) => { + val answers = ontology ask query + Logger.print(s"$answers", Logger.QUIET) + Logger print s"Number of answer: ${answers.length}" + + val unfiltered = ontology askUnfiltered query + val percentage = unfiltered match { + case Some(u) => + if (u.length > 0) (1 - answers.length / u.length) * 100 else 0 + case None => 0 + } + Logger.print( + s"Percentage of spurious answers: $percentage%", + Logger.DEBUG + ) + } case None => throw new RuntimeException("Submitted query is not conjunctive") } + } } 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 708e4c7..6a34555 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala @@ -403,6 +403,20 @@ class RSAOntology(val ontology: OWLOntology) { answers } + /** Returns set of unfiltered answers. + * + * This is equivalent to quering just the canonical model. + * + * @note this method does not load any data to RDFox. The return + * value is considered well defined only after + * [[uk.ac.ox.cs.rsacomb.RSAOntology.ask RSAOntology.ask]] + * for the corresponding query has been called. + */ + def askUnfiltered(cq: ConjunctiveQuery): Option[Seq[Seq[Resource]]] = { + val query = RDFoxUtil.buildDescriptionQuery("QM", cq.variables.length) + queryDataStore(cq, query, RSA.Prefixes) + } + def self(axiom: OWLSubClassOfAxiom): Set[Term] = { // Assuming just one role in the signature of a T5 axiom val role = axiom.objectPropertyExpressionsInSignature(0) diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswers.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswers.scala index 327ae8e..50cbb86 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswers.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswers.scala @@ -17,6 +17,9 @@ class ConjunctiveQueryAnswers( val answers: Seq[Seq[Resource]] ) { + /** Returns number of answers. */ + val length: Int = if (bcq) 0 else answers.length + override def toString(): String = if (bcq) { if (answers.isEmpty) "FALSE" else "TRUE" -- cgit v1.2.3