diff options
| author | Federico Igne <git@federicoigne.com> | 2021-08-03 12:20:34 +0100 |
|---|---|---|
| committer | Federico Igne <git@federicoigne.com> | 2021-08-03 12:20:34 +0100 |
| commit | 19c22a38ccaf1685e345a18883ffbac891f97df3 (patch) | |
| tree | 197672906b482999405192fbe5b1a0799b73b6b6 | |
| parent | 71367fb626710dcdca0fa09f1902b521c966ef71 (diff) | |
| download | RSAComb-19c22a38ccaf1685e345a18883ffbac891f97df3.tar.gz RSAComb-19c22a38ccaf1685e345a18883ffbac891f97df3.zip | |
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.
| -rw-r--r-- | src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala | 38 | ||||
| -rw-r--r-- | src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala | 64 |
2 files changed, 36 insertions, 66 deletions
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] { | |||
| 55 | ) | 55 | ) |
| 56 | ) | 56 | ) |
| 57 | 57 | ||
| 58 | /** Discards all axioms outside ALCHOIQ */ | ||
| 59 | // private def inALCHOIQ(axiom: OWLLogicalAxiom): Boolean = | ||
| 60 | // axiom match { | ||
| 61 | // case a: OWLSubClassOfAxiom => { | ||
| 62 | // val sub = a.getSubClass.getNNF | ||
| 63 | // val sup = a.getSuperClass.getNNF | ||
| 64 | // (sub, sup) match { | ||
| 65 | // case (sub: OWLObjectAllValuesFrom, _) => false | ||
| 66 | // case (sub: OWLDataAllValuesFrom, _) => false | ||
| 67 | // case (_, sup: OWLDataAllValuesFrom) => false | ||
| 68 | // case (sub: OWLObjectMinCardinality, _) if sub.getCardinality >= 2 => | ||
| 69 | // false | ||
| 70 | // case (sub: OWLDataMinCardinality, _) if sub.getCardinality >= 2 => | ||
| 71 | // false | ||
| 72 | // case (_, sup: OWLObjectMinCardinality) if sup.getCardinality >= 2 => | ||
| 73 | // false | ||
| 74 | // case (_, sup: OWLDataMinCardinality) if sup.getCardinality >= 2 => | ||
| 75 | // false | ||
| 76 | // case (sub: OWLObjectMaxCardinality, _) => false | ||
| 77 | // case (sub: OWLDataMaxCardinality, _) => false | ||
| 78 | // case (_, sup: OWLObjectMaxCardinality) if sup.getCardinality >= 2 => | ||
| 79 | // false | ||
| 80 | // case (_, sup: OWLDataMaxCardinality) if sup.getCardinality >= 1 => | ||
| 81 | // false | ||
| 82 | // case (_, sup: OWLObjectOneOf) if sup.getIndividuals.length > 2 => | ||
| 83 | // false | ||
| 84 | // case (sub: OWLObjectHasSelf, _) => false | ||
| 85 | // case (_, sup: OWLObjectHasSelf) => false | ||
| 86 | // case _ => true | ||
| 87 | // } | ||
| 88 | // } | ||
| 89 | // case a: OWLTransitiveObjectPropertyAxiom => false | ||
| 90 | // case a: OWLReflexiveObjectPropertyAxiom => false | ||
| 91 | // case a: OWLSubPropertyChainOfAxiom => false | ||
| 92 | // case a: OWLAsymmetricObjectPropertyAxiom => false | ||
| 93 | // case a => true | ||
| 94 | // } | ||
| 95 | |||
| 96 | /** Turn disjuncts into conjuncts | 58 | /** Turn disjuncts into conjuncts |
| 97 | * | 59 | * |
| 98 | * This is a very naïve way of getting rid of disjunction preserving | 60 | * 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 { | |||
| 91 | protected def ResultF(atoms: List[TupleTableAtom]): Result = (atoms, List()) | 91 | protected def ResultF(atoms: List[TupleTableAtom]): Result = (atoms, List()) |
| 92 | protected def ResultR(rules: List[Rule]): Result = (List(), rules) | 92 | protected def ResultR(rules: List[Rule]): Result = (List(), rules) |
| 93 | 93 | ||
| 94 | /** Converts a | 94 | /** Converts a [[OWLLogicalAxiom]] into a collection of [[TupleTableAtoms]] and [[Rules]]. |
| 95 | * [[org.semanticweb.owlapi.model.OWLLogicalAxiom OWLLogicalAxiom]] | ||
| 96 | * into a collection of | ||
| 97 | * [[tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom TupleTableAtoms]] | ||
| 98 | * and | ||
| 99 | * [[tech.oxfordsemantic.jrdfox.logic.datalog.Rule Rules]]. | ||
| 100 | * | 95 | * |
| 101 | * @note not all possible axioms are handled correctly, and in | 96 | * @note not all possible axioms are handled correctly, and in |
| 102 | * general they are assumed to be normalised. Following is a list of | 97 | * general they are assumed to be normalised. Following is a list of |
| 103 | * all unhandled class expressions: | 98 | * all unhandled class expressions: |
| 104 | * - [[org.semanticweb.owlapi.model.OWLAsymmetricObjectPropertyAxiom OWLAsymmetricObjectPropertyAxiom]] | 99 | * - [[org.semanticweb.owlapi.model.OWLAsymmetricObjectPropertyAxiom OWLAsymmetricObjectPropertyAxiom]] |
| 105 | * - [[org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom OWLDataPropertyAssertionAxiom]] | ||
| 106 | * - [[org.semanticweb.owlapi.model.OWLDataPropertyRangeAxiom OWLDataPropertyRangeAxiom]] | ||
| 107 | * - [[org.semanticweb.owlapi.model.OWLDatatypeDefinitionAxiom OWLDatatypeDefinitionAxiom]] | 100 | * - [[org.semanticweb.owlapi.model.OWLDatatypeDefinitionAxiom OWLDatatypeDefinitionAxiom]] |
| 108 | * - [[org.semanticweb.owlapi.model.OWLDifferentIndividualsAxiom OWLDifferentIndividualsAxiom]] | ||
| 109 | * - [[org.semanticweb.owlapi.model.OWLDisjointDataPropertiesAxiom OWLDisjointDataPropertiesAxiom]] | 101 | * - [[org.semanticweb.owlapi.model.OWLDisjointDataPropertiesAxiom OWLDisjointDataPropertiesAxiom]] |
| 110 | * - [[org.semanticweb.owlapi.model.OWLDisjointObjectPropertiesAxiom OWLDisjointObjectPropertiesAxiom]] | 102 | * - [[org.semanticweb.owlapi.model.OWLDisjointObjectPropertiesAxiom OWLDisjointObjectPropertiesAxiom]] |
| 111 | * - [[org.semanticweb.owlapi.model.OWLDisjointUnionAxiom OWLDisjointUnionAxiom]] | ||
| 112 | * - [[org.semanticweb.owlapi.model.OWLEquivalentDataPropertiesAxiom OWLEquivalentDataPropertiesAxiom]] | ||
| 113 | * - [[org.semanticweb.owlapi.model.OWLFunctionalDataPropertyAxiom OWLFunctionalDataPropertyAxiom]] | ||
| 114 | * - [[org.semanticweb.owlapi.model.OWLHasKeyAxiom OWLHasKeyAxiom]] | 103 | * - [[org.semanticweb.owlapi.model.OWLHasKeyAxiom OWLHasKeyAxiom]] |
| 115 | * - [[org.semanticweb.owlapi.model.OWLIrreflexiveObjectPropertyAxiom OWLIrreflexiveObjectPropertyAxiom]] | 104 | * - [[org.semanticweb.owlapi.model.SWRLRule SWRLRule]] |
| 116 | * - [[org.semanticweb.owlapi.model.OWLNegativeDataPropertyAssertionAxiom OWLNegativeDataPropertyAssertionAxiom]] | 105 | * |
| 117 | * - [[org.semanticweb.owlapi.model.OWLNegativeObjectPropertyAssertionAxiom OWLNegativeObjectPropertyAssertionAxiom]] | 106 | * @note The following axioms are not handled directly but can be |
| 107 | * normalised beforehand. | ||
| 108 | * | ||
| 109 | * - [[org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom OWLTransitiveObjectPropertyAxiom]] | ||
| 110 | * - [[org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom OWLDataPropertyAssertionAxiom]] | ||
| 111 | * - [[org.semanticweb.owlapi.model.OWLDataPropertyRangeAxiom OWLDataPropertyRangeAxiom]] | ||
| 112 | * - [[org.semanticweb.owlapi.model.OWLDifferentIndividualsAxiom OWLDifferentIndividualsAxiom]] | ||
| 118 | * - [[org.semanticweb.owlapi.model.OWLReflexiveObjectPropertyAxiom OWLReflexiveObjectPropertyAxiom]] | 113 | * - [[org.semanticweb.owlapi.model.OWLReflexiveObjectPropertyAxiom OWLReflexiveObjectPropertyAxiom]] |
| 119 | * - [[org.semanticweb.owlapi.model.OWLSameIndividualAxiom OWLSameIndividualAxiom]] | 114 | * - [[org.semanticweb.owlapi.model.OWLSameIndividualAxiom OWLSameIndividualAxiom]] |
| 120 | * - [[org.semanticweb.owlapi.model.OWLSubPropertyChainOfAxiom OWLSubPropertyChainOfAxiom]] | 115 | * - [[org.semanticweb.owlapi.model.OWLNegativeDataPropertyAssertionAxiom OWLNegativeDataPropertyAssertionAxiom]] |
| 121 | * - [[org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom OWLTransitiveObjectPropertyAxiom]] | 116 | * - [[org.semanticweb.owlapi.model.OWLNegativeObjectPropertyAssertionAxiom OWLNegativeObjectPropertyAssertionAxiom]] |
| 122 | * - [[org.semanticweb.owlapi.model.SWRLRule SWRLRule]] | 117 | * - [[org.semanticweb.owlapi.model.OWLIrreflexiveObjectPropertyAxiom OWLIrreflexiveObjectPropertyAxiom]] |
| 118 | * - [[org.semanticweb.owlapi.model.OWLDisjointUnionAxiom OWLDisjointUnionAxiom]] | ||
| 119 | * - [[org.semanticweb.owlapi.model.OWLEquivalentDataPropertiesAxiom OWLEquivalentDataPropertiesAxiom]] | ||
| 120 | * - [[org.semanticweb.owlapi.model.OWLFunctionalDataPropertyAxiom OWLFunctionalDataPropertyAxiom]] | ||
| 121 | * | ||
| 122 | * @see [[Normaliser]] | ||
| 123 | * @see | ||
| 124 | * http://owlcs.github.io/owlapi/apidocs_5/index.html | ||
| 123 | */ | 125 | */ |
| 124 | def convert( | 126 | def convert( |
| 125 | axiom: OWLLogicalAxiom, | 127 | axiom: OWLLogicalAxiom, |
| @@ -250,20 +252,26 @@ trait RDFoxConverter { | |||
| 250 | ResultF(List(prop)) | 252 | ResultF(List(prop)) |
| 251 | } | 253 | } |
| 252 | 254 | ||
| 253 | case a: OWLDataPropertyRangeAxiom => | 255 | case a: OWLSubPropertyChainOfAxiom => { |
| 254 | Result() // ignored | 256 | val (term1, body) = a.getPropertyChain.foldLeft((term, List[TupleTableAtom]())){ |
| 255 | 257 | case ((term, atoms), prop) => { | |
| 256 | case a: OWLFunctionalDataPropertyAxiom => | 258 | val term1 = RSAUtil.genFreshVariable() |
| 257 | Result() | 259 | val atom = convert(prop, term, term1, suffix) |
| 258 | 260 | (term1, atoms :+ atom) | |
| 259 | case a: OWLTransitiveObjectPropertyAxiom => | 261 | } |
| 260 | Result() | 262 | } |
| 263 | val head = convert(a.getSuperProperty, term, term1, suffix) | ||
| 264 | ResultR(List(Rule.create(head, body))) | ||
| 265 | } | ||
| 261 | 266 | ||
| 262 | /** Catch-all case for all unhandled axiom types. */ | 267 | /** Catch-all case for all unhandled axiom types. */ |
| 263 | case a => default(axiom) | 268 | case a => unsupported(axiom) |
| 264 | } | 269 | } |
| 265 | 270 | ||
| 266 | protected def default(axiom: OWLLogicalAxiom): Result = | 271 | protected def toBeNormalised(axiom: OWLLogicalAxiom): Result = |
| 272 | throw new RuntimeException(s"Axiom '$axiom' should be normalised!") | ||
| 273 | |||
| 274 | protected def unsupported(axiom: OWLLogicalAxiom): Result = | ||
| 267 | throw new RuntimeException(s"Axiom '$axiom' is not supported (yet?)") | 275 | throw new RuntimeException(s"Axiom '$axiom' is not supported (yet?)") |
| 268 | 276 | ||
| 269 | /** Converts a class expression into a collection of atoms. | 277 | /** Converts a class expression into a collection of atoms. |
