From 19c22a38ccaf1685e345a18883ffbac891f97df3 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Tue, 3 Aug 2021 12:20:34 +0100 Subject: Extend converter to RDFox rules to handle property chain axioms The converter to RDFox datalog rules shouldn't worry about which axiom is supported or not (it should be a job of the approximation algorithm or of a previous step). Now the converter tries its best to convert anything that makes sense in datalog. Also upperbound is ready for testing. --- .../ox/cs/rsacomb/approximation/Upperbound.scala | 38 ------------- .../ox/cs/rsacomb/converter/RDFoxConverter.scala | 64 ++++++++++++---------- 2 files changed, 36 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala index 65cdee1..ad924aa 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala @@ -55,44 +55,6 @@ class Upperbound extends Approximation[RSAOntology] { ) ) - /** Discards all axioms outside ALCHOIQ */ - // private def inALCHOIQ(axiom: OWLLogicalAxiom): Boolean = - // axiom match { - // case a: OWLSubClassOfAxiom => { - // val sub = a.getSubClass.getNNF - // val sup = a.getSuperClass.getNNF - // (sub, sup) match { - // case (sub: OWLObjectAllValuesFrom, _) => false - // case (sub: OWLDataAllValuesFrom, _) => false - // case (_, sup: OWLDataAllValuesFrom) => false - // case (sub: OWLObjectMinCardinality, _) if sub.getCardinality >= 2 => - // false - // case (sub: OWLDataMinCardinality, _) if sub.getCardinality >= 2 => - // false - // case (_, sup: OWLObjectMinCardinality) if sup.getCardinality >= 2 => - // false - // case (_, sup: OWLDataMinCardinality) if sup.getCardinality >= 2 => - // false - // case (sub: OWLObjectMaxCardinality, _) => false - // case (sub: OWLDataMaxCardinality, _) => false - // case (_, sup: OWLObjectMaxCardinality) if sup.getCardinality >= 2 => - // false - // case (_, sup: OWLDataMaxCardinality) if sup.getCardinality >= 1 => - // false - // case (_, sup: OWLObjectOneOf) if sup.getIndividuals.length > 2 => - // false - // case (sub: OWLObjectHasSelf, _) => false - // case (_, sup: OWLObjectHasSelf) => false - // case _ => true - // } - // } - // case a: OWLTransitiveObjectPropertyAxiom => false - // case a: OWLReflexiveObjectPropertyAxiom => false - // case a: OWLSubPropertyChainOfAxiom => false - // case a: OWLAsymmetricObjectPropertyAxiom => false - // case a => true - // } - /** Turn disjuncts into conjuncts * * This is a very naïve way of getting rid of disjunction preserving diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala index 3aa3c5f..03c1246 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala @@ -91,35 +91,37 @@ trait RDFoxConverter { protected def ResultF(atoms: List[TupleTableAtom]): Result = (atoms, List()) protected def ResultR(rules: List[Rule]): Result = (List(), rules) - /** Converts a - * [[org.semanticweb.owlapi.model.OWLLogicalAxiom OWLLogicalAxiom]] - * into a collection of - * [[tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom TupleTableAtoms]] - * and - * [[tech.oxfordsemantic.jrdfox.logic.datalog.Rule Rules]]. + /** Converts a [[OWLLogicalAxiom]] into a collection of [[TupleTableAtoms]] and [[Rules]]. * * @note not all possible axioms are handled correctly, and in * general they are assumed to be normalised. Following is a list of * all unhandled class expressions: * - [[org.semanticweb.owlapi.model.OWLAsymmetricObjectPropertyAxiom OWLAsymmetricObjectPropertyAxiom]] - * - [[org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom OWLDataPropertyAssertionAxiom]] - * - [[org.semanticweb.owlapi.model.OWLDataPropertyRangeAxiom OWLDataPropertyRangeAxiom]] * - [[org.semanticweb.owlapi.model.OWLDatatypeDefinitionAxiom OWLDatatypeDefinitionAxiom]] - * - [[org.semanticweb.owlapi.model.OWLDifferentIndividualsAxiom OWLDifferentIndividualsAxiom]] * - [[org.semanticweb.owlapi.model.OWLDisjointDataPropertiesAxiom OWLDisjointDataPropertiesAxiom]] * - [[org.semanticweb.owlapi.model.OWLDisjointObjectPropertiesAxiom OWLDisjointObjectPropertiesAxiom]] - * - [[org.semanticweb.owlapi.model.OWLDisjointUnionAxiom OWLDisjointUnionAxiom]] - * - [[org.semanticweb.owlapi.model.OWLEquivalentDataPropertiesAxiom OWLEquivalentDataPropertiesAxiom]] - * - [[org.semanticweb.owlapi.model.OWLFunctionalDataPropertyAxiom OWLFunctionalDataPropertyAxiom]] * - [[org.semanticweb.owlapi.model.OWLHasKeyAxiom OWLHasKeyAxiom]] - * - [[org.semanticweb.owlapi.model.OWLIrreflexiveObjectPropertyAxiom OWLIrreflexiveObjectPropertyAxiom]] - * - [[org.semanticweb.owlapi.model.OWLNegativeDataPropertyAssertionAxiom OWLNegativeDataPropertyAssertionAxiom]] - * - [[org.semanticweb.owlapi.model.OWLNegativeObjectPropertyAssertionAxiom OWLNegativeObjectPropertyAssertionAxiom]] + * - [[org.semanticweb.owlapi.model.SWRLRule SWRLRule]] + * + * @note The following axioms are not handled directly but can be + * normalised beforehand. + * + * - [[org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom OWLTransitiveObjectPropertyAxiom]] + * - [[org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom OWLDataPropertyAssertionAxiom]] + * - [[org.semanticweb.owlapi.model.OWLDataPropertyRangeAxiom OWLDataPropertyRangeAxiom]] + * - [[org.semanticweb.owlapi.model.OWLDifferentIndividualsAxiom OWLDifferentIndividualsAxiom]] * - [[org.semanticweb.owlapi.model.OWLReflexiveObjectPropertyAxiom OWLReflexiveObjectPropertyAxiom]] * - [[org.semanticweb.owlapi.model.OWLSameIndividualAxiom OWLSameIndividualAxiom]] - * - [[org.semanticweb.owlapi.model.OWLSubPropertyChainOfAxiom OWLSubPropertyChainOfAxiom]] - * - [[org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom OWLTransitiveObjectPropertyAxiom]] - * - [[org.semanticweb.owlapi.model.SWRLRule SWRLRule]] + * - [[org.semanticweb.owlapi.model.OWLNegativeDataPropertyAssertionAxiom OWLNegativeDataPropertyAssertionAxiom]] + * - [[org.semanticweb.owlapi.model.OWLNegativeObjectPropertyAssertionAxiom OWLNegativeObjectPropertyAssertionAxiom]] + * - [[org.semanticweb.owlapi.model.OWLIrreflexiveObjectPropertyAxiom OWLIrreflexiveObjectPropertyAxiom]] + * - [[org.semanticweb.owlapi.model.OWLDisjointUnionAxiom OWLDisjointUnionAxiom]] + * - [[org.semanticweb.owlapi.model.OWLEquivalentDataPropertiesAxiom OWLEquivalentDataPropertiesAxiom]] + * - [[org.semanticweb.owlapi.model.OWLFunctionalDataPropertyAxiom OWLFunctionalDataPropertyAxiom]] + * + * @see [[Normaliser]] + * @see + * http://owlcs.github.io/owlapi/apidocs_5/index.html */ def convert( axiom: OWLLogicalAxiom, @@ -250,20 +252,26 @@ trait RDFoxConverter { ResultF(List(prop)) } - case a: OWLDataPropertyRangeAxiom => - Result() // ignored - - case a: OWLFunctionalDataPropertyAxiom => - Result() - - case a: OWLTransitiveObjectPropertyAxiom => - Result() + case a: OWLSubPropertyChainOfAxiom => { + val (term1, body) = a.getPropertyChain.foldLeft((term, List[TupleTableAtom]())){ + case ((term, atoms), prop) => { + val term1 = RSAUtil.genFreshVariable() + val atom = convert(prop, term, term1, suffix) + (term1, atoms :+ atom) + } + } + val head = convert(a.getSuperProperty, term, term1, suffix) + ResultR(List(Rule.create(head, body))) + } /** Catch-all case for all unhandled axiom types. */ - case a => default(axiom) + case a => unsupported(axiom) } - protected def default(axiom: OWLLogicalAxiom): Result = + protected def toBeNormalised(axiom: OWLLogicalAxiom): Result = + throw new RuntimeException(s"Axiom '$axiom' should be normalised!") + + protected def unsupported(axiom: OWLLogicalAxiom): Result = throw new RuntimeException(s"Axiom '$axiom' is not supported (yet?)") /** Converts a class expression into a collection of atoms. -- cgit v1.2.3