aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Igne <federico.igne@cs.ox.ac.uk>2021-04-09 20:52:47 +0100
committerFederico Igne <federico.igne@cs.ox.ac.uk>2021-04-09 20:52:47 +0100
commitc6a63f565b8311348a800366c05dc3a6e964872c (patch)
treefc08c1635d75fb17f65cb1367f5298f564bff2fd
parente6048bd85da50a8f40538b968fe7ac3b957fdd97 (diff)
downloadRSAComb-c6a63f565b8311348a800366c05dc3a6e964872c.tar.gz
RSAComb-c6a63f565b8311348a800366c05dc3a6e964872c.zip
Fix handling of class expression OWLObjectHasSelf
It was not properly handled in the normalization process.
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala89
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/converter/Normalizer.scala11
2 files changed, 54 insertions, 46 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 c5a2730..3527da5 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala
@@ -117,7 +117,6 @@ class RSAOntology(val original: OWLOntology, val datafiles: File*) {
117 .collect(Collectors.toList()) 117 .collect(Collectors.toList())
118 .collect { case a: OWLLogicalAxiom => a } 118 .collect { case a: OWLLogicalAxiom => a }
119 .flatMap(normalizer.normalize) 119 .flatMap(normalizer.normalize)
120 //Logger.print(s"Normalized TBox: ${tbox.length}", Logger.DEBUG)
121 120
122 /** RBox axioms */ 121 /** RBox axioms */
123 var rbox: List[OWLLogicalAxiom] = 122 var rbox: List[OWLLogicalAxiom] =
@@ -126,7 +125,6 @@ class RSAOntology(val original: OWLOntology, val datafiles: File*) {
126 .collect(Collectors.toList()) 125 .collect(Collectors.toList())
127 .collect { case a: OWLLogicalAxiom => a } 126 .collect { case a: OWLLogicalAxiom => a }
128 .flatMap(normalizer.normalize) 127 .flatMap(normalizer.normalize)
129 //Logger.print(s"Normalized RBox: ${rbox.length}", Logger.DEBUG)
130 128
131 /** ABox axioms 129 /** ABox axioms
132 * 130 *
@@ -141,7 +139,6 @@ class RSAOntology(val original: OWLOntology, val datafiles: File*) {
141 .collect(Collectors.toList()) 139 .collect(Collectors.toList())
142 .collect { case a: OWLLogicalAxiom => a } 140 .collect { case a: OWLLogicalAxiom => a }
143 .flatMap(normalizer.normalize) 141 .flatMap(normalizer.normalize)
144 //Logger.print(s"Normalized ABox: ${abox.length}", Logger.DEBUG)
145 142
146 /** Collection of logical axioms in the input ontology */ 143 /** Collection of logical axioms in the input ontology */
147 var axioms: List[OWLLogicalAxiom] = abox ::: tbox ::: rbox 144 var axioms: List[OWLLogicalAxiom] = abox ::: tbox ::: rbox
@@ -316,57 +313,61 @@ class RSAOntology(val original: OWLOntology, val datafiles: File*) {
316 * @param graph the graph used to compute the axioms to remove. 313 * @param graph the graph used to compute the axioms to remove.
317 * @param nodemap map from graph nodes to ontology axioms. 314 * @param nodemap map from graph nodes to ontology axioms.
318 */ 315 */
319 def toRSA(): RSAOntology = { 316 def toRSA(): RSAOntology = Logger.timed(
317 {
320 318
321 /* Compute the dependency graph for the ontology */ 319 /* Compute the dependency graph for the ontology */
322 val (graph, nodemap) = this.dependencyGraph() 320 val (graph, nodemap) = this.dependencyGraph()
323 321
324 /* Define node colors for the graph visit */ 322 /* Define node colors for the graph visit */
325 sealed trait NodeColor 323 sealed trait NodeColor
326 case object Unvisited extends NodeColor 324 case object Unvisited extends NodeColor
327 case object Visited extends NodeColor 325 case object Visited extends NodeColor
328 case object ToDelete extends NodeColor 326 case object ToDelete extends NodeColor
329 327
330 /* Keep track of node colors during graph visit */ 328 /* Keep track of node colors during graph visit */
331 var color = Map.from[Resource, NodeColor]( 329 var color = Map.from[Resource, NodeColor](
332 graph.nodes.toOuter.map(k => (k, Unvisited)) 330 graph.nodes.toOuter.map(k => (k, Unvisited))
333 ) 331 )
334 332
335 for { 333 for {
336 component <- graph.componentTraverser().map(_ to Graph) 334 component <- graph.componentTraverser().map(_ to Graph)
337 edge <- component 335 edge <- component
338 .outerEdgeTraverser(component.nodes.head) 336 .outerEdgeTraverser(component.nodes.head)
339 .withKind(BreadthFirst) 337 .withKind(BreadthFirst)
340 } yield { 338 } yield {
341 val source = edge._1 339 val source = edge._1
342 val target = edge._2 340 val target = edge._2
343 color(source) match { 341 color(source) match {
344 case Unvisited | Visited => { 342 case Unvisited | Visited => {
345 color(target) match { 343 color(target) match {
346 case Unvisited => 344 case Unvisited =>
347 color(source) = Visited; 345 color(source) = Visited;
348 color(target) = Visited 346 color(target) = Visited
349 case Visited => 347 case Visited =>
350 color(source) = ToDelete 348 color(source) = ToDelete
351 case ToDelete => 349 case ToDelete =>
352 color(source) = Visited 350 color(source) = Visited
351 }
353 } 352 }
353 case ToDelete =>
354 } 354 }
355 case ToDelete =>
356 } 355 }
357 }
358 356
359 val toDelete = color.iterator.collect { case (resource: IRI, ToDelete) => 357 val toDelete = color.iterator.collect { case (resource: IRI, ToDelete) =>
360 nodemap(resource.getIRI) 358 nodemap(resource.getIRI)
361 }.toSeq 359 }.toSeq
362 360
363 /* Remove axioms from approximated ontology */ 361 /* Remove axioms from approximated ontology */
364 ontology.removeAxioms(toDelete: _*) 362 ontology.removeAxioms(toDelete: _*)
365 this.removed = toDelete 363 this.removed = toDelete
366 364
367 /* Return RSA ontology */ 365 /* Return RSA ontology */
368 RSAOntology(ontology, datafiles: _*) 366 RSAOntology(ontology, datafiles: _*)
369 } 367 },
368 "Horn-ALCHOIQ to RSA approximation:",
369 Logger.DEBUG
370 )
370 // val edges1 = Seq('A ~> 'B, 'B ~> 'C, 'C ~> 'D, 'D ~> 'H, 'H ~> 371 // val edges1 = Seq('A ~> 'B, 'B ~> 'C, 'C ~> 'D, 'D ~> 'H, 'H ~>
371 // 'G, 'G ~> 'F, 'E ~> 'A, 'E ~> 'F, 'B ~> 'E, 'F ~> 'G, 'B ~> 'F, 372 // 'G, 'G ~> 'F, 'E ~> 'A, 'E ~> 'F, 'B ~> 'E, 'F ~> 'G, 'B ~> 'F,
372 // 'C ~> 'G, 'D ~> 'C, 'H ~> 'D) 373 // 'C ~> 'G, 'D ~> 'C, 'H ~> 'D)
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 205c369..5329f26 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
@@ -401,6 +401,10 @@ class Normalizer() {
401 factory.getOWLNothing 401 factory.getOWLNothing
402 ) 402 )
403 ) 403 )
404 /** Self-restriction over an object property */
405 case (sub: OWLObjectHasSelf, _) => notInHornALCHOIQ(a)
406 case (_, sup: OWLObjectHasSelf) => notInHornALCHOIQ(a)
407
404 /** Axiom is already normalized */ 408 /** Axiom is already normalized */
405 case _ => Seq(a) 409 case _ => Seq(a)
406 } 410 }
@@ -507,7 +511,7 @@ class Normalizer() {
507 511
508 /** Unsupported */ 512 /** Unsupported */
509 513
510 case a: OWLAsymmetricObjectPropertyAxiom => notSupported(a) 514 case a: OWLAsymmetricObjectPropertyAxiom => notInHornALCHOIQ(a)
511 515
512 case a: OWLDatatypeDefinitionAxiom => notSupported(a) 516 case a: OWLDatatypeDefinitionAxiom => notSupported(a)
513 517
@@ -577,7 +581,10 @@ class Normalizer() {
577 ): Seq[OWLLogicalAxiom] = { 581 ): Seq[OWLLogicalAxiom] = {
578 /* Update statistics */ 582 /* Update statistics */
579 discarded += 1 583 discarded += 1
580 Logger print s"'$axiom' has been ignored because it is not in Horn-ALCHOIQ" 584 Logger.print(
585 s"'$axiom' has been ignored because it is not in Horn-ALCHOIQ",
586 Logger.VERBOSE
587 )
581 Seq() 588 Seq()
582 } 589 }
583 590