diff options
author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-10-23 20:55:36 +0200 |
---|---|---|
committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-10-23 20:55:36 +0200 |
commit | 697dd84aa64bbfb40b60a4d132f91168eba19d5a (patch) | |
tree | 64d8318d279aebc8f44f8b535518997d74414346 /src | |
parent | 4ac28e74095c473e4ae0a44b0fb8db77a9ef3193 (diff) | |
download | RSAComb-697dd84aa64bbfb40b60a4d132f91168eba19d5a.tar.gz RSAComb-697dd84aa64bbfb40b60a4d132f91168eba19d5a.zip |
Implement naive version of 'cycle' as in paper
This implementation is more closely related to the paper definition of
'cycle'. The initial implementation was an improvement on the generation
of the logic program (but not necessarely on the Datalog engine side)
because it generate far fewer new constants.
We decided to stick with the naive version to be as close as possible to
the paper description.
This temporarely breaks some tests.
Diffstat (limited to 'src')
-rw-r--r-- | src/main/scala/rsacomb/RSAOntology.scala | 71 |
1 files changed, 54 insertions, 17 deletions
diff --git a/src/main/scala/rsacomb/RSAOntology.scala b/src/main/scala/rsacomb/RSAOntology.scala index b410bf0..6d39bae 100644 --- a/src/main/scala/rsacomb/RSAOntology.scala +++ b/src/main/scala/rsacomb/RSAOntology.scala | |||
@@ -6,6 +6,7 @@ import java.util.stream.{Collectors, Stream} | |||
6 | 6 | ||
7 | import org.semanticweb.owlapi.model.OWLOntology | 7 | import org.semanticweb.owlapi.model.OWLOntology |
8 | import org.semanticweb.owlapi.model.{ | 8 | import org.semanticweb.owlapi.model.{ |
9 | OWLClass, | ||
9 | OWLObjectProperty, | 10 | OWLObjectProperty, |
10 | OWLObjectPropertyExpression, | 11 | OWLObjectPropertyExpression, |
11 | OWLSubClassOfAxiom | 12 | OWLSubClassOfAxiom |
@@ -288,31 +289,67 @@ trait RSAOntology { | |||
288 | } | 289 | } |
289 | } | 290 | } |
290 | 291 | ||
291 | // TODO: this implementation is not correct when taking into | 292 | // def cycle(axiom: OWLSubClassOfAxiom): Set[Term] = { |
292 | // account equality. | 293 | // // Assuming just one role in the signature of a T5 axiom |
294 | // val roleR = axiom.objectPropertyExpressionsInSignature(0) | ||
295 | // val conflR = this.confl(roleR) | ||
296 | // // We just need the TBox to find | ||
297 | // val tbox = ontology | ||
298 | // .tboxAxioms(Imports.INCLUDED) | ||
299 | // .collect(Collectors.toSet()) | ||
300 | // .asScala | ||
301 | // for { | ||
302 | // axiom1 <- tbox | ||
303 | // // TODO: is this an optimization or an error? | ||
304 | // if axiom1.isT5 | ||
305 | // // We expect only one role coming out of a T5 axiom | ||
306 | // roleS <- axiom1.objectPropertyExpressionsInSignature | ||
307 | // // Triples ordering is among triples involving safe roles. | ||
308 | // if !unsafeRoles.contains(roleS) | ||
309 | // if conflR.contains(roleS) | ||
310 | // individual = | ||
311 | // if (axiom.hashCode < axiom1.hashCode) { | ||
312 | // RSA.internal("v0_" ++ axiom1.hashCode.toString()) | ||
313 | // } else { | ||
314 | // RSA.internal("v1_" ++ axiom1.hashCode.toString()) | ||
315 | // } | ||
316 | // } yield individual | ||
317 | // } | ||
318 | |||
293 | def cycle(axiom: OWLSubClassOfAxiom): Set[Term] = { | 319 | def cycle(axiom: OWLSubClassOfAxiom): Set[Term] = { |
294 | // Assuming just one role in the signature of a T5 axiom | 320 | val classes = |
295 | val roleR = axiom.objectPropertyExpressionsInSignature(0) | 321 | axiom.classesInSignature.collect(Collectors.toList()).asScala |
322 | val classA = classes(0) | ||
323 | val roleR = axiom | ||
324 | .objectPropertyExpressionsInSignature(0) | ||
325 | .asInstanceOf[OWLObjectProperty] | ||
326 | val classB = classes(1) | ||
327 | cycle_aux(classA, roleR, classB) | ||
328 | } | ||
329 | |||
330 | def cycle_aux( | ||
331 | classA: OWLClass, | ||
332 | roleR: OWLObjectProperty, | ||
333 | classB: OWLClass | ||
334 | ): Set[Term] = { | ||
296 | val conflR = this.confl(roleR) | 335 | val conflR = this.confl(roleR) |
297 | // We just need the TBox to find | 336 | val classes = ontology |
298 | val tbox = ontology | 337 | .classesInSignature(Imports.INCLUDED) |
299 | .tboxAxioms(Imports.INCLUDED) | ||
300 | .collect(Collectors.toSet()) | 338 | .collect(Collectors.toSet()) |
301 | .asScala | 339 | .asScala |
302 | for { | 340 | for { |
303 | axiom1 <- tbox | 341 | classD <- classes |
304 | // TODO: is this an optimization or an error? | 342 | roleS <- conflR |
305 | if axiom1.isT5 | 343 | classC <- classes |
306 | // We expect only one role coming out of a T5 axiom | 344 | // Keeping this check for now |
307 | roleS <- axiom1.objectPropertyExpressionsInSignature | ||
308 | // Triples ordering is among triples involving safe roles. | ||
309 | if !unsafeRoles.contains(roleS) | 345 | if !unsafeRoles.contains(roleS) |
310 | if conflR.contains(roleS) | 346 | tripleARB = Seq(classA, roleR, classB).hashCode |
347 | tripleDSC = Seq(classD, roleS, classC).hashCode | ||
311 | individual = | 348 | individual = |
312 | if (axiom.hashCode < axiom1.hashCode) { | 349 | if (tripleARB < tripleDSC) { |
313 | RSA.internal("v0_" ++ axiom1.hashCode.toString()) | 350 | RSA.internal("v0_" ++ tripleDSC.hashCode.toString()) |
314 | } else { | 351 | } else { |
315 | RSA.internal("v1_" ++ axiom1.hashCode.toString()) | 352 | RSA.internal("v1_" ++ tripleDSC.hashCode.toString()) |
316 | } | 353 | } |
317 | } yield individual | 354 | } yield individual |
318 | } | 355 | } |