aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/rsacomb/RDFoxAxiomConverter.scala
blob: 9b78e8e8f228a3e5940fea2996a0d2ca7694c98d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package rsacomb

import org.semanticweb.owlapi.model.{
  OWLAxiom,
  OWLSubClassOfAxiom,
  OWLEquivalentClassesAxiom,
  OWLObjectPropertyExpression
}
import org.semanticweb.owlapi.model.OWLAxiomVisitorEx

import tech.oxfordsemantic.jrdfox.logic.datalog.{
  Rule,
  BodyFormula,
  TupleTableAtom,
  TupleTableName
}
import tech.oxfordsemantic.jrdfox.logic.expression.{
  Term,
  IRI,
  Variable,
  Literal
}

import scala.collection.JavaConverters._

import rsacomb.SkolemStrategy
import rsacomb.RDFoxRuleShards
import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom
import org.semanticweb.owlapi.model.OWLObjectProperty
import org.semanticweb.owlapi.model.OWLClassAssertionAxiom

import suffix.{RSASuffix, Empty}

object RDFoxAxiomConverter {

  def apply(
      term: Term,
      unsafe: List[OWLObjectPropertyExpression],
      skolem: SkolemStrategy = SkolemStrategy.None,
      suffix: RSASuffix = Empty
  ): RDFoxAxiomConverter =
    new RDFoxAxiomConverter(term, unsafe, skolem, suffix)

} // object RDFoxAxiomConverter

class RDFoxAxiomConverter(
    term: Term,
    unsafe: List[OWLObjectPropertyExpression],
    skolem: SkolemStrategy,
    suffix: RSASuffix
) extends OWLAxiomVisitorEx[List[Rule]] {

  override def visit(axiom: OWLSubClassOfAxiom): List[Rule] = {
    // Skolemization is needed only for the head of an axiom
    val subVisitor =
      new RDFoxClassExprConverter(term, unsafe, SkolemStrategy.None, suffix)
    val superVisitor = new RDFoxClassExprConverter(term, unsafe, skolem, suffix)
    // Each visitor returns a `RDFoxRuleShards`, a tuple (res,ext):
    // - the `res` List is a list of atoms resulting from the conversion
    //   of the axiom.
    // - for some Class Expressions appearing in the head of an Axiom,
    //   the conversion might produce atoms that need to appear in the
    //   body (and not in the head) of the rule. This is what the `ext`
    //   List is for.
    val sub = axiom.getSubClass.accept(subVisitor)
    val sup = axiom.getSuperClass.accept(superVisitor)
    val head = sup.res.asJava
    val body = (sub.res ++ sup.ext).asJava
    List(Rule.create(head, body))
  }

  override def visit(axiom: OWLEquivalentClassesAxiom): List[Rule] = {
    for {
      axiom1 <- axiom.asPairwiseAxioms.asScala.toList
      axiom2 <- axiom1.asOWLSubClassOfAxioms.asScala.toList
      rule <- axiom2.accept(this)
    } yield rule
  }

  override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = {
    val term1 = RSAOntology.genFreshVariable()
    val subVisitor =
      new RDFoxPropertyExprConverter(term, term1, suffix)
    val superVisitor = new RDFoxPropertyExprConverter(term, term1, suffix)
    val body: List[BodyFormula] = axiom.getSubProperty.accept(subVisitor)
    val head: List[TupleTableAtom] = axiom.getSuperProperty.accept(superVisitor)
    List(Rule.create(head.asJava, body.asJava))
  }

  override def visit(axiom: OWLClassAssertionAxiom): List[Rule] = {
    val ind = axiom.getIndividual
    if (ind.isNamed) {
      val term = IRI.create(ind.asOWLNamedIndividual().getIRI.getIRIString)
      val cls = axiom.getClassExpression
      val visitor =
        new RDFoxClassExprConverter(term, unsafe, SkolemStrategy.None, suffix)
      val shard = cls.accept(visitor)
      List(Rule.create(shard.res.asJava, shard.ext.asJava))
    } else {
      List()
    }
  }

  def doDefault(axiom: OWLAxiom): List[Rule] = List()

} // class RDFoxAxiomConverter