diff options
5 files changed, 148 insertions, 82 deletions
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 8e05f3a..6e9a119 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | |||
@@ -96,7 +96,10 @@ object RSAOntology { | |||
96 | * @param query the query to derive the filtering program | 96 | * @param query the query to derive the filtering program |
97 | * @return the filtering program for the given query | 97 | * @return the filtering program for the given query |
98 | */ | 98 | */ |
99 | def filteringProgram(query: ConjunctiveQuery): FilteringProgram = | 99 | def filteringProgram( |
100 | graph: String, | ||
101 | query: ConjunctiveQuery | ||
102 | ): FilteringProgram = | ||
100 | Logger.timed( | 103 | Logger.timed( |
101 | FilteringProgram(FilterType.REVISED)(query), | 104 | FilteringProgram(FilterType.REVISED)(query), |
102 | "Generating filtering program", | 105 | "Generating filtering program", |
@@ -496,76 +499,131 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[File]) | |||
496 | def unfold(axiom: OWLSubClassOfAxiom): Set[Term] = | 499 | def unfold(axiom: OWLSubClassOfAxiom): Set[Term] = |
497 | this.self(axiom) | this.cycle(axiom) | 500 | this.self(axiom) | this.cycle(axiom) |
498 | 501 | ||
499 | def ask(queries: Seq[ConjunctiveQuery]): Seq[ConjunctiveQueryAnswers] = ??? | 502 | /** Returns the answers to a collection of queries |
500 | |||
501 | /** Returns the answers to a query | ||
502 | * | 503 | * |
503 | * @param query query to execute | 504 | * @param queries a sequence of conjunctive queries to answer. |
504 | * @return a collection of answers | 505 | * @return a collection of answers for each query. |
505 | */ | 506 | */ |
506 | def ask(query: ConjunctiveQuery): ConjunctiveQueryAnswers = Logger.timed( | 507 | def ask(queries: Seq[ConjunctiveQuery]): Seq[ConjunctiveQueryAnswers] = { |
507 | { | 508 | val (server, data) = RDFoxUtil.openConnection(RSAOntology.DataStore) |
508 | val (server, data) = RDFoxUtil.openConnection(RSAOntology.DataStore) | 509 | val canonNamedGraph = "http://cs.ox.ac.uk/isg/RSAComb#CanonicalModel" |
509 | val canon = this.canonicalModel | 510 | // Create a new NamedGraph for the canonical model |
510 | val filter = RSAOntology.filteringProgram(query) | 511 | data.createTupleTable(canonNamedGraph, Map("type" -> "named-graph").asJava) |
511 | 512 | ||
512 | /* Upload data from data file */ | 513 | /* Upload data from data file */ |
513 | RDFoxUtil.addData(data, datafiles: _*) | 514 | RDFoxUtil.addData(canonNamedGraph, data, datafiles: _*) |
514 | 515 | /* Top / equality axiomatization */ | |
515 | RDFoxUtil printStatisticsFor data | 516 | RDFoxUtil.addRules(data, topAxioms ++ equalityAxioms) |
516 | 517 | /* Generate `named` predicates */ | |
517 | /* Top / equality axiomatization */ | 518 | RDFoxUtil.addFacts( |
518 | RDFoxUtil.addRules(data, topAxioms ++ equalityAxioms) | 519 | canonNamedGraph, |
519 | 520 | data, | |
520 | /* Generate `named` predicates */ | 521 | (individuals ++ literals) map RSA.Named |
521 | RDFoxUtil.addFacts(data, (individuals ++ literals) map RSA.Named) | 522 | ) |
522 | data.evaluateUpdate( | 523 | data.evaluateUpdate( |
523 | null, // the base IRI for the query (if null, a default is used) | 524 | null, // the base IRI for the query (if null, a default is used) |
524 | RSA.Prefixes, | 525 | RSA.Prefixes, |
525 | "INSERT { ?X a rsa:Named } WHERE { ?X a owl:Thing }", | 526 | s""" |
526 | new java.util.HashMap[String, String] | 527 | INSERT { |
527 | ) | 528 | GRAPH <$canonNamedGraph> { ?X a rsa:Named } |
528 | 529 | } WHERE { | |
529 | /* Add canonical model */ | 530 | GRAPH <$canonNamedGraph> { ?X a owl:Thing } |
530 | Logger print s"Canonical model rules: ${canon.rules.length}" | 531 | } |
531 | RDFoxUtil.addRules(data, canon.rules) | 532 | """, |
532 | 533 | new java.util.HashMap[String, String] | |
533 | Logger print s"Canonical model facts: ${canon.facts.length}" | 534 | ) |
534 | RDFoxUtil.addFacts(data, canon.facts) | ||
535 | 535 | ||
536 | RDFoxUtil printStatisticsFor data | 536 | /* Add canonical model */ |
537 | Logger print s"Canonical model rules: ${this.canonicalModel.rules.length}" | ||
538 | RDFoxUtil.addRules(data, this.canonicalModel.rules) | ||
537 | 539 | ||
538 | //{ | 540 | Logger print s"Canonical model facts: ${this.canonicalModel.facts.length}" |
539 | // import java.io.{PrintStream, FileOutputStream, File} | 541 | RDFoxUtil.addFacts(canonNamedGraph, data, this.canonicalModel.facts) |
540 | // val rules1 = new FileOutputStream(new File("rules1-lubm200.dlog")) | ||
541 | // val facts1 = new FileOutputStream(new File("facts1-lubm200.ttl")) | ||
542 | // RDFoxUtil.export(data, rules1, facts1) | ||
543 | // val rules2 = new PrintStream(new File("rules2-q34.dlog")) | ||
544 | // rules2.print(filter.rules.mkString("\n")) | ||
545 | //} | ||
546 | 542 | ||
547 | /* Add filtering program */ | 543 | queries map { query => |
548 | Logger print s"Filtering program rules: ${filter.rules.length}" | 544 | { |
549 | RDFoxUtil.addRules(data, filter.rules) | 545 | val filterNamedGraph = |
546 | s"http://cs.ox.ac.uk/isg/RSAComb#Filter${query.id}" | ||
547 | val filter = RSAOntology.filteringProgram(filterNamedGraph, query) | ||
548 | /* Add filtering program */ | ||
549 | Logger print s"Filtering program rules: ${filter.rules.length}" | ||
550 | RDFoxUtil.addRules(data, filter.rules) | ||
550 | 551 | ||
551 | RDFoxUtil printStatisticsFor data | 552 | // We remove the rules, should we drop the tuple table as well? |
553 | data.clearRulesAxiomsExplicateFacts() | ||
552 | 554 | ||
553 | /* Gather answers to the query */ | 555 | /* Gather answers to the query */ |
554 | val answers = { | ||
555 | val ans = filter.answerQuery | ||
556 | RDFoxUtil | 556 | RDFoxUtil |
557 | .submitQuery(data, ans, RSA.Prefixes) | 557 | .submitQuery(data, filter.answerQuery, RSA.Prefixes) |
558 | .map(new ConjunctiveQueryAnswers(query, query.variables, _)) | 558 | .map(new ConjunctiveQueryAnswers(query, query.variables, _)) |
559 | .get | 559 | .get |
560 | } | 560 | } |
561 | } | ||
562 | } | ||
561 | 563 | ||
562 | RDFoxUtil.closeConnection(server, data) | 564 | //def ask(query: ConjunctiveQuery): ConjunctiveQueryAnswers = Logger.timed( |
563 | 565 | // { | |
564 | answers | 566 | // val (server, data) = RDFoxUtil.openConnection(RSAOntology.DataStore) |
565 | }, | 567 | // val canon = this.canonicalModel |
566 | "Answers computation", | 568 | // val filter = RSAOntology.filteringProgram(query) |
567 | Logger.DEBUG | 569 | |
568 | ) | 570 | // /* Upload data from data file */ |
571 | // RDFoxUtil.addData(data, datafiles: _*) | ||
572 | |||
573 | // RDFoxUtil printStatisticsFor data | ||
574 | |||
575 | // /* Top / equality axiomatization */ | ||
576 | // RDFoxUtil.addRules(data, topAxioms ++ equalityAxioms) | ||
577 | |||
578 | // /* Generate `named` predicates */ | ||
579 | // RDFoxUtil.addFacts(data, (individuals ++ literals) map RSA.Named) | ||
580 | // data.evaluateUpdate( | ||
581 | // null, // the base IRI for the query (if null, a default is used) | ||
582 | // RSA.Prefixes, | ||
583 | // "INSERT { ?X a rsa:Named } WHERE { ?X a owl:Thing }", | ||
584 | // new java.util.HashMap[String, String] | ||
585 | // ) | ||
586 | |||
587 | // /* Add canonical model */ | ||
588 | // Logger print s"Canonical model rules: ${canon.rules.length}" | ||
589 | // RDFoxUtil.addRules(data, canon.rules) | ||
590 | |||
591 | // Logger print s"Canonical model facts: ${canon.facts.length}" | ||
592 | // RDFoxUtil.addFacts(data, canon.facts) | ||
593 | |||
594 | // RDFoxUtil printStatisticsFor data | ||
595 | |||
596 | // //{ | ||
597 | // // import java.io.{PrintStream, FileOutputStream, File} | ||
598 | // // val rules1 = new FileOutputStream(new File("rules1-lubm200.dlog")) | ||
599 | // // val facts1 = new FileOutputStream(new File("facts1-lubm200.ttl")) | ||
600 | // // RDFoxUtil.export(data, rules1, facts1) | ||
601 | // // val rules2 = new PrintStream(new File("rules2-q34.dlog")) | ||
602 | // // rules2.print(filter.rules.mkString("\n")) | ||
603 | // //} | ||
604 | |||
605 | // /* Add filtering program */ | ||
606 | // Logger print s"Filtering program rules: ${filter.rules.length}" | ||
607 | // RDFoxUtil.addRules(data, filter.rules) | ||
608 | |||
609 | // RDFoxUtil printStatisticsFor data | ||
610 | |||
611 | // /* Gather answers to the query */ | ||
612 | // val answers = { | ||
613 | // val ans = filter.answerQuery | ||
614 | // RDFoxUtil | ||
615 | // .submitQuery(data, ans, RSA.Prefixes) | ||
616 | // .map(new ConjunctiveQueryAnswers(query, query.variables, _)) | ||
617 | // .get | ||
618 | // } | ||
619 | |||
620 | // RDFoxUtil.closeConnection(server, data) | ||
621 | |||
622 | // answers | ||
623 | // }, | ||
624 | // "Answers computation", | ||
625 | // Logger.DEBUG | ||
626 | //) | ||
569 | 627 | ||
570 | /** Query the RDFox data store used for query answering. | 628 | /** Query the RDFox data store used for query answering. |
571 | * | 629 | * |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/FilteringProgram.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/FilteringProgram.scala index 2774cb1..d6ad8c5 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/FilteringProgram.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/FilteringProgram.scala | |||
@@ -46,6 +46,9 @@ object FilteringProgram extends Versioned[FilterType] { | |||
46 | */ | 46 | */ |
47 | trait FilteringProgram { | 47 | trait FilteringProgram { |
48 | 48 | ||
49 | /** Named graph used for filtering process */ | ||
50 | val graph: String | ||
51 | |||
49 | /** Query from which the filtering program is generated */ | 52 | /** Query from which the filtering program is generated */ |
50 | val query: ConjunctiveQuery | 53 | val query: ConjunctiveQuery |
51 | 54 | ||
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/NaiveFilteringProgram.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/NaiveFilteringProgram.scala index 45dd867..3d9717c 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/NaiveFilteringProgram.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/NaiveFilteringProgram.scala | |||
@@ -36,8 +36,8 @@ object NaiveFilteringProgram { | |||
36 | * | 36 | * |
37 | * @param query CQ to be converted into logic rules. | 37 | * @param query CQ to be converted into logic rules. |
38 | */ | 38 | */ |
39 | def apply(query: ConjunctiveQuery): FilteringProgram = | 39 | def apply(graph: String, query: ConjunctiveQuery): FilteringProgram = |
40 | new NaiveFilteringProgram(query) | 40 | new NaiveFilteringProgram(graph, query) |
41 | } | 41 | } |
42 | 42 | ||
43 | /** Filtering Program generator | 43 | /** Filtering Program generator |
@@ -47,7 +47,7 @@ object NaiveFilteringProgram { | |||
47 | * | 47 | * |
48 | * Instances can be created using the companion object. | 48 | * Instances can be created using the companion object. |
49 | */ | 49 | */ |
50 | class NaiveFilteringProgram(val query: ConjunctiveQuery) | 50 | class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) |
51 | extends FilteringProgram { | 51 | extends FilteringProgram { |
52 | 52 | ||
53 | /** Extends capabilities of | 53 | /** Extends capabilities of |
@@ -321,5 +321,6 @@ class NaiveFilteringProgram(val query: ConjunctiveQuery) | |||
321 | r9 :: List()) map RDFoxUtil.reify | 321 | r9 :: List()) map RDFoxUtil.reify |
322 | } | 322 | } |
323 | 323 | ||
324 | val answerQuery = RDFoxUtil.buildDescriptionQuery("Ans", query.answer.size) | 324 | val answerQuery = |
325 | RDFoxUtil.buildDescriptionQuery(graph, "Ans", query.answer.size) | ||
325 | } | 326 | } |
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 4a4e65c..5d11369 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 | |||
@@ -422,12 +422,12 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery) | |||
422 | s""" | 422 | s""" |
423 | SELECT $answer | 423 | SELECT $answer |
424 | WHERE { | 424 | WHERE { |
425 | ?K a rsa:Ans . | 425 | GRAPH <$graph> { ?K a rsa:Ans } . |
426 | TT <http://oxfordsemantic.tech/RDFox#SKOLEM> { $answer $bounded ?K } . | 426 | TT <http://oxfordsemantic.tech/RDFox#SKOLEM> { $answer $bounded ?K } . |
427 | } | 427 | } |
428 | """ | 428 | """ |
429 | } else { | 429 | } else { |
430 | "ASK { ?X a rsa:Ans }" | 430 | s"ASK { GRAPH <$graph> { ?X a rsa:Ans } }" |
431 | } | 431 | } |
432 | } | 432 | } |
433 | 433 | ||
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 620d2dd..6f5ff31 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 | |||
@@ -124,13 +124,14 @@ object RDFoxUtil { | |||
124 | def addRules(data: DataStoreConnection, rules: Seq[Rule]): Unit = | 124 | def addRules(data: DataStoreConnection, rules: Seq[Rule]): Unit = |
125 | Logger.timed( | 125 | Logger.timed( |
126 | if (rules.length > 0) { | 126 | if (rules.length > 0) { |
127 | data.importData( | 127 | data addRules rules |
128 | UpdateType.ADDITION, | 128 | // data.importData( |
129 | RSA.Prefixes, | 129 | // UpdateType.ADDITION, |
130 | rules | 130 | // RSA.Prefixes, |
131 | .map(_.toString(Prefixes.s_emptyPrefixes)) | 131 | // rules |
132 | .mkString("\n") | 132 | // .map(_.toString(Prefixes.s_emptyPrefixes)) |
133 | ) | 133 | // .mkString("\n") |
134 | // ) | ||
134 | }, | 135 | }, |
135 | s"Loading ${rules.length} rules", | 136 | s"Loading ${rules.length} rules", |
136 | Logger.DEBUG | 137 | Logger.DEBUG |
@@ -141,10 +142,15 @@ object RDFoxUtil { | |||
141 | * @param data datastore connection | 142 | * @param data datastore connection |
142 | * @param facts collection of facts to be added to the data store | 143 | * @param facts collection of facts to be added to the data store |
143 | */ | 144 | */ |
144 | def addFacts(data: DataStoreConnection, facts: Seq[TupleTableAtom]): Unit = | 145 | def addFacts( |
146 | graph: String, | ||
147 | data: DataStoreConnection, | ||
148 | facts: Seq[TupleTableAtom] | ||
149 | ): Unit = | ||
145 | Logger.timed( | 150 | Logger.timed( |
146 | if (facts.length > 0) { | 151 | if (facts.length > 0) { |
147 | data.importData( | 152 | data.importData( |
153 | graph, | ||
148 | UpdateType.ADDITION, | 154 | UpdateType.ADDITION, |
149 | RSA.Prefixes, | 155 | RSA.Prefixes, |
150 | facts | 156 | facts |
@@ -161,14 +167,10 @@ object RDFoxUtil { | |||
161 | * @param data datastore connection. | 167 | * @param data datastore connection. |
162 | * @param files sequence of files to upload. | 168 | * @param files sequence of files to upload. |
163 | */ | 169 | */ |
164 | def addData(data: DataStoreConnection, files: File*): Unit = | 170 | def addData(graph: String, data: DataStoreConnection, files: File*): Unit = |
165 | Logger.timed( | 171 | Logger.timed( |
166 | files.foreach { | 172 | files.foreach { |
167 | data.importData( | 173 | data.importData(graph, UpdateType.ADDITION, RSA.Prefixes, _) |
168 | UpdateType.ADDITION, | ||
169 | RSA.Prefixes, | ||
170 | _ | ||
171 | ) | ||
172 | }, | 174 | }, |
173 | "Loading data files", | 175 | "Loading data files", |
174 | Logger.DEBUG | 176 | Logger.DEBUG |
@@ -315,11 +317,13 @@ object RDFoxUtil { | |||
315 | * compatible with RDFox engine. This helper allows to build a query | 317 | * compatible with RDFox engine. This helper allows to build a query |
316 | * to gather all instances of an internal predicate | 318 | * to gather all instances of an internal predicate |
317 | * | 319 | * |
320 | * @param graph named graph to query for the provided predicate | ||
318 | * @param pred name of the predicate to describe. | 321 | * @param pred name of the predicate to describe. |
319 | * @param arity arity of the predicate. | 322 | * @param arity arity of the predicate. |
320 | * @return a string containing a SPARQL query. | 323 | * @return a string containing a SPARQL query. |
321 | */ | 324 | */ |
322 | def buildDescriptionQuery( | 325 | def buildDescriptionQuery( |
326 | graph: String, | ||
323 | pred: String, | 327 | pred: String, |
324 | arity: Int | 328 | arity: Int |
325 | ): String = { | 329 | ): String = { |
@@ -328,12 +332,12 @@ object RDFoxUtil { | |||
328 | s""" | 332 | s""" |
329 | SELECT $variables | 333 | SELECT $variables |
330 | WHERE { | 334 | WHERE { |
331 | ?K a rsa:$pred. | 335 | GRAPH <$graph> { ?K a rsa:$pred }. |
332 | TT <http://oxfordsemantic.tech/RDFox#SKOLEM> { $variables ?K } . | 336 | TT <http://oxfordsemantic.tech/RDFox#SKOLEM> { $variables ?K } . |
333 | } | 337 | } |
334 | """ | 338 | """ |
335 | } else { | 339 | } else { |
336 | "ASK { ?X a rsa:Ans }" | 340 | s"ASK { GRAPH <$graph> { ?X a rsa:Ans } }" |
337 | } | 341 | } |
338 | } | 342 | } |
339 | 343 | ||