diff options
author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-11-09 10:38:04 +0000 |
---|---|---|
committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-11-09 10:38:04 +0000 |
commit | b60f60013c560a4d481e95f762e6a7c31c7a5ad2 (patch) | |
tree | d85d7518ddb870adfd25fa7edfb6ebdc8d011c60 /src/main/scala/rsacomb | |
parent | 3fe7e89a277f6ffa44d2a698d9edfe4304ed8257 (diff) | |
download | RSAComb-b60f60013c560a4d481e95f762e6a7c31c7a5ad2.tar.gz RSAComb-b60f60013c560a4d481e95f762e6a7c31c7a5ad2.zip |
Simplify reification process and add negation reification
Diffstat (limited to 'src/main/scala/rsacomb')
-rw-r--r-- | src/main/scala/rsacomb/FilteringProgram.scala | 106 | ||||
-rw-r--r-- | src/main/scala/rsacomb/Main.scala | 4 |
2 files changed, 42 insertions, 68 deletions
diff --git a/src/main/scala/rsacomb/FilteringProgram.scala b/src/main/scala/rsacomb/FilteringProgram.scala index 7683a32..7cd9de7 100644 --- a/src/main/scala/rsacomb/FilteringProgram.scala +++ b/src/main/scala/rsacomb/FilteringProgram.scala | |||
@@ -13,6 +13,7 @@ import tech.oxfordsemantic.jrdfox.logic.datalog.{ | |||
13 | TupleTableAtom, | 13 | TupleTableAtom, |
14 | BindAtom, | 14 | BindAtom, |
15 | TupleTableName, | 15 | TupleTableName, |
16 | Atom, | ||
16 | BodyFormula, | 17 | BodyFormula, |
17 | Negation | 18 | Negation |
18 | } | 19 | } |
@@ -364,84 +365,53 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
364 | .prepended(r1) | 365 | .prepended(r1) |
365 | } | 366 | } |
366 | 367 | ||
367 | private sealed trait Reified; | 368 | private def reifyTupleTableAtom( |
368 | private case class ReifiedHead(bind: BindAtom, atoms: List[TupleTableAtom]) | 369 | atom: TupleTableAtom |
369 | extends Reified | 370 | ): (Option[BindAtom], List[TupleTableAtom]) = { |
370 | private case class ReifiedBody(atoms: List[TupleTableAtom]) extends Reified | 371 | if (!atom.isRdfTriple) { |
371 | private case class Unaltered(formula: BodyFormula) extends Reified | 372 | // Compute binding atom |
372 | 373 | val bvar = RSA.getFreshVariable() | |
373 | private def getBindAtom(atom: TupleTableAtom): BindAtom = { | 374 | val name = |
374 | val newvar = RSA.getFreshVariable() | 375 | Literal.create(atom.getTupleTableName.toString(), Datatype.XSD_STRING) |
375 | val name = | 376 | val args = atom.getArguments.asScala.toList.prepended(name) |
376 | Literal.create(atom.getTupleTableName.toString(), Datatype.XSD_STRING) | 377 | val bind = BindAtom.create(FunctionCall.create("SKOLEM", args: _*), bvar) |
377 | val args = atom | 378 | // Compute reified atom |
378 | .getArguments() | 379 | def reifiedIRI(i: Int) = atom.getTupleTableName.getName ++ s"_$i" |
379 | .asScala | 380 | val atoms = atom.getArguments.asScala.toList.zipWithIndex |
380 | .toSeq | 381 | .map { case (t, i) => TupleTableAtom.rdf(bvar, reifiedIRI(i), t) } |
381 | .prepended(name) /* Unclear requirement for SKOLEM func calls */ | 382 | (Some(bind), atoms) |
382 | BindAtom.create( | 383 | } else { |
383 | FunctionCall | 384 | (None, List(atom)) |
384 | .create("SKOLEM", args: _*), | 385 | } |
385 | newvar | ||
386 | ) | ||
387 | } | 386 | } |
388 | 387 | ||
389 | private def reifyAtom( | 388 | private def reifyAtom(atom: Atom): (Option[BindAtom], List[Atom]) = { |
390 | atom: TupleTableAtom, | 389 | atom match { |
391 | variable: Variable | 390 | case tta: TupleTableAtom => reifyTupleTableAtom(tta) |
392 | ): List[TupleTableAtom] = { | 391 | case other => (None, List(other)) |
393 | def iri(i: Int) = atom.getTupleTableName.getName ++ s"_$i" | 392 | } |
394 | atom | ||
395 | .getArguments() | ||
396 | .asScala | ||
397 | .zipWithIndex | ||
398 | .map { case (t, i) => TupleTableAtom.rdf(variable, iri(i), t) } | ||
399 | .toList | ||
400 | } | 393 | } |
401 | 394 | ||
402 | private def reifyBodyFormula( | 395 | private def reifyBodyFormula(formula: BodyFormula): List[BodyFormula] = { |
403 | formula: BodyFormula, | ||
404 | head: Boolean | ||
405 | ): Reified = { | ||
406 | formula match { | 396 | formula match { |
407 | case a: TupleTableAtom => { | 397 | case atom: TupleTableAtom => reifyTupleTableAtom(atom)._2 |
408 | if (!a.isRdfTriple) { | 398 | case neg: Negation => { |
409 | if (head) { | 399 | val (bs, as) = neg.getNegatedAtoms.asScala.toList.map(reifyAtom).unzip |
410 | val b = getBindAtom(a) | 400 | val bind = bs.flatten.map(_.getBoundVariable).asJava |
411 | ReifiedHead(b, reifyAtom(a, b.getBoundVariable)) | 401 | val atoms = as.flatten.asJava |
412 | } else { | 402 | List(Negation.create(bind, atoms)) |
413 | ReifiedBody(reifyAtom(a, RSA.getFreshVariable)) | ||
414 | } | ||
415 | } else { | ||
416 | Unaltered(a) | ||
417 | } | ||
418 | } | 403 | } |
419 | case a => Unaltered(a) | 404 | case other => List(other) |
420 | } | 405 | } |
421 | } | 406 | } |
422 | 407 | ||
423 | private def reifyRule(rule: Rule): Rule = { | 408 | private def reifyRule(rule: Rule): Rule = { |
424 | // Rule body | 409 | val (bs, hs) = rule.getHead.asScala.toList.map(reifyTupleTableAtom).unzip |
425 | val body = | 410 | val head: List[TupleTableAtom] = hs.flatten |
426 | rule.getBody.asScala.map(reifyBodyFormula(_, false)).flatMap { | 411 | val bind: List[BodyFormula] = bs.flatten |
427 | case ReifiedHead(_, _) => List(); /* handle impossible case */ | 412 | val body: List[BodyFormula] = |
428 | case ReifiedBody(x) => x; | 413 | rule.getBody.asScala.toList.map(reifyBodyFormula).flatten |
429 | case Unaltered(x) => List(x) | 414 | Rule.create(head.asJava, (body ++ bind).asJava) |
430 | } | ||
431 | // Rule head | ||
432 | val reified = rule.getHead.asScala.map(reifyBodyFormula(_, true)) | ||
433 | val skols = reified.flatMap { | ||
434 | case ReifiedHead(x, _) => Some(x); | ||
435 | case ReifiedBody(_) => None; /* handle impossible case */ | ||
436 | case Unaltered(_) => None | ||
437 | } | ||
438 | val head = reified.flatMap { | ||
439 | case ReifiedHead(_, x) => x; | ||
440 | case ReifiedBody(_) => List(); /* handle impossible case */ | ||
441 | case Unaltered(x) => | ||
442 | List(x.asInstanceOf[TupleTableAtom]) /* Can we do better that a cast? */ | ||
443 | } | ||
444 | Rule.create(head.asJava, (skols ++ body).asJava) | ||
445 | } | 415 | } |
446 | 416 | ||
447 | } // class FilteringProgram | 417 | } // class FilteringProgram |
diff --git a/src/main/scala/rsacomb/Main.scala b/src/main/scala/rsacomb/Main.scala index 64343f5..b893c4f 100644 --- a/src/main/scala/rsacomb/Main.scala +++ b/src/main/scala/rsacomb/Main.scala | |||
@@ -76,6 +76,10 @@ object RSAComb extends App { | |||
76 | val canon = ontology.canonicalModel | 76 | val canon = ontology.canonicalModel |
77 | val filter = ontology.filteringProgram(query) | 77 | val filter = ontology.filteringProgram(query) |
78 | 78 | ||
79 | { | ||
80 | filter.rules.foreach(println) | ||
81 | } | ||
82 | |||
79 | // Import relevant data | 83 | // Import relevant data |
80 | data.importData(UpdateType.ADDITION, RSA.Prefixes, ":a a :A .") | 84 | data.importData(UpdateType.ADDITION, RSA.Prefixes, ":a a :A .") |
81 | data.addRules(canon.rules.asJava) | 85 | data.addRules(canon.rules.asJava) |