From 6b4226c41ec2a2439fb44a312ccaff01769e8212 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Tue, 1 Jun 2021 11:20:39 +0100 Subject: Fix minor compilation errors --- src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala | 3 +- .../scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | 130 +++++++++++---------- .../ox/cs/rsacomb/approximation/lowerbound.scala | 31 ++++- .../uk/ac/ox/cs/rsacomb/converter/Normalizer.scala | 25 ++-- 4 files changed, 106 insertions(+), 83 deletions(-) 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 a807f75..f2d1a5d 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala @@ -106,12 +106,11 @@ object RSAComb extends App { /* Command-line options */ val config = RSAConfig.parse(args.toList) - val ontology = RSAOntology( + val rsa = RSAOntology( config('ontology).get[File], config('data).get[List[File]], None ) - val rsa = ontology.toRSA() if (config contains 'query) { val query = 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 4d0f13d..247b5d5 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala @@ -80,7 +80,7 @@ object RSAUtil { * construction of the dependency graph is computed regardless. The * input axioms are assumed to be normalized. */ - private def dependencyGraph( + def dependencyGraph( axioms: List[OWLLogicalAxiom], datafiles: List[File] ): (Graph[Resource, DiEdge], Map[String, OWLAxiom]) = { @@ -166,18 +166,23 @@ object RSAOntology { import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ + /** Manager instance to interface with OWLAPI */ + val manager = OWLManager.createOWLOntologyManager() + val factory = manager.getOWLDataFactory() + /** Name of the RDFox data store used for CQ answering */ private val DataStore = "answer_computation" - /** Simple fresh variable generator */ + /** Simple fresh variable/class generator */ private var counter = -1; def genFreshVariable(): Variable = { counter += 1 Variable.create(f"I$counter%05d") } - - /** Manager instance to interface with OWLAPI */ - val manager = OWLManager.createOWLOntologyManager() + def getFreshOWLClass(): OWLClass = { + counter += 1 + factory.getOWLClass(s"X$counter") + } def apply( axioms: List[OWLLogicalAxiom], @@ -254,13 +259,16 @@ class RSAOntology(val axioms: List[OWLLogicalAxiom], val datafiles: File*) { /** Simplify conversion between OWLAPI and RDFox concepts */ import implicits.RDFox._ import uk.ac.ox.cs.rsacomb.implicits.RSAAxiom._ + + /** Simplify conversion between Java and Scala collections */ import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ /** Set of axioms removed during the approximation to RSA */ private var removed: Seq[OWLAxiom] = Seq.empty /** Normalized Horn-ALCHOIQ ontology */ - val ontology = RSAOntology.manager.createOntology(axioms.asJava) + val ontology = + RSAOntology.manager.createOntology((axioms: List[OWLAxiom]).asJava) /** OWLAPI internal reasoner instantiated over the approximated ontology */ private val reasoner = @@ -340,61 +348,61 @@ class RSAOntology(val axioms: List[OWLLogicalAxiom], val datafiles: File*) { * @param graph the graph used to compute the axioms to remove. * @param nodemap map from graph nodes to ontology axioms. */ - def toRSA(): RSAOntology = Logger.timed( - { - - /* Compute the dependency graph for the ontology */ - val (graph, nodemap) = this.dependencyGraph() - - /* Define node colors for the graph visit */ - sealed trait NodeColor - case object Unvisited extends NodeColor - case object Visited extends NodeColor - case object ToDelete extends NodeColor - - /* Keep track of node colors during graph visit */ - var color = Map.from[Resource, NodeColor]( - graph.nodes.toOuter.map(k => (k, Unvisited)) - ) - - for { - component <- graph.componentTraverser().map(_ to Graph) - edge <- component - .outerEdgeTraverser(component.nodes.head) - .withKind(BreadthFirst) - } yield { - val source = edge._1 - val target = edge._2 - color(source) match { - case Unvisited | Visited => { - color(target) match { - case Unvisited => - color(source) = Visited; - color(target) = Visited - case Visited => - color(source) = ToDelete - case ToDelete => - color(source) = Visited - } - } - case ToDelete => - } - } - - val toDelete = color.iterator.collect { case (resource: IRI, ToDelete) => - nodemap(resource.getIRI) - }.toSeq - - /* Remove axioms from approximated ontology */ - ontology.removeAxioms(toDelete: _*) - this.removed = toDelete - - /* Return RSA ontology */ - RSAOntology(ontology, datafiles: _*) - }, - "Horn-ALCHOIQ to RSA approximation:", - Logger.DEBUG - ) + // def toRSA(): RSAOntology = Logger.timed( + // { + + // /* Compute the dependency graph for the ontology */ + // val (graph, nodemap) = this.dependencyGraph() + + // /* Define node colors for the graph visit */ + // sealed trait NodeColor + // case object Unvisited extends NodeColor + // case object Visited extends NodeColor + // case object ToDelete extends NodeColor + + // /* Keep track of node colors during graph visit */ + // var color = Map.from[Resource, NodeColor]( + // graph.nodes.toOuter.map(k => (k, Unvisited)) + // ) + + // for { + // component <- graph.componentTraverser().map(_ to Graph) + // edge <- component + // .outerEdgeTraverser(component.nodes.head) + // .withKind(BreadthFirst) + // } yield { + // val source = edge._1 + // val target = edge._2 + // color(source) match { + // case Unvisited | Visited => { + // color(target) match { + // case Unvisited => + // color(source) = Visited; + // color(target) = Visited + // case Visited => + // color(source) = ToDelete + // case ToDelete => + // color(source) = Visited + // } + // } + // case ToDelete => + // } + // } + + // val toDelete = color.iterator.collect { case (resource: IRI, ToDelete) => + // nodemap(resource.getIRI) + // }.toSeq + + // /* Remove axioms from approximated ontology */ + // ontology.removeAxioms(toDelete: _*) + // this.removed = toDelete + + // /* Return RSA ontology */ + // RSAOntology(ontology, datafiles: _*) + // }, + // "Horn-ALCHOIQ to RSA approximation:", + // Logger.DEBUG + // ) // val edges1 = Seq('A ~> 'B, 'B ~> 'C, 'C ~> 'D, 'D ~> 'H, 'H ~> // 'G, 'G ~> 'F, 'E ~> 'A, 'E ~> 'F, 'B ~> 'E, 'F ~> 'G, 'B ~> 'F, // 'C ~> 'G, 'D ~> 'C, 'H ~> 'D) diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/lowerbound.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/lowerbound.scala index 3437bcd..8a86d19 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/lowerbound.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/lowerbound.scala @@ -2,13 +2,18 @@ package uk.ac.ox.cs.rsacomb.approximation import java.io.File -import org.semanticweb.owlapi.model._ +import org.semanticweb.owlapi.apibinding.OWLManager +import org.semanticweb.owlapi.model.{IRI => _, _} + +import tech.oxfordsemantic.jrdfox.logic.expression.{Resource, IRI} import scala.collection.mutable.{Set, Map} import scalax.collection.Graph import scalax.collection.GraphPredef._, scalax.collection.GraphEdge._ import scalax.collection.GraphTraversal._ +import uk.ac.ox.cs.rsacomb.RSAOntology +import uk.ac.ox.cs.rsacomb.RSAUtil import uk.ac.ox.cs.rsacomb.converter.Normalizer /** Approximation algorithm that mantains soundness for CQ answering. @@ -28,6 +33,16 @@ import uk.ac.ox.cs.rsacomb.converter.Normalizer */ class LowerBound extends Approximation { + /** Simplify conversion between Java and Scala collections */ + import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ + + /** Simplify conversion between OWLAPI and RDFox concepts */ + import uk.ac.ox.cs.rsacomb.implicits.RDFox._ + + /** Manager instance to interface with OWLAPI */ + val manager = OWLManager.createOWLOntologyManager() + val factory = manager.getOWLDataFactory() + val normalizer = new Normalizer() /** Main entry point for the approximation algorithm */ @@ -36,14 +51,14 @@ class LowerBound extends Approximation { datafiles: List[File] ): List[OWLLogicalAxiom] = { /* Normalize axioms */ - val axioms1 = axioms flatMap normalizer.normalize(_) + val axioms1 = ontology flatMap normalizer.normalize /* Delete any axiom outside of ALCHOIQ */ - val axioms2 = axioms1 filterNot inHornLACHOIQ + val axioms2 = axioms1 filterNot inALCHOIQ /* Shift any axiom with disjunction on the rhs */ val axioms3 = for { a1 <- axioms1 a2 <- shift(a1) - a3 <- normalize(a2) + a3 <- normalizer.normalize(a2) } yield a3 /* Approximate to RSA */ toRSA(axioms3, datafiles) @@ -113,8 +128,12 @@ class LowerBound extends Approximation { val sup = a.getSuperClass.getNNF sup match { case sup: OWLObjectUnionOf => { - val body = sub.asConjunctSet.map((atom) => (atom, freshOWLClass())) - val head = sup.asDisjunctSet.map((atom) => (atom, freshOWLClass())) + val body = sub.asConjunctSet.map((atom) => + (atom, RSAOntology.getFreshOWLClass()) + ) + val head = sup.asDisjunctSet.map((atom) => + (atom, RSAOntology.getFreshOWLClass()) + ) val r1 = factory.getOWLSubClassOfAxiom( diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/Normalizer.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/Normalizer.scala index 5329f26..4b298f4 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/Normalizer.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/Normalizer.scala @@ -4,6 +4,7 @@ import org.semanticweb.owlapi.apibinding.OWLManager import org.semanticweb.owlapi.model._ import uk.ac.ox.cs.rsacomb.util.Logger +import uk.ac.ox.cs.rsacomb.RSAOntology object Normalizer { @@ -25,12 +26,6 @@ class Normalizer() { /** Simplify conversion between Java and Scala collections */ import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ - private var counter = -1 - def freshOWLClass(): OWLClass = { - counter += 1 - factory.getOWLClass(s"X$counter") - } - /** Statistics */ var discarded = 0 var shifted = 0 @@ -58,7 +53,7 @@ class Normalizer() { * C c D -> { C c X, X c D } */ case _ if !sub.isOWLClass && !sup.isOWLClass => { - val cls = freshOWLClass() + val cls = RSAOntology.getFreshOWLClass() Seq( factory.getOWLSubClassOfAxiom(sub, cls), factory.getOWLSubClassOfAxiom(cls, sup) @@ -79,7 +74,7 @@ class Normalizer() { if (conj.isOWLClass) (acc1 :+ conj, acc2) else { - val cls = freshOWLClass() + val cls = RSAOntology.getFreshOWLClass() ( acc1 :+ cls, acc2 :+ factory.getOWLSubClassOfAxiom(conj, cls) @@ -138,7 +133,7 @@ class Normalizer() { */ case (sub: OWLObjectSomeValuesFrom, _) if !sub.getFiller.isOWLClass => { - val cls = freshOWLClass() + val cls = RSAOntology.getFreshOWLClass() Seq( factory.getOWLSubClassOfAxiom(sub.getFiller, cls), factory.getOWLSubClassOfAxiom( @@ -153,7 +148,7 @@ class Normalizer() { */ case (_, sup: OWLObjectSomeValuesFrom) if !sup.getFiller.isOWLClass => { - val cls = freshOWLClass() + val cls = RSAOntology.getFreshOWLClass() Seq( factory.getOWLSubClassOfAxiom(cls, sup.getFiller), factory.getOWLSubClassOfAxiom( @@ -298,7 +293,7 @@ class Normalizer() { ) case (_, sup: OWLObjectMaxCardinality) if sup.getCardinality == 1 && !sup.getFiller.isOWLClass => { - val cls = freshOWLClass() + val cls = RSAOntology.getFreshOWLClass() Seq( factory.getOWLSubClassOfAxiom(cls, sup.getFiller), factory.getOWLSubClassOfAxiom( @@ -488,7 +483,7 @@ class Normalizer() { * C(a) -> { X(a), X c C } */ case a: OWLClassAssertionAxiom if !a.getClassExpression.isOWLClass => { - val cls = freshOWLClass() + val cls = RSAOntology.getFreshOWLClass() Seq( factory.getOWLClassAssertionAxiom(cls, a.getIndividual), factory.getOWLSubClassOfAxiom(cls, a.getClassExpression) @@ -532,8 +527,10 @@ class Normalizer() { sub: OWLClassExpression, sup: OWLObjectUnionOf ): Seq[OWLLogicalAxiom] = { - val body = sub.asConjunctSet.map((atom) => (atom, freshOWLClass())) - val head = sup.asDisjunctSet.map((atom) => (atom, freshOWLClass())) + val body = + sub.asConjunctSet.map((atom) => (atom, RSAOntology.getFreshOWLClass())) + val head = + sup.asDisjunctSet.map((atom) => (atom, RSAOntology.getFreshOWLClass())) /* Update statistics */ shifted += 1 -- cgit v1.2.3