aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Igne <federico.igne@cs.ox.ac.uk>2021-04-02 11:09:41 +0100
committerFederico Igne <federico.igne@cs.ox.ac.uk>2021-04-02 11:09:41 +0100
commit9baa097349d6622870d60847893f76d9c6dc7f29 (patch)
treebcc68df463c007304154df601ce5fc304572f7b5
parent80dbaf650804182e0db9f8bdfc9ba884a3a8a846 (diff)
downloadRSAComb-9baa097349d6622870d60847893f76d9c6dc7f29.tar.gz
RSAComb-9baa097349d6622870d60847893f76d9c6dc7f29.zip
Fix minor issues with revised filtering program
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/filtering/RevisedFilteringProgram.scala174
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/util/RSA.scala3
2 files changed, 97 insertions, 80 deletions
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 b75bc81..3773423 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
@@ -3,6 +3,7 @@ package uk.ac.ox.cs.rsacomb.filtering
3//import scala.collection.JavaConverters._ 3//import scala.collection.JavaConverters._
4import tech.oxfordsemantic.jrdfox.logic.Datatype 4import tech.oxfordsemantic.jrdfox.logic.Datatype
5import tech.oxfordsemantic.jrdfox.logic.datalog.{ 5import tech.oxfordsemantic.jrdfox.logic.datalog.{
6 Atom,
6 FilterAtom, 7 FilterAtom,
7 Rule, 8 Rule,
8 TupleTableAtom, 9 TupleTableAtom,
@@ -20,6 +21,16 @@ import uk.ac.ox.cs.rsacomb.sparql.ConjunctiveQuery
20import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Forward, Backward} 21import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Forward, Backward}
21import uk.ac.ox.cs.rsacomb.util.{RSA, RDFoxUtil} 22import uk.ac.ox.cs.rsacomb.util.{RSA, RDFoxUtil}
22 23
24object RDFoxDSL {
25
26 import scala.collection.JavaConverters._
27
28 implicit class MyVariable(private val str: StringContext) extends AnyVal {
29 def v(args: Any*): Variable = Variable.create(s"${str.s(args: _*)}i")
30 }
31
32}
33
23/** Factory for [[uk.ac.ox.cs.rsacomb.FilteringProgram FilteringProgram]] */ 34/** Factory for [[uk.ac.ox.cs.rsacomb.FilteringProgram FilteringProgram]] */
24object RevisedFilteringProgram { 35object RevisedFilteringProgram {
25 36
@@ -29,6 +40,7 @@ object RevisedFilteringProgram {
29 */ 40 */
30 def apply(query: ConjunctiveQuery): RevisedFilteringProgram = 41 def apply(query: ConjunctiveQuery): RevisedFilteringProgram =
31 new RevisedFilteringProgram(query) 42 new RevisedFilteringProgram(query)
43
32} 44}
33 45
34/** Filtering Program generator 46/** Filtering Program generator
@@ -41,6 +53,8 @@ object RevisedFilteringProgram {
41class RevisedFilteringProgram(val query: ConjunctiveQuery) 53class RevisedFilteringProgram(val query: ConjunctiveQuery)
42 extends FilteringProgram { 54 extends FilteringProgram {
43 55
56 import RDFoxDSL._
57
44 /** Extends capabilities of 58 /** Extends capabilities of
45 * [[tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom TupleTableAtom]] 59 * [[tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom TupleTableAtom]]
46 */ 60 */
@@ -54,11 +68,15 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery)
54 68
55 /** Helpers */ 69 /** Helpers */
56 70
57 private def ?(name: String): Term = Variable.create(s"${name}i") 71 //private def v(name: String): Term = Variable.create(s"${name}i")
58 private def not(atom: TupleTableAtom): BodyFormula = Negation.create(atom) 72 private def not(atom: TupleTableAtom): BodyFormula = Negation.create(atom)
59 private def skolem(terms: List[Term]): TupleTableAtom =
60 TupleTableAtom.create(TupleTableName.SKOLEM, terms: _*)
61 73
74 private def named(x: Term): TupleTableAtom =
75 TupleTableAtom.rdf(x, IRI.RDF_TYPE, RSA.NAMED)
76 private def congruent(x: Term, y: Term): TupleTableAtom =
77 TupleTableAtom.rdf(x, RSA.CONGRUENT, y)
78 private def skolem(skolem: Term, terms: List[Term]): TupleTableAtom =
79 TupleTableAtom.create(TupleTableName.SKOLEM, (terms :+ skolem): _*)
62 private def QM(x: Term): TupleTableAtom = 80 private def QM(x: Term): TupleTableAtom =
63 TupleTableAtom.rdf(x, IRI.RDF_TYPE, RSA("QM")) 81 TupleTableAtom.rdf(x, IRI.RDF_TYPE, RSA("QM"))
64 private def FK(x: Term): TupleTableAtom = 82 private def FK(x: Term): TupleTableAtom =
@@ -91,8 +109,7 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery)
91 * predicate, this is not feasible, and the instances are instead 109 * predicate, this is not feasible, and the instances are instead
92 * generate in the filtering program using a logic rule. 110 * generate in the filtering program using a logic rule.
93 */ 111 */
94 val nis: Rule = 112 val nis: Rule = Rule.create(NI(v"X"), named(v"Y"), congruent(v"X", v"Y"))
95 Rule.create(NI(?("X")), RSA.Congruent(?("X"), ?("Y")), RSA.Named(?("Y")))
96 113
97 /** Collection of filtering program rules. */ 114 /** Collection of filtering program rules. */
98 val rules: List[Rule] = 115 val rules: List[Rule] =
@@ -105,10 +122,7 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery)
105 * @note corresponds to rule 1 in Table 3 in the paper. 122 * @note corresponds to rule 1 in Table 3 in the paper.
106 */ 123 */
107 val r1 = 124 val r1 =
108 Rule.create( 125 Rule.create(QM(v"K"), (query.atoms :+ skolem(v"K", variables)): _*)
109 QM(?("K")),
110 (query.atoms :+ skolem(variables :+ ?("K"))): _*
111 )
112 126
113 /** Initializes instances of `rsa:ID`. 127 /** Initializes instances of `rsa:ID`.
114 * 128 *
@@ -121,28 +135,28 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery)
121 val r3a = 135 val r3a =
122 for ((v, i) <- query.bounded.zipWithIndex) 136 for ((v, i) <- query.bounded.zipWithIndex)
123 yield Rule.create( 137 yield Rule.create(
124 ID(?("K"), ?("S")), 138 ID(v"K", v"S"),
125 QM(?("K")), 139 QM(v"K"),
126 skolem(variables :+ ?("K")), 140 skolem(v"K", variables),
127 not(NI(v)), 141 not(NI(v)),
128 skolem(variables :+ RSA(i) :+ RSA(i) :+ ?("S")) 142 skolem(v"S", variables :+ RSA(i) :+ RSA(i))
129 ) 143 )
130 val r3b = Rule.create( 144 val r3b = Rule.create(
131 ID(?("K"), ?("T")), 145 ID(v"K", v"T"),
132 ID(?("K"), ?("S")), 146 ID(v"K", v"S"),
133 skolem(variables :+ ?("U") :+ ?("V") :+ ?("S")), 147 skolem(v"S", variables :+ v"U" :+ v"V"),
134 skolem(variables :+ ?("V") :+ ?("U") :+ ?("T")) 148 skolem(v"T", variables :+ v"V" :+ v"U")
135 ) 149 )
136 val r3c = Rule.create( 150 val r3c = Rule.create(
137 ID(?("K1"), ?("Q")), 151 ID(v"K1", v"Q"),
138 QM(?("K1")), 152 QM(v"K1"),
139 ID(?("K2"), ?("S")), 153 ID(v"K2", v"S"),
140 FilterAtom.create(FunctionCall.equal(?("K1"), ?("K2"))), 154 FilterAtom.create(FunctionCall.equal(v"K1", v"K2")),
141 skolem(variables :+ ?("U") :+ ?("V") :+ ?("S")), 155 skolem(v"S", variables :+ v"U" :+ v"V"),
142 ID(?("K3"), ?("T")), 156 ID(v"K3", v"T"),
143 FilterAtom.create(FunctionCall.equal(?("K1"), ?("K3"))), 157 FilterAtom.create(FunctionCall.equal(v"K1", v"K3")),
144 skolem(variables :+ ?("V") :+ ?("W") :+ ?("T")), 158 skolem(v"T", variables :+ v"V" :+ v"W"),
145 skolem(variables :+ ?("U") :+ ?("W") :+ ?("Q")) 159 skolem(v"Q", variables :+ v"U" :+ v"W")
146 ) 160 )
147 161
148 /** Detects forks in the canonical model. 162 /** Detects forks in the canonical model.
@@ -157,9 +171,9 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery)
157 index2 = query.bounded indexOf (role2.getArguments get 2) 171 index2 = query.bounded indexOf (role2.getArguments get 2)
158 if index2 >= 0 172 if index2 >= 0
159 } yield Rule.create( 173 } yield Rule.create(
160 FK(?("K")), 174 FK(v"K"),
161 ID(?("K"), ?("S")), 175 ID(v"K", v"S"),
162 skolem(variables :+ RSA(index1) :+ RSA(index2) :+ ?("S")), 176 skolem(v"S", variables :+ RSA(index1) :+ RSA(index2)),
163 role1 << Forward, 177 role1 << Forward,
164 role2 << Forward, 178 role2 << Forward,
165 not(RSA.Congruent(role1.getArguments get 0, role2.getArguments get 0)) 179 not(RSA.Congruent(role1.getArguments get 0, role2.getArguments get 0))
@@ -172,9 +186,9 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery)
172 index2 = query.bounded indexOf (role2.getArguments get 0) 186 index2 = query.bounded indexOf (role2.getArguments get 0)
173 if index2 >= 0 187 if index2 >= 0
174 } yield Rule.create( 188 } yield Rule.create(
175 FK(?("K")), 189 FK(v"K"),
176 ID(?("K"), ?("S")), 190 ID(v"K", v"S"),
177 skolem(variables :+ RSA(index1) :+ RSA(index2) :+ ?("S")), 191 skolem(v"S", variables :+ RSA(index1) :+ RSA(index2)),
178 role1 << Forward, 192 role1 << Forward,
179 role2 << Backward, 193 role2 << Backward,
180 not(RSA.Congruent(role1.getArguments get 0, role2.getArguments get 2)) 194 not(RSA.Congruent(role1.getArguments get 0, role2.getArguments get 2))
@@ -187,9 +201,9 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery)
187 index2 = query.bounded indexOf (role2.getArguments get 0) 201 index2 = query.bounded indexOf (role2.getArguments get 0)
188 if index2 >= 0 202 if index2 >= 0
189 } yield Rule.create( 203 } yield Rule.create(
190 FK(?("K")), 204 FK(v"K"),
191 ID(?("K"), ?("S")), 205 ID(v"K", v"S"),
192 skolem(variables :+ RSA(index1) :+ RSA(index2) :+ ?("S")), 206 skolem(v"S", variables :+ RSA(index1) :+ RSA(index2)),
193 role1 << Backward, 207 role1 << Backward,
194 role2 << Backward, 208 role2 << Backward,
195 not(RSA.Congruent(role1.getArguments get 2, role2.getArguments get 2)) 209 not(RSA.Congruent(role1.getArguments get 2, role2.getArguments get 2))
@@ -211,23 +225,23 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery)
211 r2arg2 = role2.getArguments get 2 225 r2arg2 = role2.getArguments get 2
212 if query.bounded contains r2arg2 226 if query.bounded contains r2arg2
213 } yield Rule.create( 227 } yield Rule.create(
214 ID(?("K"), ?("T")), 228 ID(v"K", v"T"),
215 ID(?("K"), ?("S")), 229 ID(v"K", v"S"),
216 skolem( 230 skolem(
231 v"S",
217 variables :+ 232 variables :+
218 RSA(query.bounded indexOf r1arg2) :+ 233 RSA(query.bounded indexOf r1arg2) :+
219 RSA(query.bounded indexOf r2arg2) :+ 234 RSA(query.bounded indexOf r2arg2)
220 ?("S")
221 ), 235 ),
222 RSA.Congruent(r1arg0, r2arg0), 236 RSA.Congruent(r1arg0, r2arg0),
223 role1 << Forward, 237 role1 << Forward,
224 role2 << Forward, 238 role2 << Forward,
225 not(NI(r1arg0)), 239 not(NI(r1arg0)),
226 skolem( 240 skolem(
241 v"T",
227 variables :+ 242 variables :+
228 RSA(query.bounded indexOf r1arg0) :+ 243 RSA(query.bounded indexOf r1arg0) :+
229 RSA(query.bounded indexOf r2arg0) :+ 244 RSA(query.bounded indexOf r2arg0)
230 ?("T")
231 ) 245 )
232 ) 246 )
233 val r5b = for { 247 val r5b = for {
@@ -242,23 +256,23 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery)
242 r2arg2 = role2.getArguments get 2 256 r2arg2 = role2.getArguments get 2
243 if query.bounded contains r2arg2 257 if query.bounded contains r2arg2
244 } yield Rule.create( 258 } yield Rule.create(
245 ID(?("K"), ?("T")), 259 ID(v"K", v"T"),
246 ID(?("K"), ?("S")), 260 ID(v"K", v"S"),
247 skolem( 261 skolem(
262 v"S",
248 variables :+ 263 variables :+
249 RSA(query.bounded indexOf r1arg2) :+ 264 RSA(query.bounded indexOf r1arg2) :+
250 RSA(query.bounded indexOf r2arg0) :+ 265 RSA(query.bounded indexOf r2arg0)
251 ?("S")
252 ), 266 ),
253 RSA.Congruent(r1arg0, r2arg2), 267 RSA.Congruent(r1arg0, r2arg2),
254 role1 << Forward, 268 role1 << Forward,
255 role2 << Backward, 269 role2 << Backward,
256 not(RSA.NI(r1arg0)), 270 not(RSA.NI(r1arg0)),
257 skolem( 271 skolem(
272 v"T",
258 variables :+ 273 variables :+
259 RSA(query.bounded indexOf r1arg0) :+ 274 RSA(query.bounded indexOf r1arg0) :+
260 RSA(query.bounded indexOf r2arg2) :+ 275 RSA(query.bounded indexOf r2arg2)
261 ?("T")
262 ) 276 )
263 ) 277 )
264 val r5c = for { 278 val r5c = for {
@@ -273,23 +287,23 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery)
273 r2arg2 = role2.getArguments get 2 287 r2arg2 = role2.getArguments get 2
274 if query.bounded contains r2arg2 288 if query.bounded contains r2arg2
275 } yield Rule.create( 289 } yield Rule.create(
276 ID(?("K"), ?("T")), 290 ID(v"K", v"T"),
277 ID(?("K"), ?("S")), 291 ID(v"K", v"S"),
278 skolem( 292 skolem(
293 v"S",
279 variables :+ 294 variables :+
280 RSA(query.bounded indexOf r1arg0) :+ 295 RSA(query.bounded indexOf r1arg0) :+
281 RSA(query.bounded indexOf r2arg0) :+ 296 RSA(query.bounded indexOf r2arg0)
282 ?("S")
283 ), 297 ),
284 RSA.Congruent(r1arg2, r2arg2), 298 RSA.Congruent(r1arg2, r2arg2),
285 role1 << Backward, 299 role1 << Backward,
286 role2 << Backward, 300 role2 << Backward,
287 not(RSA.NI(r1arg2)), 301 not(RSA.NI(r1arg2)),
288 skolem( 302 skolem(
303 v"T",
289 variables :+ 304 variables :+
290 RSA(query.bounded indexOf r1arg2) :+ 305 RSA(query.bounded indexOf r1arg2) :+
291 RSA(query.bounded indexOf r2arg2) :+ 306 RSA(query.bounded indexOf r2arg2)
292 ?("T")
293 ) 307 )
294 ) 308 )
295 309
@@ -309,31 +323,31 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery)
309 if index2 >= 0 323 if index2 >= 0
310 suffix <- Seq(Forward, Backward) 324 suffix <- Seq(Forward, Backward)
311 } yield Rule.create( 325 } yield Rule.create(
312 AQ(suffix, ?("K1"), ?("Q")), 326 AQ(suffix, v"K1", v"Q"),
313 ID(?("K1"), ?("S")), 327 ID(v"K1", v"S"),
314 skolem(variables :+ RSA(index0) :+ ?("V") :+ ?("S")), 328 skolem(v"S", variables :+ RSA(index0) :+ v"V"),
315 ID(?("K2"), ?("T")), 329 ID(v"K2", v"T"),
316 FilterAtom.create(FunctionCall.equal(?("K1"), ?("K2"))), 330 FilterAtom.create(FunctionCall.equal(v"K1", v"K2")),
317 skolem(variables :+ RSA(index2) :+ ?("W") :+ ?("T")), 331 skolem(v"T", variables :+ RSA(index2) :+ v"W"),
318 role << suffix, 332 role << suffix,
319 skolem(variables :+ ?("V") :+ ?("W") :+ ?("Q")) 333 skolem(v"Q", variables :+ v"V" :+ v"W")
320 ) 334 )
321 val r7a = 335 val r7a =
322 for (suffix <- List(Forward, Backward)) 336 for (suffix <- List(Forward, Backward))
323 yield Rule.create( 337 yield Rule.create(
324 TQ(suffix, ?("K"), ?("S")), 338 TQ(suffix, v"K", v"S"),
325 AQ(suffix, ?("K"), ?("S")) 339 AQ(suffix, v"K", v"S")
326 ) 340 )
327 val r7b = 341 val r7b =
328 for (suffix <- List(Forward, Backward)) 342 for (suffix <- List(Forward, Backward))
329 yield Rule.create( 343 yield Rule.create(
330 TQ(suffix, ?("K1"), ?("Q")), 344 TQ(suffix, v"K1", v"Q"),
331 AQ(suffix, ?("K1"), ?("S")), 345 AQ(suffix, v"K1", v"S"),
332 skolem(variables :+ ?("U") :+ ?("V") :+ ?("S")), 346 skolem(v"S", variables :+ v"U" :+ v"V"),
333 TQ(suffix, ?("K2"), ?("T")), 347 TQ(suffix, v"K2", v"T"),
334 FilterAtom.create(FunctionCall.equal(?("K1"), ?("K2"))), 348 FilterAtom.create(FunctionCall.equal(v"K1", v"K2")),
335 skolem(variables :+ ?("V") :+ ?("W") :+ ?("T")), 349 skolem(v"T", variables :+ v"V" :+ v"W"),
336 skolem(variables :+ ?("U") :+ ?("W") :+ ?("Q")) 350 skolem(v"Q", variables :+ v"U" :+ v"W")
337 ) 351 )
338 352
339 /** Flag spurious answers. 353 /** Flag spurious answers.
@@ -343,21 +357,21 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery)
343 val r8a = 357 val r8a =
344 for (v <- query.answer) 358 for (v <- query.answer)
345 yield Rule.create( 359 yield Rule.create(
346 SP(?("K")), 360 SP(v"K"),
347 QM(?("K")), 361 QM(v"K"),
348 skolem(variables :+ ?("K")), 362 skolem(v"K", variables),
349 not(RSA.Named(v)) 363 not(RSA.Named(v))
350 ) 364 )
351 val r8b = Rule.create( 365 val r8b = Rule.create(
352 SP(?("K")), 366 SP(v"K"),
353 FK(?("K")) 367 FK(v"K")
354 ) 368 )
355 val r8c = 369 val r8c =
356 for (suffix <- List(Forward, Backward)) 370 for (suffix <- List(Forward, Backward))
357 yield Rule.create( 371 yield Rule.create(
358 SP(?("K")), 372 SP(v"K"),
359 TQ(suffix, ?("K"), ?("S")), 373 TQ(suffix, v"K", v"S"),
360 skolem(variables :+ ?("V") :+ ?("V") :+ ?("S")) 374 skolem(v"S", variables :+ v"V" :+ v"V")
361 ) 375 )
362 376
363 /** Determine answers to the query 377 /** Determine answers to the query
@@ -376,9 +390,9 @@ class RevisedFilteringProgram(val query: ConjunctiveQuery)
376 * @note corresponds to rule 9 in Table 3. 390 * @note corresponds to rule 9 in Table 3.
377 */ 391 */
378 val r9 = Rule.create( 392 val r9 = Rule.create(
379 Ans(?("K")), 393 Ans(v"K"),
380 QM(?("K")), 394 QM(v"K"),
381 not(SP(?("K"))) 395 not(SP(v"K"))
382 ) 396 )
383 397
384 (r1 :: r3a ::: r3b :: r3c :: r4a ::: r4b ::: r4c ::: r5a ::: r5b ::: r5c ::: r6 ::: r7b ::: r7a ::: r8a ::: r8b :: r8c ::: r9 :: List()) 398 (r1 :: r3a ::: r3b :: r3c :: r4a ::: r4b ::: r4c ::: r5a ::: r5b ::: r5c ::: r6 ::: r7b ::: r7a ::: r8a ::: r8b :: r8c ::: r9 :: List())
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 ee2fdc1..187c9a0 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
@@ -30,6 +30,9 @@ object RSA {
30 Prefixes.declarePrefix("rsa:", "http://www.cs.ox.ac.uk/isg/rsa/") 30 Prefixes.declarePrefix("rsa:", "http://www.cs.ox.ac.uk/isg/rsa/")
31 Prefixes.declarePrefix("owl:", "http://www.w3.org/2002/07/owl#") 31 Prefixes.declarePrefix("owl:", "http://www.w3.org/2002/07/owl#")
32 32
33 val CONGRUENT = RSA("congruent")
34 val NAMED = RSA("Named")
35
33 private def atom(name: IRI, vars: List[Term]): TupleTableAtom = 36 private def atom(name: IRI, vars: List[Term]): TupleTableAtom =
34 TupleTableAtom.create(TupleTableName.create(name.getIRI), vars: _*) 37 TupleTableAtom.create(TupleTableName.create(name.getIRI), vars: _*)
35 38