diff options
Diffstat (limited to 'src/main/scala')
6 files changed, 169 insertions, 10 deletions
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala index a8107b5..28196be 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala | |||
| @@ -113,7 +113,7 @@ object RSAComb extends App { | |||
| 113 | ontology.individuals.foreach(println) | 113 | ontology.individuals.foreach(println) |
| 114 | 114 | ||
| 115 | println("\nThings:") | 115 | println("\nThings:") |
| 116 | val things = RDFoxHelpers.submitSelectQuery( | 116 | val things = RDFoxHelpers.submitQuery( |
| 117 | data, | 117 | data, |
| 118 | """ | 118 | """ |
| 119 | PREFIX owl: <http://www.w3.org/2002/07/owl#> | 119 | PREFIX owl: <http://www.w3.org/2002/07/owl#> |
| @@ -126,7 +126,7 @@ object RSAComb extends App { | |||
| 126 | println(things) | 126 | println(things) |
| 127 | 127 | ||
| 128 | println("\nNAMEDs:") | 128 | println("\nNAMEDs:") |
| 129 | val named = RDFoxHelpers.submitSelectQuery( | 129 | val named = RDFoxHelpers.submitQuery( |
| 130 | data, | 130 | data, |
| 131 | """ | 131 | """ |
| 132 | SELECT ?X { | 132 | SELECT ?X { |
| @@ -138,7 +138,7 @@ object RSAComb extends App { | |||
| 138 | println(named) | 138 | println(named) |
| 139 | 139 | ||
| 140 | println("\nNIs:") | 140 | println("\nNIs:") |
| 141 | val nis = RDFoxHelpers.submitSelectQuery( | 141 | val nis = RDFoxHelpers.submitQuery( |
| 142 | data, | 142 | data, |
| 143 | """ | 143 | """ |
| 144 | SELECT ?X { | 144 | SELECT ?X { |
| @@ -159,7 +159,7 @@ object RSAComb extends App { | |||
| 159 | println(ids) | 159 | println(ids) |
| 160 | 160 | ||
| 161 | println("\nCongruent:") | 161 | println("\nCongruent:") |
| 162 | val equivs = RDFoxHelpers.submitSelectQuery( | 162 | val equivs = RDFoxHelpers.submitQuery( |
| 163 | data, | 163 | data, |
| 164 | """ | 164 | """ |
| 165 | SELECT ?X ?Y { | 165 | SELECT ?X ?Y { |
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 93fd5cd..c4d4184 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | |||
| @@ -254,7 +254,7 @@ class RSAOntology(val ontology: OWLOntology) extends RSAAxiom { | |||
| 254 | data: DataStoreConnection | 254 | data: DataStoreConnection |
| 255 | ): Graph[Resource, UnDiEdge] = { | 255 | ): Graph[Resource, UnDiEdge] = { |
| 256 | val query = "SELECT ?X ?Y WHERE { ?X rsa:E ?Y }" | 256 | val query = "SELECT ?X ?Y WHERE { ?X rsa:E ?Y }" |
| 257 | val answers = RDFoxHelpers.submitSelectQuery(data, query, RSA.Prefixes) | 257 | val answers = RDFoxHelpers.submitQuery(data, query, RSA.Prefixes).get |
| 258 | var edges: List[UnDiEdge[Resource]] = answers.map { | 258 | var edges: List[UnDiEdge[Resource]] = answers.map { |
| 259 | case n1 :: n2 :: _ => UnDiEdge(n1, n2) | 259 | case n1 :: n2 :: _ => UnDiEdge(n1, n2) |
| 260 | } | 260 | } |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/JavaCollections.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/JavaCollections.scala index 3b621f4..9d205b5 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/JavaCollections.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/JavaCollections.scala | |||
| @@ -9,5 +9,4 @@ object JavaCollections { | |||
| 9 | 9 | ||
| 10 | implicit def scalaToJavaList[A](list: List[A]): java.util.List[A] = | 10 | implicit def scalaToJavaList[A](list: List[A]): java.util.List[A] = |
| 11 | list.asJava | 11 | list.asJava |
| 12 | |||
| 13 | } | 12 | } |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuery.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuery.scala new file mode 100644 index 0000000..b523938 --- /dev/null +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuery.scala | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | package uk.ac.ox.cs.rsacomb.sparql | ||
| 2 | |||
| 3 | import java.util.{Map => JMap, HashMap => JHashMap} | ||
| 4 | import tech.oxfordsemantic.jrdfox.Prefixes | ||
| 5 | import tech.oxfordsemantic.jrdfox.client.DataStoreConnection | ||
| 6 | import tech.oxfordsemantic.jrdfox.logic.expression.Variable | ||
| 7 | import tech.oxfordsemantic.jrdfox.logic.sparql.pattern.{ | ||
| 8 | ConjunctionPattern, | ||
| 9 | QueryPattern, | ||
| 10 | TriplePattern | ||
| 11 | } | ||
| 12 | import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery | ||
| 13 | import uk.ac.ox.cs.rsacomb.util.RDFoxHelpers | ||
| 14 | |||
| 15 | /** Factory for [[uk.ac.ox.cs.rsacomb.sparql.ConjunctiveQuery]]. */ | ||
| 16 | object ConjunctiveQuery { | ||
| 17 | |||
| 18 | /** Creates a new ConjunctiveQuery instance. | ||
| 19 | * | ||
| 20 | * @param query `SelectQuery` instance representing the actual query | ||
| 21 | */ | ||
| 22 | def apply(query: SelectQuery): ConjunctiveQuery = | ||
| 23 | new ConjunctiveQuery(query) | ||
| 24 | |||
| 25 | /** Creates a new ConjunctiveQuery from a query string | ||
| 26 | * | ||
| 27 | * @param query a string representing the query in SPARQL format | ||
| 28 | * @param prefixes additional prefixes used in the query. Defaults to | ||
| 29 | * an empty set of prefixes. | ||
| 30 | * @return an [[scala.Option]] containing a ConjunctiveQuery if the | ||
| 31 | * input query represents one, None is returned otherwise. | ||
| 32 | */ | ||
| 33 | def apply( | ||
| 34 | query: String, | ||
| 35 | prefixes: Prefixes = new Prefixes() | ||
| 36 | ): Option[ConjunctiveQuery] = | ||
| 37 | RDFoxHelpers.parseSelectQuery(query, prefixes).map(ConjunctiveQuery(_)) | ||
| 38 | |||
| 39 | } | ||
| 40 | |||
| 41 | /** A conjunctive query | ||
| 42 | * | ||
| 43 | * A thin layer around | ||
| 44 | * [[tech.oxfordsemantics.jrdfox.logic.sparql.statement.SelectQuery]]. | ||
| 45 | * | ||
| 46 | * Instances should be created using the companion object. | ||
| 47 | * | ||
| 48 | * @todo additional checks need to be performed in order for a | ||
| 49 | * `SelectQuery` to be considered a conjunctive query. | ||
| 50 | */ | ||
| 51 | class ConjunctiveQuery( | ||
| 52 | query: SelectQuery, | ||
| 53 | val prefixes: Prefixes = new Prefixes() | ||
| 54 | ) { | ||
| 55 | |||
| 56 | import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ | ||
| 57 | |||
| 58 | /** SELECT section of the SPARQL query. | ||
| 59 | * | ||
| 60 | * Simply exposes the underlying `getSelection` method in | ||
| 61 | * [[tech.oxfordsemantics.jrdfox.logic.sparql.statement.SelectQuery]]. | ||
| 62 | */ | ||
| 63 | val select = query.getSelection | ||
| 64 | |||
| 65 | /** WHERE section of the SPARQL query. | ||
| 66 | * | ||
| 67 | * Simply exposes the underlying `getWherePattern` method in | ||
| 68 | * [[tech.oxfordsemantics.jrdfox.logic.sparql.statement.QueryBody]]. | ||
| 69 | */ | ||
| 70 | val where = query.getQueryBody.getWherePattern | ||
| 71 | |||
| 72 | /** Returns true if it is a boolean CQ. | ||
| 73 | * | ||
| 74 | * @note checking for `select` being empty is not enough. When a | ||
| 75 | * query selects '''all''' variables with `*`, `select` is empty as | ||
| 76 | * well. | ||
| 77 | */ | ||
| 78 | val boolean: Boolean = select.isEmpty && !query.getAllPossibleVariables | ||
| 79 | |||
| 80 | /** Returns the full set of variables involved in the query. */ | ||
| 81 | val variables: Set[Variable] = | ||
| 82 | where match { | ||
| 83 | case b: ConjunctionPattern => { | ||
| 84 | b.getConjuncts.toSet.flatMap { conj: QueryPattern => | ||
| 85 | conj match { | ||
| 86 | case c: TriplePattern => | ||
| 87 | Set(c.getSubject, c.getPredicate, c.getObject).collect { | ||
| 88 | case v: Variable => v | ||
| 89 | } | ||
| 90 | case _ => Set() | ||
| 91 | } | ||
| 92 | } | ||
| 93 | } | ||
| 94 | case _ => Set() | ||
| 95 | } | ||
| 96 | |||
| 97 | /** Returns the collection of answer variables in the query. */ | ||
| 98 | val answer: Set[Variable] = | ||
| 99 | if (query.getAllPossibleVariables) | ||
| 100 | variables | ||
| 101 | else | ||
| 102 | select.map(_.getVariable).toSet | ||
| 103 | |||
| 104 | /** Returns the collection of bounded (existential) variables in the query. */ | ||
| 105 | val bounded: Set[Variable] = variables &~ answer | ||
| 106 | |||
| 107 | /** Returns the answers to a query | ||
| 108 | * | ||
| 109 | * @param data data store against which the query is executed | ||
| 110 | * @param opts additional options passed to RDFox | ||
| 111 | * @return a new [[ConjunctiveQueryAnswers]] instance containing the | ||
| 112 | * collection of answers. | ||
| 113 | */ | ||
| 114 | def answers( | ||
| 115 | data: DataStoreConnection, | ||
| 116 | opts: JMap[String, String] = new JHashMap[String, String]() | ||
| 117 | ): ConjunctiveQueryAnswers = | ||
| 118 | new ConjunctiveQueryAnswers( | ||
| 119 | boolean, | ||
| 120 | RDFoxHelpers.submitSelectQuery(data, query, opts) | ||
| 121 | ) | ||
| 122 | |||
| 123 | override def toString(): String = query.toString | ||
| 124 | } | ||
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswers.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswers.scala new file mode 100644 index 0000000..223e121 --- /dev/null +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswers.scala | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | package uk.ac.ox.cs.rsacomb.sparql | ||
| 2 | |||
| 3 | import tech.oxfordsemantic.jrdfox.logic.expression.Resource | ||
| 4 | |||
| 5 | /** A collections of answers to a query | ||
| 6 | * | ||
| 7 | * Will take the query type (CQ or BCQ) into consideration when | ||
| 8 | * serialised. | ||
| 9 | * | ||
| 10 | * @param boolean whether the answers are to a BCQ | ||
| 11 | * @param answers collection of answers to a query. When dealing with | ||
| 12 | * BCQs, and empty collection represents a ''false'', | ||
| 13 | * ''true'' otherwise. | ||
| 14 | */ | ||
| 15 | class ConjunctiveQueryAnswers( | ||
| 16 | boolean: Boolean, | ||
| 17 | val answers: Seq[Seq[Resource]] | ||
| 18 | ) { | ||
| 19 | |||
| 20 | override def toString(): String = | ||
| 21 | if (boolean) { | ||
| 22 | if (answers.isEmpty) "FALSE" else "TRUE" | ||
| 23 | } else { | ||
| 24 | if (answers.isEmpty) | ||
| 25 | "NO ANSWER" | ||
| 26 | else | ||
| 27 | answers.map(_.mkString("(", ", ", ")")).mkString("\n") | ||
| 28 | } | ||
| 29 | } | ||
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxHelpers.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxHelpers.scala index fd9e1c5..5b85436 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxHelpers.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxHelpers.scala | |||
| @@ -54,11 +54,10 @@ object RDFoxHelpers { | |||
| 54 | 54 | ||
| 55 | def submitSelectQuery( | 55 | def submitSelectQuery( |
| 56 | data: DataStoreConnection, | 56 | data: DataStoreConnection, |
| 57 | query: String, | 57 | query: SelectQuery, |
| 58 | prefixes: Prefixes = new Prefixes(), | ||
| 59 | opts: JMap[String, String] = new JHashMap[String, String]() | 58 | opts: JMap[String, String] = new JHashMap[String, String]() |
| 60 | ): List[List[Resource]] = { | 59 | ): List[List[Resource]] = { |
| 61 | val cursor = data.createCursor(prefixes, query, opts) | 60 | val cursor = data.createCursor(query, opts) |
| 62 | var answers: List[List[Resource]] = List() | 61 | var answers: List[List[Resource]] = List() |
| 63 | var mul = cursor.open() | 62 | var mul = cursor.open() |
| 64 | while (mul > 0) { | 63 | while (mul > 0) { |
| @@ -71,6 +70,14 @@ object RDFoxHelpers { | |||
| 71 | answers | 70 | answers |
| 72 | } | 71 | } |
| 73 | 72 | ||
| 73 | def submitQuery( | ||
| 74 | data: DataStoreConnection, | ||
| 75 | query: String, | ||
| 76 | prefixes: Prefixes = new Prefixes(), | ||
| 77 | opts: JMap[String, String] = new JHashMap[String, String]() | ||
| 78 | ): Option[List[List[Resource]]] = | ||
| 79 | parseSelectQuery(query, prefixes).map(submitSelectQuery(data, _, opts)) | ||
| 80 | |||
| 74 | def queryInternalPredicate( | 81 | def queryInternalPredicate( |
| 75 | data: DataStoreConnection, | 82 | data: DataStoreConnection, |
| 76 | pred: String, | 83 | pred: String, |
| @@ -86,7 +93,7 @@ object RDFoxHelpers { | |||
| 86 | query ++= s" ?S rsa:${pred :: Nth(i)} ?X$i ." | 93 | query ++= s" ?S rsa:${pred :: Nth(i)} ?X$i ." |
| 87 | } | 94 | } |
| 88 | query ++= " }" | 95 | query ++= " }" |
| 89 | submitSelectQuery(data, query, RSA.Prefixes, opts) | 96 | submitQuery(data, query, RSA.Prefixes, opts).get |
| 90 | } | 97 | } |
| 91 | 98 | ||
| 92 | def closeConnection( | 99 | def closeConnection( |
