diff options
Diffstat (limited to 'src/main/scala/rsacomb/RSAOntology.scala')
| -rw-r--r-- | src/main/scala/rsacomb/RSAOntology.scala | 105 |
1 files changed, 101 insertions, 4 deletions
diff --git a/src/main/scala/rsacomb/RSAOntology.scala b/src/main/scala/rsacomb/RSAOntology.scala index 3d9210e..efd6e7f 100644 --- a/src/main/scala/rsacomb/RSAOntology.scala +++ b/src/main/scala/rsacomb/RSAOntology.scala | |||
| @@ -19,6 +19,7 @@ import scalax.collection.GraphEdge.UnDiEdge | |||
| 19 | 19 | ||
| 20 | /* Debug only */ | 20 | /* Debug only */ |
| 21 | import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer | 21 | import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer |
| 22 | import tech.oxfordsemantic.jrdfox.logic._ | ||
| 22 | 23 | ||
| 23 | /* Wrapper trait for the implicit class `RSAOntology`. | 24 | /* Wrapper trait for the implicit class `RSAOntology`. |
| 24 | */ | 25 | */ |
| @@ -27,7 +28,9 @@ trait RSAOntology { | |||
| 27 | /* Implements additional features to reason about RSA ontologies | 28 | /* Implements additional features to reason about RSA ontologies |
| 28 | * on top of `OWLOntology` from the OWLAPI. | 29 | * on top of `OWLOntology` from the OWLAPI. |
| 29 | */ | 30 | */ |
| 30 | implicit class RSAOntology(ontology: OWLOntology) extends RSAAxiom { | 31 | implicit class RSAOntology(ontology: OWLOntology) |
| 32 | extends RSAAxiom | ||
| 33 | with RDFTriple { | ||
| 31 | 34 | ||
| 32 | /* Steps for RSA check | 35 | /* Steps for RSA check |
| 33 | * 1) convert ontology axioms into LP rules | 36 | * 1) convert ontology axioms into LP rules |
| @@ -60,7 +63,7 @@ trait RSAOntology { | |||
| 60 | val datalog = for { | 63 | val datalog = for { |
| 61 | axiom <- axioms | 64 | axiom <- axioms |
| 62 | visitor = new RDFoxAxiomConverter( | 65 | visitor = new RDFoxAxiomConverter( |
| 63 | Variable.create("x"), | 66 | RSA.getFreshVariable(), |
| 64 | SkolemStrategy.ConstantRSA(axiom.toString), | 67 | SkolemStrategy.ConstantRSA(axiom.toString), |
| 65 | unsafe | 68 | unsafe |
| 66 | ) | 69 | ) |
| @@ -163,8 +166,9 @@ trait RSAOntology { | |||
| 163 | } yield role1 | 166 | } yield role1 |
| 164 | 167 | ||
| 165 | /* TODO: We should be able to avoid this last conversion to List. | 168 | /* TODO: We should be able to avoid this last conversion to List. |
| 166 | * Maybe we should just move everything to Sets instead of Lists, since | 169 | * Maybe we should just move everything to Sets instead of Lists, |
| 167 | * they have a more straightforward conversion from Java collections. | 170 | * since they have a more straightforward conversion from Java |
| 171 | * collections. | ||
| 168 | */ | 172 | */ |
| 169 | (unsafe1 ++ unsafe2).toList | 173 | (unsafe1 ++ unsafe2).toList |
| 170 | } | 174 | } |
| @@ -184,6 +188,99 @@ trait RSAOntology { | |||
| 184 | Graph(edges: _*) | 188 | Graph(edges: _*) |
| 185 | } | 189 | } |
| 186 | 190 | ||
| 191 | def getFilteringProgram(query: Query): List[Rule] = { | ||
| 192 | |||
| 193 | // Import implicit conversion to RDFox IRI | ||
| 194 | import RDFoxUtil._ | ||
| 195 | |||
| 196 | sealed trait Reified; | ||
| 197 | case class ReifiedHead(bind: BindAtom, atoms: List[Atom]) extends Reified | ||
| 198 | case class ReifiedBody(atoms: List[Atom]) extends Reified | ||
| 199 | case class Unaltered(formula: BodyFormula) extends Reified | ||
| 200 | |||
| 201 | def getBindAtom(atom: Atom): BindAtom = { | ||
| 202 | // TODO: We need to implement another way to introduce fresh | ||
| 203 | // variables. | ||
| 204 | val newvar = RSA.getFreshVariable() | ||
| 205 | val name = | ||
| 206 | Literal.create(atom.getTupleTableName.getIRI, Datatype.XSD_STRING) | ||
| 207 | val args = atom | ||
| 208 | .getArguments() | ||
| 209 | .asScala | ||
| 210 | .toSeq | ||
| 211 | .prepended(name) | ||
| 212 | BindAtom.create( | ||
| 213 | BuiltinFunctionCall | ||
| 214 | .create("SKOLEM", args: _*), | ||
| 215 | newvar | ||
| 216 | ) | ||
| 217 | } | ||
| 218 | |||
| 219 | def reifyAtom(atom: Atom, variable: Variable): List[Atom] = { | ||
| 220 | def iri(i: Int) = atom.getTupleTableName().getIRI() ++ s"_$i" | ||
| 221 | atom | ||
| 222 | .getArguments() | ||
| 223 | .asScala | ||
| 224 | .zipWithIndex | ||
| 225 | .map { case (t, i) => Atom.rdf(variable, iri(i), t) } | ||
| 226 | .toList | ||
| 227 | } | ||
| 228 | |||
| 229 | def reify( | ||
| 230 | formula: BodyFormula, | ||
| 231 | head: Boolean | ||
| 232 | ): Reified = { | ||
| 233 | def default[A <: BodyFormula](x: A) = Unaltered(x) | ||
| 234 | formula match { | ||
| 235 | case a: Atom => { | ||
| 236 | if (!a.isRdfTriple) { | ||
| 237 | if (head) { | ||
| 238 | val b = getBindAtom(a) | ||
| 239 | ReifiedHead(b, reifyAtom(a, b.getBoundVariable)) | ||
| 240 | } else { | ||
| 241 | val varA = RSA.getFreshVariable() | ||
| 242 | ReifiedBody(reifyAtom(a, varA)) | ||
| 243 | } | ||
| 244 | } else { | ||
| 245 | default(a) | ||
| 246 | } | ||
| 247 | } | ||
| 248 | case a => default(a) | ||
| 249 | } | ||
| 250 | } | ||
| 251 | |||
| 252 | def skolemizeRule(rule: Rule): Rule = { | ||
| 253 | // Rule body | ||
| 254 | val body = | ||
| 255 | rule.getBody.asScala.map(reify(_, false)).flatMap { | ||
| 256 | case ReifiedHead(_, _) => List(); /* handle impossible case */ | ||
| 257 | case ReifiedBody(x) => x; | ||
| 258 | case Unaltered(x) => List(x) | ||
| 259 | } | ||
| 260 | // Rule head | ||
| 261 | val reified = rule.getHead.asScala.map(reify(_, true)) | ||
| 262 | val skols = reified.flatMap { | ||
| 263 | case ReifiedHead(x, _) => Some(x); | ||
| 264 | case ReifiedBody(_) => None; /* handle impossible case */ | ||
| 265 | case Unaltered(_) => None | ||
| 266 | } | ||
| 267 | val head = reified.flatMap { | ||
| 268 | case ReifiedHead(_, x) => x; | ||
| 269 | case ReifiedBody(_) => List(); /* handle impossible case */ | ||
| 270 | case Unaltered(x) => | ||
| 271 | List(x.asInstanceOf[Atom]) /* Can we do better that a cast? */ | ||
| 272 | } | ||
| 273 | Rule.create(head.asJava, (skols ++ body).asJava) | ||
| 274 | } | ||
| 275 | |||
| 276 | // DEBUG | ||
| 277 | val rules = FilteringProgram(query, List()).rules | ||
| 278 | println("FILTERING PROGRAM:") | ||
| 279 | rules.map(skolemizeRule(_)).foreach(println(_)) | ||
| 280 | |||
| 281 | List() | ||
| 282 | } | ||
| 283 | |||
| 187 | } // implicit class RSAOntology | 284 | } // implicit class RSAOntology |
| 188 | 285 | ||
| 189 | } // trait RSAOntology | 286 | } // trait RSAOntology |
