aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/rsacomb/CanonicalModel.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/rsacomb/CanonicalModel.scala')
-rw-r--r--src/main/scala/rsacomb/CanonicalModel.scala278
1 files changed, 0 insertions, 278 deletions
diff --git a/src/main/scala/rsacomb/CanonicalModel.scala b/src/main/scala/rsacomb/CanonicalModel.scala
deleted file mode 100644
index d9e1641..0000000
--- a/src/main/scala/rsacomb/CanonicalModel.scala
+++ /dev/null
@@ -1,278 +0,0 @@
1package rsacomb
2
3import org.semanticweb.owlapi.model.{OWLObjectInverseOf, OWLObjectProperty}
4import org.semanticweb.owlapi.model.{
5 OWLClass,
6 // OWLObjectProperty,
7 OWLSubObjectPropertyOfAxiom,
8 // OWLObjectPropertyExpression,
9 OWLObjectSomeValuesFrom,
10 OWLSubClassOfAxiom
11}
12
13import tech.oxfordsemantic.jrdfox.logic.datalog.{
14 Rule,
15 BodyFormula,
16 TupleTableAtom,
17 Negation
18}
19import tech.oxfordsemantic.jrdfox.logic.expression.{
20 Term,
21 Variable,
22 // Resource,
23 IRI
24}
25
26import suffix.{Empty, Forward, Backward, Inverse}
27import util.RSA
28
29class CanonicalModel(val ontology: RSAOntology) extends RSAAxiom {
30
31 import implicits.RDFox._
32 import implicits.JavaCollections._
33
34 val named: List[Rule] =
35 ontology.individuals.map(a => Rule.create(RSA.Named(a)))
36
37 val rolesAdditionalRules: List[Rule] = {
38 // Given a role (predicate) compute additional logic rules
39 def additional(pred: String): Seq[Rule] = {
40 val varX = Variable.create("X")
41 val varY = Variable.create("Y")
42 for (
43 (hSuffix, bSuffix) <- List(
44 (Empty, Forward),
45 (Empty, Backward),
46 (Inverse, Forward + Inverse),
47 (Inverse, Backward + Inverse),
48 (Backward + Inverse, Forward),
49 (Forward + Inverse, Backward),
50 (Backward, Forward + Inverse),
51 (Forward, Backward + Inverse)
52 )
53 )
54 yield Rule.create(
55 TupleTableAtom.rdf(varX, pred :: hSuffix, varY),
56 TupleTableAtom.rdf(varX, pred :: bSuffix, varY)
57 )
58 }
59 // Compute additional rules per role
60 ontology.roles
61 .collect { case prop: OWLObjectProperty => prop }
62 .map(_.getIRI.getIRIString)
63 .flatMap(additional)
64 }
65
66 private lazy val topAxioms: List[Rule] = {
67 val varX = Variable.create("X")
68 val varY = Variable.create("Y")
69 val concepts = ontology.concepts.map(c => {
70 Rule.create(
71 RSA.Thing(varX),
72 TupleTableAtom.rdf(varX, IRI.RDF_TYPE, c.getIRI)
73 )
74 })
75 val roles = ontology.roles.map(r => {
76 val name = r match {
77 case x: OWLObjectProperty => x.getIRI.getIRIString
78 case x: OWLObjectInverseOf =>
79 x.getInverse.getNamedProperty.getIRI.getIRIString :: Inverse
80 }
81 Rule.create(
82 List(RSA.Thing(varX), RSA.Thing(varY)),
83 List(TupleTableAtom.rdf(varX, name, varY))
84 )
85 })
86 concepts ::: roles
87 }
88
89 private val equalityAxioms: List[Rule] = {
90 val varX = Variable.create("X")
91 val varY = Variable.create("Y")
92 val varZ = Variable.create("Z")
93 List(
94 // Reflexivity
95 Rule.create(RSA.congruent(varX, varX), RSA.Thing(varX)),
96 // Simmetry
97 Rule.create(RSA.congruent(varY, varX), RSA.congruent(varX, varY)),
98 // Transitivity
99 Rule.create(
100 RSA.congruent(varX, varZ),
101 RSA.congruent(varX, varY),
102 RSA.congruent(varY, varZ)
103 )
104 )
105 }
106
107 val rules: List[Rule] = {
108 // Compute rules from ontology axioms
109 val rules = ontology.axioms.flatMap(_.accept(RuleGenerator))
110 // Return full set of rules
111 rules ::: rolesAdditionalRules ::: topAxioms ::: equalityAxioms ::: named
112 }
113
114 object RuleGenerator
115 extends RDFoxAxiomConverter(
116 Variable.create("X"),
117 ontology.unsafeRoles,
118 SkolemStrategy.None,
119 Empty
120 ) {
121
122 private def rules1(axiom: OWLSubClassOfAxiom): List[Rule] = {
123 val unfold = ontology.unfold(axiom).toList
124 // Fresh Variables
125 val v0 = RSA("v0_" ++ axiom.hashed)
126 val varX = Variable.create("X")
127 implicit val unfoldTerm = RSA(unfold.hashCode.toString)
128 // TODO: use axiom.toTriple instead
129 val atomA: TupleTableAtom = {
130 val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI
131 TupleTableAtom.rdf(varX, IRI.RDF_TYPE, cls)
132 }
133 val roleRf: TupleTableAtom = {
134 val visitor =
135 new RDFoxPropertyExprConverter(varX, v0, Forward)
136 axiom.getSuperClass
137 .asInstanceOf[OWLObjectSomeValuesFrom]
138 .getProperty
139 .accept(visitor)
140 .head
141 }
142 val atomB: TupleTableAtom = {
143 val cls = axiom.getSuperClass
144 .asInstanceOf[OWLObjectSomeValuesFrom]
145 .getFiller
146 .asInstanceOf[OWLClass]
147 .getIRI
148 TupleTableAtom.rdf(v0, IRI.RDF_TYPE, cls)
149 }
150 // TODO: To be consistent with the specifics of the visitor we are
151 // returning facts as `Rule`s with true body. While this is correct
152 // there is an easier way to import facts into RDFox. Are we able to
153 // do that?
154 val facts = unfold.map(x => Rule.create(RSA.In(x)))
155 val rules = List(
156 Rule.create(roleRf, atomA, RSA.notIn(varX)),
157 Rule.create(atomB, atomA, RSA.notIn(varX))
158 )
159 facts ++ rules
160 }
161
162 private def rules2(axiom: OWLSubClassOfAxiom): List[Rule] = {
163 val roleR =
164 axiom.getSuperClass
165 .asInstanceOf[OWLObjectSomeValuesFrom]
166 .getProperty
167 if (ontology.confl(roleR) contains roleR) {
168 // Fresh Variables
169 val v0 = RSA("v0_" ++ axiom.hashed)
170 val v1 = RSA("v1_" ++ axiom.hashed)
171 val v2 = RSA("v2_" ++ axiom.hashed)
172 // Predicates
173 def atomA(t: Term): TupleTableAtom = {
174 val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI
175 TupleTableAtom.rdf(t, IRI.RDF_TYPE, cls)
176 }
177 def roleRf(t1: Term, t2: Term): TupleTableAtom = {
178 val visitor =
179 new RDFoxPropertyExprConverter(t1, t2, Forward)
180 roleR.accept(visitor).head
181 }
182 def atomB(t: Term): TupleTableAtom = {
183 val cls = axiom.getSuperClass
184 .asInstanceOf[OWLObjectSomeValuesFrom]
185 .getFiller
186 .asInstanceOf[OWLClass]
187 .getIRI
188 TupleTableAtom.rdf(t, IRI.RDF_TYPE, cls)
189 }
190 //Rules
191 List(
192 Rule.create(roleRf(v0, v1), atomA(v0)),
193 Rule.create(atomB(v1), atomA(v0)),
194 Rule.create(roleRf(v1, v2), atomA(v1)),
195 Rule.create(atomB(v2), atomA(v1))
196 )
197 } else {
198 List()
199 }
200 }
201
202 private def rules3(axiom: OWLSubClassOfAxiom): List[Rule] = {
203 val cycle = ontology.cycle(axiom).toList
204 val roleR =
205 axiom.getSuperClass
206 .asInstanceOf[OWLObjectSomeValuesFrom]
207 .getProperty
208 // Fresh Variables
209 val v1 = RSA("v1_" ++ axiom.hashed)
210 // Predicates
211 def atomA(t: Term): TupleTableAtom = {
212 val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI
213 TupleTableAtom.rdf(t, IRI.RDF_TYPE, cls)
214 }
215 def roleRf(t: Term): TupleTableAtom = {
216 val visitor =
217 new RDFoxPropertyExprConverter(t, v1, Forward)
218 roleR.accept(visitor).head
219 }
220 val atomB: TupleTableAtom = {
221 val cls = axiom.getSuperClass
222 .asInstanceOf[OWLObjectSomeValuesFrom]
223 .getFiller
224 .asInstanceOf[OWLClass]
225 .getIRI
226 TupleTableAtom.rdf(v1, IRI.RDF_TYPE, cls)
227 }
228 cycle.flatMap { x =>
229 List(
230 Rule.create(roleRf(x), atomA(x)),
231 Rule.create(atomB, atomA(x))
232 )
233 }
234 }
235
236 override def visit(axiom: OWLSubClassOfAxiom): List[Rule] = {
237 if (axiom.isT5) {
238 // TODO: get role in T5 axiom
239 // Assuming one role here
240 val role = axiom.objectPropertyExpressionsInSignature(0)
241 if (ontology.unsafeRoles contains role) {
242 val visitor =
243 new RDFoxAxiomConverter(
244 Variable.create("X"),
245 ontology.unsafeRoles,
246 SkolemStrategy.Standard(axiom.toString),
247 Forward
248 )
249 axiom.accept(visitor)
250 } else {
251 rules1(axiom) ::: rules2(axiom) ::: rules3(axiom)
252 }
253 } else {
254 // Fallback to standard OWL to LP translation
255 super.visit(axiom)
256 }
257 }
258
259 override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = {
260 val varX = Variable.create("X")
261 val visitorF = new RDFoxAxiomConverter(
262 varX,
263 ontology.unsafeRoles,
264 SkolemStrategy.None,
265 Forward
266 )
267 val visitorB = new RDFoxAxiomConverter(
268 varX,
269 ontology.unsafeRoles,
270 SkolemStrategy.None,
271 Backward
272 )
273 axiom.accept(visitorB) ::: axiom.accept(visitorF)
274 }
275
276 }
277
278}