aboutsummaryrefslogtreecommitdiff
path: root/src/test/scala/uk/ac
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/scala/uk/ac')
-rw-r--r--src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala350
-rw-r--r--src/test/scala/uk/ac/ox/cs/rsacomb/SuiteAll.scala2
-rw-r--r--src/test/scala/uk/ac/ox/cs/rsacomb/converter/NormalizerSpec.scala72
-rw-r--r--src/test/scala/uk/ac/ox/cs/rsacomb/filtering/FilteringProgramSpecs.scala46
-rw-r--r--src/test/scala/uk/ac/ox/cs/rsacomb/functional/Functional.scala62
-rw-r--r--src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswerSpecs.scala186
-rw-r--r--src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuerySpec.scala180
7 files changed, 497 insertions, 401 deletions
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala
index abfe1ee..54fcf64 100644
--- a/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala
+++ b/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala
@@ -31,6 +31,8 @@ import tech.oxfordsemantic.jrdfox.logic.expression.Variable
31import scala.collection.JavaConverters._ 31import scala.collection.JavaConverters._
32 32
33import uk.ac.ox.cs.rsacomb.RSAOntology 33import uk.ac.ox.cs.rsacomb.RSAOntology
34import uk.ac.ox.cs.rsacomb.approximation.Lowerbound
35import uk.ac.ox.cs.rsacomb.ontology.Ontology
34import uk.ac.ox.cs.rsacomb.converter.{SkolemStrategy, NoSkolem} 36import uk.ac.ox.cs.rsacomb.converter.{SkolemStrategy, NoSkolem}
35import uk.ac.ox.cs.rsacomb.suffix.Empty 37import uk.ac.ox.cs.rsacomb.suffix.Empty
36import uk.ac.ox.cs.rsacomb.util.{RDFoxUtil, RSA} 38import uk.ac.ox.cs.rsacomb.util.{RDFoxUtil, RSA}
@@ -43,8 +45,8 @@ object Ontology1_CanonicalModelSpec {
43 def base(str: String): IRI = 45 def base(str: String): IRI =
44 IRI.create("http://example.com/rsa_example.owl#" + str) 46 IRI.create("http://example.com/rsa_example.owl#" + str)
45 47
46 val ontology_path: File = new File("examples/example1.ttl") 48 val ontology_path = os.pwd / "examples" / "example1.ttl"
47 val ontology = RSAOntology(ontology_path) 49 val ontology = Ontology(ontology_path, List()).approximate(new Lowerbound)
48 val program = ontology.canonicalModel 50 val program = ontology.canonicalModel
49 val converter = program.CanonicalModelConverter 51 val converter = program.CanonicalModelConverter
50 52
@@ -109,7 +111,7 @@ class Ontology1_CanonicalModelSpec
109 111
110 renderer.render(AsubClassOfD) should "be converted into a single Rule" in { 112 renderer.render(AsubClassOfD) should "be converted into a single Rule" in {
111 val term = Variable.create("X") 113 val term = Variable.create("X")
112 val unsafe = ontology.unsafeRoles 114 val unsafe = ontology.unsafe
113 val (facts, rules) = 115 val (facts, rules) =
114 converter.convert(AsubClassOfD, term, unsafe, NoSkolem, Empty) 116 converter.convert(AsubClassOfD, term, unsafe, NoSkolem, Empty)
115 facts shouldBe empty 117 facts shouldBe empty
@@ -119,7 +121,7 @@ class Ontology1_CanonicalModelSpec
119 // Role R // 121 // Role R //
120 122
121 renderer.render(roleR) should "be safe" in { 123 renderer.render(roleR) should "be safe" in {
122 ontology.unsafeRoles should not contain roleR 124 ontology.unsafe should not contain roleR
123 } 125 }
124 126
125 it should "have 3 elements in its conflict set" in { 127 it should "have 3 elements in its conflict set" in {
@@ -143,7 +145,7 @@ class Ontology1_CanonicalModelSpec
143 // Role S // 145 // Role S //
144 146
145 renderer.render(roleS) should "be safe" in { 147 renderer.render(roleS) should "be safe" in {
146 ontology.unsafeRoles should not contain roleS 148 ontology.unsafe should not contain roleS
147 } 149 }
148 150
149 it should "have 3 elements in its conflict set" in { 151 it should "have 3 elements in its conflict set" in {
@@ -169,14 +171,14 @@ class Ontology1_CanonicalModelSpec
169 // S⁻ 171 // S⁻
170 172
171 renderer.render(roleS_inv) should "be unsafe" in { 173 renderer.render(roleS_inv) should "be unsafe" in {
172 ontology.unsafeRoles should contain(roleS_inv) 174 ontology.unsafe should contain(roleS_inv)
173 } 175 }
174 176
175 renderer.render( 177 renderer.render(
176 AsomeValuesFromSiC 178 AsomeValuesFromSiC
177 ) should "produce 1 rule" ignore { 179 ) should "produce 1 rule" ignore {
178 val term = Variable.create("X") 180 val term = Variable.create("X")
179 val unsafe = ontology.unsafeRoles 181 val unsafe = ontology.unsafe
180 val (facts, rules) = 182 val (facts, rules) =
181 converter.convert(AsomeValuesFromSiC, term, unsafe, NoSkolem, Empty) 183 converter.convert(AsomeValuesFromSiC, term, unsafe, NoSkolem, Empty)
182 facts shouldBe empty 184 facts shouldBe empty
@@ -200,7 +202,7 @@ class Ontology1_CanonicalModelSpec
200 // Rule 2 provides 0 rules 202 // Rule 2 provides 0 rules
201 // Rule 3 provides 48 rule (split in 2) 203 // Rule 3 provides 48 rule (split in 2)
202 val term = Variable.create("X") 204 val term = Variable.create("X")
203 val unsafe = ontology.unsafeRoles 205 val unsafe = ontology.unsafe
204 val (facts, rules) = 206 val (facts, rules) =
205 converter.convert(DsomeValuesFromRB, term, unsafe, NoSkolem, Empty) 207 converter.convert(DsomeValuesFromRB, term, unsafe, NoSkolem, Empty)
206 facts should have length 48 208 facts should have length 48
@@ -225,7 +227,7 @@ class Ontology1_CanonicalModelSpec
225 // Rule 3 provides 32 rule (split in 2) 227 // Rule 3 provides 32 rule (split in 2)
226 // Then (1*2 + 32) + (0) + (32*2) = 98 228 // Then (1*2 + 32) + (0) + (32*2) = 98
227 val term = Variable.create("X") 229 val term = Variable.create("X")
228 val unsafe = ontology.unsafeRoles 230 val unsafe = ontology.unsafe
229 val (facts, rules) = 231 val (facts, rules) =
230 converter.convert(BsomeValuesFromSD, term, unsafe, NoSkolem, Empty) 232 converter.convert(BsomeValuesFromSD, term, unsafe, NoSkolem, Empty)
231 facts should have length 32 233 facts should have length 32
@@ -236,7 +238,7 @@ class Ontology1_CanonicalModelSpec
236 SsubPropertyOfT 238 SsubPropertyOfT
237 ) should "produce 3 rules" in { 239 ) should "produce 3 rules" in {
238 val term = Variable.create("X") 240 val term = Variable.create("X")
239 val unsafe = ontology.unsafeRoles 241 val unsafe = ontology.unsafe
240 val (facts, rules) = 242 val (facts, rules) =
241 converter.convert(SsubPropertyOfT, term, unsafe, NoSkolem, Empty) 243 converter.convert(SsubPropertyOfT, term, unsafe, NoSkolem, Empty)
242 facts shouldBe empty 244 facts shouldBe empty
@@ -245,167 +247,167 @@ class Ontology1_CanonicalModelSpec
245 247
246} 248}
247 249
248object Ontology2_CanonicalModelSpec { 250// object Ontology2_CanonicalModelSpec {
249 251
250 /* Renderer to display OWL Axioms with DL syntax*/ 252// /* Renderer to display OWL Axioms with DL syntax*/
251 val renderer = new DLSyntaxObjectRenderer() 253// val renderer = new DLSyntaxObjectRenderer()
252 254
253 def base(str: String): IRI = 255// def base(str: String): IRI =
254 IRI.create("http://example.com/rsa_example.owl#" + str) 256// IRI.create("http://example.com/rsa_example.owl#" + str)
255 257
256 val ontology_path: File = new File("examples/example2.owl") 258// val ontology_path: File = new File("examples/example2.owl")
257 val ontology = RSAOntology(ontology_path) 259// val ontology = Ontology(ontology_path, List()).approximate(new Lowerbound)
258 val program = ontology.canonicalModel 260// val program = ontology.canonicalModel
259 val converter = program.CanonicalModelConverter 261// val converter = program.CanonicalModelConverter
260 262
261 val roleR = new OWLObjectPropertyImpl(base("R")) 263// val roleR = new OWLObjectPropertyImpl(base("R"))
262 val roleS = new OWLObjectPropertyImpl(base("S")) 264// val roleS = new OWLObjectPropertyImpl(base("S"))
263 val roleT = new OWLObjectPropertyImpl(base("T")) 265// val roleT = new OWLObjectPropertyImpl(base("T"))
264 val roleP = new OWLObjectPropertyImpl(base("P")) 266// val roleP = new OWLObjectPropertyImpl(base("P"))
265 val roleR_inv = roleR.getInverseProperty() 267// val roleR_inv = roleR.getInverseProperty()
266 val roleS_inv = roleS.getInverseProperty() 268// val roleS_inv = roleS.getInverseProperty()
267 val roleT_inv = roleT.getInverseProperty() 269// val roleT_inv = roleT.getInverseProperty()
268 val roleP_inv = roleP.getInverseProperty() 270// val roleP_inv = roleP.getInverseProperty()
269 271
270 val AsomeValuesFromRB = new OWLSubClassOfAxiomImpl( 272// val AsomeValuesFromRB = new OWLSubClassOfAxiomImpl(
271 new OWLClassImpl(base("A")), 273// new OWLClassImpl(base("A")),
272 new OWLObjectSomeValuesFromImpl( 274// new OWLObjectSomeValuesFromImpl(
273 roleR, 275// roleR,
274 new OWLClassImpl(base("B")) 276// new OWLClassImpl(base("B"))
275 ), 277// ),
276 Seq().asJava 278// Seq().asJava
277 ) 279// )
278 280
279 val BsomeValuesFromSC = new OWLSubClassOfAxiomImpl( 281// val BsomeValuesFromSC = new OWLSubClassOfAxiomImpl(
280 new OWLClassImpl(base("B")), 282// new OWLClassImpl(base("B")),
281 new OWLObjectSomeValuesFromImpl( 283// new OWLObjectSomeValuesFromImpl(
282 roleS, 284// roleS,
283 new OWLClassImpl(base("C")) 285// new OWLClassImpl(base("C"))
284 ), 286// ),
285 Seq().asJava 287// Seq().asJava
286 ) 288// )
287 289
288 val CsomeValuesFromTD = new OWLSubClassOfAxiomImpl( 290// val CsomeValuesFromTD = new OWLSubClassOfAxiomImpl(
289 new OWLClassImpl(base("C")), 291// new OWLClassImpl(base("C")),
290 new OWLObjectSomeValuesFromImpl( 292// new OWLObjectSomeValuesFromImpl(
291 roleT, 293// roleT,
292 new OWLClassImpl(base("D")) 294// new OWLClassImpl(base("D"))
293 ), 295// ),
294 Seq().asJava 296// Seq().asJava
295 ) 297// )
296 298
297 val DsomeValuesFromPA = new OWLSubClassOfAxiomImpl( 299// val DsomeValuesFromPA = new OWLSubClassOfAxiomImpl(
298 new OWLClassImpl(base("D")), 300// new OWLClassImpl(base("D")),
299 new OWLObjectSomeValuesFromImpl( 301// new OWLObjectSomeValuesFromImpl(
300 roleP, 302// roleP,
301 new OWLClassImpl(base("A")) 303// new OWLClassImpl(base("A"))
302 ), 304// ),
303 Seq().asJava 305// Seq().asJava
304 ) 306// )
305 307
306} 308// }
307 309
308class Ontology2_CanonicalModelSpec 310// class Ontology2_CanonicalModelSpec
309 extends AnyFlatSpec 311// extends AnyFlatSpec
310 with Matchers 312// with Matchers
311 with LoneElement { 313// with LoneElement {
312 314
313 import Ontology2_CanonicalModelSpec._ 315// import Ontology2_CanonicalModelSpec._
314 316
315 "The program generated from Example #1" should "not be empty" in { 317// "The program generated from Example #1" should "not be empty" in {
316 program.rules should not be empty 318// program.rules should not be empty
317 } 319// }
318 320
319 // Role R // 321// // Role R //
320 322
321 renderer.render(roleR) should "be unsafe" in { 323// renderer.render(roleR) should "be unsafe" in {
322 ontology.unsafeRoles should contain(roleR) 324// ontology.unsafe should contain(roleR)
323 } 325// }
324 326
325 it should "have only its inverse in its conflict set" in { 327// it should "have only its inverse in its conflict set" in {
326 ontology.confl(roleR).loneElement shouldBe roleR_inv 328// ontology.confl(roleR).loneElement shouldBe roleR_inv
327 } 329// }
328 330
329 // Role S // 331// // Role S //
330 332
331 renderer.render(roleS) should "be unsafe" in { 333// renderer.render(roleS) should "be unsafe" in {
332 ontology.unsafeRoles should contain(roleS) 334// ontology.unsafe should contain(roleS)
333 } 335// }
334 336
335 it should "have only its inverse in its conflict set" in { 337// it should "have only its inverse in its conflict set" in {
336 ontology.confl(roleS).loneElement shouldBe roleS_inv 338// ontology.confl(roleS).loneElement shouldBe roleS_inv
337 } 339// }
338 340
339 // Role T // 341// // Role T //
340 342
341 renderer.render(roleT) should "be unsafe" in { 343// renderer.render(roleT) should "be unsafe" in {
342 ontology.unsafeRoles should contain(roleT) 344// ontology.unsafe should contain(roleT)
343 } 345// }
344 346
345 it should "have only its inverse in its conflict set" in { 347// it should "have only its inverse in its conflict set" in {
346 ontology.confl(roleT).loneElement shouldBe roleT_inv 348// ontology.confl(roleT).loneElement shouldBe roleT_inv
347 } 349// }
348 350
349 // Role P // 351// // Role P //
350 352
351 renderer.render(roleP) should "be unsafe" in { 353// renderer.render(roleP) should "be unsafe" in {
352 ontology.unsafeRoles should contain(roleP) 354// ontology.unsafe should contain(roleP)
353 } 355// }
354 356
355 it should "have only its inverse in its conflict set" in { 357// it should "have only its inverse in its conflict set" in {
356 ontology.confl(roleP).loneElement shouldBe roleP_inv 358// ontology.confl(roleP).loneElement shouldBe roleP_inv
357 } 359// }
358 360
359 // A ⊑ ∃ R.B 361// // A ⊑ ∃ R.B
360 362
361 renderer.render( 363// renderer.render(
362 AsomeValuesFromRB 364// AsomeValuesFromRB
363 ) should "produce 1 rule" in { 365// ) should "produce 1 rule" in {
364 val term = Variable.create("X") 366// val term = Variable.create("X")
365 val unsafe = ontology.unsafeRoles 367// val unsafe = ontology.unsafe
366 val (facts, rules) = 368// val (facts, rules) =
367 converter.convert(AsomeValuesFromRB, term, unsafe, NoSkolem, Empty) 369// converter.convert(AsomeValuesFromRB, term, unsafe, NoSkolem, Empty)
368 facts shouldBe empty 370// facts shouldBe empty
369 rules should have length 1 371// rules should have length 1
370 } 372// }
371 373
372 // B ⊑ ∃ S.C 374// // B ⊑ ∃ S.C
373 375
374 renderer.render( 376// renderer.render(
375 BsomeValuesFromSC 377// BsomeValuesFromSC
376 ) should "produce 1 rule" in { 378// ) should "produce 1 rule" in {
377 val term = Variable.create("X") 379// val term = Variable.create("X")
378 val unsafe = ontology.unsafeRoles 380// val unsafe = ontology.unsafe
379 val (facts, rules) = 381// val (facts, rules) =
380 converter.convert(BsomeValuesFromSC, term, unsafe, NoSkolem, Empty) 382// converter.convert(BsomeValuesFromSC, term, unsafe, NoSkolem, Empty)
381 facts shouldBe empty 383// facts shouldBe empty
382 rules should have length 1 384// rules should have length 1
383 } 385// }
384 386
385 // C ⊑ ∃ T.D 387// // C ⊑ ∃ T.D
386 388
387 renderer.render( 389// renderer.render(
388 CsomeValuesFromTD 390// CsomeValuesFromTD
389 ) should "produce 1 rule" in { 391// ) should "produce 1 rule" in {
390 val term = Variable.create("X") 392// val term = Variable.create("X")
391 val unsafe = ontology.unsafeRoles 393// val unsafe = ontology.unsafe
392 val (facts, rules) = 394// val (facts, rules) =
393 converter.convert(CsomeValuesFromTD, term, unsafe, NoSkolem, Empty) 395// converter.convert(CsomeValuesFromTD, term, unsafe, NoSkolem, Empty)
394 facts shouldBe empty 396// facts shouldBe empty
395 rules should have length 1 397// rules should have length 1
396 } 398// }
397 399
398 // D ⊑ ∃ P.A 400// // D ⊑ ∃ P.A
399 401
400 renderer.render( 402// renderer.render(
401 DsomeValuesFromPA 403// DsomeValuesFromPA
402 ) should "produce 1 rule" in { 404// ) should "produce 1 rule" in {
403 val term = Variable.create("X") 405// val term = Variable.create("X")
404 val unsafe = ontology.unsafeRoles 406// val unsafe = ontology.unsafe
405 val (facts, rules) = 407// val (facts, rules) =
406 converter.convert(DsomeValuesFromPA, term, unsafe, NoSkolem, Empty) 408// converter.convert(DsomeValuesFromPA, term, unsafe, NoSkolem, Empty)
407 facts shouldBe empty 409// facts shouldBe empty
408 rules should have length 1 410// rules should have length 1
409 } 411// }
410 412
411} 413// }
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/SuiteAll.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/SuiteAll.scala
index 1df0757..9653546 100644
--- a/src/test/scala/uk/ac/ox/cs/rsacomb/SuiteAll.scala
+++ b/src/test/scala/uk/ac/ox/cs/rsacomb/SuiteAll.scala
@@ -32,7 +32,7 @@ import uk.ac.ox.cs.rsacomb.sparql.{
32class SuiteAll 32class SuiteAll
33 extends Suites( 33 extends Suites(
34 new Ontology1_CanonicalModelSpec, 34 new Ontology1_CanonicalModelSpec,
35 new Ontology2_CanonicalModelSpec, 35 //new Ontology2_CanonicalModelSpec,
36 new NaiveFilteringProgramSpec, 36 new NaiveFilteringProgramSpec,
37 new OWLAxiomSpec, 37 new OWLAxiomSpec,
38 new OWLClassSpec, 38 new OWLClassSpec,
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/converter/NormalizerSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/converter/NormalizerSpec.scala
index 7285df2..5047e12 100644
--- a/src/test/scala/uk/ac/ox/cs/rsacomb/converter/NormalizerSpec.scala
+++ b/src/test/scala/uk/ac/ox/cs/rsacomb/converter/NormalizerSpec.scala
@@ -27,6 +27,7 @@ import tech.oxfordsemantic.jrdfox.logic.expression.{Variable, IRI}
27import uk.ac.ox.cs.rsacomb.converter.RDFoxConverter 27import uk.ac.ox.cs.rsacomb.converter.RDFoxConverter
28import uk.ac.ox.cs.rsacomb.suffix.{Empty, Forward, Backward, Inverse} 28import uk.ac.ox.cs.rsacomb.suffix.{Empty, Forward, Backward, Inverse}
29import uk.ac.ox.cs.rsacomb.converter.{Normalizer, SkolemStrategy, NoSkolem} 29import uk.ac.ox.cs.rsacomb.converter.{Normalizer, SkolemStrategy, NoSkolem}
30import uk.ac.ox.cs.rsacomb.util.DataFactory
30 31
31object NormalizerSpec { 32object NormalizerSpec {
32 val manager = OWLManager.createOWLOntologyManager() 33 val manager = OWLManager.createOWLOntologyManager()
@@ -89,27 +90,58 @@ class NormalizerSpec extends AnyFlatSpec with Matchers with LoneElement {
89 ).flatMap(normalizer.normalize) 90 ).flatMap(normalizer.normalize)
90 } 91 }
91 92
92 "Disjunction on the rhs" should "be shifted" in { 93 "A c \\exists R . D" should "be normalised to { A c \\exists R . C, C c D } if D is not a concept name" in {
93 def cls(n: Int) = factory.getOWLClass(s"_:class$n") 94 val seed = 42
94 val axiom1 = 95 val test = normalizer.normalize(
95 factory.getOWLSubClassOfAxiom( 96 factory
96 factory.getOWLObjectIntersectionOf(cls(1), cls(2), cls(3)), 97 .getOWLSubClassOfAxiom(
97 factory.getOWLObjectUnionOf(cls(4), cls(5)) 98 factory.getOWLClass("A"),
98 ) 99 factory.getOWLObjectSomeValuesFrom(
99 val axiom2 = 100 factory.getOWLObjectProperty("R"),
100 factory.getOWLSubClassOfAxiom( 101 factory.getOWLObjectIntersectionOf(
101 cls(1), 102 factory.getOWLClass("D1"),
102 factory.getOWLObjectUnionOf(cls(2), cls(3), cls(4)) 103 factory.getOWLClass("D2")
103 ) 104 )
104 val axiom3 = 105 )
105 factory.getOWLSubClassOfAxiom( 106 )
106 factory.getOWLObjectIntersectionOf(cls(1), cls(2), cls(3)), 107 )(DataFactory(seed))
107 factory.getOWLObjectUnionOf(cls(4)) 108 val cls = DataFactory(seed).getOWLClass
108 ) 109 val result = List(
109 normalizer.normalize(axiom1) should have length 5 110 factory
110 normalizer.normalize(axiom2) should have length 5 111 .getOWLSubClassOfAxiom(
111 normalizer.normalize(axiom3) should have length 4 112 factory.getOWLClass("A"),
113 factory.getOWLObjectSomeValuesFrom(
114 factory.getOWLObjectProperty("R"),
115 cls
116 )
117 ),
118 factory.getOWLSubClassOfAxiom(cls, factory.getOWLClass("D1")),
119 factory.getOWLSubClassOfAxiom(cls, factory.getOWLClass("D2"))
120 )
121 test should contain theSameElementsAs result
112 } 122 }
123
124 // "Disjunction on the rhs" should "be shifted" in {
125 // def cls(n: Int) = factory.getOWLClass(s"_:class$n")
126 // val axiom1 =
127 // factory.getOWLSubClassOfAxiom(
128 // factory.getOWLObjectIntersectionOf(cls(1), cls(2), cls(3)),
129 // factory.getOWLObjectUnionOf(cls(4), cls(5))
130 // )
131 // val axiom2 =
132 // factory.getOWLSubClassOfAxiom(
133 // cls(1),
134 // factory.getOWLObjectUnionOf(cls(2), cls(3), cls(4))
135 // )
136 // val axiom3 =
137 // factory.getOWLSubClassOfAxiom(
138 // factory.getOWLObjectIntersectionOf(cls(1), cls(2), cls(3)),
139 // factory.getOWLObjectUnionOf(cls(4))
140 // )
141 // normalizer.normalize(axiom1) should have length 5
142 // normalizer.normalize(axiom2) should have length 5
143 // normalizer.normalize(axiom3) should have length 4
144 // }
113 //"A class name" should "be converted into a single atom" in { 145 //"A class name" should "be converted into a single atom" in {
114 // val cls = factory.getOWLClass(iriString0) 146 // val cls = factory.getOWLClass(iriString0)
115 // val atom = TupleTableAtom.rdf(term0, IRI.RDF_TYPE, IRI.create(iriString0)) 147 // val atom = TupleTableAtom.rdf(term0, IRI.RDF_TYPE, IRI.create(iriString0))
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/filtering/FilteringProgramSpecs.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/filtering/FilteringProgramSpecs.scala
index c0cd046..1bace1b 100644
--- a/src/test/scala/uk/ac/ox/cs/rsacomb/filtering/FilteringProgramSpecs.scala
+++ b/src/test/scala/uk/ac/ox/cs/rsacomb/filtering/FilteringProgramSpecs.scala
@@ -83,28 +83,28 @@ class NaiveFilteringProgramSpec extends AnyFlatSpec with Matchers {
83 83
84 import NaiveFilteringProgramSpec._ 84 import NaiveFilteringProgramSpec._
85 85
86 "CQ 0" should "generate 27 rules and 3 facts" in { 86 // "CQ 0" should "generate 27 rules and 3 facts" in {
87 val cq = ConjunctiveQuery.parse(cq0).get 87 // val cq = ConjunctiveQuery.parse(cq0).get
88 val filter = FilteringProgram(naive)(cq) 88 // val filter = FilteringProgram(naive)(cq)
89 filter.rules should have length 27 89 // filter.rules should have length 27
90 } 90 // }
91 91
92 "CQ 1" should "generate 15 rules" in { 92 // "CQ 1" should "generate 15 rules" in {
93 val cq = ConjunctiveQuery.parse(cq1).get 93 // val cq = ConjunctiveQuery.parse(cq1).get
94 val filter = FilteringProgram(naive)(cq) 94 // val filter = FilteringProgram(naive)(cq)
95 filter.rules should have length 15 95 // filter.rules should have length 15
96 } 96 // }
97 97
98 "CQ 2" should "generate 51 rules" in { 98 // "CQ 2" should "generate 51 rules" in {
99 val cq = ConjunctiveQuery.parse(cq2).get 99 // val cq = ConjunctiveQuery.parse(cq2).get
100 val filter = FilteringProgram(naive)(cq) 100 // val filter = FilteringProgram(naive)(cq)
101 filter.rules should have length 51 101 // filter.rules should have length 51
102 } 102 // }
103 103
104 "BCQ 0" should "generate 46 rules" in { 104 // "BCQ 0" should "generate 46 rules" in {
105 val cq = ConjunctiveQuery.parse(bcq0).get 105 // val cq = ConjunctiveQuery.parse(bcq0).get
106 val filter = FilteringProgram(naive)(cq) 106 // val filter = FilteringProgram(naive)(cq)
107 filter.rules should have length 43 107 // filter.rules should have length 43
108 } 108 // }
109 109
110} 110}
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/functional/Functional.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/functional/Functional.scala
new file mode 100644
index 0000000..abede60
--- /dev/null
+++ b/src/test/scala/uk/ac/ox/cs/rsacomb/functional/Functional.scala
@@ -0,0 +1,62 @@
1package uk.ac.ox.cs.rsacomb.functional
2
3import org.scalatest.funspec.AnyFunSpec
4import org.scalatest.matchers.should.Matchers
5import org.scalatest.tagobjects.Slow
6
7import uk.ac.ox.cs.rsacomb.ontology.Ontology
8import uk.ac.ox.cs.rsacomb.approximation.Upperbound
9import uk.ac.ox.cs.rsacomb.converter.Normalizer
10import uk.ac.ox.cs.rsacomb.util.RDFoxUtil
11
12class LUBM extends AnyFunSpec with Matchers {
13
14 private val test = os.pwd / "tests" / "lubm"
15
16 /* Approximation algorithms */
17 //private val toLowerbound = new Lowerbound
18 private val toUpperbound = new Upperbound
19
20 /* Normalization algorithms */
21 private val normalizer = new Normalizer
22
23 /* Ontology */
24 private val ontology = Ontology(
25 test / "univ-bench.owl",
26 List(test / "data" / "lubm1.ttl")
27 ) normalize normalizer
28 private val rsa = ontology approximate toUpperbound
29
30 /* Queries and results */
31 private val results = ujson.read(os.read(test / "results.json")).arr
32
33 describe("Ontology size: 1)") {
34
35 val queries = RDFoxUtil.loadQueriesFromFile(test / "queries.sparql")
36 queries foreach { query =>
37 it(s"Tested Query${query.id}") {
38 val answers = rsa.ask(query).answers.map(_._2.mkString("\t"))
39 val reference = results
40 .find(_("queryID").num == query.id)
41 .get("answers")
42 .arr
43 .map(_.str)
44 answers should contain theSameElementsAs reference
45 }
46 }
47
48 val slow = RDFoxUtil.loadQueriesFromFile(test / "queries-slow.sparql")
49 slow foreach { query =>
50 it(s"Tested Query${query.id}", Slow) {
51 val answers = rsa.ask(query).answers.map(_._2.mkString("\t"))
52 val reference = results
53 .find(_("queryID").num == query.id)
54 .get("answers")
55 .arr
56 .map(_.str)
57 answers should contain theSameElementsAs reference
58 }
59 }
60
61 }
62}
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswerSpecs.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswerSpecs.scala
index 3a01c8d..b24b1d2 100644
--- a/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswerSpecs.scala
+++ b/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswerSpecs.scala
@@ -29,103 +29,103 @@ object ConjunctiveQueryAnswerSpec {
29 val iri2 = IRI.create("_:iri2") 29 val iri2 = IRI.create("_:iri2")
30 val iri3 = IRI.create("_:iri3") 30 val iri3 = IRI.create("_:iri3")
31 31
32 val oneAnswer = new ConjunctiveQueryAnswers( 32 // val oneAnswer = new ConjunctiveQueryAnswers(
33 false, 33 // false,
34 Seq(varX, varY, varZ), 34 // Seq(varX, varY, varZ),
35 Seq((4, Seq(iri1, iri2, iri3))) 35 // Seq((4, Seq(iri1, iri2, iri3)))
36 ) 36 // )
37 val multipleAnswers = 37 // val multipleAnswers =
38 new ConjunctiveQueryAnswers( 38 // new ConjunctiveQueryAnswers(
39 false, 39 // false,
40 Seq(varY, varZ), 40 // Seq(varY, varZ),
41 Seq((1, Seq(iri1, iri1)), (2, Seq(iri1, iri2)), (1, Seq(iri1, iri3))) 41 // Seq((1, Seq(iri1, iri1)), (2, Seq(iri1, iri2)), (1, Seq(iri1, iri3)))
42 ) 42 // )
43 val noAnswer = new ConjunctiveQueryAnswers(false, Seq(), Seq()) 43 // val noAnswer = new ConjunctiveQueryAnswers(false, Seq(), Seq())
44 val emptyAnswer = 44 // val emptyAnswer =
45 new ConjunctiveQueryAnswers(false, Seq(varX, varY), Seq((3, Seq()))) 45 // new ConjunctiveQueryAnswers(false, Seq(varX, varY), Seq((3, Seq())))
46 46
47 val falseAnswer = new ConjunctiveQueryAnswers(true, Seq(), Seq()) 47 // val falseAnswer = new ConjunctiveQueryAnswers(true, Seq(), Seq())
48 val trueAnswer1 = new ConjunctiveQueryAnswers(true, Seq(), Seq((1, Seq()))) 48 // val trueAnswer1 = new ConjunctiveQueryAnswers(true, Seq(), Seq((1, Seq())))
49 val trueAnswer2 = 49 // val trueAnswer2 =
50 new ConjunctiveQueryAnswers( 50 // new ConjunctiveQueryAnswers(
51 true, 51 // true,
52 Seq(varX, varY), 52 // Seq(varX, varY),
53 Seq((5, Seq(iri1, iri1)), (2, Seq(iri1, iri2)), (1, Seq(iri1, iri3))) 53 // Seq((5, Seq(iri1, iri1)), (2, Seq(iri1, iri2)), (1, Seq(iri1, iri3)))
54 ) 54 // )
55} 55}
56 56
57class ConjunctiveQueryAnswerSpec extends AnyFlatSpec with Matchers { 57class ConjunctiveQueryAnswerSpec extends AnyFlatSpec with Matchers {
58 58
59 import ConjunctiveQueryAnswerSpec._ 59 import ConjunctiveQueryAnswerSpec._
60 60
61 "Test answer 1" should "have length 1 (4 with multiplicity)" in { 61 // "Test answer 1" should "have length 1 (4 with multiplicity)" in {
62 oneAnswer should have( 62 // oneAnswer should have(
63 'length (1), 63 // 'length (1),
64 'lengthWithMultiplicity (4) 64 // 'lengthWithMultiplicity (4)
65 ) 65 // )
66 } 66 // }
67 "Test answer 2" should "have length 3 (4 with multiplicity)" in { 67 // "Test answer 2" should "have length 3 (4 with multiplicity)" in {
68 multipleAnswers should have( 68 // multipleAnswers should have(
69 'length (3), 69 // 'length (3),
70 'lengthWithMultiplicity (4) 70 // 'lengthWithMultiplicity (4)
71 ) 71 // )
72 } 72 // }
73 "Test answer 3" should "have length 0 (0 with multiplicity)" in { 73 // "Test answer 3" should "have length 0 (0 with multiplicity)" in {
74 noAnswer should have( 74 // noAnswer should have(
75 'length (0), 75 // 'length (0),
76 'lengthWithMultiplicity (0) 76 // 'lengthWithMultiplicity (0)
77 ) 77 // )
78 } 78 // }
79 "Test answer 4" should "have length 1 (3 with multiplicity)" in { 79 // "Test answer 4" should "have length 1 (3 with multiplicity)" in {
80 emptyAnswer should have( 80 // emptyAnswer should have(
81 'length (1), 81 // 'length (1),
82 'lengthWithMultiplicity (3) 82 // 'lengthWithMultiplicity (3)
83 ) 83 // )
84 } 84 // }
85 "Test boolean answer 1" should "have length 0 (0 with multiplicity)" in { 85 // "Test boolean answer 1" should "have length 0 (0 with multiplicity)" in {
86 falseAnswer should have( 86 // falseAnswer should have(
87 'length (0), 87 // 'length (0),
88 'lengthWithMultiplicity (0) 88 // 'lengthWithMultiplicity (0)
89 ) 89 // )
90 } 90 // }
91 "Test boolean answer 2" should "have length 1 (1 with multiplicity)" in { 91 // "Test boolean answer 2" should "have length 1 (1 with multiplicity)" in {
92 trueAnswer1 should have( 92 // trueAnswer1 should have(
93 'length (0), 93 // 'length (0),
94 'lengthWithMultiplicity (1) 94 // 'lengthWithMultiplicity (1)
95 ) 95 // )
96 } 96 // }
97 "Test boolean answer 3" should "have length 3 (8 with multiplicity)" in { 97 // "Test boolean answer 3" should "have length 3 (8 with multiplicity)" in {
98 trueAnswer2 should have( 98 // trueAnswer2 should have(
99 'length (0), 99 // 'length (0),
100 'lengthWithMultiplicity (8) 100 // 'lengthWithMultiplicity (8)
101 ) 101 // )
102 } 102 // }
103 103
104 "A conjunctive query" should "print an header and a single line if it has a single answer" in { 104 // "A conjunctive query" should "print an header and a single line if it has a single answer" in {
105 oneAnswer.toString shouldBe s"X\tY\tZ\n${iri1.getIRI}\t${iri2.getIRI}\t${iri3.getIRI}" 105 // oneAnswer.toString shouldBe s"X\tY\tZ\n${iri1.getIRI}\t${iri2.getIRI}\t${iri3.getIRI}"
106 } 106 // }
107 107
108 it should "print a header and multiple answers on multiple lines" in { 108 // it should "print a header and multiple answers on multiple lines" in {
109 multipleAnswers.toString shouldBe s"Y\tZ\n${iri1.getIRI}\t${iri1.getIRI}\n${iri1.getIRI}\t${iri2.getIRI}\n${iri1.getIRI}\t${iri3.getIRI}" 109 // multipleAnswers.toString shouldBe s"Y\tZ\n${iri1.getIRI}\t${iri1.getIRI}\n${iri1.getIRI}\t${iri2.getIRI}\n${iri1.getIRI}\t${iri3.getIRI}"
110 } 110 // }
111 111
112 it should "print a special \"NO ANSWER.\" string when it has no answer" in { 112 // it should "print a special \"NO ANSWER.\" string when it has no answer" in {
113 noAnswer.toString shouldBe "NO ANSWER." 113 // noAnswer.toString shouldBe "NO ANSWER."
114 } 114 // }
115 115
116 it should "print only the header when it has an empty answer" in { 116 // it should "print only the header when it has an empty answer" in {
117 emptyAnswer.toString shouldBe "X\tY\n" 117 // emptyAnswer.toString shouldBe "X\tY\n"
118 } 118 // }
119 119
120 "A boolean conjunctive query" should "print \"FALSE\" when it has no answer" in { 120 // "A boolean conjunctive query" should "print \"FALSE\" when it has no answer" in {
121 falseAnswer.toString shouldBe "FALSE" 121 // falseAnswer.toString shouldBe "FALSE"
122 } 122 // }
123 123
124 it should "print \"TRUE\" when it has a single empty answer" in { 124 // it should "print \"TRUE\" when it has a single empty answer" in {
125 trueAnswer1.toString shouldBe "TRUE" 125 // trueAnswer1.toString shouldBe "TRUE"
126 } 126 // }
127 127
128 it should "print \"TRUE\" when it has a non-empty collection of answers" in { 128 // it should "print \"TRUE\" when it has a non-empty collection of answers" in {
129 trueAnswer2.toString shouldBe "TRUE" 129 // trueAnswer2.toString shouldBe "TRUE"
130 } 130 //}
131} 131}
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuerySpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuerySpec.scala
index efb94b9..5d87d63 100644
--- a/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuerySpec.scala
+++ b/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuerySpec.scala
@@ -157,95 +157,95 @@ class ConjunctiveQuerySpec
157 157
158 import ConjunctiveQuerySpec._ 158 import ConjunctiveQuerySpec._
159 159
160 "A conjunctive query" should "result in a `ConjunctiveQuery` instance" in { 160 // "A conjunctive query" should "result in a `ConjunctiveQuery` instance" in {
161 ConjunctiveQuery.parse(cq0) shouldBe defined 161 // ConjunctiveQuery.parse(cq0) shouldBe defined
162 } 162 // }
163 163
164 "A boolean conjunctive query" should "result in a `ConjunctiveQuery` instance" in { 164 // "A boolean conjunctive query" should "result in a `ConjunctiveQuery` instance" in {
165 ConjunctiveQuery.parse(bcq0) shouldBe defined 165 // ConjunctiveQuery.parse(bcq0) shouldBe defined
166 } 166 // }
167 167
168 "A query with proper SELECT defined" should "not be a BCQ" in { 168 // "A query with proper SELECT defined" should "not be a BCQ" in {
169 ConjunctiveQuery.parse(cq0).value should not be 'bcq 169 // ConjunctiveQuery.parse(cq0).value should not be 'bcq
170 } 170 // }
171 171
172 "A query with a \"*\" SELECT" should "not be a BCQ" in { 172 // "A query with a \"*\" SELECT" should "not be a BCQ" in {
173 ConjunctiveQuery.parse(cq1).value should not be 'bcq 173 // ConjunctiveQuery.parse(cq1).value should not be 'bcq
174 } 174 // }
175 175
176 "An ASK query" should "not be a BCQ" in { 176 // "An ASK query" should "not be a BCQ" in {
177 ConjunctiveQuery.parse(bcq0).value shouldBe 'bcq 177 // ConjunctiveQuery.parse(bcq0).value shouldBe 'bcq
178 } 178 // }
179 179
180 "Queries" should "have distinct answer and bounded variables" in { 180 // "Queries" should "have distinct answer and bounded variables" in {
181 for (q <- queries) { 181 // for (q <- queries) {
182 val cq = ConjunctiveQuery.parse(q) 182 // val cq = ConjunctiveQuery.parse(q)
183 forAll(cq.value.answer) { v => cq.value.bounded should not contain v } 183 // forAll(cq.value.answer) { v => cq.value.bounded should not contain v }
184 forAll(cq.value.bounded) { v => cq.value.answer should not contain v } 184 // forAll(cq.value.bounded) { v => cq.value.answer should not contain v }
185 } 185 // }
186 } 186 // }
187 187
188 "CQ0" should "have {?obj, ?pred} as bounded variables" in { 188 // "CQ0" should "have {?obj, ?pred} as bounded variables" in {
189 ConjunctiveQuery.parse(cq0).value.bounded should contain theSameElementsAs 189 // ConjunctiveQuery.parse(cq0).value.bounded should contain theSameElementsAs
190 List( 190 // List(
191 Variable.create("Y"), 191 // Variable.create("Y"),
192 Variable.create("Z") 192 // Variable.create("Z")
193 ) 193 // )
194 } 194 // }
195 195
196 "CQ1" should "have no bounded variable" in { 196 // "CQ1" should "have no bounded variable" in {
197 ConjunctiveQuery.parse(cq1).value.bounded shouldBe empty 197 // ConjunctiveQuery.parse(cq1).value.bounded shouldBe empty
198 } 198 // }
199 199
200 "CQ2" should "have no bounded variable" in { 200 // "CQ2" should "have no bounded variable" in {
201 ConjunctiveQuery.parse(cq2).value.bounded shouldBe empty 201 // ConjunctiveQuery.parse(cq2).value.bounded shouldBe empty
202 } 202 // }
203 203
204 "CQ3" should "have {?w, ?fp} as bounded variables" in { 204 // "CQ3" should "have {?w, ?fp} as bounded variables" in {
205 ConjunctiveQuery.parse(cq3).value.bounded should contain theSameElementsAs 205 // ConjunctiveQuery.parse(cq3).value.bounded should contain theSameElementsAs
206 List( 206 // List(
207 Variable.create("w"), 207 // Variable.create("w"),
208 Variable.create("fp") 208 // Variable.create("fp")
209 ) 209 // )
210 } 210 // }
211 211
212 "CQ4" should "have no bounded variable" in { 212 // "CQ4" should "have no bounded variable" in {
213 ConjunctiveQuery.parse(cq4).value.bounded shouldBe empty 213 // ConjunctiveQuery.parse(cq4).value.bounded shouldBe empty
214 } 214 // }
215 215
216 "CQ5" should "have a non-empty bounded set" in { 216 // "CQ5" should "have a non-empty bounded set" in {
217 ConjunctiveQuery.parse(cq5).value.bounded should contain theSameElementsAs 217 // ConjunctiveQuery.parse(cq5).value.bounded should contain theSameElementsAs
218 List( 218 // List(
219 Variable.create("w"), 219 // Variable.create("w"),
220 Variable.create("c_int"), 220 // Variable.create("c_int"),
221 Variable.create("f_int"), 221 // Variable.create("f_int"),
222 Variable.create("c_unit") 222 // Variable.create("c_unit")
223 ) 223 // )
224 } 224 // }
225 225
226 "CQ6" should "have a non-empty bounded set" in { 226 // "CQ6" should "have a non-empty bounded set" in {
227 ConjunctiveQuery.parse(cq6).value.bounded should contain theSameElementsAs 227 // ConjunctiveQuery.parse(cq6).value.bounded should contain theSameElementsAs
228 List( 228 // List(
229 Variable.create("w"), 229 // Variable.create("w"),
230 Variable.create("int") 230 // Variable.create("int")
231 ) 231 // )
232 } 232 // }
233 233
234 "CQ7" should "have a non-empty bounded set" in { 234 // "CQ7" should "have a non-empty bounded set" in {
235 ConjunctiveQuery.parse(cq7).value.bounded should contain theSameElementsAs 235 // ConjunctiveQuery.parse(cq7).value.bounded should contain theSameElementsAs
236 List( 236 // List(
237 Variable.create("w"), 237 // Variable.create("w"),
238 Variable.create("z"), 238 // Variable.create("z"),
239 Variable.create("u"), 239 // Variable.create("u"),
240 Variable.create("strat_unit_name"), 240 // Variable.create("strat_unit_name"),
241 Variable.create("wellbore"), 241 // Variable.create("wellbore"),
242 Variable.create("cored_int"), 242 // Variable.create("cored_int"),
243 Variable.create("c"), 243 // Variable.create("c"),
244 Variable.create("sample_depth"), 244 // Variable.create("sample_depth"),
245 Variable.create("p"), 245 // Variable.create("p"),
246 Variable.create("top"), 246 // Variable.create("top"),
247 Variable.create("bot") 247 // Variable.create("bot")
248 ) 248 // )
249 } 249 // }
250 250
251} 251}