diff options
| author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-11-18 19:13:25 +0000 |
|---|---|---|
| committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-11-18 19:13:25 +0000 |
| commit | 1efc189e90240c162b54cbc50362b46786643dad (patch) | |
| tree | 9beabe0a2af7ba1674aea0060787782aa72e8a83 /src/test/scala/uk | |
| parent | a45aeff72b82bbc9a52f10929bf15b414c868525 (diff) | |
| download | RSAComb-1efc189e90240c162b54cbc50362b46786643dad.tar.gz RSAComb-1efc189e90240c162b54cbc50362b46786643dad.zip | |
Reorganize project with Java-like folder structure
Diffstat (limited to 'src/test/scala/uk')
4 files changed, 1381 insertions, 0 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 new file mode 100644 index 0000000..376729c --- /dev/null +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala | |||
| @@ -0,0 +1,370 @@ | |||
| 1 | package rsacomb | ||
| 2 | |||
| 3 | import java.io.File | ||
| 4 | import org.scalatest.LoneElement | ||
| 5 | import org.scalatest.flatspec.AnyFlatSpec | ||
| 6 | import org.scalatest.matchers.should.Matchers | ||
| 7 | |||
| 8 | import org.semanticweb.owlapi.model._ | ||
| 9 | import uk.ac.manchester.cs.owl.owlapi._ | ||
| 10 | import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer | ||
| 11 | |||
| 12 | import tech.oxfordsemantic.jrdfox.logic.datalog.Rule | ||
| 13 | import tech.oxfordsemantic.jrdfox.logic.expression.Variable | ||
| 14 | |||
| 15 | import scala.collection.JavaConverters._ | ||
| 16 | |||
| 17 | import uk.ac.ox.cs.rsacomb.RSAOntology | ||
| 18 | import uk.ac.ox.cs.rsacomb.util.{RDFoxHelpers, RSA} | ||
| 19 | |||
| 20 | object Ontology1_CanonicalModelSpec { | ||
| 21 | |||
| 22 | /* Renderer to display OWL Axioms with DL syntax*/ | ||
| 23 | val renderer = new DLSyntaxObjectRenderer() | ||
| 24 | |||
| 25 | def base(str: String): IRI = | ||
| 26 | IRI.create("http://example.com/rsa_example.owl#" + str) | ||
| 27 | |||
| 28 | val ontology_path: File = new File("examples/example1.ttl") | ||
| 29 | val ontology = RSAOntology(ontology_path) | ||
| 30 | val program = ontology.canonicalModel | ||
| 31 | |||
| 32 | val roleR = new OWLObjectPropertyImpl(base("R")) | ||
| 33 | val roleS = new OWLObjectPropertyImpl(base("S")) | ||
| 34 | val roleT = new OWLObjectPropertyImpl(base("T")) | ||
| 35 | val roleR_inv = roleR.getInverseProperty() | ||
| 36 | val roleS_inv = roleS.getInverseProperty() | ||
| 37 | val roleT_inv = roleT.getInverseProperty() | ||
| 38 | |||
| 39 | val AsubClassOfD = new OWLSubClassOfAxiomImpl( | ||
| 40 | new OWLClassImpl(base("A")), | ||
| 41 | new OWLClassImpl(base("D")), | ||
| 42 | Seq().asJava | ||
| 43 | ) | ||
| 44 | |||
| 45 | val DsomeValuesFromRB = new OWLSubClassOfAxiomImpl( | ||
| 46 | new OWLClassImpl(base("D")), | ||
| 47 | new OWLObjectSomeValuesFromImpl( | ||
| 48 | roleR, | ||
| 49 | new OWLClassImpl(base("B")) | ||
| 50 | ), | ||
| 51 | Seq().asJava | ||
| 52 | ) | ||
| 53 | |||
| 54 | val BsomeValuesFromSD = new OWLSubClassOfAxiomImpl( | ||
| 55 | new OWLClassImpl(base("B")), | ||
| 56 | new OWLObjectSomeValuesFromImpl( | ||
| 57 | roleS, | ||
| 58 | new OWLClassImpl(base("D")) | ||
| 59 | ), | ||
| 60 | Seq().asJava | ||
| 61 | ) | ||
| 62 | |||
| 63 | val AsomeValuesFromSiC = new OWLSubClassOfAxiomImpl( | ||
| 64 | new OWLClassImpl(base("A")), | ||
| 65 | new OWLObjectSomeValuesFromImpl( | ||
| 66 | roleS_inv, | ||
| 67 | new OWLClassImpl(base("C")) | ||
| 68 | ), | ||
| 69 | Seq().asJava | ||
| 70 | ) | ||
| 71 | |||
| 72 | val SsubPropertyOfT = new OWLSubObjectPropertyOfAxiomImpl( | ||
| 73 | new OWLObjectPropertyImpl(base("S")), | ||
| 74 | new OWLObjectPropertyImpl(base("T")), | ||
| 75 | Seq().asJava | ||
| 76 | ) | ||
| 77 | |||
| 78 | } | ||
| 79 | |||
| 80 | class Ontology1_CanonicalModelSpec | ||
| 81 | extends AnyFlatSpec | ||
| 82 | with Matchers | ||
| 83 | with LoneElement { | ||
| 84 | |||
| 85 | import Ontology1_CanonicalModelSpec._ | ||
| 86 | |||
| 87 | "The program generated from Example #1" should "not be empty" in { | ||
| 88 | program.rules should not be empty | ||
| 89 | } | ||
| 90 | |||
| 91 | renderer.render(AsubClassOfD) should "be converted into a single Rule" in { | ||
| 92 | val varX = Variable.create("X") | ||
| 93 | val visitor = program.RuleGenerator | ||
| 94 | val rules = AsubClassOfD.accept(visitor) | ||
| 95 | rules.loneElement shouldBe a[Rule] | ||
| 96 | } | ||
| 97 | |||
| 98 | // Role R // | ||
| 99 | |||
| 100 | renderer.render(roleR) should "be safe" in { | ||
| 101 | ontology.unsafeRoles should not contain roleR | ||
| 102 | } | ||
| 103 | |||
| 104 | it should "have 3 elements in its conflict set" in { | ||
| 105 | ontology.confl(roleR) should have size 3 | ||
| 106 | } | ||
| 107 | |||
| 108 | it should "contain S in its conflict set" in { | ||
| 109 | ontology.confl(roleR) should contain(roleS) | ||
| 110 | } | ||
| 111 | |||
| 112 | it should "contain T in its conflict set" in { | ||
| 113 | ontology.confl(roleR) should contain(roleT) | ||
| 114 | } | ||
| 115 | |||
| 116 | it should ("contain " + renderer.render( | ||
| 117 | roleR_inv | ||
| 118 | ) + " in its conflict set") in { | ||
| 119 | ontology.confl(roleR) should contain(roleR_inv) | ||
| 120 | } | ||
| 121 | |||
| 122 | // Role S // | ||
| 123 | |||
| 124 | renderer.render(roleS) should "be safe" in { | ||
| 125 | ontology.unsafeRoles should not contain roleS | ||
| 126 | } | ||
| 127 | |||
| 128 | it should "have 3 elements in its conflict set" in { | ||
| 129 | ontology.confl(roleS) should have size 3 | ||
| 130 | } | ||
| 131 | |||
| 132 | it should "contain R in its conflict set" in { | ||
| 133 | ontology.confl(roleS) should contain(roleR) | ||
| 134 | } | ||
| 135 | |||
| 136 | it should ("contain " + renderer.render( | ||
| 137 | roleS_inv | ||
| 138 | ) + " in its conflict set") in { | ||
| 139 | ontology.confl(roleS) should contain(roleS_inv) | ||
| 140 | } | ||
| 141 | |||
| 142 | it should ("contain " + renderer.render( | ||
| 143 | roleT_inv | ||
| 144 | ) + " in its conflict set") in { | ||
| 145 | ontology.confl(roleS) should contain(roleT_inv) | ||
| 146 | } | ||
| 147 | |||
| 148 | // S⁻ | ||
| 149 | |||
| 150 | renderer.render(roleS_inv) should "be unsafe" in { | ||
| 151 | ontology.unsafeRoles should contain(roleS_inv) | ||
| 152 | } | ||
| 153 | |||
| 154 | renderer.render( | ||
| 155 | AsomeValuesFromSiC | ||
| 156 | ) should "produce 1 rule" in { | ||
| 157 | val varX = Variable.create("X") | ||
| 158 | val visitor = program.RuleGenerator | ||
| 159 | val rules = AsomeValuesFromSiC.accept(visitor) | ||
| 160 | rules should have length 1 | ||
| 161 | } | ||
| 162 | |||
| 163 | renderer.render( | ||
| 164 | DsomeValuesFromRB | ||
| 165 | ) should "have a 'cycle' set of 48 elements" in { | ||
| 166 | // Cycle introduces a new constant for each possible triple (the | ||
| 167 | // order among triples is total). In this example there are 4 | ||
| 168 | // concept names and R has 3 safe roles in its conflict set (S, T, | ||
| 169 | // Inv(R)). Triples are | ||
| 170 | // (concept, role, concept) | ||
| 171 | // and hence we have 4*3*4=48 new constants introduced. | ||
| 172 | ontology.cycle(DsomeValuesFromRB) should have size 48 | ||
| 173 | } | ||
| 174 | |||
| 175 | it should "produce 5 rules" in { | ||
| 176 | // Rule 1 provides 1 rule (split in 2) + 48 fact | ||
| 177 | // Rule 2 provides 0 rules | ||
| 178 | // Rule 3 provides 48 rule (split in 2) | ||
| 179 | // Then (1*2 + 48) + (0) + (48*2) = 146 | ||
| 180 | val varX = Variable.create("X") | ||
| 181 | val visitor = program.RuleGenerator | ||
| 182 | val rules = DsomeValuesFromRB.accept(visitor) | ||
| 183 | rules should have length 146 | ||
| 184 | } | ||
| 185 | |||
| 186 | renderer.render( | ||
| 187 | BsomeValuesFromSD | ||
| 188 | ) should "have a 'cycle' set of 32 elements" in { | ||
| 189 | // Cycle introduces a new constant for each possible triple (the | ||
| 190 | // order among triples is total). In this example there are 4 | ||
| 191 | // concept names and S has 2 safe roles in its conflict set (R, | ||
| 192 | // Inv(T)). Triples are | ||
| 193 | // (concept, role, concept) | ||
| 194 | // and hence we have 4*2*4=32 new constants introduced. | ||
| 195 | ontology.cycle(BsomeValuesFromSD) should have size 32 | ||
| 196 | } | ||
| 197 | |||
| 198 | it should "produce 5 rules" in { | ||
| 199 | // Rule 1 provides 1 rule (split in 2) + 32 fact | ||
| 200 | // Rule 2 provides 0 rules | ||
| 201 | // Rule 3 provides 32 rule (split in 2) | ||
| 202 | // Then (1*2 + 32) + (0) + (32*2) = 98 | ||
| 203 | val varX = Variable.create("X") | ||
| 204 | val visitor = program.RuleGenerator | ||
| 205 | val rules = DsomeValuesFromRB.accept(visitor) | ||
| 206 | rules should have length 146 | ||
| 207 | } | ||
| 208 | |||
| 209 | renderer.render( | ||
| 210 | SsubPropertyOfT | ||
| 211 | ) should "produce 2 rules" in { | ||
| 212 | val varX = Variable.create("X") | ||
| 213 | val visitor = program.RuleGenerator | ||
| 214 | val rules = SsubPropertyOfT.accept(visitor) | ||
| 215 | rules should have length 2 | ||
| 216 | } | ||
| 217 | |||
| 218 | } | ||
| 219 | |||
| 220 | object Ontology2_CanonicalModelSpec { | ||
| 221 | |||
| 222 | /* Renderer to display OWL Axioms with DL syntax*/ | ||
| 223 | val renderer = new DLSyntaxObjectRenderer() | ||
| 224 | |||
| 225 | def base(str: String): IRI = | ||
| 226 | IRI.create("http://example.com/rsa_example.owl#" + str) | ||
| 227 | |||
| 228 | val ontology_path: File = new File("examples/example2.owl") | ||
| 229 | val ontology = RSAOntology(ontology_path) | ||
| 230 | val program = ontology.canonicalModel | ||
| 231 | |||
| 232 | val roleR = new OWLObjectPropertyImpl(base("R")) | ||
| 233 | val roleS = new OWLObjectPropertyImpl(base("S")) | ||
| 234 | val roleT = new OWLObjectPropertyImpl(base("T")) | ||
| 235 | val roleP = new OWLObjectPropertyImpl(base("P")) | ||
| 236 | val roleR_inv = roleR.getInverseProperty() | ||
| 237 | val roleS_inv = roleS.getInverseProperty() | ||
| 238 | val roleT_inv = roleT.getInverseProperty() | ||
| 239 | val roleP_inv = roleP.getInverseProperty() | ||
| 240 | |||
| 241 | val AsomeValuesFromRB = new OWLSubClassOfAxiomImpl( | ||
| 242 | new OWLClassImpl(base("A")), | ||
| 243 | new OWLObjectSomeValuesFromImpl( | ||
| 244 | roleR, | ||
| 245 | new OWLClassImpl(base("B")) | ||
| 246 | ), | ||
| 247 | Seq().asJava | ||
| 248 | ) | ||
| 249 | |||
| 250 | val BsomeValuesFromSC = new OWLSubClassOfAxiomImpl( | ||
| 251 | new OWLClassImpl(base("B")), | ||
| 252 | new OWLObjectSomeValuesFromImpl( | ||
| 253 | roleS, | ||
| 254 | new OWLClassImpl(base("C")) | ||
| 255 | ), | ||
| 256 | Seq().asJava | ||
| 257 | ) | ||
| 258 | |||
| 259 | val CsomeValuesFromTD = new OWLSubClassOfAxiomImpl( | ||
| 260 | new OWLClassImpl(base("C")), | ||
| 261 | new OWLObjectSomeValuesFromImpl( | ||
| 262 | roleT, | ||
| 263 | new OWLClassImpl(base("D")) | ||
| 264 | ), | ||
| 265 | Seq().asJava | ||
| 266 | ) | ||
| 267 | |||
| 268 | val DsomeValuesFromPA = new OWLSubClassOfAxiomImpl( | ||
| 269 | new OWLClassImpl(base("D")), | ||
| 270 | new OWLObjectSomeValuesFromImpl( | ||
| 271 | roleP, | ||
| 272 | new OWLClassImpl(base("A")) | ||
| 273 | ), | ||
| 274 | Seq().asJava | ||
| 275 | ) | ||
| 276 | |||
| 277 | } | ||
| 278 | |||
| 279 | class Ontology2_CanonicalModelSpec | ||
| 280 | extends AnyFlatSpec | ||
| 281 | with Matchers | ||
| 282 | with LoneElement { | ||
| 283 | |||
| 284 | import Ontology2_CanonicalModelSpec._ | ||
| 285 | |||
| 286 | "The program generated from Example #1" should "not be empty" in { | ||
| 287 | program.rules should not be empty | ||
| 288 | } | ||
| 289 | |||
| 290 | // Role R // | ||
| 291 | |||
| 292 | renderer.render(roleR) should "be unsafe" in { | ||
| 293 | ontology.unsafeRoles should contain(roleR) | ||
| 294 | } | ||
| 295 | |||
| 296 | it should "have only its inverse in its conflict set" in { | ||
| 297 | ontology.confl(roleR).loneElement shouldBe roleR_inv | ||
| 298 | } | ||
| 299 | |||
| 300 | // Role S // | ||
| 301 | |||
| 302 | renderer.render(roleS) should "be unsafe" in { | ||
| 303 | ontology.unsafeRoles should contain(roleS) | ||
| 304 | } | ||
| 305 | |||
| 306 | it should "have only its inverse in its conflict set" in { | ||
| 307 | ontology.confl(roleS).loneElement shouldBe roleS_inv | ||
| 308 | } | ||
| 309 | |||
| 310 | // Role T // | ||
| 311 | |||
| 312 | renderer.render(roleT) should "be unsafe" in { | ||
| 313 | ontology.unsafeRoles should contain(roleT) | ||
| 314 | } | ||
| 315 | |||
| 316 | it should "have only its inverse in its conflict set" in { | ||
| 317 | ontology.confl(roleT).loneElement shouldBe roleT_inv | ||
| 318 | } | ||
| 319 | |||
| 320 | // Role P // | ||
| 321 | |||
| 322 | renderer.render(roleP) should "be unsafe" in { | ||
| 323 | ontology.unsafeRoles should contain(roleP) | ||
| 324 | } | ||
| 325 | |||
| 326 | it should "have only its inverse in its conflict set" in { | ||
| 327 | ontology.confl(roleP).loneElement shouldBe roleP_inv | ||
| 328 | } | ||
| 329 | |||
| 330 | // A ⊑ ∃ R.B | ||
| 331 | |||
| 332 | renderer.render( | ||
| 333 | AsomeValuesFromRB | ||
| 334 | ) should "produce 1 rule" in { | ||
| 335 | val visitor = program.RuleGenerator | ||
| 336 | val rules = AsomeValuesFromRB.accept(visitor) | ||
| 337 | rules should have length 1 | ||
| 338 | } | ||
| 339 | |||
| 340 | // B ⊑ ∃ S.C | ||
| 341 | |||
| 342 | renderer.render( | ||
| 343 | BsomeValuesFromSC | ||
| 344 | ) should "produce 1 rule" in { | ||
| 345 | val visitor = program.RuleGenerator | ||
| 346 | val rules = BsomeValuesFromSC.accept(visitor) | ||
| 347 | rules should have length 1 | ||
| 348 | } | ||
| 349 | |||
| 350 | // C ⊑ ∃ T.D | ||
| 351 | |||
| 352 | renderer.render( | ||
| 353 | CsomeValuesFromTD | ||
| 354 | ) should "produce 1 rule" in { | ||
| 355 | val visitor = program.RuleGenerator | ||
| 356 | val rules = CsomeValuesFromTD.accept(visitor) | ||
| 357 | rules should have length 1 | ||
| 358 | } | ||
| 359 | |||
| 360 | // D ⊑ ∃ P.A | ||
| 361 | |||
| 362 | renderer.render( | ||
| 363 | DsomeValuesFromPA | ||
| 364 | ) should "produce 1 rule" in { | ||
| 365 | val visitor = program.RuleGenerator | ||
| 366 | val rules = DsomeValuesFromPA.accept(visitor) | ||
| 367 | rules should have length 1 | ||
| 368 | } | ||
| 369 | |||
| 370 | } | ||
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala new file mode 100644 index 0000000..49abd48 --- /dev/null +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala | |||
| @@ -0,0 +1,398 @@ | |||
| 1 | package rsacomb | ||
| 2 | |||
| 3 | import java.io.File | ||
| 4 | import java.util.{ArrayList => JList} | ||
| 5 | import org.scalatest.LoneElement | ||
| 6 | import org.scalatest.Inspectors | ||
| 7 | import org.scalatest.flatspec.AnyFlatSpec | ||
| 8 | import org.scalatest.matchers.should.Matchers | ||
| 9 | |||
| 10 | import tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom | ||
| 11 | import tech.oxfordsemantic.jrdfox.logic.expression.{Variable, IRI} | ||
| 12 | import tech.oxfordsemantic.jrdfox.logic.sparql.statement.{Query, SelectQuery} | ||
| 13 | import tech.oxfordsemantic.jrdfox.Prefixes | ||
| 14 | |||
| 15 | import scala.collection.JavaConverters._ | ||
| 16 | |||
| 17 | import uk.ac.ox.cs.rsacomb.FilteringProgram | ||
| 18 | import uk.ac.ox.cs.rsacomb.util.RDFoxHelpers | ||
| 19 | |||
| 20 | object FilteringProgramSpec { | ||
| 21 | |||
| 22 | val prefixes = new Prefixes() | ||
| 23 | prefixes.declarePrefix( | ||
| 24 | ":", | ||
| 25 | "http://slegger.gitlab.io/slegge-obda/ontology/subsurface-exploration#" | ||
| 26 | ) | ||
| 27 | prefixes.declarePrefix("rdf:", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") | ||
| 28 | prefixes.declarePrefix("rdfs:", "http://www.w3.org/2000/01/rdf-schema#") | ||
| 29 | prefixes.declarePrefix("owl:", "http://www.w3.org/2002/07/owl#") | ||
| 30 | |||
| 31 | // DEBUG: Quick helper functions | ||
| 32 | def v(v: String): Variable = Variable.create(v) | ||
| 33 | def c(c: String): IRI = IRI.create(":" + c) | ||
| 34 | |||
| 35 | // QUERY 0 | ||
| 36 | |||
| 37 | val query0 = RDFoxHelpers | ||
| 38 | .parseSelectQuery(""" | ||
| 39 | SELECT ?subj | ||
| 40 | WHERE { | ||
| 41 | ?subj ?pred ?obj | ||
| 42 | } | ||
| 43 | """, prefixes) | ||
| 44 | .get | ||
| 45 | |||
| 46 | // val query0 = Query.create( | ||
| 47 | // QueryType.SELECT, | ||
| 48 | // false, | ||
| 49 | // List(v("subj")).asJava, | ||
| 50 | // Atom.rdf(v("subj"), v("pred"), v("obj")) | ||
| 51 | // ) | ||
| 52 | |||
| 53 | // QUERY 1 | ||
| 54 | |||
| 55 | val query1 = RDFoxHelpers | ||
| 56 | .parseSelectQuery(""" | ||
| 57 | SELECT * | ||
| 58 | WHERE { | ||
| 59 | ?w a :Wellbore | ||
| 60 | } | ||
| 61 | """, prefixes) | ||
| 62 | .get | ||
| 63 | |||
| 64 | // val query1 = Query.create( | ||
| 65 | // QueryType.SELECT, | ||
| 66 | // false, | ||
| 67 | // List(v("w")).asJava, | ||
| 68 | // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")) | ||
| 69 | // ) | ||
| 70 | |||
| 71 | // QUERY 2 | ||
| 72 | |||
| 73 | val query2 = RDFoxHelpers | ||
| 74 | .parseSelectQuery( | ||
| 75 | """ | ||
| 76 | SELECT * | ||
| 77 | WHERE { | ||
| 78 | ?w a :Wellbore ; | ||
| 79 | :wellboreDocument ?doc . | ||
| 80 | ?doc :hasURL ?document_hyperlink | ||
| 81 | } | ||
| 82 | """, | ||
| 83 | prefixes | ||
| 84 | ) | ||
| 85 | .get | ||
| 86 | |||
| 87 | // val query2 = Query.create( | ||
| 88 | // QueryType.SELECT, | ||
| 89 | // false, | ||
| 90 | // List(v("w"), v("doc"), v("document_hyperlink")).asJava, | ||
| 91 | // Conjunction.create( | ||
| 92 | // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), | ||
| 93 | // Atom.rdf(v("w"), c("wellboreDocument"), v("doc")), | ||
| 94 | // Atom.rdf(v("doc"), c("hasURL"), v("document_hyperlink")) | ||
| 95 | // ) | ||
| 96 | // ) | ||
| 97 | |||
| 98 | // QUERY 3 | ||
| 99 | |||
| 100 | val query3 = RDFoxHelpers | ||
| 101 | .parseSelectQuery( | ||
| 102 | """ | ||
| 103 | SELECT ?wellbore ?formation_pressure | ||
| 104 | WHERE { | ||
| 105 | ?w a :Wellbore ; | ||
| 106 | :name ?wellbore ; | ||
| 107 | :hasFormationPressure ?fp . | ||
| 108 | ?fp :valueInStandardUnit ?formation_pressure | ||
| 109 | } | ||
| 110 | """, | ||
| 111 | prefixes | ||
| 112 | ) | ||
| 113 | .get | ||
| 114 | |||
| 115 | // val query3 = Query.create( | ||
| 116 | // QueryType.SELECT, | ||
| 117 | // false, | ||
| 118 | // List(v("wellbore"), v("formation_pressure")).asJava, | ||
| 119 | // Conjunction.create( | ||
| 120 | // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), | ||
| 121 | // Atom.rdf(v("w"), c("name"), v("wellbore")), | ||
| 122 | // Atom.rdf(v("w"), c("hasFormationPressure"), v("fp")), | ||
| 123 | // Atom.rdf(v("fp"), c("valueInStandardUnit"), v("formation_pressure")) | ||
| 124 | // ) | ||
| 125 | // ) | ||
| 126 | |||
| 127 | // QUERY 4 | ||
| 128 | |||
| 129 | val query4 = RDFoxHelpers | ||
| 130 | .parseSelectQuery( | ||
| 131 | """ | ||
| 132 | SELECT * | ||
| 133 | WHERE { | ||
| 134 | ?w a :Wellbore ; | ||
| 135 | :hasGeochemicalMeasurement ?measurement . | ||
| 136 | ?measurement :cgType ?cgtype ; | ||
| 137 | :peakName ?peakType ; | ||
| 138 | :peakHeight ?peak_height ; | ||
| 139 | :peakAmount ?peak_amount | ||
| 140 | } | ||
| 141 | """, | ||
| 142 | prefixes | ||
| 143 | ) | ||
| 144 | .get | ||
| 145 | |||
| 146 | // val query4 = Query.create( | ||
| 147 | // QueryType.SELECT, | ||
| 148 | // false, | ||
| 149 | // List( | ||
| 150 | // v("w"), | ||
| 151 | // v("measurement"), | ||
| 152 | // v("cgtype"), | ||
| 153 | // v("peakType"), | ||
| 154 | // v("peak_height"), | ||
| 155 | // v("peak_amount") | ||
| 156 | // ).asJava, | ||
| 157 | // Conjunction.create( | ||
| 158 | // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), | ||
| 159 | // Atom.rdf(v("w"), c("hasGeochemicalMeasurement"), v("measurement")), | ||
| 160 | // Atom.rdf(v("measurement"), c("cgType"), v("cgtype")), | ||
| 161 | // Atom.rdf(v("measurement"), c("peakName"), v("peakType")), | ||
| 162 | // Atom.rdf(v("measurement"), c("peakHeight"), v("peak_height")), | ||
| 163 | // Atom.rdf(v("measurement"), c("peakAmount"), v("peak_amount")) | ||
| 164 | // ) | ||
| 165 | // ) | ||
| 166 | |||
| 167 | // QUERY 5 | ||
| 168 | |||
| 169 | val query5 = RDFoxHelpers | ||
| 170 | .parseSelectQuery( | ||
| 171 | """ | ||
| 172 | SELECT ?wellbore ?unit_name ?discovery | ||
| 173 | WHERE { | ||
| 174 | ?w a :Wellbore ; | ||
| 175 | :name ?wellbore ; | ||
| 176 | :hasWellboreInterval ?c_int ; | ||
| 177 | :hasWellboreInterval ?f_int . | ||
| 178 | ?c_int :hasUnit ?c_unit . | ||
| 179 | ?c_unit :name ?unit_name . | ||
| 180 | ?f_int a :FluidZone ; | ||
| 181 | :name ?discovery ; | ||
| 182 | :overlapsWellboreInterval ?c_int | ||
| 183 | } | ||
| 184 | """, | ||
| 185 | prefixes | ||
| 186 | ) | ||
| 187 | .get | ||
| 188 | |||
| 189 | // val query5 = Query.create( | ||
| 190 | // QueryType.SELECT, | ||
| 191 | // false, | ||
| 192 | // List(v("wellbore"), v("unit_name"), v("discovery")).asJava, | ||
| 193 | // Conjunction.create( | ||
| 194 | // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), | ||
| 195 | // Atom.rdf(v("w"), c("name"), v("wellbore")), | ||
| 196 | // Atom.rdf(v("w"), c("hasWellboreInterval"), v("c_int")), | ||
| 197 | // Atom.rdf(v("w"), c("hasWellboreInterval"), v("f_int")), | ||
| 198 | // Atom.rdf(v("c_int"), c("hasUnit"), v("c_unit")), | ||
| 199 | // Atom.rdf(v("c_unit"), c("name"), v("unit_name")), | ||
| 200 | // Atom.rdf(v("f_int"), IRI.RDF_TYPE, c("FluidZone")), | ||
| 201 | // Atom.rdf(v("f_int"), c("name"), v("discovery")), | ||
| 202 | // Atom.rdf(v("f_int"), c("overlapsWellboreInterval"), v("c_int")) | ||
| 203 | // ) | ||
| 204 | // ) | ||
| 205 | |||
| 206 | // QUERY 6 | ||
| 207 | |||
| 208 | val query6 = RDFoxHelpers | ||
| 209 | .parseSelectQuery( | ||
| 210 | """ | ||
| 211 | SELECT DISTINCT ?wellbore ?content | ||
| 212 | WHERE { | ||
| 213 | ?w a :Wellbore ; | ||
| 214 | :name ?wellbore ; | ||
| 215 | :hasWellboreInterval ?int . | ||
| 216 | ?int a :FluidZone ; | ||
| 217 | :fluidZoneContent ?content | ||
| 218 | } | ||
| 219 | """, | ||
| 220 | prefixes | ||
| 221 | ) | ||
| 222 | .get | ||
| 223 | |||
| 224 | // val query6 = Query.create( | ||
| 225 | // QueryType.SELECT, | ||
| 226 | // true, | ||
| 227 | // List(v("wellbore"), v("content")).asJava, | ||
| 228 | // Conjunction.create( | ||
| 229 | // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), | ||
| 230 | // Atom.rdf(v("w"), c("name"), v("wellbore")), | ||
| 231 | // Atom.rdf(v("w"), c("hasWellboreInterval"), v("int")), | ||
| 232 | // Atom.rdf(v("int"), IRI.RDF_TYPE, c("FluidZone")), | ||
| 233 | // Atom.rdf(v("int"), c("fluidZoneContent"), v("content")) | ||
| 234 | // ) | ||
| 235 | // ) | ||
| 236 | |||
| 237 | // QUERY 7 | ||
| 238 | |||
| 239 | val query7 = RDFoxHelpers | ||
| 240 | .parseSelectQuery( | ||
| 241 | """ | ||
| 242 | SELECT ?wName ?sample ?porosity ?top_depth_md ?bot_depth_md | ||
| 243 | WHERE { | ||
| 244 | ?w a :Wellbore ; | ||
| 245 | :name ?wName ; | ||
| 246 | :hasWellboreInterval ?z . | ||
| 247 | ?z :hasUnit ?u . | ||
| 248 | ?u :name ?strat_unit_name . | ||
| 249 | ?wellbore :hasWellboreInterval ?cored_int . | ||
| 250 | ?c :extractedFrom ?cored_int ; | ||
| 251 | :hasCoreSample ?sample . | ||
| 252 | ?sample :hasDepth ?sample_depth . | ||
| 253 | ?sample_depth | ||
| 254 | :inWellboreInterval ?z . | ||
| 255 | ?sample :hasPorosity ?p . | ||
| 256 | ?p :valueInStandardUnit ?porosity . | ||
| 257 | ?z :hasTopDepth ?top . | ||
| 258 | ?top a :MeasuredDepth ; | ||
| 259 | :valueInStandardUnit ?top_depth_md . | ||
| 260 | ?z :hasBottomDepth ?bot . | ||
| 261 | ?bot a :MeasuredDepth ; | ||
| 262 | :valueInStandardUnit ?bot_depth_md | ||
| 263 | } | ||
| 264 | """, | ||
| 265 | prefixes | ||
| 266 | ) | ||
| 267 | .get | ||
| 268 | |||
| 269 | // val query7 = Query.create( | ||
| 270 | // QueryType.SELECT, | ||
| 271 | // false, | ||
| 272 | // List( | ||
| 273 | // v("wName"), | ||
| 274 | // v("sample"), | ||
| 275 | // v("porosity"), | ||
| 276 | // v("top_depth_md"), | ||
| 277 | // v("bot_depth_md") | ||
| 278 | // ).asJava, | ||
| 279 | // Conjunction.create( | ||
| 280 | // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), | ||
| 281 | // Atom.rdf(v("w"), c("name"), v("wName")), | ||
| 282 | // Atom.rdf(v("w"), c("hasWellboreInterval"), v("z")), | ||
| 283 | // Atom.rdf(v("z"), c("hasUnit"), v("u")), | ||
| 284 | // Atom.rdf(v("u"), c("name"), v("strat_unit_name")), | ||
| 285 | // Atom.rdf(v("wellbore"), c("hasWellboreInterval"), v("cored_int")), | ||
| 286 | // Atom.rdf(v("c"), c("extractedFrom"), v("cored_int")), | ||
| 287 | // Atom.rdf(v("c"), c("hasCoreSample"), v("sample")), | ||
| 288 | // Atom.rdf(v("sample"), c("hasDepth"), v("sample_depth")), | ||
| 289 | // Atom.rdf(v("sample_depth"), c("inWellboreInterval"), v("z")), | ||
| 290 | // Atom.rdf(v("sample"), c("hasPorosity"), v("p")), | ||
| 291 | // Atom.rdf(v("p"), c("valueInStandardUnit"), v("porosity")), | ||
| 292 | // Atom.rdf(v("z"), c("hasTopDepth"), v("top")), | ||
| 293 | // Atom.rdf(v("top"), IRI.RDF_TYPE, c("MeasuredDepth")), | ||
| 294 | // Atom.rdf(v("top"), c("valueInStandardUnit"), v("top_depth_md")), | ||
| 295 | // Atom.rdf(v("z"), c("hasBottomDepth"), v("bot")), | ||
| 296 | // Atom.rdf(v("bot"), IRI.RDF_TYPE, c("MeasuredDepth")), | ||
| 297 | // Atom.rdf(v("bot"), c("valueInStandardUnit"), v("bot_depth_md")) | ||
| 298 | // ) | ||
| 299 | // ) | ||
| 300 | |||
| 301 | val queries = | ||
| 302 | List(query0, query1, query2, query3, query4, query5, query6, query7) | ||
| 303 | } | ||
| 304 | |||
| 305 | class FilteringProgramSpec | ||
| 306 | extends AnyFlatSpec | ||
| 307 | with Matchers | ||
| 308 | with LoneElement | ||
| 309 | with Inspectors { | ||
| 310 | |||
| 311 | import FilteringProgramSpec._ | ||
| 312 | |||
| 313 | "Queries" should "have distinct answer and bounded variables" in { | ||
| 314 | for (query <- queries) { | ||
| 315 | val program = new FilteringProgram(query, List()) | ||
| 316 | forAll(program.answer) { v => program.bounded should not contain v } | ||
| 317 | forAll(program.bounded) { v => program.answer should not contain v } | ||
| 318 | } | ||
| 319 | } | ||
| 320 | |||
| 321 | "Query 0" should "have {?obj, ?pred} as bounded variables" in { | ||
| 322 | val pred = Variable.create("obj") | ||
| 323 | val obj = Variable.create("pred") | ||
| 324 | val program = new FilteringProgram(query0, List()) | ||
| 325 | program.bounded should contain theSameElementsAs List(pred, obj) | ||
| 326 | } | ||
| 327 | |||
| 328 | "Query 1" should "have no bounded variable" in { | ||
| 329 | val program = new FilteringProgram(query1, List()) | ||
| 330 | program.bounded shouldBe empty | ||
| 331 | } | ||
| 332 | |||
| 333 | "Query 2" should "have no bounded variable" in { | ||
| 334 | val program = new FilteringProgram(query2, List()) | ||
| 335 | program.bounded shouldBe empty | ||
| 336 | } | ||
| 337 | |||
| 338 | "Query 3" should "have {?w, ?fp} as bounded variables" in { | ||
| 339 | val w = Variable.create("w") | ||
| 340 | val fp = Variable.create("fp") | ||
| 341 | val program = new FilteringProgram(query3, List()) | ||
| 342 | program.bounded should contain theSameElementsAs List(w, fp) | ||
| 343 | } | ||
| 344 | |||
| 345 | "Query 4" should "have no bounded variable" in { | ||
| 346 | val program = new FilteringProgram(query4, List()) | ||
| 347 | program.bounded shouldBe empty | ||
| 348 | } | ||
| 349 | |||
| 350 | "Query 5" should "have a non-empty bounded set" in { | ||
| 351 | val w = Variable.create("w") | ||
| 352 | val c_int = Variable.create("c_int") | ||
| 353 | val f_int = Variable.create("f_int") | ||
| 354 | val c_unit = Variable.create("c_unit") | ||
| 355 | val program = new FilteringProgram(query5, List()) | ||
| 356 | program.bounded should contain theSameElementsAs List( | ||
| 357 | w, | ||
| 358 | c_int, | ||
| 359 | f_int, | ||
| 360 | c_unit | ||
| 361 | ) | ||
| 362 | } | ||
| 363 | |||
| 364 | "Query 6" should "have a non-empty bounded set" in { | ||
| 365 | val w = Variable.create("w") | ||
| 366 | val int = Variable.create("int") | ||
| 367 | val program = new FilteringProgram(query6, List()) | ||
| 368 | program.bounded should contain theSameElementsAs List(w, int) | ||
| 369 | } | ||
| 370 | |||
| 371 | "Query 7" should "have a non-empty bounded set" in { | ||
| 372 | val w = Variable.create("w") | ||
| 373 | val z = Variable.create("z") | ||
| 374 | val u = Variable.create("u") | ||
| 375 | val strat_unit_name = Variable.create("strat_unit_name") | ||
| 376 | val wellbore = Variable.create("wellbore") | ||
| 377 | val cored_int = Variable.create("cored_int") | ||
| 378 | val c = Variable.create("c") | ||
| 379 | val sample_depth = Variable.create("sample_depth") | ||
| 380 | val p = Variable.create("p") | ||
| 381 | val top = Variable.create("top") | ||
| 382 | val bot = Variable.create("bot") | ||
| 383 | val program = new FilteringProgram(query7, List()) | ||
| 384 | program.bounded should contain theSameElementsAs List( | ||
| 385 | w, | ||
| 386 | z, | ||
| 387 | u, | ||
| 388 | strat_unit_name, | ||
| 389 | wellbore, | ||
| 390 | cored_int, | ||
| 391 | c, | ||
| 392 | sample_depth, | ||
| 393 | p, | ||
| 394 | top, | ||
| 395 | bot | ||
| 396 | ) | ||
| 397 | } | ||
| 398 | } | ||
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/OWLAxiomSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/OWLAxiomSpec.scala new file mode 100644 index 0000000..8aee03d --- /dev/null +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/OWLAxiomSpec.scala | |||
| @@ -0,0 +1,336 @@ | |||
| 1 | package rsacomb | ||
| 2 | |||
| 3 | import java.util.{ArrayList => JList} | ||
| 4 | import org.scalatest.LoneElement | ||
| 5 | import org.scalatest.flatspec.AnyFlatSpec | ||
| 6 | import org.scalatest.matchers.should.Matchers | ||
| 7 | |||
| 8 | import org.semanticweb.owlapi.model.OWLClassExpression | ||
| 9 | import uk.ac.manchester.cs.owl.owlapi.{OWLSubClassOfAxiomImpl} | ||
| 10 | import uk.ac.manchester.cs.owl.owlapi.{ | ||
| 11 | OWLClassImpl, | ||
| 12 | OWLObjectSomeValuesFromImpl, | ||
| 13 | OWLObjectIntersectionOfImpl, | ||
| 14 | OWLObjectOneOfImpl, | ||
| 15 | OWLObjectAllValuesFromImpl, | ||
| 16 | OWLObjectMaxCardinalityImpl, | ||
| 17 | OWLNamedIndividualImpl | ||
| 18 | } | ||
| 19 | import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl} | ||
| 20 | import org.semanticweb.owlapi.model.{OWLAxiom} | ||
| 21 | |||
| 22 | import tech.oxfordsemantic.jrdfox.logic.Datatype | ||
| 23 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ | ||
| 24 | Rule, | ||
| 25 | BindAtom, | ||
| 26 | TupleTableAtom, | ||
| 27 | TupleTableName | ||
| 28 | } | ||
| 29 | import tech.oxfordsemantic.jrdfox.logic.expression.{ | ||
| 30 | FunctionCall, | ||
| 31 | Term, | ||
| 32 | Variable, | ||
| 33 | Literal | ||
| 34 | } | ||
| 35 | |||
| 36 | import org.semanticweb.owlapi.model.{IRI => OWLIRI} | ||
| 37 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI} | ||
| 38 | |||
| 39 | import uk.ac.ox.cs.rsacomb.converter.{RDFoxAxiomConverter, SkolemStrategy} | ||
| 40 | import uk.ac.ox.cs.rsacomb.util.RSA | ||
| 41 | |||
| 42 | object OWLAxiomSpec { | ||
| 43 | |||
| 44 | // IRI | ||
| 45 | val iri_Professor = OWLIRI.create("univ:Professor") | ||
| 46 | val iri_Female = OWLIRI.create("std:Female") | ||
| 47 | val iri_Student = OWLIRI.create("univ:Student") | ||
| 48 | val iri_PartTimeStudent = OWLIRI.create("univ:PartTimeStudent") | ||
| 49 | val iri_Worker = OWLIRI.create("univ:Worker") | ||
| 50 | val iri_alice = OWLIRI.create("univ:alice") | ||
| 51 | val iri_supervises = OWLIRI.create("univ:supervises") | ||
| 52 | val iri_hasSupervisor = OWLIRI.create("univ:hasSupervisor") | ||
| 53 | val iri_sameAs = OWLIRI.create("owl:sameAs") | ||
| 54 | |||
| 55 | // RDFox Terms | ||
| 56 | val term_x = Variable.create("x") | ||
| 57 | val term_y = Variable.create("y") | ||
| 58 | val term_z = Variable.create("z") | ||
| 59 | val term_c1 = RSA("c_1") | ||
| 60 | val term_c2 = RSA("c_2") | ||
| 61 | val term_alice = RDFIRI.create("univ:alice") | ||
| 62 | |||
| 63 | // RDFox Predicates | ||
| 64 | val pred_sameAs = TupleTableName.create("owl:sameAs") | ||
| 65 | val pred_Professor = TupleTableName.create(iri_Professor.getIRIString) | ||
| 66 | val pred_hasSupervisor = TupleTableName.create(iri_hasSupervisor.getIRIString) | ||
| 67 | |||
| 68 | // OWL Classes | ||
| 69 | // Name Class corresponding to | ||
| 70 | // | ||
| 71 | // Professor | ||
| 72 | // | ||
| 73 | val class_Professor = new OWLClassImpl(iri_Professor) | ||
| 74 | val class_Female = new OWLClassImpl(iri_Female) | ||
| 75 | val class_Student = new OWLClassImpl(iri_Student) | ||
| 76 | val class_PartTimeStudent = new OWLClassImpl(iri_PartTimeStudent) | ||
| 77 | val class_Worker = new OWLClassImpl(iri_Worker) | ||
| 78 | val class_OWLClass = class_Professor | ||
| 79 | // Class Conjunction corresponding to | ||
| 80 | // | ||
| 81 | // Student ∧ Worker | ||
| 82 | // | ||
| 83 | val class_OWLObjectIntersectionOf = { | ||
| 84 | val conjuncts = new JList[OWLClassExpression]() | ||
| 85 | conjuncts.add(class_Student) | ||
| 86 | conjuncts.add(class_Worker) | ||
| 87 | new OWLObjectIntersectionOfImpl(conjuncts) | ||
| 88 | } | ||
| 89 | // Singleton Class corresponding to | ||
| 90 | // | ||
| 91 | // { alice } | ||
| 92 | // | ||
| 93 | val class_OWLObjectOneOf = | ||
| 94 | new OWLObjectOneOfImpl( | ||
| 95 | new OWLNamedIndividualImpl(iri_alice) | ||
| 96 | ) | ||
| 97 | // Object Existential Restiction corresponding to | ||
| 98 | // | ||
| 99 | // ∃ hasSupervisor.Professor | ||
| 100 | // | ||
| 101 | val class_OWLObjectSomeValuesFrom = | ||
| 102 | new OWLObjectSomeValuesFromImpl( | ||
| 103 | new OWLObjectPropertyImpl(iri_hasSupervisor), | ||
| 104 | class_Professor | ||
| 105 | ) | ||
| 106 | // Object Max Cardinality Restriction corresponding to | ||
| 107 | // | ||
| 108 | // ≤ 1 hasSupervisor . Professor | ||
| 109 | val class_OWLObjectMaxCardinality = | ||
| 110 | new OWLObjectMaxCardinalityImpl( | ||
| 111 | new OWLObjectPropertyImpl(iri_hasSupervisor), | ||
| 112 | 1, | ||
| 113 | class_Professor | ||
| 114 | ) | ||
| 115 | |||
| 116 | // OWL Axioms | ||
| 117 | // Axiom SubClassOf corresponding to | ||
| 118 | // | ||
| 119 | // Student ∧ Worker -> PartTimeStudent | ||
| 120 | // | ||
| 121 | val axiom_OWLSubClassOf1 = | ||
| 122 | new OWLSubClassOfAxiomImpl( | ||
| 123 | class_OWLObjectIntersectionOf, | ||
| 124 | class_PartTimeStudent, | ||
| 125 | new JList() | ||
| 126 | ) | ||
| 127 | |||
| 128 | // Axiom SubClassOf corresponding to | ||
| 129 | // | ||
| 130 | // Student -> ∃ hasSupervisor.Professor | ||
| 131 | // | ||
| 132 | val axiom_OWLSubClassOf2 = | ||
| 133 | new OWLSubClassOfAxiomImpl( | ||
| 134 | class_Student, | ||
| 135 | class_OWLObjectSomeValuesFrom, | ||
| 136 | new JList() | ||
| 137 | ) | ||
| 138 | |||
| 139 | // Axiom SubClassOf corresponding to | ||
| 140 | // | ||
| 141 | // ∃ hasSupervisor.Professor -> Student | ||
| 142 | // | ||
| 143 | val axiom_OWLSubClassOf3 = | ||
| 144 | new OWLSubClassOfAxiomImpl( | ||
| 145 | class_OWLObjectSomeValuesFrom, | ||
| 146 | class_Student, | ||
| 147 | new JList() | ||
| 148 | ) | ||
| 149 | |||
| 150 | // Axiom SubClassOf corresponding to | ||
| 151 | // | ||
| 152 | // Student -> { alice } | ||
| 153 | // | ||
| 154 | val axiom_OWLSubClassOf4 = | ||
| 155 | new OWLSubClassOfAxiomImpl( | ||
| 156 | class_Student, | ||
| 157 | class_OWLObjectOneOf, | ||
| 158 | new JList() | ||
| 159 | ) | ||
| 160 | |||
| 161 | // Axiom SubClassOf corresponding to | ||
| 162 | // | ||
| 163 | // Student -> ≤1 hasSupervisor.Professor | ||
| 164 | // | ||
| 165 | val axiom_OWLSubClassOf5 = | ||
| 166 | new OWLSubClassOfAxiomImpl( | ||
| 167 | class_Student, | ||
| 168 | class_OWLObjectMaxCardinality, | ||
| 169 | new JList() | ||
| 170 | ) | ||
| 171 | |||
| 172 | def convertAxiom( | ||
| 173 | axiom: OWLAxiom, | ||
| 174 | term: Term, | ||
| 175 | skolem: SkolemStrategy = SkolemStrategy.None | ||
| 176 | ): List[Rule] = { | ||
| 177 | axiom.accept(RDFoxAxiomConverter(term, List())) | ||
| 178 | } | ||
| 179 | |||
| 180 | } // object OWLAxiomSpec | ||
| 181 | |||
| 182 | class OWLAxiomSpec extends AnyFlatSpec with Matchers with LoneElement { | ||
| 183 | |||
| 184 | // Import required data | ||
| 185 | import OWLAxiomSpec._ | ||
| 186 | // Implicit convertion from IRI in OWLAPI to IRI in JRDFox | ||
| 187 | import uk.ac.ox.cs.rsacomb.implicits.RDFox._ | ||
| 188 | |||
| 189 | // OWLSubClassOfAxiom #1 | ||
| 190 | axiom_OWLSubClassOf1.toString should "be converted into a singleton List[Rule]" in { | ||
| 191 | val result = convertAxiom(axiom_OWLSubClassOf1, term_x) | ||
| 192 | result.loneElement shouldBe a[Rule] | ||
| 193 | } | ||
| 194 | |||
| 195 | it should "contain a conjuction of atoms (Student[?x],Worker[?x]) in the body of the rule" in { | ||
| 196 | val result = convertAxiom(axiom_OWLSubClassOf1, term_x) | ||
| 197 | val body = List( | ||
| 198 | TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student), | ||
| 199 | TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Worker) | ||
| 200 | ) | ||
| 201 | result.loneElement.getBody should contain theSameElementsAs body | ||
| 202 | } | ||
| 203 | |||
| 204 | it should "contain a single atom (PartTimeStudent[?x]) in the head of the rule" in { | ||
| 205 | val result = convertAxiom(axiom_OWLSubClassOf1, term_x) | ||
| 206 | val head = TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_PartTimeStudent) | ||
| 207 | result.loneElement.getHead.loneElement should be(head) | ||
| 208 | } | ||
| 209 | |||
| 210 | // OWLSubClassOfAxiom #2 (w/ constant skolemization) | ||
| 211 | (axiom_OWLSubClassOf2.toString + "\n(w/ constant skolemization)") should | ||
| 212 | "be converted into a singleton List[Rule]" in { | ||
| 213 | val skolem = SkolemStrategy.Constant(axiom_OWLSubClassOf2.toString) | ||
| 214 | val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) | ||
| 215 | result.loneElement shouldBe a[Rule] | ||
| 216 | } | ||
| 217 | |||
| 218 | it should "contain a single atom (Student[?x]) in the body of the rule" in { | ||
| 219 | val skolem = SkolemStrategy.Constant(axiom_OWLSubClassOf2.toString) | ||
| 220 | val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) | ||
| 221 | val body = | ||
| 222 | TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student.getIRIString) | ||
| 223 | result.loneElement.getBody.loneElement should equal(body) | ||
| 224 | } | ||
| 225 | |||
| 226 | // it should "contain a conjuction of atoms (hasSupervisor[?x,?c],Professor[?c]) in the head of the rule" in { | ||
| 227 | // val skolem = SkolemStrategy.Constant(axiom_OWLSubClassOf2.toString) | ||
| 228 | // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) | ||
| 229 | // val term_c = RSA.rsa(skolem.const.getIRI) | ||
| 230 | // val head = List( | ||
| 231 | // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_c), | ||
| 232 | // TupleTableAtom.rdf(term_c, RDFIRI.RDF_TYPE, iri_Professor) | ||
| 233 | // ) | ||
| 234 | // result.loneElement.getHead should contain theSameElementsAs (head) | ||
| 235 | // } | ||
| 236 | |||
| 237 | // OWLSubClassOfAxiom #2 (w/ skolemization) | ||
| 238 | (axiom_OWLSubClassOf2.toString + "\n(w/ skolemization)") should | ||
| 239 | "be converted into a singleton List[Rule]" in { | ||
| 240 | val skolem = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString) | ||
| 241 | val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) | ||
| 242 | result.loneElement shouldBe a[Rule] | ||
| 243 | } | ||
| 244 | |||
| 245 | it should "contain an atom (Student[?x]) in the body of the rule" in { | ||
| 246 | val skolem = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString) | ||
| 247 | val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) | ||
| 248 | val body = | ||
| 249 | TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student) | ||
| 250 | result.loneElement.getBody should contain(body) | ||
| 251 | } | ||
| 252 | |||
| 253 | // it should "contain a built-in function call (BIND(?y,SKOLEM(?f,?x))) in the body of the rule" in { | ||
| 254 | // val skolem = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString) | ||
| 255 | // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) | ||
| 256 | // val call = | ||
| 257 | // BindAtom.create(BuiltinFunctionCall.create("SKOLEM", term_x), term_y) | ||
| 258 | // result.loneElement.getBody should contain(call) | ||
| 259 | // } | ||
| 260 | |||
| 261 | // it should "contain a conjuction of atom (hasSupervisor[?x,?y],Professor[?y]) in the head of the rule" in { | ||
| 262 | // val skolem = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString) | ||
| 263 | // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) | ||
| 264 | // val head = List( | ||
| 265 | // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y), | ||
| 266 | // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor) | ||
| 267 | // ) | ||
| 268 | // result.loneElement.getHead should contain theSameElementsAs head | ||
| 269 | // } | ||
| 270 | |||
| 271 | // OWLSubClassOfAxiom #3 | ||
| 272 | axiom_OWLSubClassOf3.toString should "be converted into a singleton List[Rule]" in { | ||
| 273 | val result = convertAxiom(axiom_OWLSubClassOf3, term_x) | ||
| 274 | result.loneElement shouldBe a[Rule] | ||
| 275 | } | ||
| 276 | |||
| 277 | // it should "contain a conjunction of atoms (hasSupervisor[?x,?y],Professor[?y]) in the body of the rule" in { | ||
| 278 | // val result = convertAxiom(axiom_OWLSubClassOf3, term_x) | ||
| 279 | // val body = List( | ||
| 280 | // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y), | ||
| 281 | // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor) | ||
| 282 | // ) | ||
| 283 | // result.loneElement.getBody should contain theSameElementsAs body | ||
| 284 | // } | ||
| 285 | |||
| 286 | it should "contain a single atom (Student[?x]) in the head of the rule" in { | ||
| 287 | val result = convertAxiom(axiom_OWLSubClassOf3, term_x) | ||
| 288 | val head = | ||
| 289 | TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student) | ||
| 290 | result.loneElement.getHead.loneElement should be(head) | ||
| 291 | } | ||
| 292 | |||
| 293 | // OWLSubClassOfAxiom #4 | ||
| 294 | axiom_OWLSubClassOf4.toString should "be converted into a singleton List[Rule]" in { | ||
| 295 | val result = convertAxiom(axiom_OWLSubClassOf4, term_x) | ||
| 296 | result.loneElement shouldBe a[Rule] | ||
| 297 | } | ||
| 298 | |||
| 299 | it should "contain a single atoms (Student[?x]) in the body of the rule" in { | ||
| 300 | val result = convertAxiom(axiom_OWLSubClassOf4, term_x) | ||
| 301 | val body = | ||
| 302 | TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student) | ||
| 303 | result.loneElement.getBody.loneElement should be(body) | ||
| 304 | } | ||
| 305 | |||
| 306 | it should "contain a single atom (sameAs[?x,alice])) in the head of the rule" in { | ||
| 307 | val result = convertAxiom(axiom_OWLSubClassOf4, term_x) | ||
| 308 | val head = TupleTableAtom.rdf(term_x, RDFIRI.SAME_AS, term_alice) | ||
| 309 | result.loneElement.getHead.loneElement should be(head) | ||
| 310 | } | ||
| 311 | |||
| 312 | // OWLSubClassOfAxiom #5 | ||
| 313 | axiom_OWLSubClassOf5.toString should "be converted into a singleton List[Rule]" in { | ||
| 314 | val result = convertAxiom(axiom_OWLSubClassOf5, term_x) | ||
| 315 | result.loneElement shouldBe a[Rule] | ||
| 316 | } | ||
| 317 | |||
| 318 | // it should "contain a conjunction of atoms (...) in the body of the rule" in { | ||
| 319 | // val result = convertAxiom(axiom_OWLSubClassOf5, term_x) | ||
| 320 | // val body = List( | ||
| 321 | // TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student), | ||
| 322 | // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y), | ||
| 323 | // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor), | ||
| 324 | // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_z), | ||
| 325 | // TupleTableAtom.rdf(term_z, RDFIRI.RDF_TYPE, iri_Professor) | ||
| 326 | // ) | ||
| 327 | // result.loneElement.getBody should contain theSameElementsAs body | ||
| 328 | // } | ||
| 329 | |||
| 330 | // it should "contain a single atom (sameAs[?x,?z])) in the head of the rule" in { | ||
| 331 | // val result = convertAxiom(axiom_OWLSubClassOf5, term_x) | ||
| 332 | // val head = TupleTableAtom.rdf(term_y, RDFIRI.SAME_AS, term_z) | ||
| 333 | // result.loneElement.getHead.loneElement should be(head) | ||
| 334 | // } | ||
| 335 | |||
| 336 | } // class OWLAxiomSpec | ||
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/OWLClassSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/OWLClassSpec.scala new file mode 100644 index 0000000..459fe21 --- /dev/null +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/OWLClassSpec.scala | |||
| @@ -0,0 +1,277 @@ | |||
| 1 | package rsacomb | ||
| 2 | |||
| 3 | import java.util.{ArrayList => JList} | ||
| 4 | |||
| 5 | import org.scalatest.LoneElement | ||
| 6 | import org.scalatest.flatspec.AnyFlatSpec | ||
| 7 | import org.scalatest.matchers.should.Matchers | ||
| 8 | |||
| 9 | import org.semanticweb.owlapi.model.OWLClassExpression | ||
| 10 | import uk.ac.manchester.cs.owl.owlapi.{ | ||
| 11 | OWLClassImpl, | ||
| 12 | OWLObjectSomeValuesFromImpl, | ||
| 13 | OWLObjectIntersectionOfImpl, | ||
| 14 | OWLObjectOneOfImpl, | ||
| 15 | OWLObjectAllValuesFromImpl, | ||
| 16 | OWLObjectMaxCardinalityImpl, | ||
| 17 | OWLNamedIndividualImpl | ||
| 18 | } | ||
| 19 | import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl} | ||
| 20 | import org.semanticweb.owlapi.model.IRI | ||
| 21 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI} | ||
| 22 | |||
| 23 | import tech.oxfordsemantic.jrdfox.logic.Datatype | ||
| 24 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ | ||
| 25 | TupleTableAtom, | ||
| 26 | TupleTableName, | ||
| 27 | BindAtom | ||
| 28 | } | ||
| 29 | import tech.oxfordsemantic.jrdfox.logic.expression.{ | ||
| 30 | FunctionCall, | ||
| 31 | Term, | ||
| 32 | Variable, | ||
| 33 | Literal | ||
| 34 | } | ||
| 35 | |||
| 36 | import uk.ac.ox.cs.rsacomb.converter.{ | ||
| 37 | RDFoxRuleShards, | ||
| 38 | RDFoxClassExprConverter, | ||
| 39 | SkolemStrategy | ||
| 40 | } | ||
| 41 | import uk.ac.ox.cs.rsacomb.util.RSA | ||
| 42 | |||
| 43 | object OWLClassSpec { | ||
| 44 | |||
| 45 | // IRI | ||
| 46 | val iri_Professor = IRI.create("univ:Professor") | ||
| 47 | val iri_Female = IRI.create("std:Female") | ||
| 48 | val iri_Student = IRI.create("univ:Student") | ||
| 49 | val iri_Worker = IRI.create("univ:Worker") | ||
| 50 | val iri_alice = IRI.create("univ:alice") | ||
| 51 | val iri_supervises = IRI.create("univ:supervises") | ||
| 52 | val iri_hasSupervisor = IRI.create("univ:hasSupervisor") | ||
| 53 | |||
| 54 | // RDFox Terms | ||
| 55 | val term_x = Variable.create("x") | ||
| 56 | val term_y = Variable.create("y") | ||
| 57 | val term_c1 = RSA("c_1") | ||
| 58 | val term_c2 = RSA("c_2") | ||
| 59 | val term_alice = RDFIRI.create("univ:alice") | ||
| 60 | |||
| 61 | // RDFox Predicates | ||
| 62 | val pred_sameAs = TupleTableName.create("owl:sameAs") | ||
| 63 | val pred_Professor = TupleTableName.create(iri_Professor.getIRIString) | ||
| 64 | val pred_hasSupervisor = TupleTableName.create(iri_hasSupervisor.getIRIString) | ||
| 65 | |||
| 66 | // OWL Classes | ||
| 67 | // Name Class corresponding to | ||
| 68 | // | ||
| 69 | // Professor | ||
| 70 | // | ||
| 71 | val class_Professor = new OWLClassImpl(iri_Professor) | ||
| 72 | val class_Female = new OWLClassImpl(iri_Female) | ||
| 73 | val class_Student = new OWLClassImpl(iri_Student) | ||
| 74 | val class_Worker = new OWLClassImpl(iri_Worker) | ||
| 75 | val class_OWLClass = class_Professor | ||
| 76 | |||
| 77 | // Class Conjunction corresponding to | ||
| 78 | // | ||
| 79 | // Female ∧ Student ∧ Worker | ||
| 80 | // | ||
| 81 | val class_OWLObjectIntersectionOf = { | ||
| 82 | val conjuncts = new JList[OWLClassExpression]() | ||
| 83 | conjuncts.add(class_Female) | ||
| 84 | conjuncts.add(class_Student) | ||
| 85 | conjuncts.add(class_Worker) | ||
| 86 | new OWLObjectIntersectionOfImpl(conjuncts) | ||
| 87 | } | ||
| 88 | // Singleton Class corresponding to | ||
| 89 | // | ||
| 90 | // { alice } | ||
| 91 | // | ||
| 92 | val class_OWLObjectOneOf = | ||
| 93 | new OWLObjectOneOfImpl( | ||
| 94 | new OWLNamedIndividualImpl(iri_alice) | ||
| 95 | ) | ||
| 96 | // Object Existential Restiction corresponding to | ||
| 97 | // | ||
| 98 | // ∃ hasSupervisor.Professor | ||
| 99 | // | ||
| 100 | val class_OWLObjectSomeValuesFrom = | ||
| 101 | new OWLObjectSomeValuesFromImpl( | ||
| 102 | new OWLObjectPropertyImpl(iri_hasSupervisor), | ||
| 103 | class_Professor | ||
| 104 | ) | ||
| 105 | // Object Max Cardinality Restriction corresponding to | ||
| 106 | // | ||
| 107 | // ≤1 hasSupervisor.Professor | ||
| 108 | val class_OWLObjectMaxCardinality = | ||
| 109 | new OWLObjectMaxCardinalityImpl( | ||
| 110 | new OWLObjectPropertyImpl(iri_hasSupervisor), | ||
| 111 | 1, | ||
| 112 | class_Professor | ||
| 113 | ) | ||
| 114 | } // object OWLClassSpec | ||
| 115 | |||
| 116 | class OWLClassSpec extends AnyFlatSpec with Matchers with LoneElement { | ||
| 117 | // Import required data | ||
| 118 | import OWLClassSpec._ | ||
| 119 | |||
| 120 | // OWLClass | ||
| 121 | class_OWLClass.toString should "be converted into a RDFoxRuleShards" in { | ||
| 122 | val visitor = RDFoxClassExprConverter(term_x) | ||
| 123 | val result = class_OWLClass.accept(visitor) | ||
| 124 | result shouldBe a[RDFoxRuleShards] | ||
| 125 | } | ||
| 126 | |||
| 127 | it should "have a single TupleTableAtom in its result list" in { | ||
| 128 | val visitor = RDFoxClassExprConverter(term_x) | ||
| 129 | val result = class_OWLClass.accept(visitor) | ||
| 130 | result.res.loneElement shouldBe an[TupleTableAtom] | ||
| 131 | } | ||
| 132 | |||
| 133 | it should "have an empty extension list" in { | ||
| 134 | val visitor = RDFoxClassExprConverter(term_x) | ||
| 135 | val result = class_OWLClass.accept(visitor) | ||
| 136 | result.ext shouldBe empty | ||
| 137 | } | ||
| 138 | |||
| 139 | // OWLObjectIntersectionOf | ||
| 140 | class_OWLObjectIntersectionOf.toString should "be converted into a RDFoxRuleShards" in { | ||
| 141 | val visitor = RDFoxClassExprConverter(term_x) | ||
| 142 | val result = class_OWLObjectIntersectionOf.accept(visitor) | ||
| 143 | result shouldBe a[RDFoxRuleShards] | ||
| 144 | } | ||
| 145 | |||
| 146 | it should "be converted in the union of its converted conjuncts" in { | ||
| 147 | val visitor = RDFoxClassExprConverter(term_x) | ||
| 148 | val result1 = class_OWLObjectIntersectionOf.accept(visitor) | ||
| 149 | val result2 = RDFoxClassExprConverter.merge( | ||
| 150 | List( | ||
| 151 | class_Female.accept(visitor), | ||
| 152 | class_Student.accept(visitor), | ||
| 153 | class_Worker.accept(visitor) | ||
| 154 | ) | ||
| 155 | ) | ||
| 156 | result1.res should contain theSameElementsAs result2.res | ||
| 157 | result1.ext should contain theSameElementsAs result2.ext | ||
| 158 | } | ||
| 159 | |||
| 160 | // OWLObjectOneOf | ||
| 161 | class_OWLObjectOneOf.toString should "be converted into a RDFoxRuleShards" in { | ||
| 162 | val visitor = RDFoxClassExprConverter(term_x) | ||
| 163 | val result = class_OWLObjectOneOf.accept(visitor) | ||
| 164 | result shouldBe a[RDFoxRuleShards] | ||
| 165 | } | ||
| 166 | |||
| 167 | // it should "be converted into a single <owl:sameAs> TupleTableAtom" in { | ||
| 168 | // val visitor = RDFoxClassExprConverter(term_x) | ||
| 169 | // val result = class_OWLObjectOneOf.accept(visitor) | ||
| 170 | // result.res.loneElement should (be (a [TupleTableAtom]) and have ('tupleTableName (pred_sameAs))) | ||
| 171 | // } | ||
| 172 | |||
| 173 | it should "have an empty extension list" in { | ||
| 174 | val visitor = RDFoxClassExprConverter(term_x) | ||
| 175 | val result = class_OWLObjectOneOf.accept(visitor) | ||
| 176 | result.ext shouldBe empty | ||
| 177 | } | ||
| 178 | |||
| 179 | // OWLObjectSomeValuesFrom | ||
| 180 | (class_OWLObjectSomeValuesFrom.toString ++ " w/o skolemization") should | ||
| 181 | "be converted into a RDFoxRuleShards" in { | ||
| 182 | val visitor = RDFoxClassExprConverter(term_x) | ||
| 183 | val result = class_OWLObjectSomeValuesFrom.accept(visitor) | ||
| 184 | result shouldBe a[RDFoxRuleShards] | ||
| 185 | } | ||
| 186 | |||
| 187 | it should "have two TupleTableAtoms in its result list" in { | ||
| 188 | val visitor = RDFoxClassExprConverter(term_x) | ||
| 189 | val result = class_OWLObjectSomeValuesFrom.accept(visitor) | ||
| 190 | exactly(2, result.res) should (be(an[TupleTableAtom]) | ||
| 191 | //and have('numberOfArguments (3)) | ||
| 192 | ) | ||
| 193 | } | ||
| 194 | |||
| 195 | it should "have an empty extension list" in { | ||
| 196 | val visitor = RDFoxClassExprConverter(term_x) | ||
| 197 | val result = class_OWLObjectSomeValuesFrom.accept(visitor) | ||
| 198 | result.ext shouldBe empty | ||
| 199 | } | ||
| 200 | |||
| 201 | (class_OWLObjectSomeValuesFrom.toString ++ " w/ skolemization") should | ||
| 202 | "be converted into a RDFoxRuleShards" in { | ||
| 203 | val skolem = SkolemStrategy.Standard(class_OWLObjectSomeValuesFrom.toString) | ||
| 204 | val visitor = RDFoxClassExprConverter(term_x, List(), skolem) | ||
| 205 | val result = class_OWLObjectSomeValuesFrom.accept(visitor) | ||
| 206 | result shouldBe a[RDFoxRuleShards] | ||
| 207 | } | ||
| 208 | |||
| 209 | it should "have exactly two TupleTableAtoms in its result list" in { | ||
| 210 | val skolem = SkolemStrategy.Standard(class_OWLObjectSomeValuesFrom.toString) | ||
| 211 | val visitor = RDFoxClassExprConverter(term_x, List(), skolem) | ||
| 212 | val result = class_OWLObjectSomeValuesFrom.accept(visitor) | ||
| 213 | exactly(2, result.res) should (be(an[TupleTableAtom]) | ||
| 214 | //and have('numberOfArguments (3)) | ||
| 215 | ) | ||
| 216 | } | ||
| 217 | |||
| 218 | it should "should have a single SKOLEM call in the extension list" in { | ||
| 219 | val skolem = SkolemStrategy.Standard(class_OWLObjectSomeValuesFrom.toString) | ||
| 220 | val visitor = RDFoxClassExprConverter(term_x, List(), skolem) | ||
| 221 | val result = class_OWLObjectSomeValuesFrom.accept(visitor) | ||
| 222 | result.ext.loneElement shouldBe a[BindAtom] | ||
| 223 | val builtin = result.ext.head.asInstanceOf[BindAtom].getExpression | ||
| 224 | builtin should (be(a[FunctionCall]) and have( | ||
| 225 | 'functionName ("SKOLEM") | ||
| 226 | )) | ||
| 227 | } | ||
| 228 | |||
| 229 | (class_OWLObjectSomeValuesFrom.toString ++ " w/ constant skolemization") should | ||
| 230 | "be converted into a RDFoxRuleShards" in { | ||
| 231 | val skolem = SkolemStrategy.Constant(class_OWLObjectSomeValuesFrom.toString) | ||
| 232 | val visitor = RDFoxClassExprConverter(term_x, List(), skolem) | ||
| 233 | val result = class_OWLObjectSomeValuesFrom.accept(visitor) | ||
| 234 | result shouldBe a[RDFoxRuleShards] | ||
| 235 | } | ||
| 236 | |||
| 237 | it should "have exactly two TupleTableAtoms in its result list" in { | ||
| 238 | val skolem = SkolemStrategy.Constant(class_OWLObjectSomeValuesFrom.toString) | ||
| 239 | val visitor = RDFoxClassExprConverter(term_x, List(), skolem) | ||
| 240 | val result = class_OWLObjectSomeValuesFrom.accept(visitor) | ||
| 241 | exactly(2, result.res) should (be(an[TupleTableAtom]) | ||
| 242 | //and have('numberOfArguments (3)) | ||
| 243 | ) | ||
| 244 | } | ||
| 245 | |||
| 246 | it should "have an empty extension list" in { | ||
| 247 | val skolem = SkolemStrategy.Constant(class_OWLObjectSomeValuesFrom.toString) | ||
| 248 | val visitor = RDFoxClassExprConverter(term_x, List(), skolem) | ||
| 249 | val result = class_OWLObjectSomeValuesFrom.accept(visitor) | ||
| 250 | result.ext shouldBe empty | ||
| 251 | } | ||
| 252 | |||
| 253 | // OWLObjectMaxCardinalityImpl | ||
| 254 | class_OWLObjectMaxCardinality.toString should | ||
| 255 | "be converted into a RDFoxRuleShards" in { | ||
| 256 | val visitor = RDFoxClassExprConverter(term_x) | ||
| 257 | val result = class_OWLObjectMaxCardinality.accept(visitor) | ||
| 258 | result shouldBe a[RDFoxRuleShards] | ||
| 259 | } | ||
| 260 | |||
| 261 | // it should "have a single <owl:sameAs> TupleTableAtom in the result list" in { | ||
| 262 | // val visitor = RDFoxClassExprConverter(term_x) | ||
| 263 | // val result = class_OWLObjectMaxCardinality.accept(visitor) | ||
| 264 | // result.res.loneElement should (be(an[TupleTableAtom]) and have( | ||
| 265 | // 'tupleTableName (pred_sameAs) | ||
| 266 | // )) | ||
| 267 | // } | ||
| 268 | |||
| 269 | it should "have 4 TupleTableAtoms in its extension list" in { | ||
| 270 | val visitor = RDFoxClassExprConverter(term_x) | ||
| 271 | val result = class_OWLObjectMaxCardinality.accept(visitor) | ||
| 272 | exactly(4, result.ext) should (be(an[TupleTableAtom]) | ||
| 273 | //and have('numberOfArguments (3)) | ||
| 274 | ) | ||
| 275 | } | ||
| 276 | |||
| 277 | } // class OWLClassSpec | ||
