diff options
| author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-12-04 14:00:21 +0000 |
|---|---|---|
| committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-12-04 16:51:38 +0000 |
| commit | ec76d6cfbf5410fc90060667612461c1e8f3c111 (patch) | |
| tree | 6d3268ba7116c2aad3c7238500e87bb990d31a27 /src/main/scala | |
| parent | d7fa665c289923c362c17ce16cda03588911a817 (diff) | |
| download | RSAComb-ec76d6cfbf5410fc90060667612461c1e8f3c111.tar.gz RSAComb-ec76d6cfbf5410fc90060667612461c1e8f3c111.zip | |
Rework skolemization strategies
In particular `ConstantRSA` has been removed, since it was *not* a
skolemization strategy. The case for extra atoms generation previously
handled by `ConstantRSA` is not dealt with inside the RSA check.
Diffstat (limited to 'src/main/scala')
7 files changed, 125 insertions, 161 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 bcc336a..c605e51 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala | |||
| @@ -24,12 +24,7 @@ import tech.oxfordsemantic.jrdfox.logic.expression.{ | |||
| 24 | IRI | 24 | IRI |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | import uk.ac.ox.cs.rsacomb.converter.{ | 27 | import uk.ac.ox.cs.rsacomb.converter._ |
| 28 | SkolemStrategy, | ||
| 29 | RDFoxConverter | ||
| 30 | // RDFoxAxiomConverter, | ||
| 31 | // RDFoxPropertyExprConverter | ||
| 32 | } | ||
| 33 | import uk.ac.ox.cs.rsacomb.suffix._ | 28 | import uk.ac.ox.cs.rsacomb.suffix._ |
| 34 | import uk.ac.ox.cs.rsacomb.util.RSA | 29 | import uk.ac.ox.cs.rsacomb.util.RSA |
| 35 | 30 | ||
| @@ -114,10 +109,8 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
| 114 | val (facts, rules) = { | 109 | val (facts, rules) = { |
| 115 | val term = RSAOntology.genFreshVariable() | 110 | val term = RSAOntology.genFreshVariable() |
| 116 | val unsafe = ontology.unsafeRoles | 111 | val unsafe = ontology.unsafeRoles |
| 117 | val skolem = SkolemStrategy.None | ||
| 118 | val suffix = Empty | ||
| 119 | ontology.axioms | 112 | ontology.axioms |
| 120 | .map(CanonicalModelConverter.convert(_, term, unsafe, skolem, suffix)) | 113 | .map(CanonicalModelConverter.convert(_, term, unsafe, NoSkolem, Empty)) |
| 121 | .unzip | 114 | .unzip |
| 122 | } | 115 | } |
| 123 | ( | 116 | ( |
| @@ -245,10 +238,9 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
| 245 | 238 | ||
| 246 | case a: OWLSubClassOfAxiom if a.isT5 => { | 239 | case a: OWLSubClassOfAxiom if a.isT5 => { |
| 247 | val role = axiom.objectPropertyExpressionsInSignature(0) | 240 | val role = axiom.objectPropertyExpressionsInSignature(0) |
| 248 | if (unsafe contains role) { | 241 | if (unsafe contains role) |
| 249 | val skolem = SkolemStrategy.Standard(a.toString) | 242 | super.convert(a, term, unsafe, new Standard(a), Forward) |
| 250 | super.convert(a, term, unsafe, skolem, Forward) | 243 | else { |
| 251 | } else { | ||
| 252 | val (f1, r1) = rules1(a) | 244 | val (f1, r1) = rules1(a) |
| 253 | (f1, r1 ::: rules2(a) ::: rules3(a)) | 245 | (f1, r1 ::: rules2(a) ::: rules3(a)) |
| 254 | } | 246 | } |
| @@ -256,9 +248,9 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
| 256 | 248 | ||
| 257 | case a: OWLSubObjectPropertyOfAxiom => { | 249 | case a: OWLSubObjectPropertyOfAxiom => { |
| 258 | val (factsF, rulesF) = | 250 | val (factsF, rulesF) = |
| 259 | super.convert(a, term, unsafe, SkolemStrategy.None, Forward) | 251 | super.convert(a, term, unsafe, NoSkolem, Forward) |
| 260 | val (factsB, rulesB) = | 252 | val (factsB, rulesB) = |
| 261 | super.convert(a, term, unsafe, SkolemStrategy.None, Backward) | 253 | super.convert(a, term, unsafe, NoSkolem, Backward) |
| 262 | (factsF ::: factsB, rulesF ::: rulesB) | 254 | (factsF ::: factsB, rulesF ::: rulesB) |
| 263 | } | 255 | } |
| 264 | 256 | ||
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala index a965ef9..8fae4c8 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | |||
| @@ -50,7 +50,7 @@ import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer | |||
| 50 | import tech.oxfordsemantic.jrdfox.logic._ | 50 | import tech.oxfordsemantic.jrdfox.logic._ |
| 51 | import org.semanticweb.owlapi.model.OWLObjectInverseOf | 51 | import org.semanticweb.owlapi.model.OWLObjectInverseOf |
| 52 | 52 | ||
| 53 | import uk.ac.ox.cs.rsacomb.converter.{RDFoxConverter, SkolemStrategy} | 53 | import uk.ac.ox.cs.rsacomb.converter._ |
| 54 | import uk.ac.ox.cs.rsacomb.suffix._ | 54 | import uk.ac.ox.cs.rsacomb.suffix._ |
| 55 | import uk.ac.ox.cs.rsacomb.sparql._ | 55 | import uk.ac.ox.cs.rsacomb.sparql._ |
| 56 | import uk.ac.ox.cs.rsacomb.util.{RDFoxUtil, RSA} | 56 | import uk.ac.ox.cs.rsacomb.util.{RDFoxUtil, RSA} |
| @@ -163,16 +163,16 @@ class RSAOntology(val ontology: OWLOntology) { | |||
| 163 | ): Shards = | 163 | ): Shards = |
| 164 | (expr, skolem) match { | 164 | (expr, skolem) match { |
| 165 | 165 | ||
| 166 | case (e: OWLObjectSomeValuesFrom, SkolemStrategy.Constant(c)) | 166 | case (e: OWLObjectSomeValuesFrom, c: Constant) |
| 167 | if unsafe contains e.getProperty => { | 167 | if unsafe contains e.getProperty => { |
| 168 | val (res, ext) = super.convert(e, term, unsafe, skolem, suffix) | 168 | val (res, ext) = super.convert(e, term, unsafe, skolem, suffix) |
| 169 | (RSA.PE(term, c) :: RSA.U(c) :: res, ext) | 169 | (RSA.PE(term, c.iri) :: RSA.U(c.iri) :: res, ext) |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | case (e: OWLDataSomeValuesFrom, SkolemStrategy.Constant(c)) | 172 | case (e: OWLDataSomeValuesFrom, c: Constant) |
| 173 | if unsafe contains e.getProperty => { | 173 | if unsafe contains e.getProperty => { |
| 174 | val (res, ext) = super.convert(e, term, unsafe, skolem, suffix) | 174 | val (res, ext) = super.convert(e, term, unsafe, skolem, suffix) |
| 175 | (RSA.PE(term, c) :: RSA.U(c) :: res, ext) | 175 | (RSA.PE(term, c.iri) :: RSA.U(c.iri) :: res, ext) |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | case _ => super.convert(expr, term, unsafe, skolem, suffix) | 178 | case _ => super.convert(expr, term, unsafe, skolem, suffix) |
| @@ -183,10 +183,7 @@ class RSAOntology(val ontology: OWLOntology) { | |||
| 183 | /* Ontology convertion into LP rules */ | 183 | /* Ontology convertion into LP rules */ |
| 184 | val term = RSAOntology.genFreshVariable() | 184 | val term = RSAOntology.genFreshVariable() |
| 185 | val datalog = axioms | 185 | val datalog = axioms |
| 186 | .map(a => { | 186 | .map(a => RSAConverter.convert(a, term, unsafe, new Constant(a), Empty)) |
| 187 | val skolem = SkolemStrategy.Constant(a.toString) | ||
| 188 | RSAConverter.convert(a, term, unsafe, skolem, Empty) | ||
| 189 | }) | ||
| 190 | .unzip | 187 | .unzip |
| 191 | val facts = datalog._1.flatten | 188 | val facts = datalog._1.flatten |
| 192 | val rules = datalog._2.flatten | 189 | val rules = datalog._2.flatten |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxAxiomConverter.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxAxiomConverter.scala index 93d8f8c..1fbf28a 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxAxiomConverter.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxAxiomConverter.scala | |||
| @@ -44,7 +44,7 @@ object RDFoxAxiomConverter { | |||
| 44 | def apply( | 44 | def apply( |
| 45 | term: Term, | 45 | term: Term, |
| 46 | unsafe: List[OWLObjectPropertyExpression], | 46 | unsafe: List[OWLObjectPropertyExpression], |
| 47 | skolem: SkolemStrategy = SkolemStrategy.None, | 47 | skolem: SkolemStrategy = NoSkolem, |
| 48 | suffix: RSASuffix = Empty | 48 | suffix: RSASuffix = Empty |
| 49 | ): RDFoxAxiomConverter = | 49 | ): RDFoxAxiomConverter = |
| 50 | new RDFoxAxiomConverter(term, unsafe, skolem, suffix) | 50 | new RDFoxAxiomConverter(term, unsafe, skolem, suffix) |
| @@ -63,7 +63,7 @@ class RDFoxAxiomConverter( | |||
| 63 | override def visit(axiom: OWLSubClassOfAxiom): List[Rule] = { | 63 | override def visit(axiom: OWLSubClassOfAxiom): List[Rule] = { |
| 64 | // Skolemization is needed only for the head of an axiom | 64 | // Skolemization is needed only for the head of an axiom |
| 65 | val subVisitor = | 65 | val subVisitor = |
| 66 | new RDFoxClassExprConverter(term, unsafe, SkolemStrategy.None, suffix) | 66 | new RDFoxClassExprConverter(term, unsafe, NoSkolem, suffix) |
| 67 | val superVisitor = new RDFoxClassExprConverter(term, unsafe, skolem, suffix) | 67 | val superVisitor = new RDFoxClassExprConverter(term, unsafe, skolem, suffix) |
| 68 | // Each visitor returns a `RDFoxRuleShards`, a tuple (res,ext): | 68 | // Each visitor returns a `RDFoxRuleShards`, a tuple (res,ext): |
| 69 | // - the `res` List is a list of atoms resulting from the conversion | 69 | // - the `res` List is a list of atoms resulting from the conversion |
| @@ -121,7 +121,7 @@ class RDFoxAxiomConverter( | |||
| 121 | val term = RDFoxIRI.create(ind.asOWLNamedIndividual().getIRI.getIRIString) | 121 | val term = RDFoxIRI.create(ind.asOWLNamedIndividual().getIRI.getIRIString) |
| 122 | val cls = axiom.getClassExpression | 122 | val cls = axiom.getClassExpression |
| 123 | val visitor = | 123 | val visitor = |
| 124 | new RDFoxClassExprConverter(term, unsafe, SkolemStrategy.None, suffix) | 124 | new RDFoxClassExprConverter(term, unsafe, NoSkolem, suffix) |
| 125 | val shard = cls.accept(visitor) | 125 | val shard = cls.accept(visitor) |
| 126 | List(Rule.create(shard.res.asJava, shard.ext.asJava)) | 126 | List(Rule.create(shard.res.asJava, shard.ext.asJava)) |
| 127 | } else { | 127 | } else { |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxClassExprConverter.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxClassExprConverter.scala index 4ededf9..9551c61 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxClassExprConverter.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxClassExprConverter.scala | |||
| @@ -39,7 +39,7 @@ object RDFoxClassExprConverter { | |||
| 39 | def apply( | 39 | def apply( |
| 40 | term: Term, | 40 | term: Term, |
| 41 | unsafe: List[OWLObjectPropertyExpression] = List(), | 41 | unsafe: List[OWLObjectPropertyExpression] = List(), |
| 42 | skolem: SkolemStrategy = SkolemStrategy.None, | 42 | skolem: SkolemStrategy = NoSkolem, |
| 43 | suffix: RSASuffix = Empty | 43 | suffix: RSASuffix = Empty |
| 44 | ): RDFoxClassExprConverter = | 44 | ): RDFoxClassExprConverter = |
| 45 | new RDFoxClassExprConverter(term, unsafe, skolem, suffix) | 45 | new RDFoxClassExprConverter(term, unsafe, skolem, suffix) |
| @@ -58,8 +58,8 @@ object RDFoxClassExprConverter { | |||
| 58 | class RDFoxClassExprConverter( | 58 | class RDFoxClassExprConverter( |
| 59 | term: Term, | 59 | term: Term, |
| 60 | unsafe: List[OWLObjectPropertyExpression], | 60 | unsafe: List[OWLObjectPropertyExpression], |
| 61 | skolem: SkolemStrategy, | 61 | skolem: SkolemStrategy = NoSkolem, |
| 62 | suffix: RSASuffix | 62 | suffix: RSASuffix = Empty |
| 63 | ) extends OWLClassExpressionVisitorEx[RDFoxRuleShards] { | 63 | ) extends OWLClassExpressionVisitorEx[RDFoxRuleShards] { |
| 64 | 64 | ||
| 65 | import uk.ac.ox.cs.rsacomb.implicits.RDFox._ | 65 | import uk.ac.ox.cs.rsacomb.implicits.RDFox._ |
| @@ -106,18 +106,14 @@ class RDFoxClassExprConverter( | |||
| 106 | // technique it might involve the introduction of additional atoms, | 106 | // technique it might involve the introduction of additional atoms, |
| 107 | // and/or fresh constants and variables. | 107 | // and/or fresh constants and variables. |
| 108 | val (head, body, term1) = skolem match { | 108 | val (head, body, term1) = skolem match { |
| 109 | case SkolemStrategy.None => (List(), List(), y) | 109 | case NoSkolem => (List(), List(), y) |
| 110 | case SkolemStrategy.Constant(c) => (List(), List(), c) | 110 | case c: Constant => (List(), List(), c.iri) |
| 111 | case SkolemStrategy.ConstantRSA(c) => { | 111 | case s: Standard => { |
| 112 | if (unsafe.contains(prop)) | ||
| 113 | (List(RSA.PE(term, c), RSA.U(c)), List(), c) | ||
| 114 | else | ||
| 115 | (List(), List(), c) | ||
| 116 | } | ||
| 117 | case SkolemStrategy.Standard(f) => { | ||
| 118 | ( | 112 | ( |
| 119 | List(), | 113 | List(), |
| 120 | List(BindAtom.create(FunctionCall.create("SKOLEM", f, term), y)), | 114 | List( |
| 115 | BindAtom.create(FunctionCall.create("SKOLEM", s.literal, term), y) | ||
| 116 | ), | ||
| 121 | y | 117 | y |
| 122 | ) | 118 | ) |
| 123 | } | 119 | } |
| @@ -152,18 +148,14 @@ class RDFoxClassExprConverter( | |||
| 152 | // technique it might involve the introduction of additional atoms, | 148 | // technique it might involve the introduction of additional atoms, |
| 153 | // and/or fresh constants and variables. | 149 | // and/or fresh constants and variables. |
| 154 | val (head, body, term1) = skolem match { | 150 | val (head, body, term1) = skolem match { |
| 155 | case SkolemStrategy.None => (List(), List(), y) | 151 | case NoSkolem => (List(), List(), y) |
| 156 | case SkolemStrategy.Constant(c) => (List(), List(), c) | 152 | case c: Constant => (List(), List(), c.iri) |
| 157 | case SkolemStrategy.ConstantRSA(c) => { | 153 | case s: Standard => { |
| 158 | if (unsafe.contains(prop)) | ||
| 159 | (List(RSA.PE(term, c), RSA.U(c)), List(), c) | ||
| 160 | else | ||
| 161 | (List(), List(), c) | ||
| 162 | } | ||
| 163 | case SkolemStrategy.Standard(f) => { | ||
| 164 | ( | 154 | ( |
| 165 | List(), | 155 | List(), |
| 166 | List(BindAtom.create(FunctionCall.create("SKOLEM", f, term), y)), | 156 | List( |
| 157 | BindAtom.create(FunctionCall.create("SKOLEM", s.literal, term), y) | ||
| 158 | ), | ||
| 167 | y | 159 | y |
| 168 | ) | 160 | ) |
| 169 | } | 161 | } |
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 7fd4dbe..1c8374c 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 | |||
| @@ -38,7 +38,7 @@ import tech.oxfordsemantic.jrdfox.logic.datalog.{ | |||
| 38 | } | 38 | } |
| 39 | import tech.oxfordsemantic.jrdfox.logic.expression.{Term, IRI, FunctionCall} | 39 | import tech.oxfordsemantic.jrdfox.logic.expression.{Term, IRI, FunctionCall} |
| 40 | import uk.ac.ox.cs.rsacomb.RSAOntology | 40 | import uk.ac.ox.cs.rsacomb.RSAOntology |
| 41 | import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Inverse} | 41 | import uk.ac.ox.cs.rsacomb.suffix.{Empty, Inverse, RSASuffix} |
| 42 | import uk.ac.ox.cs.rsacomb.util.RSA | 42 | import uk.ac.ox.cs.rsacomb.util.RSA |
| 43 | 43 | ||
| 44 | /** Horn-ALCHOIQ to RDFox axiom converter. | 44 | /** Horn-ALCHOIQ to RDFox axiom converter. |
| @@ -144,7 +144,7 @@ trait RDFoxConverter { | |||
| 144 | 144 | ||
| 145 | case a: OWLSubClassOfAxiom => { | 145 | case a: OWLSubClassOfAxiom => { |
| 146 | val (sub, _) = | 146 | val (sub, _) = |
| 147 | convert(a.getSubClass, term, unsafe, SkolemStrategy.None, suffix) | 147 | convert(a.getSubClass, term, unsafe, NoSkolem, suffix) |
| 148 | val (sup, ext) = | 148 | val (sup, ext) = |
| 149 | convert(a.getSuperClass, term, unsafe, skolem, suffix) | 149 | convert(a.getSuperClass, term, unsafe, skolem, suffix) |
| 150 | val rule = Rule.create(sup, ext ::: sub) | 150 | val rule = Rule.create(sup, ext ::: sub) |
| @@ -202,7 +202,7 @@ trait RDFoxConverter { | |||
| 202 | case i: OWLNamedIndividual => { | 202 | case i: OWLNamedIndividual => { |
| 203 | val cls = a.getClassExpression | 203 | val cls = a.getClassExpression |
| 204 | val (res, _) = | 204 | val (res, _) = |
| 205 | convert(cls, i.getIRI, unsafe, SkolemStrategy.None, suffix) | 205 | convert(cls, i.getIRI, unsafe, NoSkolem, suffix) |
| 206 | ResultF(res) | 206 | ResultF(res) |
| 207 | } | 207 | } |
| 208 | case _ => Result() | 208 | case _ => Result() |
| @@ -309,32 +309,18 @@ trait RDFoxConverter { | |||
| 309 | case e: OWLObjectSomeValuesFrom => { | 309 | case e: OWLObjectSomeValuesFrom => { |
| 310 | val cls = e.getFiller() | 310 | val cls = e.getFiller() |
| 311 | val role = e.getProperty() | 311 | val role = e.getProperty() |
| 312 | // TODO: simplify this: | 312 | val varX = RSAOntology.genFreshVariable |
| 313 | // Computes the result of rule skolemization. Depending on the used | 313 | val (bind, term1) = skolem match { |
| 314 | // technique it might involve the introduction of additional atoms, | 314 | case NoSkolem => (None, varX) |
| 315 | // and/or fresh constants and variables. | 315 | case c: Constant => (None, c.iri) |
| 316 | val (head, body, term1) = skolem match { | 316 | case s: Standard => { |
| 317 | case SkolemStrategy.None => | 317 | val func = FunctionCall.create("SKOLEM", s.literal, term) |
| 318 | (List(), List(), RSAOntology.genFreshVariable) | 318 | (Some(BindAtom.create(func, varX)), varX) |
| 319 | case SkolemStrategy.Constant(c) => (List(), List(), c) | ||
| 320 | case SkolemStrategy.ConstantRSA(c) => { | ||
| 321 | if (unsafe.contains(role)) | ||
| 322 | (List(RSA.PE(term, c), RSA.U(c)), List(), c) | ||
| 323 | else | ||
| 324 | (List(), List(), c) | ||
| 325 | } | ||
| 326 | case SkolemStrategy.Standard(f) => { | ||
| 327 | val x = RSAOntology.genFreshVariable | ||
| 328 | ( | ||
| 329 | List(), | ||
| 330 | List(BindAtom.create(FunctionCall.create("SKOLEM", f, term), x)), | ||
| 331 | x | ||
| 332 | ) | ||
| 333 | } | 319 | } |
| 334 | } | 320 | } |
| 335 | val (res, ext) = convert(cls, term1, unsafe, skolem, suffix) | 321 | val (res, ext) = convert(cls, term1, unsafe, skolem, suffix) |
| 336 | val prop = convert(role, term, term1, suffix) | 322 | val prop = convert(role, term, term1, suffix) |
| 337 | (prop :: head ::: res, body ::: ext) | 323 | (prop :: res, ext ++ bind) |
| 338 | } | 324 | } |
| 339 | 325 | ||
| 340 | /** Existential class expression (for data properties). | 326 | /** Existential class expression (for data properties). |
| @@ -354,27 +340,17 @@ trait RDFoxConverter { | |||
| 354 | // Computes the result of rule skolemization. Depending on the used | 340 | // Computes the result of rule skolemization. Depending on the used |
| 355 | // technique it might involve the introduction of additional atoms, | 341 | // technique it might involve the introduction of additional atoms, |
| 356 | // and/or fresh constants and variables. | 342 | // and/or fresh constants and variables. |
| 357 | val (head, body, term1) = skolem match { | 343 | val varX = RSAOntology.genFreshVariable |
| 358 | case SkolemStrategy.None => | 344 | val (bind, term1) = skolem match { |
| 359 | (List(), List(), RSAOntology.genFreshVariable) | 345 | case NoSkolem => (None, varX) |
| 360 | case SkolemStrategy.Constant(c) => (List(), List(), c) | 346 | case c: Constant => (None, c.iri) |
| 361 | case SkolemStrategy.ConstantRSA(c) => { | 347 | case s: Standard => { |
| 362 | if (unsafe.contains(role)) | 348 | val func = FunctionCall.create("SKOLEM", s.literal, term) |
| 363 | (List(RSA.PE(term, c), RSA.U(c)), List(), c) | 349 | (Some(BindAtom.create(func, varX)), varX) |
| 364 | else | ||
| 365 | (List(), List(), c) | ||
| 366 | } | ||
| 367 | case SkolemStrategy.Standard(f) => { | ||
| 368 | val y = RSAOntology.genFreshVariable() | ||
| 369 | ( | ||
| 370 | List(), | ||
| 371 | List(BindAtom.create(FunctionCall.create("SKOLEM", f, term), y)), | ||
| 372 | y | ||
| 373 | ) | ||
| 374 | } | 350 | } |
| 375 | } | 351 | } |
| 376 | val prop = convert(role, term, term1, suffix) | 352 | val prop = convert(role, term, term1, suffix) |
| 377 | (prop :: head, body) | 353 | (List(prop), bind.toList) |
| 378 | } | 354 | } |
| 379 | 355 | ||
| 380 | /** Maximum cardinality restriction class | 356 | /** Maximum cardinality restriction class |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/SkolemStrategy.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/SkolemStrategy.scala index 0d72226..587db91 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/SkolemStrategy.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/SkolemStrategy.scala | |||
| @@ -1,78 +1,76 @@ | |||
| 1 | package uk.ac.ox.cs.rsacomb.converter | 1 | package uk.ac.ox.cs.rsacomb.converter |
| 2 | 2 | ||
| 3 | import org.semanticweb.owlapi.model.OWLAxiom | ||
| 3 | import tech.oxfordsemantic.jrdfox.logic.Datatype | 4 | import tech.oxfordsemantic.jrdfox.logic.Datatype |
| 4 | import tech.oxfordsemantic.jrdfox.logic.expression.{Literal, IRI} | 5 | import tech.oxfordsemantic.jrdfox.logic.expression.{Literal, IRI} |
| 5 | 6 | ||
| 6 | sealed trait SkolemStrategy | 7 | sealed trait SkolemStrategy |
| 7 | 8 | ||
| 8 | object SkolemStrategy { | 9 | /** No skolemization. |
| 9 | // TODO: might want to use something else other than `hashCode` as a | 10 | * |
| 10 | // function to generate a fresh function/constant | 11 | * @example role `R` from |
| 12 | * {{{ | ||
| 13 | * ∃R.A ⊑ B | ||
| 14 | * }}} | ||
| 15 | * to | ||
| 16 | * {{{ | ||
| 17 | * R(x,y), B(y) -> B(x) | ||
| 18 | * }}} | ||
| 19 | */ | ||
| 20 | case object NoSkolem extends SkolemStrategy | ||
| 11 | 21 | ||
| 12 | /* No skolemization at all. | 22 | /** Functional skolemization |
| 13 | * | 23 | * |
| 14 | * From | 24 | * The factory object should be used to create new instances of the |
| 15 | * ∃R.A ⊑ B | 25 | * class. |
| 16 | * to | 26 | * |
| 17 | * R(x,y), B(y) -> B(x) | 27 | * @example role `R` from |
| 18 | */ | 28 | * {{{ |
| 19 | case object None extends SkolemStrategy | 29 | * A ⊑ ∃R.B |
| 20 | 30 | * }}} | |
| 21 | /* Functional skolemization | 31 | * to |
| 22 | * | 32 | * {{{ |
| 23 | * From | 33 | * A(x) -> R(x,f(x)), B(f(x)) |
| 24 | * A ⊑ ∃R.B | 34 | * }}} |
| 25 | * to | 35 | * for `f`, fresh function uniquely associated with the input axiom. |
| 26 | * A(x) -> R(x,f(x)), B(f(x)) | 36 | * |
| 27 | * for f, fresh function associated with the input axiom | 37 | * RDFox does not support function symbols. We can still implement |
| 28 | * | 38 | * function symbols combining the `BIND` operator with the `SKOLEM` |
| 29 | * In RDFox this can represented combining the BIND operator with the | 39 | * operator as such: |
| 30 | * SKOLEM operator as such: | 40 | * {{{ |
| 31 | * A(x), BIND(y, SKOLEM("f", x)) -> R(x,y), B(y) | 41 | * A(x), BIND(y, SKOLEM("f", x)) -> R(x,y), B(y) |
| 32 | * The first argument of a SKOLEM call is a literal string (ideally | 42 | * }}} |
| 33 | * identifing the simulated function name). | 43 | * The first argument of a `SKOLEM` call '''must''' be a literal string |
| 34 | * | 44 | * (ideally identifing the simulated function name). |
| 35 | * NOTE: this requirement for the SKOLEM operator is not enforced by | 45 | * |
| 36 | * RDFox, that will fail silently if omitted. | 46 | * @note this requirement is not enforced by RDFox, that will fail |
| 37 | */ | 47 | * silently if a string argument is omitted. |
| 38 | case class Standard(func: Literal) extends SkolemStrategy | 48 | */ |
| 39 | object Standard { | 49 | class Standard(var axiom: OWLAxiom)(implicit toString: (OWLAxiom) => String) |
| 40 | def apply(axiom: String) = | 50 | extends SkolemStrategy { |
| 41 | new Standard( | 51 | def dup(a: OWLAxiom) = new Standard(a)(toString) |
| 42 | Literal.create(genFunctionString(axiom), Datatype.XSD_STRING) | 52 | lazy val literal = |
| 43 | ) | 53 | Literal.create(s"f_${toString(axiom)}", Datatype.XSD_STRING) |
| 44 | def genFunctionString(str: String) = "f_" ++ str.hashCode.toString | 54 | } |
| 45 | } | ||
| 46 | |||
| 47 | /* Constant skolemization | ||
| 48 | * | ||
| 49 | * From | ||
| 50 | * A ⊑ ∃R.B | ||
| 51 | * to | ||
| 52 | * A(y) -> R(x,c), B(c) | ||
| 53 | * for c, fresh constant associated with the input axiom | ||
| 54 | */ | ||
| 55 | case class Constant(const: IRI) extends SkolemStrategy | ||
| 56 | object Constant { | ||
| 57 | def apply(axiom: String) = | ||
| 58 | new Constant(IRI.create(genConstantString(axiom))) | ||
| 59 | def genConstantString(str: String) = "c_" ++ str.hashCode.toString | ||
| 60 | } | ||
| 61 | 55 | ||
| 62 | /* (RSA) Constant skolemization | 56 | /** Constant skolemization |
| 63 | * This is a special skolemization option to introduce additional atoms for RSA | 57 | * |
| 64 | * checking algorithm. | 58 | * The factory object should be used to create new instances of the |
| 65 | * | 59 | * class. |
| 66 | * From | 60 | * |
| 67 | * A ⊑ ∃R.B | 61 | * @example role `R` from |
| 68 | * to | 62 | * {{{ |
| 69 | * A(y) -> R(x,c), PE(x,c), B(c) | 63 | * A ⊑ ∃R.B |
| 70 | * for c, fresh constant associated with the input axiom and PE an internal predicate. | 64 | * }}} |
| 71 | */ | 65 | * to |
| 72 | case class ConstantRSA(const: IRI) extends SkolemStrategy | 66 | * {{{ |
| 73 | object ConstantRSA { | 67 | * A(y) -> R(x,c), B(c) |
| 74 | def apply(axiom: String) = | 68 | * }}} |
| 75 | new ConstantRSA(IRI.create(genConstantString(axiom))) | 69 | * for `c`, fresh constant '''uniquely''' associated with the input |
| 76 | def genConstantString(str: String) = "c_" ++ str.hashCode.toString | 70 | * axiom |
| 77 | } | 71 | */ |
| 72 | class Constant(var axiom: OWLAxiom)(implicit toString: (OWLAxiom) => String) | ||
| 73 | extends SkolemStrategy { | ||
| 74 | def dup(a: OWLAxiom) = new Constant(a)(toString) | ||
| 75 | lazy val iri = IRI.create(s"c_${toString(axiom)}") | ||
| 78 | } | 76 | } |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/package.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/package.scala new file mode 100644 index 0000000..0484153 --- /dev/null +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/package.scala | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | package uk.ac.ox.cs.rsacomb | ||
| 2 | package object converter { | ||
| 3 | |||
| 4 | import org.semanticweb.owlapi.model.OWLAxiom | ||
| 5 | |||
| 6 | implicit def axiomToHashedString(axiom: OWLAxiom): String = | ||
| 7 | s"${axiom.toString.hashCode}" | ||
| 8 | |||
| 9 | } | ||
