diff options
| author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2021-05-31 16:58:15 +0100 |
|---|---|---|
| committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2021-05-31 16:58:15 +0100 |
| commit | 5f9815c3f67114645593840a8648bffb1207b8d0 (patch) | |
| tree | 2a2e14d7fd9c686a8167447b91500bb86de696e4 | |
| parent | e932527e33b6f4c1634995224188b26d870d92b2 (diff) | |
| download | RSAComb-5f9815c3f67114645593840a8648bffb1207b8d0.tar.gz RSAComb-5f9815c3f67114645593840a8648bffb1207b8d0.zip | |
Multiple fixes
4 files changed, 80 insertions, 54 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 74084af..a807f75 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala | |||
| @@ -108,10 +108,10 @@ object RSAComb extends App { | |||
| 108 | 108 | ||
| 109 | val ontology = RSAOntology( | 109 | val ontology = RSAOntology( |
| 110 | config('ontology).get[File], | 110 | config('ontology).get[File], |
| 111 | config('data).get[List[File]]: _* | 111 | config('data).get[List[File]], |
| 112 | None | ||
| 112 | ) | 113 | ) |
| 113 | val rsa = ontology.toRSA() | 114 | val rsa = ontology.toRSA() |
| 114 | ontology.statistics() | ||
| 115 | 115 | ||
| 116 | if (config contains 'query) { | 116 | if (config contains 'query) { |
| 117 | val query = | 117 | 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 e048c28..4d0f13d 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | |||
| @@ -50,13 +50,13 @@ import scala.collection.JavaConverters._ | |||
| 50 | import scala.collection.mutable.{Set, Map} | 50 | import scala.collection.mutable.{Set, Map} |
| 51 | import scalax.collection.Graph | 51 | import scalax.collection.Graph |
| 52 | import scalax.collection.GraphPredef._, scalax.collection.GraphEdge._ | 52 | import scalax.collection.GraphPredef._, scalax.collection.GraphEdge._ |
| 53 | import scalax.collection.GraphTraversal._ | ||
| 54 | 53 | ||
| 55 | /* Debug only */ | 54 | /* Debug only */ |
| 56 | import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer | 55 | import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer |
| 57 | import tech.oxfordsemantic.jrdfox.logic._ | 56 | import tech.oxfordsemantic.jrdfox.logic._ |
| 58 | import org.semanticweb.owlapi.model.OWLObjectInverseOf | 57 | import org.semanticweb.owlapi.model.OWLObjectInverseOf |
| 59 | 58 | ||
| 59 | import uk.ac.ox.cs.rsacomb.approximation.Approximation | ||
| 60 | import uk.ac.ox.cs.rsacomb.converter._ | 60 | import uk.ac.ox.cs.rsacomb.converter._ |
| 61 | import uk.ac.ox.cs.rsacomb.filtering.{FilteringProgram, FilterType} | 61 | import uk.ac.ox.cs.rsacomb.filtering.{FilteringProgram, FilterType} |
| 62 | import uk.ac.ox.cs.rsacomb.suffix._ | 62 | import uk.ac.ox.cs.rsacomb.suffix._ |
| @@ -66,10 +66,10 @@ import uk.ac.ox.cs.rsacomb.util.Logger | |||
| 66 | 66 | ||
| 67 | object RSAUtil { | 67 | object RSAUtil { |
| 68 | 68 | ||
| 69 | implicit def axiomsToOntology(axioms: Seq[OWLAxiom]) = { | 69 | // implicit def axiomsToOntology(axioms: Seq[OWLAxiom]) = { |
| 70 | val manager = OWLManager.createOWLOntologyManager() | 70 | // val manager = OWLManager.createOWLOntologyManager() |
| 71 | manager.createOntology(axioms.asJava) | 71 | // manager.createOntology(axioms.asJava) |
| 72 | } | 72 | // } |
| 73 | 73 | ||
| 74 | /** Compute the RSA dependency graph for a set of axioms | 74 | /** Compute the RSA dependency graph for a set of axioms |
| 75 | * | 75 | * |
| @@ -81,10 +81,10 @@ object RSAUtil { | |||
| 81 | * input axioms are assumed to be normalized. | 81 | * input axioms are assumed to be normalized. |
| 82 | */ | 82 | */ |
| 83 | private def dependencyGraph( | 83 | private def dependencyGraph( |
| 84 | axioms: Seq[OWLAxiom], | 84 | axioms: List[OWLLogicalAxiom], |
| 85 | datafiles: Seq[File] | 85 | datafiles: List[File] |
| 86 | ): (Graph[Resource, DiEdge], Map[String, OWLAxiom]) = { | 86 | ): (Graph[Resource, DiEdge], Map[String, OWLAxiom]) = { |
| 87 | val unsafe = this.unsafeRoles | 87 | val unsafe = RSAOntology(axioms, datafiles).unsafeRoles |
| 88 | var nodemap = Map.empty[String, OWLAxiom] | 88 | var nodemap = Map.empty[String, OWLAxiom] |
| 89 | 89 | ||
| 90 | object RSAConverter extends RDFoxConverter { | 90 | object RSAConverter extends RDFoxConverter { |
| @@ -164,6 +164,8 @@ object RSAUtil { | |||
| 164 | 164 | ||
| 165 | object RSAOntology { | 165 | object RSAOntology { |
| 166 | 166 | ||
| 167 | import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ | ||
| 168 | |||
| 167 | /** Name of the RDFox data store used for CQ answering */ | 169 | /** Name of the RDFox data store used for CQ answering */ |
| 168 | private val DataStore = "answer_computation" | 170 | private val DataStore = "answer_computation" |
| 169 | 171 | ||
| @@ -178,9 +180,14 @@ object RSAOntology { | |||
| 178 | val manager = OWLManager.createOWLOntologyManager() | 180 | val manager = OWLManager.createOWLOntologyManager() |
| 179 | 181 | ||
| 180 | def apply( | 182 | def apply( |
| 183 | axioms: List[OWLLogicalAxiom], | ||
| 184 | datafiles: List[File] | ||
| 185 | ): RSAOntology = new RSAOntology(axioms, datafiles: _*) | ||
| 186 | |||
| 187 | def apply( | ||
| 181 | ontofile: File, | 188 | ontofile: File, |
| 182 | datafiles: Seq[File], | 189 | datafiles: List[File], |
| 183 | approx: Option[Approximation] = None | 190 | approx: Option[Approximation] |
| 184 | ): RSAOntology = { | 191 | ): RSAOntology = { |
| 185 | val ontology = manager.loadOntologyFromOntologyDocument(ontofile) | 192 | val ontology = manager.loadOntologyFromOntologyDocument(ontofile) |
| 186 | RSAOntology(ontology, datafiles, approx) | 193 | RSAOntology(ontology, datafiles, approx) |
| @@ -188,14 +195,14 @@ object RSAOntology { | |||
| 188 | 195 | ||
| 189 | def apply( | 196 | def apply( |
| 190 | ontology: OWLOntology, | 197 | ontology: OWLOntology, |
| 191 | datafiles: Seq[File], | 198 | datafiles: List[File], |
| 192 | approx: Option[Approximation] = None | 199 | approx: Option[Approximation] |
| 193 | ): RSAOntology = { | 200 | ): RSAOntology = { |
| 194 | val normalizer = new Normalizer() | 201 | val normalizer = new Normalizer() |
| 195 | 202 | ||
| 196 | /** TBox axioms */ | 203 | /** TBox axioms */ |
| 197 | var tbox: List[OWLLogicalAxiom] = | 204 | var tbox: List[OWLLogicalAxiom] = |
| 198 | original | 205 | ontology |
| 199 | .tboxAxioms(Imports.INCLUDED) | 206 | .tboxAxioms(Imports.INCLUDED) |
| 200 | .collect(Collectors.toList()) | 207 | .collect(Collectors.toList()) |
| 201 | .collect { case a: OWLLogicalAxiom => a } | 208 | .collect { case a: OWLLogicalAxiom => a } |
| @@ -203,7 +210,7 @@ object RSAOntology { | |||
| 203 | 210 | ||
| 204 | /** RBox axioms */ | 211 | /** RBox axioms */ |
| 205 | var rbox: List[OWLLogicalAxiom] = | 212 | var rbox: List[OWLLogicalAxiom] = |
| 206 | original | 213 | ontology |
| 207 | .rboxAxioms(Imports.INCLUDED) | 214 | .rboxAxioms(Imports.INCLUDED) |
| 208 | .collect(Collectors.toList()) | 215 | .collect(Collectors.toList()) |
| 209 | .collect { case a: OWLLogicalAxiom => a } | 216 | .collect { case a: OWLLogicalAxiom => a } |
| @@ -217,7 +224,7 @@ object RSAOntology { | |||
| 217 | * large data files via OWLAPI. | 224 | * large data files via OWLAPI. |
| 218 | */ | 225 | */ |
| 219 | var abox: List[OWLLogicalAxiom] = | 226 | var abox: List[OWLLogicalAxiom] = |
| 220 | original | 227 | ontology |
| 221 | .aboxAxioms(Imports.INCLUDED) | 228 | .aboxAxioms(Imports.INCLUDED) |
| 222 | .collect(Collectors.toList()) | 229 | .collect(Collectors.toList()) |
| 223 | .collect { case a: OWLLogicalAxiom => a } | 230 | .collect { case a: OWLLogicalAxiom => a } |
| @@ -231,9 +238,10 @@ object RSAOntology { | |||
| 231 | case Some(a) => a.approximate(axioms, datafiles) | 238 | case Some(a) => a.approximate(axioms, datafiles) |
| 232 | case None => axioms | 239 | case None => axioms |
| 233 | }, | 240 | }, |
| 234 | datafiles | 241 | datafiles: _* |
| 235 | ) | 242 | ) |
| 236 | } | 243 | } |
| 244 | |||
| 237 | } | 245 | } |
| 238 | 246 | ||
| 239 | /** Wrapper class for an ontology in RSA | 247 | /** Wrapper class for an ontology in RSA |
| @@ -241,7 +249,7 @@ object RSAOntology { | |||
| 241 | * @param ontology the input OWL2 ontology. | 249 | * @param ontology the input OWL2 ontology. |
| 242 | * @param datafiles additinal data (treated as part of the ABox) | 250 | * @param datafiles additinal data (treated as part of the ABox) |
| 243 | */ | 251 | */ |
| 244 | class RSAOntology(val axioms: Seq[OWLAxiom], val datafiles: File*) { | 252 | class RSAOntology(val axioms: List[OWLLogicalAxiom], val datafiles: File*) { |
| 245 | 253 | ||
| 246 | /** Simplify conversion between OWLAPI and RDFox concepts */ | 254 | /** Simplify conversion between OWLAPI and RDFox concepts */ |
| 247 | import implicits.RDFox._ | 255 | import implicits.RDFox._ |
| @@ -697,28 +705,28 @@ class RSAOntology(val axioms: Seq[OWLAxiom], val datafiles: File*) { | |||
| 697 | this.self(axiom) | this.cycle(axiom) | 705 | this.self(axiom) | this.cycle(axiom) |
| 698 | 706 | ||
| 699 | /** Log normalization/approximation statistics */ | 707 | /** Log normalization/approximation statistics */ |
| 700 | def statistics(level: Logger.Level = Logger.DEBUG): Unit = { | 708 | // def statistics(level: Logger.Level = Logger.DEBUG): Unit = { |
| 701 | Logger.print( | 709 | // Logger.print( |
| 702 | s"Logical axioms in original input ontology: ${original.getLogicalAxiomCount(true)}", | 710 | // s"Logical axioms in original input ontology: ${original.getLogicalAxiomCount(true)}", |
| 703 | level | 711 | // level |
| 704 | ) | 712 | // ) |
| 705 | Logger.print( | 713 | // Logger.print( |
| 706 | s"Logical axioms discarded in Horn-ALCHOIQ approximation: ${normalizer.discarded}", | 714 | // s"Logical axioms discarded in Horn-ALCHOIQ approximation: ${normalizer.discarded}", |
| 707 | level | 715 | // level |
| 708 | ) | 716 | // ) |
| 709 | Logger.print( | 717 | // Logger.print( |
| 710 | s"Logical axioms shifted in Horn-ALCHOIQ approximation: ${normalizer.shifted}", | 718 | // s"Logical axioms shifted in Horn-ALCHOIQ approximation: ${normalizer.shifted}", |
| 711 | level | 719 | // level |
| 712 | ) | 720 | // ) |
| 713 | Logger.print( | 721 | // Logger.print( |
| 714 | s"Logical axioms in Horn-ALCHOIQ ontology: ${ontology | 722 | // s"Logical axioms in Horn-ALCHOIQ ontology: ${ontology |
| 715 | .getLogicalAxiomCount(true)} (${axioms.length}/${axioms.length}/${axioms.length})", | 723 | // .getLogicalAxiomCount(true)} (${axioms.length}/${axioms.length}/${axioms.length})", |
| 716 | level | 724 | // level |
| 717 | ) | 725 | // ) |
| 718 | Logger.print( | 726 | // Logger.print( |
| 719 | s"Logical axioms discarded in RSA approximation: ${removed.length}", | 727 | // s"Logical axioms discarded in RSA approximation: ${removed.length}", |
| 720 | level | 728 | // level |
| 721 | ) | 729 | // ) |
| 722 | } | 730 | // } |
| 723 | 731 | ||
| 724 | } // class RSAOntology | 732 | } // class RSAOntology |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/approximation.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/approximation.scala index 073d0d9..1b49413 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/approximation.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/approximation.scala | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | package uk.ac.ox.cs.rsacomb.approximation | 1 | package uk.ac.ox.cs.rsacomb.approximation |
| 2 | 2 | ||
| 3 | import java.io.File | 3 | import java.io.File |
| 4 | import org.semanticweb.owlapi.model.OWLAxiom | 4 | import org.semanticweb.owlapi.model.OWLLogicalAxiom |
| 5 | 5 | ||
| 6 | /** Ontology approximation technique. */ | 6 | /** Ontology approximation technique. */ |
| 7 | trait Approximation { | 7 | trait Approximation { |
| @@ -11,6 +11,9 @@ trait Approximation { | |||
| 11 | * @param ontology input ontology | 11 | * @param ontology input ontology |
| 12 | * @return a new approximated ontology | 12 | * @return a new approximated ontology |
| 13 | */ | 13 | */ |
| 14 | def approximate(ontology: Seq[OWLAxiom], datafiles: Seq[File]): Seq[OWLAxiom] | 14 | def approximate( |
| 15 | ontology: List[OWLLogicalAxiom], | ||
| 16 | datafiles: List[File] | ||
| 17 | ): List[OWLLogicalAxiom] | ||
| 15 | 18 | ||
| 16 | } | 19 | } |
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 8036250..3437bcd 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 | |||
| @@ -1,5 +1,16 @@ | |||
| 1 | package uk.ac.ox.cs.rsacomb.approximation | 1 | package uk.ac.ox.cs.rsacomb.approximation |
| 2 | 2 | ||
| 3 | import java.io.File | ||
| 4 | |||
| 5 | import org.semanticweb.owlapi.model._ | ||
| 6 | |||
| 7 | import scala.collection.mutable.{Set, Map} | ||
| 8 | import scalax.collection.Graph | ||
| 9 | import scalax.collection.GraphPredef._, scalax.collection.GraphEdge._ | ||
| 10 | import scalax.collection.GraphTraversal._ | ||
| 11 | |||
| 12 | import uk.ac.ox.cs.rsacomb.converter.Normalizer | ||
| 13 | |||
| 3 | /** Approximation algorithm that mantains soundness for CQ answering. | 14 | /** Approximation algorithm that mantains soundness for CQ answering. |
| 4 | * | 15 | * |
| 5 | * The input OWL 2 ontology is assumed to be normalized and the output | 16 | * The input OWL 2 ontology is assumed to be normalized and the output |
| @@ -21,11 +32,11 @@ class LowerBound extends Approximation { | |||
| 21 | 32 | ||
| 22 | /** Main entry point for the approximation algorithm */ | 33 | /** Main entry point for the approximation algorithm */ |
| 23 | def approximate( | 34 | def approximate( |
| 24 | ontology: Seq[OWLAxiom], | 35 | ontology: List[OWLLogicalAxiom], |
| 25 | datafiles: Seq[File] | 36 | datafiles: List[File] |
| 26 | ): Seq[OWLAxiom] = { | 37 | ): List[OWLLogicalAxiom] = { |
| 27 | /* Normalize axioms */ | 38 | /* Normalize axioms */ |
| 28 | val axioms1 = axioms flatMap normalizer.normalize | 39 | val axioms1 = axioms flatMap normalizer.normalize(_) |
| 29 | /* Delete any axiom outside of ALCHOIQ */ | 40 | /* Delete any axiom outside of ALCHOIQ */ |
| 30 | val axioms2 = axioms1 filterNot inHornLACHOIQ | 41 | val axioms2 = axioms1 filterNot inHornLACHOIQ |
| 31 | /* Shift any axiom with disjunction on the rhs */ | 42 | /* Shift any axiom with disjunction on the rhs */ |
| @@ -95,7 +106,7 @@ class LowerBound extends Approximation { | |||
| 95 | * where nA, nB1, nB2, nB3 are fresh predicates "corresponding" to | 106 | * where nA, nB1, nB2, nB3 are fresh predicates "corresponding" to |
| 96 | * the negation of A, B1, B2, B3 respectively. | 107 | * the negation of A, B1, B2, B3 respectively. |
| 97 | */ | 108 | */ |
| 98 | def shift(axiom: OWLLogicalAxiom): Seq[OWLLogicalAxiom] = | 109 | def shift(axiom: OWLLogicalAxiom): List[OWLLogicalAxiom] = |
| 99 | axiom match { | 110 | axiom match { |
| 100 | case a: OWLSubClassOfAxiom => { | 111 | case a: OWLSubClassOfAxiom => { |
| 101 | val sub = a.getSubClass.getNNF | 112 | val sub = a.getSubClass.getNNF |
| @@ -135,12 +146,12 @@ class LowerBound extends Approximation { | |||
| 135 | na | 146 | na |
| 136 | ) | 147 | ) |
| 137 | 148 | ||
| 138 | Seq(r1) ++ r2s ++ r3s | 149 | List(r1) ++ r2s ++ r3s |
| 139 | } | 150 | } |
| 140 | case _ => Seq(axiom) | 151 | case _ => List(axiom) |
| 141 | } | 152 | } |
| 142 | } | 153 | } |
| 143 | case _ => Seq(axiom) | 154 | case _ => List(axiom) |
| 144 | } | 155 | } |
| 145 | 156 | ||
| 146 | /** Approximate a Horn-ALCHOIQ ontology to RSA | 157 | /** Approximate a Horn-ALCHOIQ ontology to RSA |
| @@ -151,7 +162,10 @@ class LowerBound extends Approximation { | |||
| 151 | * @param axioms the set of axioms to approximate. | 162 | * @param axioms the set of axioms to approximate. |
| 152 | * @return the approximated set of axioms. | 163 | * @return the approximated set of axioms. |
| 153 | */ | 164 | */ |
| 154 | def toRSA(axioms: Seq[OWLAxiom], datafiles: Seq[File]): Seq[OWLAxiom] = { | 165 | def toRSA( |
| 166 | axioms: List[OWLLogicalAxiom], | ||
| 167 | datafiles: List[File] | ||
| 168 | ): List[OWLLogicalAxiom] = { | ||
| 155 | /* Compute the dependency graph for the ontology */ | 169 | /* Compute the dependency graph for the ontology */ |
| 156 | val (graph, nodemap) = RSAUtil.dependencyGraph(axioms, datafiles) | 170 | val (graph, nodemap) = RSAUtil.dependencyGraph(axioms, datafiles) |
| 157 | 171 | ||
| @@ -192,11 +206,12 @@ class LowerBound extends Approximation { | |||
| 192 | 206 | ||
| 193 | val toDelete = color.iterator.collect { case (resource: IRI, ToDelete) => | 207 | val toDelete = color.iterator.collect { case (resource: IRI, ToDelete) => |
| 194 | nodemap(resource.getIRI) | 208 | nodemap(resource.getIRI) |
| 195 | }.toSeq | 209 | }.toList |
| 196 | 210 | ||
| 197 | /* Remove axioms from approximated ontology */ | 211 | /* Remove axioms from approximated ontology */ |
| 198 | axioms diff toDelete | 212 | axioms diff toDelete |
| 199 | } | 213 | } |
| 214 | |||
| 200 | // val edges1 = Seq('A ~> 'B, 'B ~> 'C, 'C ~> 'D, 'D ~> 'H, 'H ~> | 215 | // val edges1 = Seq('A ~> 'B, 'B ~> 'C, 'C ~> 'D, 'D ~> 'H, 'H ~> |
| 201 | // 'G, 'G ~> 'F, 'E ~> 'A, 'E ~> 'F, 'B ~> 'E, 'F ~> 'G, 'B ~> 'F, | 216 | // 'G, 'G ~> 'F, 'E ~> 'A, 'E ~> 'F, 'B ~> 'E, 'F ~> 'G, 'B ~> 'F, |
| 202 | // 'C ~> 'G, 'D ~> 'C, 'H ~> 'D) | 217 | // 'C ~> 'G, 'D ~> 'C, 'H ~> 'D) |
