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. |