diff options
| author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-11-14 14:00:55 +0000 |
|---|---|---|
| committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-11-14 14:00:55 +0000 |
| commit | 313d3f835977f4d7f59e32e1b6cf4a508e1a3431 (patch) | |
| tree | 79c9985bf826ae3557539bd1cffe49f1bfa9320a /src/main/scala | |
| parent | 77900dc5a9439336eed37e7b8d6c587d1f9288fc (diff) | |
| download | RSAComb-313d3f835977f4d7f59e32e1b6cf4a508e1a3431.tar.gz RSAComb-313d3f835977f4d7f59e32e1b6cf4a508e1a3431.zip | |
Fix NI predicate computation
Now NAMED is introduced during the canonical model computation, while
NI instances are computed and introduced in the filtering program
generation phase.
Diffstat (limited to 'src/main/scala')
| -rw-r--r-- | src/main/scala/rsacomb/FilteringProgram.scala | 30 | ||||
| -rw-r--r-- | src/main/scala/rsacomb/Main.scala | 54 | ||||
| -rw-r--r-- | src/main/scala/rsacomb/RSA.scala | 2 | ||||
| -rw-r--r-- | src/main/scala/rsacomb/RSAOntology.scala | 27 |
4 files changed, 76 insertions, 37 deletions
diff --git a/src/main/scala/rsacomb/FilteringProgram.scala b/src/main/scala/rsacomb/FilteringProgram.scala index 4d5a5c0..e9a69ff 100644 --- a/src/main/scala/rsacomb/FilteringProgram.scala +++ b/src/main/scala/rsacomb/FilteringProgram.scala | |||
| @@ -57,16 +57,12 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
| 57 | } | 57 | } |
| 58 | val bounded: List[Term] = this.variables.filterNot(answer.contains(_)) | 58 | val bounded: List[Term] = this.variables.filterNot(answer.contains(_)) |
| 59 | 59 | ||
| 60 | val facts: List[TupleTableAtom] = constants.map(named) | 60 | val facts: List[Rule] = constants.map(c => Rule.create(predNI(c))) |
| 61 | val rules: List[Rule] = | 61 | val rules: List[Rule] = |
| 62 | this.generateFilteringProgram().map(reifyRule) ++ facts.map(Rule.create(_)) | 62 | this.generateFilteringProgram().map(reifyRule) ++ facts |
| 63 | 63 | ||
| 64 | private def named(t: Term): TupleTableAtom = | 64 | private def predNI(t: Term): TupleTableAtom = |
| 65 | TupleTableAtom.rdf( | 65 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, RSA.internal("NI")) |
| 66 | t, | ||
| 67 | IRI.RDF_TYPE, | ||
| 68 | RSA.internal("NAMED") | ||
| 69 | ) | ||
| 70 | 66 | ||
| 71 | /* NOTE: we are restricting to queries that contain conjunctions of | 67 | /* NOTE: we are restricting to queries that contain conjunctions of |
| 72 | * atoms for the time being. This might need to be reviewed in the | 68 | * atoms for the time being. This might need to be reviewed in the |
| @@ -104,8 +100,8 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
| 104 | TupleTableName.create(RSA.internal("ID").getIRI), | 100 | TupleTableName.create(RSA.internal("ID").getIRI), |
| 105 | (answer ++ bounded).appended(t1).appended(t2): _* | 101 | (answer ++ bounded).appended(t1).appended(t2): _* |
| 106 | ) | 102 | ) |
| 107 | def predNI(t1: Term): TupleTableAtom = | 103 | def predNAMED(t1: Term): TupleTableAtom = |
| 108 | TupleTableAtom.rdf(t1, IRI.RDF_TYPE, RSA.internal("NI")) | 104 | TupleTableAtom.rdf(t1, IRI.RDF_TYPE, RSA.internal("NAMED")) |
| 109 | def predTQ(sx: String, t1: Term, t2: Term) = | 105 | def predTQ(sx: String, t1: Term, t2: Term) = |
| 110 | TupleTableAtom.create( | 106 | TupleTableAtom.create( |
| 111 | TupleTableName.create(RSA.internal(s"TQ_$sx").getIRI), | 107 | TupleTableName.create(RSA.internal(s"TQ_$sx").getIRI), |
| @@ -170,7 +166,7 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
| 170 | not( | 166 | not( |
| 171 | TupleTableAtom.rdf( | 167 | TupleTableAtom.rdf( |
| 172 | role1.getArguments.get(0), | 168 | role1.getArguments.get(0), |
| 173 | IRI.SAME_AS, | 169 | RSA.EquivTo, |
| 174 | role2.getArguments.get(0) | 170 | role2.getArguments.get(0) |
| 175 | ) | 171 | ) |
| 176 | ) | 172 | ) |
| @@ -191,7 +187,7 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
| 191 | not( | 187 | not( |
| 192 | TupleTableAtom.rdf( | 188 | TupleTableAtom.rdf( |
| 193 | role1.getArguments.get(0), | 189 | role1.getArguments.get(0), |
| 194 | IRI.SAME_AS, | 190 | RSA.EquivTo, |
| 195 | role2.getArguments.get(2) | 191 | role2.getArguments.get(2) |
| 196 | ) | 192 | ) |
| 197 | ) | 193 | ) |
| @@ -212,7 +208,7 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
| 212 | not( | 208 | not( |
| 213 | TupleTableAtom.rdf( | 209 | TupleTableAtom.rdf( |
| 214 | role1.getArguments.get(2), | 210 | role1.getArguments.get(2), |
| 215 | IRI.SAME_AS, | 211 | RSA.EquivTo, |
| 216 | role2.getArguments.get(2) | 212 | role2.getArguments.get(2) |
| 217 | ) | 213 | ) |
| 218 | ) | 214 | ) |
| @@ -241,7 +237,7 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
| 241 | RSA.internal(bounded indexOf role1arg2), | 237 | RSA.internal(bounded indexOf role1arg2), |
| 242 | RSA.internal(bounded indexOf role2arg2) | 238 | RSA.internal(bounded indexOf role2arg2) |
| 243 | ), | 239 | ), |
| 244 | TupleTableAtom.rdf(role1arg0, IRI.SAME_AS, role2arg0), | 240 | TupleTableAtom.rdf(role1arg0, RSA.EquivTo, role2arg0), |
| 245 | not(predNI(role1arg0)) | 241 | not(predNI(role1arg0)) |
| 246 | ) | 242 | ) |
| 247 | val r5b = for { | 243 | val r5b = for { |
| @@ -266,7 +262,7 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
| 266 | RSA.internal(bounded indexOf role1arg2), | 262 | RSA.internal(bounded indexOf role1arg2), |
| 267 | RSA.internal(bounded indexOf role2arg0) | 263 | RSA.internal(bounded indexOf role2arg0) |
| 268 | ), | 264 | ), |
| 269 | TupleTableAtom.rdf(role1arg0, IRI.SAME_AS, role2arg2), | 265 | TupleTableAtom.rdf(role1arg0, RSA.EquivTo, role2arg2), |
| 270 | not(predNI(role1arg0)) | 266 | not(predNI(role1arg0)) |
| 271 | ) | 267 | ) |
| 272 | val r5c = for { | 268 | val r5c = for { |
| @@ -291,7 +287,7 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
| 291 | RSA.internal(bounded indexOf role1arg0), | 287 | RSA.internal(bounded indexOf role1arg0), |
| 292 | RSA.internal(bounded indexOf role2arg0) | 288 | RSA.internal(bounded indexOf role2arg0) |
| 293 | ), | 289 | ), |
| 294 | TupleTableAtom.rdf(role1arg2, IRI.SAME_AS, role2arg2), | 290 | TupleTableAtom.rdf(role1arg2, RSA.EquivTo, role2arg2), |
| 295 | not(predNI(role1arg2)) | 291 | not(predNI(role1arg2)) |
| 296 | ) | 292 | ) |
| 297 | 293 | ||
| @@ -333,7 +329,7 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
| 333 | 329 | ||
| 334 | /* Rules 8x */ | 330 | /* Rules 8x */ |
| 335 | val r8a = | 331 | val r8a = |
| 336 | for (v <- answer) yield Rule.create(predSP, predQM, not(named(v))) | 332 | for (v <- answer) yield Rule.create(predSP, predQM, not(predNAMED(v))) |
| 337 | val r8b = | 333 | val r8b = |
| 338 | Rule.create(predSP, predFK) | 334 | Rule.create(predSP, predFK) |
| 339 | val r8c = | 335 | val r8c = |
diff --git a/src/main/scala/rsacomb/Main.scala b/src/main/scala/rsacomb/Main.scala index 39040fc..596ef33 100644 --- a/src/main/scala/rsacomb/Main.scala +++ b/src/main/scala/rsacomb/Main.scala | |||
| @@ -7,6 +7,7 @@ import scala.collection.JavaConverters._ | |||
| 7 | 7 | ||
| 8 | import tech.oxfordsemantic.jrdfox.client.UpdateType | 8 | import tech.oxfordsemantic.jrdfox.client.UpdateType |
| 9 | import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery | 9 | import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery |
| 10 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI, Term} | ||
| 10 | 11 | ||
| 11 | /* Local imports */ | 12 | /* Local imports */ |
| 12 | import rsacomb.RSA._ | 13 | import rsacomb.RSA._ |
| @@ -73,23 +74,50 @@ object RSAComb extends App { | |||
| 73 | // Open connection to RDFox | 74 | // Open connection to RDFox |
| 74 | val (server, data) = RDFoxUtil.openConnection("AnswerComputation") | 75 | val (server, data) = RDFoxUtil.openConnection("AnswerComputation") |
| 75 | 76 | ||
| 76 | // Gather canonical model and filtering rules | 77 | { |
| 78 | println("\nQuery") | ||
| 79 | println(query) | ||
| 80 | } | ||
| 81 | |||
| 82 | // Step 1. Computing the canonical model | ||
| 77 | val canon = ontology.canonicalModel | 83 | val canon = ontology.canonicalModel |
| 78 | val filter = ontology.filteringProgram(query) | 84 | data.addRules(canon.rules.asJava) |
| 79 | 85 | ||
| 80 | { | 86 | { |
| 81 | println("\nCanonical Model rules:") | 87 | println("\nCanonical Model rules:") |
| 82 | canon.rules.foreach(println) | 88 | canon.rules.foreach(println) |
| 83 | println("\nFiltering rules") | ||
| 84 | filter.rules.foreach(println) | ||
| 85 | println("\nQuery") | ||
| 86 | println(query) | ||
| 87 | } | 89 | } |
| 88 | 90 | ||
| 89 | // Add canonical model and filtering rules | 91 | // Step 2. Computing the canonical model |
| 90 | data.addRules(canon.rules.asJava) | 92 | val nis = { |
| 93 | val query = | ||
| 94 | "SELECT ?Y WHERE { ?X internal:EquivTo ?Y ; a internal:NAMED . }" | ||
| 95 | val cursor = | ||
| 96 | data.createCursor( | ||
| 97 | RSA.Prefixes, | ||
| 98 | query, | ||
| 99 | new HashMap[String, String]() | ||
| 100 | ); | ||
| 101 | var mul = cursor.open() | ||
| 102 | var iris: List[IRI] = List() | ||
| 103 | while (mul > 0) { | ||
| 104 | println(cursor.getResource(0)) | ||
| 105 | iris = cursor.getResource(0) match { | ||
| 106 | case iri: IRI => iri :: iris | ||
| 107 | case _ => iris | ||
| 108 | } | ||
| 109 | mul = cursor.advance() | ||
| 110 | } | ||
| 111 | iris | ||
| 112 | } | ||
| 113 | val filter = ontology.filteringProgram(query, nis) | ||
| 91 | data.addRules(filter.rules.asJava) | 114 | data.addRules(filter.rules.asJava) |
| 92 | 115 | ||
| 116 | { | ||
| 117 | println("\nFiltering rules") | ||
| 118 | filter.rules.foreach(println) | ||
| 119 | } | ||
| 120 | |||
| 93 | def retrieveInstances(pred: String, arity: Int): Unit = { | 121 | def retrieveInstances(pred: String, arity: Int): Unit = { |
| 94 | // Build query | 122 | // Build query |
| 95 | var query = "SELECT" | 123 | var query = "SELECT" |
| @@ -127,6 +155,14 @@ object RSAComb extends App { | |||
| 127 | 1 | 155 | 1 |
| 128 | ) | 156 | ) |
| 129 | 157 | ||
| 158 | println("\nNAMEDs:") | ||
| 159 | RDFoxUtil.submitQuery( | ||
| 160 | data, | ||
| 161 | RSA.Prefixes, | ||
| 162 | "SELECT ?X { ?X a internal:NAMED }", | ||
| 163 | 1 | ||
| 164 | ) | ||
| 165 | |||
| 130 | println("\nNIs:") | 166 | println("\nNIs:") |
| 131 | RDFoxUtil.submitQuery( | 167 | RDFoxUtil.submitQuery( |
| 132 | data, | 168 | data, |
| @@ -143,7 +179,7 @@ object RSAComb extends App { | |||
| 143 | RDFoxUtil.submitQuery( | 179 | RDFoxUtil.submitQuery( |
| 144 | data, | 180 | data, |
| 145 | RSA.Prefixes, | 181 | RSA.Prefixes, |
| 146 | "SELECT ?X ?Y { ?X owl:sameAs ?Y }", | 182 | "SELECT ?X ?Y { ?X internal:EquivTo ?Y }", |
| 147 | 2 | 183 | 2 |
| 148 | ) | 184 | ) |
| 149 | 185 | ||
diff --git a/src/main/scala/rsacomb/RSA.scala b/src/main/scala/rsacomb/RSA.scala index 66de974..10a9d47 100644 --- a/src/main/scala/rsacomb/RSA.scala +++ b/src/main/scala/rsacomb/RSA.scala | |||
| @@ -28,6 +28,8 @@ object RSA extends RSAOntology with RSAAxiom { | |||
| 28 | Prefixes.declarePrefix("rdfs:", "http://www.w3.org/2000/01/rdf-schema#") | 28 | Prefixes.declarePrefix("rdfs:", "http://www.w3.org/2000/01/rdf-schema#") |
| 29 | Prefixes.declarePrefix("owl:", "http://www.w3.org/2002/07/owl#") | 29 | Prefixes.declarePrefix("owl:", "http://www.w3.org/2002/07/owl#") |
| 30 | 30 | ||
| 31 | val EquivTo: IRI = this.internal("EquivTo") | ||
| 32 | |||
| 31 | // Counter used to implement a simple fresh variable generator | 33 | // Counter used to implement a simple fresh variable generator |
| 32 | private var counter = -1; | 34 | private var counter = -1; |
| 33 | 35 | ||
diff --git a/src/main/scala/rsacomb/RSAOntology.scala b/src/main/scala/rsacomb/RSAOntology.scala index dcd9c63..9220434 100644 --- a/src/main/scala/rsacomb/RSAOntology.scala +++ b/src/main/scala/rsacomb/RSAOntology.scala | |||
| @@ -245,8 +245,11 @@ trait RSAOntology { | |||
| 245 | Graph(edges: _*) | 245 | Graph(edges: _*) |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | def filteringProgram(query: SelectQuery): FilteringProgram = | 248 | def filteringProgram( |
| 249 | FilteringProgram(query, individuals) | 249 | query: SelectQuery, |
| 250 | nis: List[Term] | ||
| 251 | ): FilteringProgram = | ||
| 252 | new FilteringProgram(query, nis) | ||
| 250 | 253 | ||
| 251 | // TODO: the following functions needs testing | 254 | // TODO: the following functions needs testing |
| 252 | def confl( | 255 | def confl( |
| @@ -359,9 +362,11 @@ trait RSAOntology { | |||
| 359 | 362 | ||
| 360 | import RDFoxUtil._ | 363 | import RDFoxUtil._ |
| 361 | 364 | ||
| 362 | val NIs: List[Rule] = | 365 | val named: List[Rule] = |
| 363 | individuals.map(a => | 366 | individuals.map(a => |
| 364 | Rule.create(TupleTableAtom.rdf(a, IRI.RDF_TYPE, RSA.internal("NI"))) | 367 | Rule.create( |
| 368 | TupleTableAtom.rdf(a, IRI.RDF_TYPE, RSA.internal("NAMED")) | ||
| 369 | ) | ||
| 365 | ) | 370 | ) |
| 366 | 371 | ||
| 367 | val rolesAdditionalRules: List[Rule] = { | 372 | val rolesAdditionalRules: List[Rule] = { |
| @@ -500,17 +505,17 @@ trait RSAOntology { | |||
| 500 | val z = Variable.create("Z") | 505 | val z = Variable.create("Z") |
| 501 | List( | 506 | List( |
| 502 | Rule.create( | 507 | Rule.create( |
| 503 | TupleTableAtom.rdf(x, IRI.SAME_AS, x), | 508 | TupleTableAtom.rdf(x, RSA.EquivTo, x), |
| 504 | TupleTableAtom.rdf(x, IRI.RDF_TYPE, IRI.THING) | 509 | TupleTableAtom.rdf(x, IRI.RDF_TYPE, IRI.THING) |
| 505 | ), | 510 | ), |
| 506 | Rule.create( | 511 | Rule.create( |
| 507 | TupleTableAtom.rdf(y, IRI.SAME_AS, x), | 512 | TupleTableAtom.rdf(y, RSA.EquivTo, x), |
| 508 | TupleTableAtom.rdf(x, IRI.SAME_AS, y) | 513 | TupleTableAtom.rdf(x, RSA.EquivTo, y) |
| 509 | ), | 514 | ), |
| 510 | Rule.create( | 515 | Rule.create( |
| 511 | TupleTableAtom.rdf(x, IRI.SAME_AS, z), | 516 | TupleTableAtom.rdf(x, RSA.EquivTo, z), |
| 512 | TupleTableAtom.rdf(x, IRI.SAME_AS, y), | 517 | TupleTableAtom.rdf(x, RSA.EquivTo, y), |
| 513 | TupleTableAtom.rdf(y, IRI.SAME_AS, z) | 518 | TupleTableAtom.rdf(y, RSA.EquivTo, z) |
| 514 | ) | 519 | ) |
| 515 | ) | 520 | ) |
| 516 | } | 521 | } |
| @@ -519,7 +524,7 @@ trait RSAOntology { | |||
| 519 | // Compute rules from ontology axioms | 524 | // Compute rules from ontology axioms |
| 520 | val rules = axioms.flatMap(_.accept(this.ProgramGenerator)) | 525 | val rules = axioms.flatMap(_.accept(this.ProgramGenerator)) |
| 521 | // Return full set of rules | 526 | // Return full set of rules |
| 522 | rules ++ rolesAdditionalRules ++ topAxioms ++ equalityAxioms ++ NIs | 527 | rules ++ rolesAdditionalRules ++ topAxioms ++ equalityAxioms ++ named |
| 523 | } | 528 | } |
| 524 | 529 | ||
| 525 | object ProgramGenerator | 530 | object ProgramGenerator |
