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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
package rsacomb
import scala.collection.JavaConverters._
import java.util.stream.{Stream,Collectors}
import org.semanticweb.owlapi.model.{OWLClassExpression, OWLClass, OWLObjectSomeValuesFrom, OWLObjectIntersectionOf, OWLObjectOneOf, OWLObjectMaxCardinality}
import org.semanticweb.owlapi.model.OWLClassExpressionVisitorEx
import tech.oxfordsemantic.jrdfox.logic.{BindAtom, BuiltinFunctionCall, TupleTableName}
import tech.oxfordsemantic.jrdfox.logic.{Atom, Term, Variable, Literal, Datatype}
import rsacomb.SkolemStrategy
import rsacomb.RDFoxRuleShards
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression
import org.semanticweb.owlapi.model.OWLObjectProperty
object RDFoxClassExprConverter {
def apply(
term : Term = Variable.create("x"),
skolem : SkolemStrategy = SkolemStrategy.None,
unsafe : List[OWLObjectPropertyExpression] = List()
) : RDFoxClassExprConverter =
new RDFoxClassExprConverter(term, skolem, unsafe)
def merge(rules : List[RDFoxRuleShards]) : RDFoxRuleShards = {
rules.foldLeft(RDFoxRuleShards(List(),List())) {
(r1,r2) =>
RDFoxRuleShards(
r1.res ++ r2.res,
r1.ext ++ r2.ext
)
}
}
} // object RDFoxClassExprConverter
class RDFoxClassExprConverter(term : Term, skolem : SkolemStrategy, unsafe : List[OWLObjectPropertyExpression])
extends OWLClassExpressionVisitorEx[RDFoxRuleShards]
{
// OWLClass
override
def visit(expr : OWLClass) : RDFoxRuleShards = {
val name = expr.getIRI.getIRIString
val atom = List(Atom.create(TupleTableName.create(name), term))
RDFoxRuleShards(atom,List())
}
// OWLObjectIntersectionOf
override
def visit(expr : OWLObjectIntersectionOf) : RDFoxRuleShards = {
val visitor = new RDFoxClassExprConverter(term, skolem, unsafe)
// TODO: maybe using `flatMap` instead of `merge` + `map` works as well
RDFoxClassExprConverter.merge (
expr.asConjunctSet.asScala.toList
.map((e : OWLClassExpression) => e.accept(visitor))
)
}
// OWLObjectOneOf
override
def visit(expr : OWLObjectOneOf) : RDFoxRuleShards = {
val visitor = RDFoxClassExprConverter(term,skolem)
// TODO: review nominal handling. Here we are taking "just" one
val ind = expr.individuals.collect(Collectors.toList()).asScala
.filter(_.isOWLNamedIndividual)
.head // restricts to proper "nominals"
.asOWLNamedIndividual.getIRI.getIRIString
val atom = List(Atom.create(
TupleTableName.create("owl:sameAs"), term, Literal.create(ind, Datatype.IRI_REFERENCE)
))
RDFoxRuleShards(atom,List())
}
// OWLObjectSomeValuesFrom
override
def visit(expr : OWLObjectSomeValuesFrom) : RDFoxRuleShards = {
// TODO: variables needs to be handled at visitor level. Hardcoding
// the name of the varibles might lead to errors for complex cases.
val y = Variable.create("y")
val prop = expr.getProperty()
// Computes the result of rule skolemization. Depending on the used
// technique it might involve the introduction of additional atoms,
// and/or fresh constants and variables.
val (head, body, term1) = skolem match {
case SkolemStrategy.None => (List(), List(), y)
case SkolemStrategy.Constant(c) => (List(), List(), Literal.create(c, Datatype.IRI_REFERENCE))
case SkolemStrategy.ConstantRSA(c) => {
val lit = Literal.create(c, Datatype.IRI_REFERENCE)
if (unsafe.contains(prop))
(List(Atom.create(TupleTableName.create("internal:PE"),term,lit), Atom.create(TupleTableName.create("internal:U"),lit)), List(), lit)
else
(List(), List(), lit)
}
case SkolemStrategy.Standard(f) =>
// At the time of writing the RDFox library does not have a
// particular class for the "SKOLEM" operator and it is instead
// a simple builtin function with a "special" name.
(List(),List(BindAtom.create(BuiltinFunctionCall.create("SKOLEM",term),y)),y)
}
val classVisitor = new RDFoxClassExprConverter(term1, skolem, unsafe)
val classResult = expr.getFiller.accept(classVisitor)
val propertyVisitor = new RDFoxPropertyExprConverter(term, term1, skolem)
val propertyResult = expr.getProperty.accept(propertyVisitor)
RDFoxRuleShards(
classResult.res ++ propertyResult ++ head,
classResult.ext ++ body
)
}
// OWLObjectMaxCardinality
override
def visit(expr : OWLObjectMaxCardinality) : RDFoxRuleShards = {
// TODO: again, no hardcoded variables
val vars = List(Variable.create("y"),Variable.create("z"))
val classResult = RDFoxClassExprConverter.merge(
vars.map(new RDFoxClassExprConverter(_,skolem, unsafe))
.map(expr.getFiller.accept(_))
)
val propertyResult =
vars.map(new RDFoxPropertyExprConverter(term,_,skolem))
.map(expr.getProperty.accept(_))
.flatten
RDFoxRuleShards(
List(Atom.create(TupleTableName.create("owl:sameAs"),vars(0),vars(1))),
classResult.res ++ propertyResult
)
}
def doDefault(expr : OWLClassExpression) : RDFoxRuleShards =
RDFoxRuleShards(List(),List())
} // class RDFoxClassExprConverter
|