aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Igne <git@federicoigne.com>2021-10-04 18:01:50 +0100
committerFederico Igne <git@federicoigne.com>2021-10-04 18:16:15 +0100
commitc86e7d32420adcc05546efa45b21e0e31d0f6c90 (patch)
treed1f006a145b9830ca45383f510348fc049e4b72b
parent55e374c98c1446c612fecd78a352cc870755ef7c (diff)
downloadRSAComb-c86e7d32420adcc05546efa45b21e0e31d0f6c90.tar.gz
RSAComb-c86e7d32420adcc05546efa45b21e0e31d0f6c90.zip
Fix issue where not all roles where considered for top axiomatisation
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala2
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala76
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Lowerbound.scala7
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala2
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/filtering/RevisedFilteringProgram.scala2
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/ontology/Ontology.scala8
6 files changed, 56 insertions, 41 deletions
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala
index a39b9c0..bd3d3c3 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala
@@ -68,7 +68,7 @@ class CanonicalModel(val ontology: RSAOntology, val graph: IRI) {
68 */ 68 */
69 val rolesAdditionalRules: List[Rule] = { 69 val rolesAdditionalRules: List[Rule] = {
70 val tt = TupleTableName.create(graph.getIRI) 70 val tt = TupleTableName.create(graph.getIRI)
71 ontology.roles 71 ontology.objroles
72 .collect { case prop: OWLObjectProperty => prop } 72 .collect { case prop: OWLObjectProperty => prop }
73 .flatMap((pred) => { 73 .flatMap((pred) => {
74 val iri = pred.getIRI.getIRIString 74 val iri = pred.getIRI.getIRIString
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala
index afda25e..1ff466b 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala
@@ -27,6 +27,7 @@ import org.semanticweb.owlapi.model.{OWLOntology, OWLAxiom, OWLLogicalAxiom}
27import org.semanticweb.owlapi.model.{ 27import org.semanticweb.owlapi.model.{
28 OWLClass, 28 OWLClass,
29 OWLClassExpression, 29 OWLClassExpression,
30 OWLDataProperty,
30 OWLDataPropertyAssertionAxiom, 31 OWLDataPropertyAssertionAxiom,
31 OWLObjectProperty, 32 OWLObjectProperty,
32 OWLSubObjectPropertyOfAxiom, 33 OWLSubObjectPropertyOfAxiom,
@@ -46,18 +47,20 @@ import tech.oxfordsemantic.jrdfox.client.{
46} 47}
47import tech.oxfordsemantic.jrdfox.Prefixes 48import tech.oxfordsemantic.jrdfox.Prefixes
48import tech.oxfordsemantic.jrdfox.logic.datalog.{ 49import tech.oxfordsemantic.jrdfox.logic.datalog.{
50 BodyFormula,
51 FilterAtom,
52 Negation,
49 Rule, 53 Rule,
50 TupleTableAtom, 54 TupleTableAtom,
51 TupleTableName, 55 TupleTableName
52 Negation,
53 BodyFormula
54} 56}
55import tech.oxfordsemantic.jrdfox.logic.expression.{ 57import tech.oxfordsemantic.jrdfox.logic.expression.{
56 Term, 58 FunctionCall,
57 Variable,
58 IRI, 59 IRI,
60 Literal,
59 Resource, 61 Resource,
60 Literal 62 Term,
63 Variable
61} 64}
62import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery 65import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery
63 66
@@ -122,9 +125,10 @@ object RSAOntology {
122 ) 125 )
123 126
124 def apply( 127 def apply(
128 origin: OWLOntology,
125 axioms: List[OWLLogicalAxiom], 129 axioms: List[OWLLogicalAxiom],
126 datafiles: List[os.Path] 130 datafiles: List[os.Path]
127 ): RSAOntology = new RSAOntology(axioms, datafiles) 131 ): RSAOntology = new RSAOntology(origin, axioms, datafiles)
128 132
129 // def apply( 133 // def apply(
130 // ontofile: File, 134 // ontofile: File,
@@ -191,8 +195,11 @@ object RSAOntology {
191 * @param ontology the input OWL2 ontology. 195 * @param ontology the input OWL2 ontology.
192 * @param datafiles additinal data (treated as part of the ABox) 196 * @param datafiles additinal data (treated as part of the ABox)
193 */ 197 */
194class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[os.Path]) 198class RSAOntology(
195 extends Ontology(axioms, datafiles) { 199 origin: OWLOntology,
200 axioms: List[OWLLogicalAxiom],
201 datafiles: List[os.Path]
202) extends Ontology(origin, axioms, datafiles) {
196 203
197 /** Simplify conversion between OWLAPI and RDFox concepts */ 204 /** Simplify conversion between OWLAPI and RDFox concepts */
198 import implicits.RDFox._ 205 import implicits.RDFox._
@@ -221,10 +228,9 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[os.Path])
221 /** Retrieve concepts/roles in the ontology */ 228 /** Retrieve concepts/roles in the ontology */
222 val concepts: List[OWLClass] = 229 val concepts: List[OWLClass] =
223 ontology.getClassesInSignature().asScala.toList 230 ontology.getClassesInSignature().asScala.toList
224 val roles: List[OWLObjectPropertyExpression] = 231 val objroles: List[OWLObjectPropertyExpression] =
225 axioms 232 axioms.flatMap(_.objectPropertyExpressionsInSignature).distinct
226 .flatMap(_.objectPropertyExpressionsInSignature) 233 val dataroles: List[OWLDataProperty] = origin.getDataPropertiesInSignature
227 .distinct
228 234
229 /** Unsafe roles of a given ontology. 235 /** Unsafe roles of a given ontology.
230 * 236 *
@@ -358,14 +364,12 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[os.Path])
358 private val topAxioms: List[Rule] = { 364 private val topAxioms: List[Rule] = {
359 val varX = Variable.create("X") 365 val varX = Variable.create("X")
360 val varY = Variable.create("Y") 366 val varY = Variable.create("Y")
367 val varZ = Variable.create("Z")
361 val graph = TupleTableName.create(RSAOntology.CanonGraph.getIRI) 368 val graph = TupleTableName.create(RSAOntology.CanonGraph.getIRI)
362 concepts 369 Rule.create(
363 .map(c => { 370 TupleTableAtom.create(graph, varX, IRI.RDF_TYPE, IRI.THING),
364 Rule.create( 371 TupleTableAtom.create(graph, varX, IRI.RDF_TYPE, varY)
365 TupleTableAtom.create(graph, varX, IRI.RDF_TYPE, IRI.THING), 372 ) :: objroles.map(r => {
366 TupleTableAtom.create(graph, varX, IRI.RDF_TYPE, c.getIRI)
367 )
368 }) ++ roles.map(r => {
369 val name = r match { 373 val name = r match {
370 case x: OWLObjectProperty => x.getIRI.getIRIString 374 case x: OWLObjectProperty => x.getIRI.getIRIString
371 case x: OWLObjectInverseOf => 375 case x: OWLObjectInverseOf =>
@@ -378,6 +382,15 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[os.Path])
378 ), 382 ),
379 List(TupleTableAtom.create(graph, varX, name, varY)) 383 List(TupleTableAtom.create(graph, varX, name, varY))
380 ) 384 )
385 }) ::: dataroles.map(r => {
386 val name = r.getIRI.getIRIString
387 Rule.create(
388 List(
389 TupleTableAtom.create(graph, varX, IRI.RDF_TYPE, IRI.THING),
390 TupleTableAtom.create(graph, varY, IRI.RDF_TYPE, IRI.THING)
391 ),
392 List(TupleTableAtom.create(graph, varX, name, varY))
393 )
381 }) 394 })
382 } 395 }
383 396
@@ -542,22 +555,17 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[os.Path])
542 queries map _ask 555 queries map _ask
543 556
544 private lazy val _ask: ConjunctiveQuery => ConjunctiveQueryAnswers = { 557 private lazy val _ask: ConjunctiveQuery => ConjunctiveQueryAnswers = {
545 /* Open connection with RDFox server */
546 val (server, data) = RDFoxUtil.openConnection(RSAOntology.DataStore) 558 val (server, data) = RDFoxUtil.openConnection(RSAOntology.DataStore)
547 559
548 /* Upload data from data file */ 560 /* Upload data from data file */
549 RDFoxUtil.addData(data, RSAOntology.CanonGraph, datafiles: _*) 561 RDFoxUtil.addData(data, RSAOntology.CanonGraph, datafiles: _*)
550 /* Top / equality axiomatization */ 562
563 /* Top/equality axiomatization */
551 RDFoxUtil.addRules(data, topAxioms ++ equalityAxioms) 564 RDFoxUtil.addRules(data, topAxioms ++ equalityAxioms)
552 Logger.write(topAxioms.mkString("\n"), "canonical_model.datalog") 565 Logger.write(topAxioms.mkString("\n"), "canonical_model.datalog")
553 Logger.write(equalityAxioms.mkString("\n"), "canonical_model.datalog") 566 Logger.write(equalityAxioms.mkString("\n"), "canonical_model.datalog")
554 /* Generate `named` predicates */ 567
555 // TODO: do I need both to generate all NAMED atoms? 568 /* Introduce `rsacomb:Named` concept */
556 RDFoxUtil.addFacts(
557 data,
558 RSAOntology.CanonGraph,
559 (individuals ++ literals) map RSA.Named(RSAOntology.CanonGraph)
560 )
561 data.evaluateUpdate( 569 data.evaluateUpdate(
562 null, // the base IRI for the query (if null, a default is used) 570 null, // the base IRI for the query (if null, a default is used)
563 RSA.Prefixes, 571 RSA.Prefixes,
@@ -572,25 +580,24 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[os.Path])
572 ) 580 )
573 581
574 /* Add canonical model */ 582 /* Add canonical model */
583 Logger print s"Canonical model facts: ${this.canonicalModel.facts.length}"
584 RDFoxUtil.addFacts(data, RSAOntology.CanonGraph, this.canonicalModel.facts)
575 Logger print s"Canonical model rules: ${this.canonicalModel.rules.length}" 585 Logger print s"Canonical model rules: ${this.canonicalModel.rules.length}"
576 Logger.write(canonicalModel.rules.mkString("\n"), "canonical_model.datalog") 586 Logger.write(canonicalModel.rules.mkString("\n"), "canonical_model.datalog")
577 RDFoxUtil.addRules(data, this.canonicalModel.rules) 587 RDFoxUtil.addRules(data, this.canonicalModel.rules)
578 588
579 Logger print s"Canonical model facts: ${this.canonicalModel.facts.length}"
580 RDFoxUtil.addFacts(data, RSAOntology.CanonGraph, this.canonicalModel.facts)
581
582 /* Close connection with RDFox server */
583 RDFoxUtil.closeConnection(server, data) 589 RDFoxUtil.closeConnection(server, data)
584 590
585 (query => { 591 (query => {
586 /* Open connection with RDFox server */
587 val (server, data) = RDFoxUtil.openConnection(RSAOntology.DataStore) 592 val (server, data) = RDFoxUtil.openConnection(RSAOntology.DataStore)
593
588 val filter = RSAOntology.filteringProgram(query) 594 val filter = RSAOntology.filteringProgram(query)
589 595
590 /* Add filtering program */ 596 /* Add filtering program */
591 Logger print s"Filtering program rules: ${filter.rules.length}" 597 Logger print s"Filtering program rules: ${filter.rules.length}"
592 Logger.write(filter.rules.mkString("\n"), s"filter${query.id}.datalog") 598 Logger.write(filter.rules.mkString("\n"), s"filter${query.id}.datalog")
593 RDFoxUtil.addRules(data, filter.rules) 599 RDFoxUtil.addRules(data, filter.rules)
600
594 // TODO: We remove the rules, should we drop the tuple table as well? 601 // TODO: We remove the rules, should we drop the tuple table as well?
595 data.clearRulesAxiomsExplicateFacts() 602 data.clearRulesAxiomsExplicateFacts()
596 603
@@ -600,7 +607,6 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[os.Path])
600 .map(new ConjunctiveQueryAnswers(query, query.variables, _)) 607 .map(new ConjunctiveQueryAnswers(query, query.variables, _))
601 .get 608 .get
602 609
603 /* Close connection with RDFox server */
604 RDFoxUtil.closeConnection(server, data) 610 RDFoxUtil.closeConnection(server, data)
605 611
606 answers 612 answers
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Lowerbound.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Lowerbound.scala
index 88732d5..e261bce 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Lowerbound.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Lowerbound.scala
@@ -51,6 +51,7 @@ class Lowerbound(implicit fresh: DataFactory)
51 def approximate(ontology: Ontology): RSAOntology = 51 def approximate(ontology: Ontology): RSAOntology =
52 toRSA( 52 toRSA(
53 new Ontology( 53 new Ontology(
54 ontology.origin,
54 ontology.axioms filter inALCHOIQ flatMap shift, 55 ontology.axioms filter inALCHOIQ flatMap shift,
55 ontology.datafiles 56 ontology.datafiles
56 ) 57 )
@@ -218,7 +219,11 @@ class Lowerbound(implicit fresh: DataFactory)
218 }.toList 219 }.toList
219 220
220 /* Remove axioms from approximated ontology */ 221 /* Remove axioms from approximated ontology */
221 RSAOntology(ontology.axioms diff toDelete, ontology.datafiles) 222 RSAOntology(
223 ontology.origin,
224 ontology.axioms diff toDelete,
225 ontology.datafiles
226 )
222 } 227 }
223 228
224 // val edges1 = Seq('A ~> 'B, 'B ~> 'C, 'C ~> 'D, 'D ~> 'H, 'H ~> 229 // val edges1 = Seq('A ~> 'B, 'B ~> 'C, 'C ~> 'D, 'D ~> 'H, 'H ~>
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala
index 1ae7941..469d774 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala
@@ -51,6 +51,7 @@ class Upperbound(implicit fresh: DataFactory)
51 def approximate(ontology: Ontology): RSAOntology = 51 def approximate(ontology: Ontology): RSAOntology =
52 toRSA( 52 toRSA(
53 new Ontology( 53 new Ontology(
54 ontology.origin,
54 ontology.axioms flatMap toConjuncts, 55 ontology.axioms flatMap toConjuncts,
55 ontology.datafiles 56 ontology.datafiles
56 ) 57 )
@@ -161,6 +162,7 @@ class Upperbound(implicit fresh: DataFactory)
161 162
162 /* Substitute selected axioms with their "skolemized" version */ 163 /* Substitute selected axioms with their "skolemized" version */
163 RSAOntology( 164 RSAOntology(
165 ontology.origin,
164 ontology.axioms diff toSkolem concat skolemized, 166 ontology.axioms diff toSkolem concat skolemized,
165 ontology.datafiles 167 ontology.datafiles
166 ) 168 )
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/RevisedFilteringProgram.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/RevisedFilteringProgram.scala
index f059bcd..94524be 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/RevisedFilteringProgram.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/RevisedFilteringProgram.scala
@@ -42,7 +42,7 @@ object RDFoxDSL {
42 import scala.collection.JavaConverters._ 42 import scala.collection.JavaConverters._
43 43
44 implicit class MyVariable(private val str: StringContext) extends AnyVal { 44 implicit class MyVariable(private val str: StringContext) extends AnyVal {
45 def v(args: Any*): Variable = Variable.create(s"${str.s(args: _*)}i") 45 def v(args: Any*): Variable = Variable.create(s"${str.s(args: _*)}")
46 } 46 }
47 47
48} 48}
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/ontology/Ontology.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/ontology/Ontology.scala
index ece6d15..0aceb01 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/ontology/Ontology.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/ontology/Ontology.scala
@@ -167,8 +167,8 @@ object Ontology {
167 (graph, nodemap) 167 (graph, nodemap)
168 } 168 }
169 169
170 def apply(axioms: List[OWLLogicalAxiom], datafiles: List[os.Path]): Ontology = 170 // def apply(axioms: List[OWLLogicalAxiom], datafiles: List[os.Path]): Ontology =
171 new Ontology(axioms, datafiles) 171 // new Ontology(axioms, datafiles)
172 172
173 def apply(ontology: OWLOntology, datafiles: List[os.Path]): Ontology = { 173 def apply(ontology: OWLOntology, datafiles: List[os.Path]): Ontology = {
174 174
@@ -199,7 +199,7 @@ object Ontology {
199 .collect(Collectors.toList()) 199 .collect(Collectors.toList())
200 .collect { case a: OWLLogicalAxiom => a } 200 .collect { case a: OWLLogicalAxiom => a }
201 201
202 Ontology(abox ::: tbox ::: rbox, datafiles) 202 new Ontology(ontology, abox ::: tbox ::: rbox, datafiles)
203 } 203 }
204 204
205 def apply(ontofile: os.Path, datafiles: List[os.Path]): Ontology = { 205 def apply(ontofile: os.Path, datafiles: List[os.Path]): Ontology = {
@@ -215,6 +215,7 @@ object Ontology {
215 * @param datafiles files containing ABox data. 215 * @param datafiles files containing ABox data.
216 */ 216 */
217class Ontology( 217class Ontology(
218 val origin: OWLOntology,
218 val axioms: List[OWLLogicalAxiom], 219 val axioms: List[OWLLogicalAxiom],
219 val datafiles: List[os.Path] 220 val datafiles: List[os.Path]
220) { 221) {
@@ -293,6 +294,7 @@ class Ontology(
293 */ 294 */
294 def normalize(normalizer: Normalizer): Ontology = 295 def normalize(normalizer: Normalizer): Ontology =
295 new Ontology( 296 new Ontology(
297 origin,
296 axioms flatMap normalizer.normalize, 298 axioms flatMap normalizer.normalize,
297 datafiles 299 datafiles
298 ) 300 )