aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/scala/rsacomb/CanonicalModel.scala52
-rw-r--r--src/main/scala/rsacomb/Main.scala14
-rw-r--r--src/main/scala/rsacomb/RSAAxiom.scala8
-rw-r--r--src/main/scala/rsacomb/RSAOntology.scala34
4 files changed, 75 insertions, 33 deletions
diff --git a/src/main/scala/rsacomb/CanonicalModel.scala b/src/main/scala/rsacomb/CanonicalModel.scala
index c957940..95eb556 100644
--- a/src/main/scala/rsacomb/CanonicalModel.scala
+++ b/src/main/scala/rsacomb/CanonicalModel.scala
@@ -29,12 +29,12 @@ object ProgramGenerator {
29 new ProgramGenerator(ontology, term, unsafe) 29 new ProgramGenerator(ontology, term, unsafe)
30 30
31 def generateRoleRules( 31 def generateRoleRules(
32 roles: List[OWLObjectPropertyExpression] 32 roles: Set[OWLObjectProperty]
33 ): List[Rule] = { 33 ): List[Rule] = {
34 def additional(pred: String): Seq[Rule] = { 34 def additional(pred: String): Seq[Rule] = {
35 val varX = Variable.create("X") 35 val varX = Variable.create("X")
36 val varY = Variable.create("Y") 36 val varY = Variable.create("Y")
37 Seq( 37 List(
38 Rule.create( 38 Rule.create(
39 Atom.rdf(varX, IRI.create(pred), varY), 39 Atom.rdf(varX, IRI.create(pred), varY),
40 Atom.rdf(varX, IRI.create(pred ++ RSASuffix.Forward.getSuffix), varY) 40 Atom.rdf(varX, IRI.create(pred ++ RSASuffix.Forward.getSuffix), varY)
@@ -62,10 +62,14 @@ object ProgramGenerator {
62 ) 62 )
63 } 63 }
64 roles 64 roles
65 .filter(_.isInstanceOf[OWLObjectProperty]) // Can we avoid this? 65 .map(_.getIRI.getIRIString)
66 .map(_.asInstanceOf[OWLObjectProperty].getIRI.getIRIString)
67 .flatMap(additional) 66 .flatMap(additional)
67 .toList
68 } 68 }
69
70 def NIs(individuals: List[IRI]): List[Atom] =
71 individuals.map(Atom.rdf(_, IRI.RDF_TYPE, RSA.internal("NI")))
72
69} 73}
70 74
71class ProgramGenerator( 75class ProgramGenerator(
@@ -78,7 +82,7 @@ class ProgramGenerator(
78 82
79 import RDFoxUtil._ 83 import RDFoxUtil._
80 84
81 def rules1(axiom: OWLSubClassOfAxiom): (List[Rule], List[Atom]) = { 85 def rules1(axiom: OWLSubClassOfAxiom): List[Rule] = {
82 val unfold = ontology.cycle(axiom).toList 86 val unfold = ontology.cycle(axiom).toList
83 // Fresh Variables 87 // Fresh Variables
84 val v0 = IRI.create("v0_" ++ axiom.hashCode.toString) 88 val v0 = IRI.create("v0_" ++ axiom.hashCode.toString)
@@ -112,13 +116,16 @@ class ProgramGenerator(
112 .getIRI 116 .getIRI
113 Atom.rdf(v0, IRI.RDF_TYPE, cls) 117 Atom.rdf(v0, IRI.RDF_TYPE, cls)
114 } 118 }
115 ( 119 // TODO: To be consistent with the specifics of the visitor we are
116 List( 120 // returning facts as `Rule`s with true body. While this is correct
117 Rule.create(roleRf, atomA, notIn(varX)), 121 // there is an easier way to import facts into RDFox. Are we able to
118 Rule.create(atomB, atomA, notIn(varX)) 122 // do that?
119 ), 123 val facts = unfold.map(x => Rule.create(notIn(x)))
120 unfold map notIn 124 val rules = List(
125 Rule.create(roleRf, atomA, notIn(varX)),
126 Rule.create(atomB, atomA, notIn(varX))
121 ) 127 )
128 facts ++ rules
122 } 129 }
123 130
124 def rules2(axiom: OWLSubClassOfAxiom): List[Rule] = { 131 def rules2(axiom: OWLSubClassOfAxiom): List[Rule] = {
@@ -209,10 +216,7 @@ class ProgramGenerator(
209 ) 216 )
210 axiom.accept(visitor) 217 axiom.accept(visitor)
211 } else { 218 } else {
212 val (r1, f1) = rules1(axiom) 219 rules1(axiom) ++ rules2(axiom) ++ rules3(axiom)
213 val r2 = rules2(axiom)
214 val r3 = rules3(axiom)
215 r1 ++ r2 ++ r3
216 } 220 }
217 } else { 221 } else {
218 // Fallback to standard OWL to LP translation 222 // Fallback to standard OWL to LP translation
@@ -221,9 +225,21 @@ class ProgramGenerator(
221 } 225 }
222 226
223 override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = { 227 override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = {
224 // TODO: Generate additional rules for role inclusion 228 val varX = Variable.create("X")
225 val additional = List() 229 val varY = Variable.create("Y")
226 super.visit(axiom) ++ additional 230 val visitorF = new RDFoxAxiomConverter(
231 term,
232 unsafe,
233 SkolemStrategy.None,
234 RSASuffix.Forward
235 )
236 val visitorB = new RDFoxAxiomConverter(
237 term,
238 unsafe,
239 SkolemStrategy.None,
240 RSASuffix.Backward
241 )
242 axiom.accept(visitorB) ++ axiom.accept(visitorF)
227 } 243 }
228 244
229} 245}
diff --git a/src/main/scala/rsacomb/Main.scala b/src/main/scala/rsacomb/Main.scala
index 7900e19..5d92061 100644
--- a/src/main/scala/rsacomb/Main.scala
+++ b/src/main/scala/rsacomb/Main.scala
@@ -54,19 +54,7 @@ object RSAComb extends App {
54 54
55 // DEBUG: print program to generate canonical model 55 // DEBUG: print program to generate canonical model
56 { 56 {
57 import tech.oxfordsemantic.jrdfox.logic.{Variable} 57 ontology.canonicalModel.foreach(println)
58 import org.semanticweb.owlapi.model.parameters.Imports
59 import java.util.stream.{Collectors}
60 import scala.collection.JavaConverters._
61
62 val visitor = ProgramGenerator(Variable.create("x"), ontology.unsafeRoles)
63 val axioms =
64 ontology
65 .tboxAxioms(Imports.INCLUDED)
66 .collect(Collectors.toList())
67 .asScala
68 println("Program to generate the canonical model:")
69 axioms.flatMap(_.accept(visitor)).foreach(println)
70 } 58 }
71 59
72 /* Load query */ 60 /* Load query */
diff --git a/src/main/scala/rsacomb/RSAAxiom.scala b/src/main/scala/rsacomb/RSAAxiom.scala
index 50dc37e..aca44b1 100644
--- a/src/main/scala/rsacomb/RSAAxiom.scala
+++ b/src/main/scala/rsacomb/RSAAxiom.scala
@@ -8,6 +8,7 @@ import org.semanticweb.owlapi.model.{
8} 8}
9import org.semanticweb.owlapi.model.{ 9import org.semanticweb.owlapi.model.{
10 OWLObjectPropertyExpression, 10 OWLObjectPropertyExpression,
11 OWLSubObjectPropertyOfAxiom,
11 OWLClass, 12 OWLClass,
12 OWLClassExpression, 13 OWLClassExpression,
13 OWLObjectSomeValuesFrom, 14 OWLObjectSomeValuesFrom,
@@ -148,11 +149,16 @@ trait RSAAxiom {
148 List() 149 List()
149 } 150 }
150 151
152 override def visit(
153 axiom: OWLSubObjectPropertyOfAxiom
154 ): List[OWLObjectPropertyExpression] =
155 List(axiom.getSubProperty(), axiom.getSuperProperty())
156
151 def doDefault(axiom: OWLAxiom): List[OWLObjectPropertyExpression] = List() 157 def doDefault(axiom: OWLAxiom): List[OWLObjectPropertyExpression] = List()
152 } 158 }
153 159
154 /* Exposed methods */ 160 /* Exposed methods */
155 def objectPropertyExpressionsInSignature 161 lazy val objectPropertyExpressionsInSignature
156 : List[OWLObjectPropertyExpression] = { 162 : List[OWLObjectPropertyExpression] = {
157 val visitor = new RSAAxiomRoleExtractor() 163 val visitor = new RSAAxiomRoleExtractor()
158 axiom.accept(visitor) 164 axiom.accept(visitor)
diff --git a/src/main/scala/rsacomb/RSAOntology.scala b/src/main/scala/rsacomb/RSAOntology.scala
index 0acf2a6..e4348d8 100644
--- a/src/main/scala/rsacomb/RSAOntology.scala
+++ b/src/main/scala/rsacomb/RSAOntology.scala
@@ -46,12 +46,13 @@ trait RSAOntology {
46 .toList 46 .toList
47 } 47 }
48 48
49 private lazy val roles: Set[OWLObjectPropertyExpression] = 49 private val roles: Set[OWLObjectPropertyExpression] = {
50 ontology 50 ontology
51 .rboxAxioms(Imports.INCLUDED) 51 .rboxAxioms(Imports.INCLUDED)
52 .collect(Collectors.toSet()) 52 .collect(Collectors.toSet())
53 .asScala 53 .asScala
54 .flatMap(_.objectPropertyExpressionsInSignature) 54 .flatMap(_.objectPropertyExpressionsInSignature)
55 }
55 56
56 // OWLAPI reasoner for same easier tasks 57 // OWLAPI reasoner for same easier tasks
57 private val reasoner = 58 private val reasoner =
@@ -199,6 +200,37 @@ trait RSAOntology {
199 (unsafe1 ++ unsafe2).toList 200 (unsafe1 ++ unsafe2).toList
200 } 201 }
201 202
203 lazy val canonicalModel: List[Rule] = {
204 // Compute program to generate canonical model
205 val tbox =
206 ontology
207 .tboxAxioms(Imports.INCLUDED)
208 .collect(Collectors.toList())
209 .asScala
210 .toList
211 val rbox =
212 ontology
213 .rboxAxioms(Imports.INCLUDED)
214 .collect(Collectors.toList())
215 .asScala
216 .toList
217 val axioms = tbox ++ rbox
218 val varX = Variable.create("X")
219 val visitor = ProgramGenerator(ontology, varX, unsafeRoles)
220 val facts = ProgramGenerator.NIs(individuals)
221 val rules1 = ProgramGenerator.generateRoleRules(
222 axioms
223 .flatMap(
224 _.objectPropertiesInSignature.collect(Collectors.toSet()).asScala
225 )
226 .toSet
227 )
228 val rules2 = axioms.flatMap(_.accept(visitor))
229
230 rules1 ++ rules2
231 // Call RDFox to generate the canonical model
232 }
233
202 private def rsaGraph( 234 private def rsaGraph(
203 data: DataStoreConnection 235 data: DataStoreConnection
204 ): Graph[Resource, UnDiEdge] = { 236 ): Graph[Resource, UnDiEdge] = {