diff options
Diffstat (limited to 'src/main/scala/uk/ac/ox')
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( |