diff options
author | Federico Igne <git@federicoigne.com> | 2021-09-30 18:10:01 +0100 |
---|---|---|
committer | Federico Igne <git@federicoigne.com> | 2021-10-01 10:25:40 +0100 |
commit | bc37ee9293d8a4098edce2a77db6efa3d87b6dd2 (patch) | |
tree | cb85cc0b3b48855aca503b07f93c7b54e4b99c07 | |
parent | 1ef8a2502532dd1736c1e3d6a1ff78ed6b8b643c (diff) | |
download | RSAComb-bc37ee9293d8a4098edce2a77db6efa3d87b6dd2.tar.gz RSAComb-bc37ee9293d8a4098edce2a77db6efa3d87b6dd2.zip |
Make canonical model generation parametric over named graph
6 files changed, 141 insertions, 83 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 3467d3c..a39b9c0 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala | |||
@@ -31,7 +31,8 @@ import tech.oxfordsemantic.jrdfox.logic.datalog.{ | |||
31 | BodyFormula, | 31 | BodyFormula, |
32 | Negation, | 32 | Negation, |
33 | Rule, | 33 | Rule, |
34 | TupleTableAtom | 34 | TupleTableAtom, |
35 | TupleTableName | ||
35 | } | 36 | } |
36 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI, Term, Variable} | 37 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI, Term, Variable} |
37 | 38 | ||
@@ -48,8 +49,9 @@ import uk.ac.ox.cs.rsacomb.util.{DataFactory, RSA} | |||
48 | * (via materialization). | 49 | * (via materialization). |
49 | * | 50 | * |
50 | * @param ontology the RSA ontology the canonical model is targeting. | 51 | * @param ontology the RSA ontology the canonical model is targeting. |
52 | * @param graph the graph the canonical model will be generated into. | ||
51 | */ | 53 | */ |
52 | class CanonicalModel(val ontology: RSAOntology) { | 54 | class CanonicalModel(val ontology: RSAOntology, val graph: IRI) { |
53 | 55 | ||
54 | /** Simplify conversion between OWLAPI and RDFox concepts */ | 56 | /** Simplify conversion between OWLAPI and RDFox concepts */ |
55 | import implicits.RDFox._ | 57 | import implicits.RDFox._ |
@@ -65,6 +67,7 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
65 | * versions need to be explicitly stated in terms of logic rules. | 67 | * versions need to be explicitly stated in terms of logic rules. |
66 | */ | 68 | */ |
67 | val rolesAdditionalRules: List[Rule] = { | 69 | val rolesAdditionalRules: List[Rule] = { |
70 | val tt = TupleTableName.create(graph.getIRI) | ||
68 | ontology.roles | 71 | ontology.roles |
69 | .collect { case prop: OWLObjectProperty => prop } | 72 | .collect { case prop: OWLObjectProperty => prop } |
70 | .flatMap((pred) => { | 73 | .flatMap((pred) => { |
@@ -83,8 +86,8 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
83 | ) | 86 | ) |
84 | ) | 87 | ) |
85 | yield Rule.create( | 88 | yield Rule.create( |
86 | TupleTableAtom.rdf(varX, iri :: hSuffix, varY), | 89 | TupleTableAtom.create(tt, varX, iri :: hSuffix, varY), |
87 | TupleTableAtom.rdf(varX, iri :: bSuffix, varY) | 90 | TupleTableAtom.create(tt, varX, iri :: bSuffix, varY) |
88 | ) | 91 | ) |
89 | }) | 92 | }) |
90 | } | 93 | } |
@@ -108,6 +111,8 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
108 | 111 | ||
109 | object CanonicalModelConverter extends RDFoxConverter { | 112 | object CanonicalModelConverter extends RDFoxConverter { |
110 | 113 | ||
114 | override val graph = TupleTableName.create(CanonicalModel.this.graph.getIRI) | ||
115 | |||
111 | private def rules1( | 116 | private def rules1( |
112 | axiom: OWLSubClassOfAxiom | 117 | axiom: OWLSubClassOfAxiom |
113 | ): Result = { | 118 | ): Result = { |
@@ -115,11 +120,10 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
115 | // Fresh Variables | 120 | // Fresh Variables |
116 | val v0 = RSA("v0_" ++ axiom.hashed) | 121 | val v0 = RSA("v0_" ++ axiom.hashed) |
117 | val varX = Variable.create("X") | 122 | val varX = Variable.create("X") |
118 | implicit val unfoldTerm = RSA(unfold.hashCode.toString) | ||
119 | // TODO: use axiom.toTriple instead | 123 | // TODO: use axiom.toTriple instead |
120 | val atomA: TupleTableAtom = { | 124 | val atomA: TupleTableAtom = { |
121 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI | 125 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI |
122 | TupleTableAtom.rdf(varX, IRI.RDF_TYPE, cls) | 126 | TupleTableAtom.create(graph, varX, IRI.RDF_TYPE, cls) |
123 | } | 127 | } |
124 | val roleRf: TupleTableAtom = { | 128 | val roleRf: TupleTableAtom = { |
125 | val prop = | 129 | val prop = |
@@ -132,12 +136,15 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
132 | .getFiller | 136 | .getFiller |
133 | .asInstanceOf[OWLClass] | 137 | .asInstanceOf[OWLClass] |
134 | .getIRI | 138 | .getIRI |
135 | TupleTableAtom.rdf(v0, IRI.RDF_TYPE, cls) | 139 | TupleTableAtom.create(graph, v0, IRI.RDF_TYPE, cls) |
136 | } | 140 | } |
137 | val facts = unfold map RSA.In | 141 | val unfoldSet = RSA(unfold.hashCode.toString) |
142 | val facts = unfold.map(TupleTableAtom.create(graph, _, RSA.IN, unfoldSet)) | ||
143 | val notInX = | ||
144 | Negation.create(TupleTableAtom.create(graph, varX, RSA.IN, unfoldSet)) | ||
138 | val rules = List( | 145 | val rules = List( |
139 | Rule.create(roleRf, atomA, RSA.NotIn(varX)), | 146 | Rule.create(roleRf, atomA, notInX), |
140 | Rule.create(atomB, atomA, RSA.NotIn(varX)) | 147 | Rule.create(atomB, atomA, notInX) |
141 | ) | 148 | ) |
142 | (facts, rules) | 149 | (facts, rules) |
143 | } | 150 | } |
@@ -155,7 +162,7 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
155 | // Predicates | 162 | // Predicates |
156 | def atomA(t: Term): TupleTableAtom = { | 163 | def atomA(t: Term): TupleTableAtom = { |
157 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI | 164 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI |
158 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, cls) | 165 | TupleTableAtom.create(graph, t, IRI.RDF_TYPE, cls) |
159 | } | 166 | } |
160 | def roleRf(t1: Term, t2: Term): TupleTableAtom = | 167 | def roleRf(t1: Term, t2: Term): TupleTableAtom = |
161 | super.convert(roleR, t1, t2, Forward) | 168 | super.convert(roleR, t1, t2, Forward) |
@@ -165,7 +172,7 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
165 | .getFiller | 172 | .getFiller |
166 | .asInstanceOf[OWLClass] | 173 | .asInstanceOf[OWLClass] |
167 | .getIRI | 174 | .getIRI |
168 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, cls) | 175 | TupleTableAtom.create(graph, t, IRI.RDF_TYPE, cls) |
169 | } | 176 | } |
170 | //Rules | 177 | //Rules |
171 | List( | 178 | List( |
@@ -190,7 +197,7 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
190 | // Predicates | 197 | // Predicates |
191 | def atomA(t: Term): TupleTableAtom = { | 198 | def atomA(t: Term): TupleTableAtom = { |
192 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI | 199 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI |
193 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, cls) | 200 | TupleTableAtom.create(graph, t, IRI.RDF_TYPE, cls) |
194 | } | 201 | } |
195 | def roleRf(t: Term): TupleTableAtom = | 202 | def roleRf(t: Term): TupleTableAtom = |
196 | super.convert(roleR, t, v1, Forward) | 203 | super.convert(roleR, t, v1, Forward) |
@@ -200,7 +207,7 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
200 | .getFiller | 207 | .getFiller |
201 | .asInstanceOf[OWLClass] | 208 | .asInstanceOf[OWLClass] |
202 | .getIRI | 209 | .getIRI |
203 | TupleTableAtom.rdf(v1, IRI.RDF_TYPE, cls) | 210 | TupleTableAtom.create(graph, v1, IRI.RDF_TYPE, cls) |
204 | } | 211 | } |
205 | cycle.flatMap { x => | 212 | cycle.flatMap { x => |
206 | List( | 213 | List( |
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 6e9a119..5a89bf9 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | |||
@@ -48,6 +48,7 @@ import tech.oxfordsemantic.jrdfox.Prefixes | |||
48 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ | 48 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ |
49 | Rule, | 49 | Rule, |
50 | TupleTableAtom, | 50 | TupleTableAtom, |
51 | TupleTableName, | ||
51 | Negation, | 52 | Negation, |
52 | BodyFormula | 53 | BodyFormula |
53 | } | 54 | } |
@@ -91,6 +92,20 @@ object RSAOntology { | |||
91 | /** Name of the RDFox data store used for CQ answering */ | 92 | /** Name of the RDFox data store used for CQ answering */ |
92 | private val DataStore = "answer_computation" | 93 | private val DataStore = "answer_computation" |
93 | 94 | ||
95 | /** Canonical model named graph */ | ||
96 | private val CanonGraph: IRI = | ||
97 | RDFoxUtil.getNamedGraph(DataStore, "CanonicalModel") | ||
98 | |||
99 | /** Filtering program named graph | ||
100 | * | ||
101 | * @param query query associated with the returned named graph. | ||
102 | * | ||
103 | * @return named graph for the filtering program associated with the | ||
104 | * input query. | ||
105 | */ | ||
106 | private def FilterGraph(query: ConjunctiveQuery): IRI = | ||
107 | RDFoxUtil.getNamedGraph(DataStore, s"Filter${query.id}") | ||
108 | |||
94 | /** Filtering program for a given query | 109 | /** Filtering program for a given query |
95 | * | 110 | * |
96 | * @param query the query to derive the filtering program | 111 | * @param query the query to derive the filtering program |
@@ -343,11 +358,12 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[File]) | |||
343 | private val topAxioms: List[Rule] = { | 358 | private val topAxioms: List[Rule] = { |
344 | val varX = Variable.create("X") | 359 | val varX = Variable.create("X") |
345 | val varY = Variable.create("Y") | 360 | val varY = Variable.create("Y") |
361 | val graph = TupleTableName.create(RSAOntology.CanonGraph.getIRI) | ||
346 | concepts | 362 | concepts |
347 | .map(c => { | 363 | .map(c => { |
348 | Rule.create( | 364 | Rule.create( |
349 | RSA.Thing(varX), | 365 | TupleTableAtom.create(graph, varX, IRI.RDF_TYPE, IRI.THING), |
350 | TupleTableAtom.rdf(varX, IRI.RDF_TYPE, c.getIRI) | 366 | TupleTableAtom.create(graph, varX, IRI.RDF_TYPE, c.getIRI) |
351 | ) | 367 | ) |
352 | }) ++ roles.map(r => { | 368 | }) ++ roles.map(r => { |
353 | val name = r match { | 369 | val name = r match { |
@@ -356,8 +372,11 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[File]) | |||
356 | x.getInverse.getNamedProperty.getIRI.getIRIString :: Inverse | 372 | x.getInverse.getNamedProperty.getIRI.getIRIString :: Inverse |
357 | } | 373 | } |
358 | Rule.create( | 374 | Rule.create( |
359 | List(RSA.Thing(varX), RSA.Thing(varY)), | 375 | List( |
360 | List(TupleTableAtom.rdf(varX, name, varY)) | 376 | TupleTableAtom.create(graph, varX, IRI.RDF_TYPE, IRI.THING), |
377 | TupleTableAtom.create(graph, varY, IRI.RDF_TYPE, IRI.THING) | ||
378 | ), | ||
379 | List(TupleTableAtom.create(graph, varX, name, varY)) | ||
361 | ) | 380 | ) |
362 | }) | 381 | }) |
363 | } | 382 | } |
@@ -382,23 +401,31 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[File]) | |||
382 | val varX = Variable.create("X") | 401 | val varX = Variable.create("X") |
383 | val varY = Variable.create("Y") | 402 | val varY = Variable.create("Y") |
384 | val varZ = Variable.create("Z") | 403 | val varZ = Variable.create("Z") |
385 | List( | 404 | val graph = TupleTableName.create(RSAOntology.CanonGraph.getIRI) |
405 | // Equality properties | ||
406 | val properties = List( | ||
386 | // Reflexivity | 407 | // Reflexivity |
387 | Rule.create(RSA.Congruent(varX, varX), RSA.Thing(varX)), | 408 | Rule.create( |
409 | TupleTableAtom.create(graph, varX, RSA.CONGRUENT, varX), | ||
410 | TupleTableAtom.create(graph, varX, IRI.RDF_TYPE, IRI.THING) | ||
411 | ), | ||
388 | // Simmetry | 412 | // Simmetry |
389 | Rule.create(RSA.Congruent(varY, varX), RSA.Congruent(varX, varY)), | 413 | Rule.create( |
414 | TupleTableAtom.create(graph, varY, RSA.CONGRUENT, varX), | ||
415 | TupleTableAtom.create(graph, varX, RSA.CONGRUENT, varY) | ||
416 | ), | ||
390 | // Transitivity | 417 | // Transitivity |
391 | Rule.create( | 418 | Rule.create( |
392 | RSA.Congruent(varX, varZ), | 419 | TupleTableAtom.create(graph, varX, RSA.CONGRUENT, varZ), |
393 | RSA.Congruent(varX, varY), | 420 | TupleTableAtom.create(graph, varX, RSA.CONGRUENT, varY), |
394 | RSA.Congruent(varY, varZ) | 421 | TupleTableAtom.create(graph, varY, RSA.CONGRUENT, varZ) |
395 | ) | 422 | ) |
396 | ) | 423 | ) |
397 | } | 424 | } |
398 | 425 | ||
399 | /** Canonical model of the ontology */ | 426 | /** Canonical model of the ontology */ |
400 | lazy val canonicalModel = Logger.timed( | 427 | lazy val canonicalModel = Logger.timed( |
401 | new CanonicalModel(this), | 428 | new CanonicalModel(this, RSAOntology.CanonGraph), |
402 | "Generating canonical model program", | 429 | "Generating canonical model program", |
403 | Logger.DEBUG | 430 | Logger.DEBUG |
404 | ) | 431 | ) |
@@ -505,19 +532,18 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[File]) | |||
505 | * @return a collection of answers for each query. | 532 | * @return a collection of answers for each query. |
506 | */ | 533 | */ |
507 | def ask(queries: Seq[ConjunctiveQuery]): Seq[ConjunctiveQueryAnswers] = { | 534 | def ask(queries: Seq[ConjunctiveQuery]): Seq[ConjunctiveQueryAnswers] = { |
535 | /* Open connection with RDFox server */ | ||
508 | val (server, data) = RDFoxUtil.openConnection(RSAOntology.DataStore) | 536 | val (server, data) = RDFoxUtil.openConnection(RSAOntology.DataStore) |
509 | val canonNamedGraph = "http://cs.ox.ac.uk/isg/RSAComb#CanonicalModel" | ||
510 | // Create a new NamedGraph for the canonical model | ||
511 | data.createTupleTable(canonNamedGraph, Map("type" -> "named-graph").asJava) | ||
512 | 537 | ||
513 | /* Upload data from data file */ | 538 | /* Upload data from data file */ |
514 | RDFoxUtil.addData(canonNamedGraph, data, datafiles: _*) | 539 | RDFoxUtil.addData(data, RSAOntology.CanonGraph, datafiles: _*) |
515 | /* Top / equality axiomatization */ | 540 | /* Top / equality axiomatization */ |
516 | RDFoxUtil.addRules(data, topAxioms ++ equalityAxioms) | 541 | RDFoxUtil.addRules(data, topAxioms ++ equalityAxioms) |
517 | /* Generate `named` predicates */ | 542 | /* Generate `named` predicates */ |
543 | // TODO: do I need both to generate all NAMED atoms? | ||
518 | RDFoxUtil.addFacts( | 544 | RDFoxUtil.addFacts( |
519 | canonNamedGraph, | ||
520 | data, | 545 | data, |
546 | RSAOntology.CanonGraph, | ||
521 | (individuals ++ literals) map RSA.Named | 547 | (individuals ++ literals) map RSA.Named |
522 | ) | 548 | ) |
523 | data.evaluateUpdate( | 549 | data.evaluateUpdate( |
@@ -525,9 +551,9 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[File]) | |||
525 | RSA.Prefixes, | 551 | RSA.Prefixes, |
526 | s""" | 552 | s""" |
527 | INSERT { | 553 | INSERT { |
528 | GRAPH <$canonNamedGraph> { ?X a rsa:Named } | 554 | GRAPH ${RSAOntology.CanonGraph} { ?X a ${RSA.NAMED} } |
529 | } WHERE { | 555 | } WHERE { |
530 | GRAPH <$canonNamedGraph> { ?X a owl:Thing } | 556 | GRAPH ${RSAOntology.CanonGraph} { ?X a ${IRI.THING} } |
531 | } | 557 | } |
532 | """, | 558 | """, |
533 | new java.util.HashMap[String, String] | 559 | new java.util.HashMap[String, String] |
@@ -538,7 +564,7 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[File]) | |||
538 | RDFoxUtil.addRules(data, this.canonicalModel.rules) | 564 | RDFoxUtil.addRules(data, this.canonicalModel.rules) |
539 | 565 | ||
540 | Logger print s"Canonical model facts: ${this.canonicalModel.facts.length}" | 566 | Logger print s"Canonical model facts: ${this.canonicalModel.facts.length}" |
541 | RDFoxUtil.addFacts(canonNamedGraph, data, this.canonicalModel.facts) | 567 | RDFoxUtil.addFacts(data, RSAOntology.CanonGraph, this.canonicalModel.facts) |
542 | 568 | ||
543 | queries map { query => | 569 | queries map { query => |
544 | { | 570 | { |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala index 276ee1a..2f48798 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala | |||
@@ -24,7 +24,8 @@ import tech.oxfordsemantic.jrdfox.logic.datalog.{ | |||
24 | BindAtom, | 24 | BindAtom, |
25 | BodyFormula, | 25 | BodyFormula, |
26 | Rule, | 26 | Rule, |
27 | TupleTableAtom | 27 | TupleTableAtom, |
28 | TupleTableName | ||
28 | } | 29 | } |
29 | import tech.oxfordsemantic.jrdfox.logic.expression.{Term, IRI, FunctionCall} | 30 | import tech.oxfordsemantic.jrdfox.logic.expression.{Term, IRI, FunctionCall} |
30 | import uk.ac.ox.cs.rsacomb.RSAOntology | 31 | import uk.ac.ox.cs.rsacomb.RSAOntology |
@@ -59,6 +60,10 @@ trait RDFoxConverter { | |||
59 | private val manager = OWLManager.createOWLOntologyManager() | 60 | private val manager = OWLManager.createOWLOntologyManager() |
60 | private val factory = manager.getOWLDataFactory() | 61 | private val factory = manager.getOWLDataFactory() |
61 | 62 | ||
63 | /** Default named graph to be used when generating new atoms */ | ||
64 | val graph: TupleTableName = | ||
65 | TupleTableName.create("http://oxfordsemantic.tech/RDFox#DefaultTriples") | ||
66 | |||
62 | /** Represents the result of the conversion of a | 67 | /** Represents the result of the conversion of a |
63 | * [[org.semanticweb.owlapi.model.OWLClassExpression OWLClassExpression]]. | 68 | * [[org.semanticweb.owlapi.model.OWLClassExpression OWLClassExpression]]. |
64 | * | 69 | * |
@@ -193,7 +198,8 @@ trait RDFoxConverter { | |||
193 | .flatMap((cls) => | 198 | .flatMap((cls) => |
194 | convert(cls, term, unsafe, NoSkolem, suffix)(fresh)._1 | 199 | convert(cls, term, unsafe, NoSkolem, suffix)(fresh)._1 |
195 | ) | 200 | ) |
196 | val bottom = TupleTableAtom.rdf(term, IRI.RDF_TYPE, IRI.NOTHING) | 201 | val bottom = |
202 | TupleTableAtom.create(graph, term, IRI.RDF_TYPE, IRI.NOTHING) | ||
197 | ResultR(List(Rule.create(bottom, body: _*))) | 203 | ResultR(List(Rule.create(bottom, body: _*))) |
198 | } | 204 | } |
199 | 205 | ||
@@ -310,7 +316,7 @@ trait RDFoxConverter { | |||
310 | */ | 316 | */ |
311 | case e: OWLClass => { | 317 | case e: OWLClass => { |
312 | val iri: IRI = if (e.isTopEntity()) IRI.THING else e.getIRI | 318 | val iri: IRI = if (e.isTopEntity()) IRI.THING else e.getIRI |
313 | val atom = TupleTableAtom.rdf(term, IRI.RDF_TYPE, iri) | 319 | val atom = TupleTableAtom.create(graph, term, IRI.RDF_TYPE, iri) |
314 | (List(atom), List()) | 320 | (List(atom), List()) |
315 | } | 321 | } |
316 | 322 | ||
@@ -340,7 +346,8 @@ trait RDFoxConverter { | |||
340 | .collect { case x: OWLNamedIndividual => x } | 346 | .collect { case x: OWLNamedIndividual => x } |
341 | if (named.length != 1) | 347 | if (named.length != 1) |
342 | throw new RuntimeException(s"Class expression '$e' has arity != 1.") | 348 | throw new RuntimeException(s"Class expression '$e' has arity != 1.") |
343 | val atom = RSA.Congruent(term, named.head.getIRI) | 349 | val atom = |
350 | TupleTableAtom.create(graph, term, RSA.CONGRUENT, named.head.getIRI) | ||
344 | (List(atom), List()) | 351 | (List(atom), List()) |
345 | } | 352 | } |
346 | 353 | ||
@@ -412,7 +419,7 @@ trait RDFoxConverter { | |||
412 | val (res, ext) = | 419 | val (res, ext) = |
413 | vars.map(convert(cls, _, unsafe, skolem, suffix)(fresh)).unzip | 420 | vars.map(convert(cls, _, unsafe, skolem, suffix)(fresh)).unzip |
414 | val props = vars.map(convert(role, term, _, suffix)(fresh)) | 421 | val props = vars.map(convert(role, term, _, suffix)(fresh)) |
415 | val eq = RSA.Congruent(y, z) | 422 | val eq = TupleTableAtom.create(graph, y, RSA.CONGRUENT, z) |
416 | (List(eq), res.flatten ++ props) | 423 | (List(eq), res.flatten ++ props) |
417 | } | 424 | } |
418 | 425 | ||
@@ -515,7 +522,7 @@ trait RDFoxConverter { | |||
515 | */ | 522 | */ |
516 | case e: OWLObjectProperty => { | 523 | case e: OWLObjectProperty => { |
517 | val role = IRI.create(e.getIRI.getIRIString :: suffix) | 524 | val role = IRI.create(e.getIRI.getIRIString :: suffix) |
518 | TupleTableAtom.rdf(term1, role, term2) | 525 | TupleTableAtom.create(graph, term1, role, term2) |
519 | } | 526 | } |
520 | 527 | ||
521 | /** Inverse of a named role/property | 528 | /** Inverse of a named role/property |
@@ -555,7 +562,7 @@ trait RDFoxConverter { | |||
555 | */ | 562 | */ |
556 | case e: OWLDataProperty => { | 563 | case e: OWLDataProperty => { |
557 | val role = IRI.create(e.getIRI.getIRIString :: suffix) | 564 | val role = IRI.create(e.getIRI.getIRIString :: suffix) |
558 | TupleTableAtom.rdf(term1, role, term2) | 565 | TupleTableAtom.create(graph, term1, role, term2) |
559 | } | 566 | } |
560 | 567 | ||
561 | /** The infamous impossible case. | 568 | /** The infamous impossible case. |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala index 795e039..ff48f1f 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala | |||
@@ -51,19 +51,14 @@ object RSAAtom { | |||
51 | import RDFox._ | 51 | import RDFox._ |
52 | import JavaCollections._ | 52 | import JavaCollections._ |
53 | 53 | ||
54 | val name: String = atom.getTupleTableName.getName | 54 | val tt: TupleTableName = atom.getTupleTableName |
55 | 55 | ||
56 | val args: List[Term] = atom.getArguments | 56 | val args: List[Term] = atom.getArguments |
57 | 57 | ||
58 | val isRDF: Boolean = | 58 | val isRDF: Boolean = atom.getArguments.length == 3 |
59 | name == "http://oxfordsemantic.tech/RDFox#DefaultTriples" | ||
60 | 59 | ||
61 | val isClassAssertion: Boolean = { | 60 | val isClassAssertion: Boolean = |
62 | isRDF && { | 61 | isRDF && atom.getArguments.get(1) == IRI.RDF_TYPE |
63 | val pred = atom.getArguments.get(1) | ||
64 | pred == IRI.RDF_TYPE | ||
65 | } | ||
66 | } | ||
67 | 62 | ||
68 | val isRoleAssertion: Boolean = isRDF && !isClassAssertion | 63 | val isRoleAssertion: Boolean = isRDF && !isClassAssertion |
69 | 64 | ||
@@ -77,18 +72,15 @@ object RSAAtom { | |||
77 | case iri: IRI => IRI.create(iri.getIRI :: suffix) | 72 | case iri: IRI => IRI.create(iri.getIRI :: suffix) |
78 | case other => other | 73 | case other => other |
79 | } | 74 | } |
80 | TupleTableAtom.rdf(subj, pred, obj1) | 75 | TupleTableAtom.create(tt, subj, pred, obj1) |
81 | } else { | 76 | } else { |
82 | val pred1 = pred match { | 77 | val pred1 = pred match { |
83 | case iri: IRI => IRI.create(iri.getIRI :: suffix) | 78 | case iri: IRI => IRI.create(iri.getIRI :: suffix) |
84 | case other => other | 79 | case other => other |
85 | } | 80 | } |
86 | TupleTableAtom.rdf(subj, pred1, obj) | 81 | TupleTableAtom.create(tt, subj, pred1, obj) |
87 | } | 82 | } |
88 | } else { | 83 | } else atom |
89 | val ttname = TupleTableName.create(name :: suffix) | ||
90 | TupleTableAtom.create(ttname, atom.getArguments()) | ||
91 | } | ||
92 | 84 | ||
93 | def reified(implicit | 85 | def reified(implicit |
94 | fresh: DataFactory | 86 | fresh: DataFactory |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxUtil.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxUtil.scala index 6f5ff31..568858c 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxUtil.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxUtil.scala | |||
@@ -17,6 +17,7 @@ | |||
17 | package uk.ac.ox.cs.rsacomb.util | 17 | package uk.ac.ox.cs.rsacomb.util |
18 | 18 | ||
19 | import java.io.{OutputStream, File, StringReader} | 19 | import java.io.{OutputStream, File, StringReader} |
20 | import scala.collection.JavaConverters._ | ||
20 | import tech.oxfordsemantic.jrdfox.Prefixes | 21 | import tech.oxfordsemantic.jrdfox.Prefixes |
21 | import tech.oxfordsemantic.jrdfox.client.{ | 22 | import tech.oxfordsemantic.jrdfox.client.{ |
22 | ComponentInfo, | 23 | ComponentInfo, |
@@ -38,7 +39,8 @@ import tech.oxfordsemantic.jrdfox.logic.expression.{ | |||
38 | Literal, | 39 | Literal, |
39 | Resource, | 40 | Resource, |
40 | Variable, | 41 | Variable, |
41 | Term | 42 | Term, |
43 | IRI | ||
42 | } | 44 | } |
43 | import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery | 45 | import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery |
44 | import uk.ac.ox.cs.rsacomb.sparql.ConjunctiveQuery | 46 | import uk.ac.ox.cs.rsacomb.sparql.ConjunctiveQuery |
@@ -92,6 +94,22 @@ object RDFoxUtil { | |||
92 | (server, data) | 94 | (server, data) |
93 | } | 95 | } |
94 | 96 | ||
97 | /** Get the IRI of a named graph (creating it if necessary) | ||
98 | * | ||
99 | * @param datastore name of the datastore to perform the action in. | ||
100 | * @param name name of the named graph. | ||
101 | * | ||
102 | * @return the full IRI for the (new) named graph. | ||
103 | */ | ||
104 | def getNamedGraph(datastore: String, name: String): IRI = { | ||
105 | val graph = RSA(name) | ||
106 | val (server, data) = openConnection(datastore) | ||
107 | if (!data.containsTupleTable(graph.getIRI)) | ||
108 | data.createTupleTable(graph.getIRI, Map("type" -> "named-graph").asJava) | ||
109 | RDFoxUtil.closeConnection(server, data) | ||
110 | return graph | ||
111 | } | ||
112 | |||
95 | /** Create a built-in `rdfox:SKOLEM` TupleTableAtom. */ | 113 | /** Create a built-in `rdfox:SKOLEM` TupleTableAtom. */ |
96 | def skolem(name: String, terms: Term*): TupleTableAtom = | 114 | def skolem(name: String, terms: Term*): TupleTableAtom = |
97 | TupleTableAtom.create( | 115 | TupleTableAtom.create( |
@@ -143,14 +161,14 @@ object RDFoxUtil { | |||
143 | * @param facts collection of facts to be added to the data store | 161 | * @param facts collection of facts to be added to the data store |
144 | */ | 162 | */ |
145 | def addFacts( | 163 | def addFacts( |
146 | graph: String, | ||
147 | data: DataStoreConnection, | 164 | data: DataStoreConnection, |
165 | graph: IRI, | ||
148 | facts: Seq[TupleTableAtom] | 166 | facts: Seq[TupleTableAtom] |
149 | ): Unit = | 167 | ): Unit = |
150 | Logger.timed( | 168 | Logger.timed( |
151 | if (facts.length > 0) { | 169 | if (facts.length > 0) { |
152 | data.importData( | 170 | data.importData( |
153 | graph, | 171 | graph.getIRI, |
154 | UpdateType.ADDITION, | 172 | UpdateType.ADDITION, |
155 | RSA.Prefixes, | 173 | RSA.Prefixes, |
156 | facts | 174 | facts |
@@ -165,12 +183,13 @@ object RDFoxUtil { | |||
165 | /** Imports a sequence of files directly into a datastore. | 183 | /** Imports a sequence of files directly into a datastore. |
166 | * | 184 | * |
167 | * @param data datastore connection. | 185 | * @param data datastore connection. |
186 | * @param graph named graph where the data should be uploaded | ||
168 | * @param files sequence of files to upload. | 187 | * @param files sequence of files to upload. |
169 | */ | 188 | */ |
170 | def addData(graph: String, data: DataStoreConnection, files: File*): Unit = | 189 | def addData(data: DataStoreConnection, graph: IRI, files: File*): Unit = |
171 | Logger.timed( | 190 | Logger.timed( |
172 | files.foreach { | 191 | files.foreach { |
173 | data.importData(graph, UpdateType.ADDITION, RSA.Prefixes, _) | 192 | data.importData(graph.getIRI, UpdateType.ADDITION, RSA.Prefixes, _) |
174 | }, | 193 | }, |
175 | "Loading data files", | 194 | "Loading data files", |
176 | Logger.DEBUG | 195 | Logger.DEBUG |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RSA.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RSA.scala index 8b341ba..96d3aa8 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RSA.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RSA.scala | |||
@@ -42,32 +42,29 @@ import scala.collection.JavaConverters._ | |||
42 | 42 | ||
43 | object RSA { | 43 | object RSA { |
44 | 44 | ||
45 | /** Set of default prefixes to be included in all datastore operations */ | ||
45 | val Prefixes: Prefixes = new Prefixes() | 46 | val Prefixes: Prefixes = new Prefixes() |
46 | Prefixes.declarePrefix("rsa:", "http://www.cs.ox.ac.uk/isg/rsa/") | 47 | Prefixes.declarePrefix("rsacomb:", "http://www.cs.ox.ac.uk/isg/RSAComb#") |
48 | Prefixes.declarePrefix("rdfox:", "http://oxfordsemantic.tech/RDFox#") | ||
47 | Prefixes.declarePrefix("owl:", "http://www.w3.org/2002/07/owl#") | 49 | Prefixes.declarePrefix("owl:", "http://www.w3.org/2002/07/owl#") |
48 | 50 | ||
49 | val CONGRUENT = RSA("congruent") | 51 | /** Creates a `rsacomb:<name>` IRI */ |
50 | val NAMED = RSA("Named") | 52 | def apply(name: Any): IRI = |
51 | 53 | IRI.create( | |
52 | private def atom(name: IRI, vars: List[Term]): TupleTableAtom = | 54 | Prefixes.getPrefixIRIsByPrefixName.get("rsacomb:").getIRI + name.toString |
53 | TupleTableAtom.create(TupleTableName.create(name.getIRI), vars: _*) | 55 | ) |
54 | |||
55 | def E(t1: Term, t2: Term) = | ||
56 | TupleTableAtom.rdf(t1, RSA("E"), t2) | ||
57 | |||
58 | def PE(t1: Term, t2: Term) = | ||
59 | TupleTableAtom.rdf(t1, RSA("PE"), t2) | ||
60 | 56 | ||
61 | def U(t: Term) = | 57 | val NAMED = RSA("Named") |
62 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, RSA("U")) | 58 | val CONGRUENT = RSA("congruent") |
59 | val IN = RSA("In") | ||
63 | 60 | ||
64 | def In(t: Term)(implicit set: Term) = | 61 | // def In(t: Term)(implicit set: Term) = |
65 | TupleTableAtom.rdf(t, RSA("In"), set) | 62 | // TupleTableAtom.rdf(t, RSA("In"), set) |
66 | 63 | ||
67 | def NotIn(t: Term)(implicit set: Term) = Negation.create(In(t)(set)) | 64 | // def NotIn(t: Term)(implicit set: Term) = Negation.create(In(t)(set)) |
68 | 65 | ||
69 | def Congruent(t1: Term, t2: Term) = | 66 | // def Congruent(t1: Term, t2: Term) = |
70 | TupleTableAtom.rdf(t1, RSA("congruent"), t2) | 67 | // TupleTableAtom.rdf(t1, RSA("congruent"), t2) |
71 | 68 | ||
72 | def QM(implicit q: ConjunctiveQuery) = | 69 | def QM(implicit q: ConjunctiveQuery) = |
73 | atom(RSA("QM"), q.answer ::: q.bounded) | 70 | atom(RSA("QM"), q.answer ::: q.bounded) |
@@ -104,8 +101,18 @@ object RSA { | |||
104 | atom(RSA("Ans"), q.answer) | 101 | atom(RSA("Ans"), q.answer) |
105 | } | 102 | } |
106 | 103 | ||
107 | def apply(name: Any): IRI = | 104 | /* TODO: review after reworking the dependency graph construction */ |
108 | IRI.create( | 105 | |
109 | Prefixes.getPrefixIRIsByPrefixName.get("rsa:").getIRI + name.toString | 106 | // private def atom(name: IRI, vars: List[Term]): TupleTableAtom = |
110 | ) | 107 | // TupleTableAtom.create(TupleTableName.create(name.getIRI), vars: _*) |
108 | |||
109 | def E(t1: Term, t2: Term) = | ||
110 | TupleTableAtom.rdf(t1, RSA("E"), t2) | ||
111 | |||
112 | def PE(t1: Term, t2: Term) = | ||
113 | TupleTableAtom.rdf(t1, RSA("PE"), t2) | ||
114 | |||
115 | def U(t: Term) = | ||
116 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, RSA("U")) | ||
117 | |||
111 | } | 118 | } |