diff options
author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-12-02 16:44:14 +0000 |
---|---|---|
committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-12-02 16:44:14 +0000 |
commit | a72e44139897052eb83fe464fca94489e8f80092 (patch) | |
tree | 547832cfe93419cbdb91db9703b39970c55470fe /src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala | |
parent | 83330598df9a806508b2157a41f17a3faaddcd56 (diff) | |
download | RSAComb-a72e44139897052eb83fe464fca94489e8f80092.tar.gz RSAComb-a72e44139897052eb83fe464fca94489e8f80092.zip |
Adapt canonical model computation to new RDFox converter
When it comes to the canonical model, now facts are imported as facts in
RDFox.
Diffstat (limited to 'src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala')
-rw-r--r-- | src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala | 133 |
1 files changed, 61 insertions, 72 deletions
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala index 0f3b16a..bcc336a 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala | |||
@@ -3,9 +3,10 @@ package uk.ac.ox.cs.rsacomb | |||
3 | import org.semanticweb.owlapi.model.{OWLObjectInverseOf, OWLObjectProperty} | 3 | import org.semanticweb.owlapi.model.{OWLObjectInverseOf, OWLObjectProperty} |
4 | import org.semanticweb.owlapi.model.{ | 4 | import org.semanticweb.owlapi.model.{ |
5 | OWLClass, | 5 | OWLClass, |
6 | OWLLogicalAxiom, | ||
6 | // OWLObjectProperty, | 7 | // OWLObjectProperty, |
7 | OWLSubObjectPropertyOfAxiom, | 8 | OWLSubObjectPropertyOfAxiom, |
8 | // OWLObjectPropertyExpression, | 9 | OWLObjectPropertyExpression, |
9 | OWLObjectSomeValuesFrom, | 10 | OWLObjectSomeValuesFrom, |
10 | OWLSubClassOfAxiom | 11 | OWLSubClassOfAxiom |
11 | } | 12 | } |
@@ -25,10 +26,11 @@ import tech.oxfordsemantic.jrdfox.logic.expression.{ | |||
25 | 26 | ||
26 | import uk.ac.ox.cs.rsacomb.converter.{ | 27 | import uk.ac.ox.cs.rsacomb.converter.{ |
27 | SkolemStrategy, | 28 | SkolemStrategy, |
28 | RDFoxAxiomConverter, | 29 | RDFoxConverter |
29 | RDFoxPropertyExprConverter | 30 | // RDFoxAxiomConverter, |
31 | // RDFoxPropertyExprConverter | ||
30 | } | 32 | } |
31 | import uk.ac.ox.cs.rsacomb.suffix.{Empty, Forward, Backward, Inverse} | 33 | import uk.ac.ox.cs.rsacomb.suffix._ |
32 | import uk.ac.ox.cs.rsacomb.util.RSA | 34 | import uk.ac.ox.cs.rsacomb.util.RSA |
33 | 35 | ||
34 | class CanonicalModel(val ontology: RSAOntology) { | 36 | class CanonicalModel(val ontology: RSAOntology) { |
@@ -107,22 +109,28 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
107 | ) | 109 | ) |
108 | } | 110 | } |
109 | 111 | ||
110 | val rules: List[Rule] = { | 112 | val (facts, rules): (List[TupleTableAtom], List[Rule]) = { |
111 | // Compute rules from ontology axioms | 113 | // Compute rules from ontology axioms |
112 | val rules = ontology.axioms.flatMap(_.accept(RuleGenerator)) | 114 | val (facts, rules) = { |
113 | // Return full set of rules | 115 | val term = RSAOntology.genFreshVariable() |
114 | rules ::: rolesAdditionalRules ::: topAxioms ::: equalityAxioms | 116 | val unsafe = ontology.unsafeRoles |
117 | val skolem = SkolemStrategy.None | ||
118 | val suffix = Empty | ||
119 | ontology.axioms | ||
120 | .map(CanonicalModelConverter.convert(_, term, unsafe, skolem, suffix)) | ||
121 | .unzip | ||
122 | } | ||
123 | ( | ||
124 | facts.flatten, | ||
125 | rolesAdditionalRules ::: topAxioms ::: equalityAxioms ::: rules.flatten | ||
126 | ) | ||
115 | } | 127 | } |
116 | 128 | ||
117 | object RuleGenerator | 129 | object CanonicalModelConverter extends RDFoxConverter { |
118 | extends RDFoxAxiomConverter( | ||
119 | Variable.create("X"), | ||
120 | ontology.unsafeRoles, | ||
121 | SkolemStrategy.None, | ||
122 | Empty | ||
123 | ) { | ||
124 | 130 | ||
125 | private def rules1(axiom: OWLSubClassOfAxiom): List[Rule] = { | 131 | private def rules1( |
132 | axiom: OWLSubClassOfAxiom | ||
133 | ): Result = { | ||
126 | val unfold = ontology.unfold(axiom).toList | 134 | val unfold = ontology.unfold(axiom).toList |
127 | // Fresh Variables | 135 | // Fresh Variables |
128 | val v0 = RSA("v0_" ++ axiom.hashed) | 136 | val v0 = RSA("v0_" ++ axiom.hashed) |
@@ -134,13 +142,9 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
134 | TupleTableAtom.rdf(varX, IRI.RDF_TYPE, cls) | 142 | TupleTableAtom.rdf(varX, IRI.RDF_TYPE, cls) |
135 | } | 143 | } |
136 | val roleRf: TupleTableAtom = { | 144 | val roleRf: TupleTableAtom = { |
137 | val visitor = | 145 | val prop = |
138 | new RDFoxPropertyExprConverter(varX, v0, Forward) | 146 | axiom.getSuperClass.asInstanceOf[OWLObjectSomeValuesFrom].getProperty |
139 | axiom.getSuperClass | 147 | super.convert(prop, varX, v0, Forward) |
140 | .asInstanceOf[OWLObjectSomeValuesFrom] | ||
141 | .getProperty | ||
142 | .accept(visitor) | ||
143 | .head | ||
144 | } | 148 | } |
145 | val atomB: TupleTableAtom = { | 149 | val atomB: TupleTableAtom = { |
146 | val cls = axiom.getSuperClass | 150 | val cls = axiom.getSuperClass |
@@ -154,12 +158,12 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
154 | // returning facts as `Rule`s with true body. While this is correct | 158 | // returning facts as `Rule`s with true body. While this is correct |
155 | // there is an easier way to import facts into RDFox. Are we able to | 159 | // there is an easier way to import facts into RDFox. Are we able to |
156 | // do that? | 160 | // do that? |
157 | val facts = unfold.map(x => Rule.create(RSA.In(x))) | 161 | val facts = unfold map RSA.In |
158 | val rules = List( | 162 | val rules = List( |
159 | Rule.create(roleRf, atomA, RSA.NotIn(varX)), | 163 | Rule.create(roleRf, atomA, RSA.NotIn(varX)), |
160 | Rule.create(atomB, atomA, RSA.NotIn(varX)) | 164 | Rule.create(atomB, atomA, RSA.NotIn(varX)) |
161 | ) | 165 | ) |
162 | facts ++ rules | 166 | (facts, rules) |
163 | } | 167 | } |
164 | 168 | ||
165 | private def rules2(axiom: OWLSubClassOfAxiom): List[Rule] = { | 169 | private def rules2(axiom: OWLSubClassOfAxiom): List[Rule] = { |
@@ -177,11 +181,8 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
177 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI | 181 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI |
178 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, cls) | 182 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, cls) |
179 | } | 183 | } |
180 | def roleRf(t1: Term, t2: Term): TupleTableAtom = { | 184 | def roleRf(t1: Term, t2: Term): TupleTableAtom = |
181 | val visitor = | 185 | super.convert(roleR, t1, t2, Forward) |
182 | new RDFoxPropertyExprConverter(t1, t2, Forward) | ||
183 | roleR.accept(visitor).head | ||
184 | } | ||
185 | def atomB(t: Term): TupleTableAtom = { | 186 | def atomB(t: Term): TupleTableAtom = { |
186 | val cls = axiom.getSuperClass | 187 | val cls = axiom.getSuperClass |
187 | .asInstanceOf[OWLObjectSomeValuesFrom] | 188 | .asInstanceOf[OWLObjectSomeValuesFrom] |
@@ -215,11 +216,8 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
215 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI | 216 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI |
216 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, cls) | 217 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, cls) |
217 | } | 218 | } |
218 | def roleRf(t: Term): TupleTableAtom = { | 219 | def roleRf(t: Term): TupleTableAtom = |
219 | val visitor = | 220 | super.convert(roleR, t, v1, Forward) |
220 | new RDFoxPropertyExprConverter(t, v1, Forward) | ||
221 | roleR.accept(visitor).head | ||
222 | } | ||
223 | val atomB: TupleTableAtom = { | 221 | val atomB: TupleTableAtom = { |
224 | val cls = axiom.getSuperClass | 222 | val cls = axiom.getSuperClass |
225 | .asInstanceOf[OWLObjectSomeValuesFrom] | 223 | .asInstanceOf[OWLObjectSomeValuesFrom] |
@@ -236,46 +234,37 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
236 | } | 234 | } |
237 | } | 235 | } |
238 | 236 | ||
239 | override def visit(axiom: OWLSubClassOfAxiom): List[Rule] = { | 237 | override def convert( |
240 | if (axiom.isT5) { | 238 | axiom: OWLLogicalAxiom, |
241 | // TODO: get role in T5 axiom | 239 | term: Term, |
242 | // Assuming one role here | 240 | unsafe: List[OWLObjectPropertyExpression], |
243 | val role = axiom.objectPropertyExpressionsInSignature(0) | 241 | skolem: SkolemStrategy, |
244 | if (ontology.unsafeRoles contains role) { | 242 | suffix: RSASuffix |
245 | val visitor = | 243 | ): Result = |
246 | new RDFoxAxiomConverter( | 244 | axiom match { |
247 | Variable.create("X"), | 245 | |
248 | ontology.unsafeRoles, | 246 | case a: OWLSubClassOfAxiom if a.isT5 => { |
249 | SkolemStrategy.Standard(axiom.toString), | 247 | val role = axiom.objectPropertyExpressionsInSignature(0) |
250 | Forward | 248 | if (unsafe contains role) { |
251 | ) | 249 | val skolem = SkolemStrategy.Standard(a.toString) |
252 | axiom.accept(visitor) | 250 | super.convert(a, term, unsafe, skolem, Forward) |
253 | } else { | 251 | } else { |
254 | rules1(axiom) ::: rules2(axiom) ::: rules3(axiom) | 252 | val (f1, r1) = rules1(a) |
253 | (f1, r1 ::: rules2(a) ::: rules3(a)) | ||
254 | } | ||
255 | } | 255 | } |
256 | } else { | ||
257 | // Fallback to standard OWL to LP translation | ||
258 | super.visit(axiom) | ||
259 | } | ||
260 | } | ||
261 | 256 | ||
262 | override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = { | 257 | case a: OWLSubObjectPropertyOfAxiom => { |
263 | val varX = Variable.create("X") | 258 | val (factsF, rulesF) = |
264 | val visitorF = new RDFoxAxiomConverter( | 259 | super.convert(a, term, unsafe, SkolemStrategy.None, Forward) |
265 | varX, | 260 | val (factsB, rulesB) = |
266 | ontology.unsafeRoles, | 261 | super.convert(a, term, unsafe, SkolemStrategy.None, Backward) |
267 | SkolemStrategy.None, | 262 | (factsF ::: factsB, rulesF ::: rulesB) |
268 | Forward | 263 | } |
269 | ) | ||
270 | val visitorB = new RDFoxAxiomConverter( | ||
271 | varX, | ||
272 | ontology.unsafeRoles, | ||
273 | SkolemStrategy.None, | ||
274 | Backward | ||
275 | ) | ||
276 | axiom.accept(visitorB) ::: axiom.accept(visitorF) | ||
277 | } | ||
278 | 264 | ||
265 | case a => super.convert(a, term, unsafe, skolem, suffix) | ||
266 | |||
267 | } | ||
279 | } | 268 | } |
280 | 269 | ||
281 | } | 270 | } |