From 697dd84aa64bbfb40b60a4d132f91168eba19d5a Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Fri, 23 Oct 2020 20:55:36 +0200 Subject: 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. --- src/main/scala/rsacomb/RSAOntology.scala | 71 ++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 17 deletions(-) (limited to 'src/main/scala/rsacomb/RSAOntology.scala') 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} import org.semanticweb.owlapi.model.OWLOntology import org.semanticweb.owlapi.model.{ + OWLClass, OWLObjectProperty, OWLObjectPropertyExpression, OWLSubClassOfAxiom @@ -288,31 +289,67 @@ trait RSAOntology { } } - // TODO: this implementation is not correct when taking into - // account equality. + // def cycle(axiom: OWLSubClassOfAxiom): Set[Term] = { + // // Assuming just one role in the signature of a T5 axiom + // val roleR = axiom.objectPropertyExpressionsInSignature(0) + // val conflR = this.confl(roleR) + // // We just need the TBox to find + // val tbox = ontology + // .tboxAxioms(Imports.INCLUDED) + // .collect(Collectors.toSet()) + // .asScala + // for { + // axiom1 <- tbox + // // TODO: is this an optimization or an error? + // if axiom1.isT5 + // // We expect only one role coming out of a T5 axiom + // roleS <- axiom1.objectPropertyExpressionsInSignature + // // Triples ordering is among triples involving safe roles. + // if !unsafeRoles.contains(roleS) + // if conflR.contains(roleS) + // individual = + // if (axiom.hashCode < axiom1.hashCode) { + // RSA.internal("v0_" ++ axiom1.hashCode.toString()) + // } else { + // RSA.internal("v1_" ++ axiom1.hashCode.toString()) + // } + // } yield individual + // } + def cycle(axiom: OWLSubClassOfAxiom): Set[Term] = { - // Assuming just one role in the signature of a T5 axiom - val roleR = axiom.objectPropertyExpressionsInSignature(0) + val classes = + axiom.classesInSignature.collect(Collectors.toList()).asScala + val classA = classes(0) + val roleR = axiom + .objectPropertyExpressionsInSignature(0) + .asInstanceOf[OWLObjectProperty] + val classB = classes(1) + cycle_aux(classA, roleR, classB) + } + + def cycle_aux( + classA: OWLClass, + roleR: OWLObjectProperty, + classB: OWLClass + ): Set[Term] = { val conflR = this.confl(roleR) - // We just need the TBox to find - val tbox = ontology - .tboxAxioms(Imports.INCLUDED) + val classes = ontology + .classesInSignature(Imports.INCLUDED) .collect(Collectors.toSet()) .asScala for { - axiom1 <- tbox - // TODO: is this an optimization or an error? - if axiom1.isT5 - // We expect only one role coming out of a T5 axiom - roleS <- axiom1.objectPropertyExpressionsInSignature - // Triples ordering is among triples involving safe roles. + classD <- classes + roleS <- conflR + classC <- classes + // Keeping this check for now if !unsafeRoles.contains(roleS) - if conflR.contains(roleS) + tripleARB = Seq(classA, roleR, classB).hashCode + tripleDSC = Seq(classD, roleS, classC).hashCode individual = - if (axiom.hashCode < axiom1.hashCode) { - RSA.internal("v0_" ++ axiom1.hashCode.toString()) + if (tripleARB < tripleDSC) { + RSA.internal("v0_" ++ tripleDSC.hashCode.toString()) } else { - RSA.internal("v1_" ++ axiom1.hashCode.toString()) + RSA.internal("v1_" ++ tripleDSC.hashCode.toString()) } } yield individual } -- cgit v1.2.3