aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xgetlibs.sh2
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala32
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala21
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxAxiomConverter.scala134
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxClassExprConverter.scala191
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala12
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxPropertyExprConverter.scala45
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/converter/SkolemStrategy.scala3
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala29
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxUtil.scala53
-rw-r--r--src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLAxiomSpec.scala640
-rw-r--r--src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLClassSpec.scala396
-rw-r--r--src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswerSpecs.scala53
13 files changed, 668 insertions, 943 deletions
diff --git a/getlibs.sh b/getlibs.sh
index 10b1392..be24be7 100755
--- a/getlibs.sh
+++ b/getlibs.sh
@@ -1,6 +1,6 @@
1#!/bin/sh 1#!/bin/sh
2 2
3VERSION="4.0.0" 3VERSION="4.1.0"
4NAME="RDFox-linux-$VERSION" 4NAME="RDFox-linux-$VERSION"
5LINK="https://rdfox-distribution.s3.eu-west-2.amazonaws.com/release/v$VERSION/$NAME.zip" 5LINK="https://rdfox-distribution.s3.eu-west-2.amazonaws.com/release/v$VERSION/$NAME.zip"
6DEST="./lib/" 6DEST="./lib/"
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala
index eaacedc..f54884f 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala
@@ -64,23 +64,35 @@ object RSAComb extends App {
64 case Some(query) => { 64 case Some(query) => {
65 val answers = ontology ask query 65 val answers = ontology ask query
66 Logger.print(s"$answers", Logger.QUIET) 66 Logger.print(s"$answers", Logger.QUIET)
67 Logger print s"Number of answer: ${answers.length}" 67 Logger print s"Number of answer: ${answers.length} (${answers.lengthWithMultiplicity})"
68 68
69 val unfiltered = ontology askUnfiltered query 69 val unfiltered = ontology askUnfiltered query
70 val percentage = unfiltered match { 70 unfiltered map { u =>
71 case Some(u) => { 71 Logger.print(
72 s"Number of unfiltered answers: ${u.length} (${u.map(_._1).sum}).",
73 Logger.DEBUG
74 )
75 //u foreach println
76 val spurious = {
77 val sp =
78 RDFoxUtil.buildDescriptionQuery("SP", query.variables.length)
79 ontology.queryDataStore(query, sp, RSA.Prefixes)
80 }
81 spurious map { s =>
72 Logger.print( 82 Logger.print(
73 s"Number of spurious answers: ${u.length}.", 83 s"Number of spurious answers: ${s.length} (${s.map(_._1).sum})",
84 Logger.DEBUG
85 )
86 //s foreach println
87 val perc =
88 if (u.length > 0) (s.length / u.length.toFloat) * 100 else 0
89 Logger.print(
90 s"Percentage of spurious answers: $perc%",
74 Logger.DEBUG 91 Logger.DEBUG
75 ) 92 )
76 if (u.length > 0) (1 - answers.length / u.length) * 100 else 0
77 } 93 }
78 case None => 0 94
79 } 95 }
80 Logger.print(
81 s"Percentage of spurious answers: $percentage%",
82 Logger.DEBUG
83 )
84 } 96 }
85 case None => 97 case None =>
86 throw new RuntimeException("Submitted query is not conjunctive") 98 throw new RuntimeException("Submitted query is not conjunctive")
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala
index 0f1cd5e..4ac5a77 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala
@@ -24,7 +24,11 @@ import org.semanticweb.owlapi.reasoner.structural.StructuralReasonerFactory
24import org.semanticweb.owlapi.model.{IRI => OWLIRI} 24import org.semanticweb.owlapi.model.{IRI => OWLIRI}
25import uk.ac.manchester.cs.owl.owlapi.OWLObjectPropertyImpl 25import uk.ac.manchester.cs.owl.owlapi.OWLObjectPropertyImpl
26 26
27import tech.oxfordsemantic.jrdfox.client.{UpdateType, DataStoreConnection} 27import tech.oxfordsemantic.jrdfox.client.{
28 DataStoreConnection,
29 TransactionType,
30 UpdateType
31}
28import tech.oxfordsemantic.jrdfox.Prefixes 32import tech.oxfordsemantic.jrdfox.Prefixes
29import tech.oxfordsemantic.jrdfox.logic.datalog.{ 33import tech.oxfordsemantic.jrdfox.logic.datalog.{
30 Rule, 34 Rule,
@@ -352,22 +356,31 @@ class RSAOntology(val ontology: OWLOntology) {
352 val canon = this.canonicalModel 356 val canon = this.canonicalModel
353 val filter = this.filteringProgram(query) 357 val filter = this.filteringProgram(query)
354 358
359 //data.beginTransaction(TransactionType.READ_WRITE)
360
355 Logger print s"Canonical model: ${canon.rules.length} rules" 361 Logger print s"Canonical model: ${canon.rules.length} rules"
356 RDFoxUtil.addRules(data, this.canonicalModel.rules) 362 RDFoxUtil.addRules(data, this.canonicalModel.rules)
357 363
358 Logger print s"Canonical model: ${canon.facts.length} facts" 364 Logger print s"Canonical model: ${canon.facts.length} facts"
359 RDFoxUtil.addFacts(data, this.canonicalModel.facts) 365 RDFoxUtil.addFacts(data, this.canonicalModel.facts)
360 366
361 RDFoxUtil printStatisticsFor data 367 Logger print s"Filtering program: ${filter.facts.length} facts"
368 RDFoxUtil.addFacts(data, filter.facts)
362 369
363 Logger print s"Filtering program: ${filter.rules.length} rules" 370 Logger print s"Filtering program: ${filter.rules.length} rules"
364 RDFoxUtil.addRules(data, filter.rules) 371 RDFoxUtil.addRules(data, filter.rules)
365 372
366 Logger print s"Filtering program: ${filter.facts.length} facts" 373 //data.commitTransaction()
367 RDFoxUtil.addFacts(data, filter.facts)
368 374
369 RDFoxUtil printStatisticsFor data 375 RDFoxUtil printStatisticsFor data
370 376
377 //{
378 // import java.io.{FileOutputStream, File}
379 // val rules = new FileOutputStream(new File("rules2.dlog"))
380 // val facts = new FileOutputStream(new File("facts2.ttl"))
381 // RDFoxUtil.export(data, rules, facts)
382 //}
383
371 val answers = { 384 val answers = {
372 val ans = RDFoxUtil.buildDescriptionQuery("Ans", query.answer.size) 385 val ans = RDFoxUtil.buildDescriptionQuery("Ans", query.answer.size)
373 RDFoxUtil 386 RDFoxUtil
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxAxiomConverter.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxAxiomConverter.scala
deleted file mode 100644
index 1fbf28a..0000000
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxAxiomConverter.scala
+++ /dev/null
@@ -1,134 +0,0 @@
1package uk.ac.ox.cs.rsacomb.converter
2
3import org.semanticweb.owlapi.model.{
4 OWLAxiom,
5 OWLSubClassOfAxiom,
6 OWLEquivalentClassesAxiom,
7 OWLObjectPropertyExpression,
8 OWLObjectPropertyDomainAxiom,
9 OWLObjectPropertyRangeAxiom,
10 OWLDataPropertyDomainAxiom,
11 OWLDataPropertyRangeAxiom,
12 OWLInverseObjectPropertiesAxiom
13}
14import org.semanticweb.owlapi.model.OWLAxiomVisitorEx
15
16import tech.oxfordsemantic.jrdfox.logic.datalog.{
17 Rule,
18 BodyFormula,
19 TupleTableAtom,
20 TupleTableName
21}
22import tech.oxfordsemantic.jrdfox.logic.expression.{
23 Term,
24 IRI => RDFoxIRI,
25 Variable,
26 Literal
27}
28
29import scala.collection.JavaConverters._
30
31import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom
32import org.semanticweb.owlapi.model.OWLObjectProperty
33import org.semanticweb.owlapi.model.OWLClassAssertionAxiom
34
35import uk.ac.ox.cs.rsacomb.RSAOntology
36import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Empty}
37import uk.ac.manchester.cs.owl.owlapi.OWLSubClassOfAxiomImpl
38import uk.ac.manchester.cs.owl.owlapi.OWLObjectSomeValuesFromImpl
39import uk.ac.manchester.cs.owl.owlapi.OWLClassImpl
40import org.semanticweb.owlapi.model.IRI
41
42object RDFoxAxiomConverter {
43
44 def apply(
45 term: Term,
46 unsafe: List[OWLObjectPropertyExpression],
47 skolem: SkolemStrategy = NoSkolem,
48 suffix: RSASuffix = Empty
49 ): RDFoxAxiomConverter =
50 new RDFoxAxiomConverter(term, unsafe, skolem, suffix)
51
52} // object RDFoxAxiomConverter
53
54class RDFoxAxiomConverter(
55 term: Term,
56 unsafe: List[OWLObjectPropertyExpression],
57 skolem: SkolemStrategy,
58 suffix: RSASuffix
59) extends OWLAxiomVisitorEx[List[Rule]] {
60
61 import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._
62
63 override def visit(axiom: OWLSubClassOfAxiom): List[Rule] = {
64 // Skolemization is needed only for the head of an axiom
65 val subVisitor =
66 new RDFoxClassExprConverter(term, unsafe, NoSkolem, suffix)
67 val superVisitor = new RDFoxClassExprConverter(term, unsafe, skolem, suffix)
68 // Each visitor returns a `RDFoxRuleShards`, a tuple (res,ext):
69 // - the `res` List is a list of atoms resulting from the conversion
70 // of the axiom.
71 // - for some Class Expressions appearing in the head of an Axiom,
72 // the conversion might produce atoms that need to appear in the
73 // body (and not in the head) of the rule. This is what the `ext`
74 // List is for.
75 val sub = axiom.getSubClass.accept(subVisitor)
76 val sup = axiom.getSuperClass.accept(superVisitor)
77 val head = sup.res.asJava
78 val body = (sub.res ++ sup.ext).asJava
79 List(Rule.create(head, body))
80 }
81
82 override def visit(axiom: OWLEquivalentClassesAxiom): List[Rule] = {
83 for {
84 axiom1 <- axiom.asPairwiseAxioms.asScala.toList
85 axiom2 <- axiom1.asOWLSubClassOfAxioms.asScala.toList
86 rule <- axiom2.accept(this)
87 } yield rule
88 }
89
90 override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = {
91 val term1 = RSAOntology.genFreshVariable()
92 val subVisitor =
93 new RDFoxPropertyExprConverter(term, term1, suffix)
94 val superVisitor = new RDFoxPropertyExprConverter(term, term1, suffix)
95 val body: List[BodyFormula] = axiom.getSubProperty.accept(subVisitor)
96 val head: List[TupleTableAtom] = axiom.getSuperProperty.accept(superVisitor)
97 List(Rule.create(head.asJava, body.asJava))
98 }
99
100 override def visit(axiom: OWLObjectPropertyDomainAxiom): List[Rule] =
101 axiom.asOWLSubClassOfAxiom.accept(this)
102
103 override def visit(axiom: OWLObjectPropertyRangeAxiom): List[Rule] = {
104 val term1 = RSAOntology.genFreshVariable()
105 val rangeVisitor = new RDFoxClassExprConverter(term, unsafe, skolem, suffix)
106 val range = axiom.getRange.accept(rangeVisitor)
107 val propertyVisitor = new RDFoxPropertyExprConverter(term1, term, suffix)
108 val prop = axiom.getProperty.accept(propertyVisitor)
109 List(Rule.create(range.res, range.ext ::: prop))
110 }
111
112 override def visit(axiom: OWLDataPropertyDomainAxiom): List[Rule] =
113 axiom.asOWLSubClassOfAxiom.accept(this)
114
115 override def visit(axiom: OWLInverseObjectPropertiesAxiom): List[Rule] =
116 axiom.asSubObjectPropertyOfAxioms.asScala.toList.flatMap(_.accept(this))
117
118 override def visit(axiom: OWLClassAssertionAxiom): List[Rule] = {
119 val ind = axiom.getIndividual
120 if (ind.isNamed) {
121 val term = RDFoxIRI.create(ind.asOWLNamedIndividual().getIRI.getIRIString)
122 val cls = axiom.getClassExpression
123 val visitor =
124 new RDFoxClassExprConverter(term, unsafe, NoSkolem, suffix)
125 val shard = cls.accept(visitor)
126 List(Rule.create(shard.res.asJava, shard.ext.asJava))
127 } else {
128 List()
129 }
130 }
131
132 def doDefault(axiom: OWLAxiom): List[Rule] = List()
133
134} // class RDFoxAxiomConverter
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxClassExprConverter.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxClassExprConverter.scala
deleted file mode 100644
index 9551c61..0000000
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxClassExprConverter.scala
+++ /dev/null
@@ -1,191 +0,0 @@
1package uk.ac.ox.cs.rsacomb.converter
2
3import scala.collection.JavaConverters._
4import java.util.stream.{Stream, Collectors}
5
6import org.semanticweb.owlapi.model.{
7 OWLClassExpression,
8 OWLClass,
9 OWLObjectSomeValuesFrom,
10 OWLDataSomeValuesFrom,
11 OWLObjectIntersectionOf,
12 OWLObjectOneOf,
13 OWLObjectMaxCardinality
14}
15import org.semanticweb.owlapi.model.OWLClassExpressionVisitorEx
16import tech.oxfordsemantic.jrdfox.logic.Datatype
17import tech.oxfordsemantic.jrdfox.logic.datalog.{
18 BindAtom,
19 TupleTableName,
20 TupleTableAtom
21}
22import tech.oxfordsemantic.jrdfox.logic.expression.{
23 Term,
24 Literal,
25 Variable,
26 FunctionCall,
27 IRI
28}
29
30import org.semanticweb.owlapi.model.OWLObjectPropertyExpression
31import org.semanticweb.owlapi.model.OWLObjectProperty
32
33import uk.ac.ox.cs.rsacomb.RSAOntology
34import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Empty}
35import uk.ac.ox.cs.rsacomb.util.RSA
36
37object RDFoxClassExprConverter {
38
39 def apply(
40 term: Term,
41 unsafe: List[OWLObjectPropertyExpression] = List(),
42 skolem: SkolemStrategy = NoSkolem,
43 suffix: RSASuffix = Empty
44 ): RDFoxClassExprConverter =
45 new RDFoxClassExprConverter(term, unsafe, skolem, suffix)
46
47 def merge(rules: List[RDFoxRuleShards]): RDFoxRuleShards = {
48 rules.foldLeft(RDFoxRuleShards(List(), List())) { (r1, r2) =>
49 RDFoxRuleShards(
50 r1.res ++ r2.res,
51 r1.ext ++ r2.ext
52 )
53 }
54 }
55
56} // object RDFoxClassExprConverter
57
58class RDFoxClassExprConverter(
59 term: Term,
60 unsafe: List[OWLObjectPropertyExpression],
61 skolem: SkolemStrategy = NoSkolem,
62 suffix: RSASuffix = Empty
63) extends OWLClassExpressionVisitorEx[RDFoxRuleShards] {
64
65 import uk.ac.ox.cs.rsacomb.implicits.RDFox._
66
67 // OWLClass
68 override def visit(expr: OWLClass): RDFoxRuleShards = {
69 val iri: IRI = if (expr.isTopEntity()) IRI.THING else expr.getIRI()
70 val atom = List(TupleTableAtom.rdf(term, IRI.RDF_TYPE, iri))
71 RDFoxRuleShards(atom, List())
72 }
73
74 // OWLObjectIntersectionOf
75 override def visit(expr: OWLObjectIntersectionOf): RDFoxRuleShards = {
76 val visitor = new RDFoxClassExprConverter(term, unsafe, skolem, suffix)
77 // TODO: maybe using `flatMap` instead of `merge` + `map` works as well
78 RDFoxClassExprConverter.merge(
79 expr.asConjunctSet.asScala.toList
80 .map((e: OWLClassExpression) => e.accept(visitor))
81 )
82 }
83
84 // OWLObjectOneOf
85 override def visit(expr: OWLObjectOneOf): RDFoxRuleShards = {
86 // TODO: review nominal handling. Here we are taking "just" one
87 val ind = expr.individuals
88 .collect(Collectors.toList())
89 .asScala
90 .filter(_.isOWLNamedIndividual)
91 .head // restricts to proper "nominals"
92 .asOWLNamedIndividual
93 .getIRI
94 val atom = List(
95 TupleTableAtom.rdf(term, IRI.SAME_AS, ind)
96 )
97 RDFoxRuleShards(atom, List())
98 }
99
100 // OWLObjectSomeValuesFrom
101 override def visit(expr: OWLObjectSomeValuesFrom): RDFoxRuleShards = {
102 val y = RSAOntology.genFreshVariable()
103 // Here we are assuming a role name
104 val prop = expr.getProperty()
105 // Computes the result of rule skolemization. Depending on the used
106 // technique it might involve the introduction of additional atoms,
107 // and/or fresh constants and variables.
108 val (head, body, term1) = skolem match {
109 case NoSkolem => (List(), List(), y)
110 case c: Constant => (List(), List(), c.iri)
111 case s: Standard => {
112 (
113 List(),
114 List(
115 BindAtom.create(FunctionCall.create("SKOLEM", s.literal, term), y)
116 ),
117 y
118 )
119 }
120 }
121 val classVisitor =
122 new RDFoxClassExprConverter(term1, unsafe, skolem, suffix)
123 val classResult = expr.getFiller.accept(classVisitor)
124 val propertyVisitor = new RDFoxPropertyExprConverter(term, term1, suffix)
125 val propertyResult = expr.getProperty.accept(propertyVisitor)
126 RDFoxRuleShards(
127 classResult.res ++ propertyResult ++ head,
128 classResult.ext ++ body
129 )
130 }
131
132 /** Converts a [[org.semanticweb.owlapi.model.OWLDataSomeValuesFrom OWLDataSomeValuesFrom]]
133 *
134 * @note we assume the expression is "simple", meaning that the
135 * property involved is a role name or the inverse of a role name.
136 * This assumption will be lifted when we will deal with the
137 * normalization of the input ontology.
138 *
139 * @todo the "filler" of this OWL expression is currently ignored. We
140 * need to find a way (if any) to handle
141 * [[org.semanticweb.owlapi.model.OWLDataRange OWLDataRange]]
142 * in RDFox.
143 */
144 override def visit(expr: OWLDataSomeValuesFrom): RDFoxRuleShards = {
145 val y = RSAOntology.genFreshVariable()
146 val prop = expr.getProperty()
147 // Computes the result of rule skolemization. Depending on the used
148 // technique it might involve the introduction of additional atoms,
149 // and/or fresh constants and variables.
150 val (head, body, term1) = skolem match {
151 case NoSkolem => (List(), List(), y)
152 case c: Constant => (List(), List(), c.iri)
153 case s: Standard => {
154 (
155 List(),
156 List(
157 BindAtom.create(FunctionCall.create("SKOLEM", s.literal, term), y)
158 ),
159 y
160 )
161 }
162 }
163 val propertyVisitor = new RDFoxPropertyExprConverter(term, term1, suffix)
164 val propertyResult = expr.getProperty.accept(propertyVisitor)
165 RDFoxRuleShards(head ::: propertyResult, body)
166 }
167
168 // OWLObjectMaxCardinality
169 override def visit(expr: OWLObjectMaxCardinality): RDFoxRuleShards = {
170 val vars =
171 List(RSAOntology.genFreshVariable(), RSAOntology.genFreshVariable())
172 val classResult = RDFoxClassExprConverter.merge(
173 vars
174 .map(new RDFoxClassExprConverter(_, unsafe, skolem, suffix))
175 .map(expr.getFiller.accept(_))
176 )
177 val propertyResult =
178 vars
179 .map(new RDFoxPropertyExprConverter(term, _, suffix))
180 .map(expr.getProperty.accept(_))
181 .flatten
182 RDFoxRuleShards(
183 List(TupleTableAtom.rdf(vars(0), IRI.SAME_AS, vars(1))),
184 classResult.res ++ propertyResult
185 )
186 }
187
188 def doDefault(expr: OWLClassExpression): RDFoxRuleShards =
189 RDFoxRuleShards(List(), List())
190
191} // class RDFoxClassExprConverter
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala
index b4f5adb..845ec1f 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala
@@ -40,7 +40,7 @@ import tech.oxfordsemantic.jrdfox.logic.datalog.{
40import tech.oxfordsemantic.jrdfox.logic.expression.{Term, IRI, FunctionCall} 40import tech.oxfordsemantic.jrdfox.logic.expression.{Term, IRI, FunctionCall}
41import uk.ac.ox.cs.rsacomb.RSAOntology 41import uk.ac.ox.cs.rsacomb.RSAOntology
42import uk.ac.ox.cs.rsacomb.suffix.{Empty, Inverse, RSASuffix} 42import uk.ac.ox.cs.rsacomb.suffix.{Empty, Inverse, RSASuffix}
43import uk.ac.ox.cs.rsacomb.util.RSA 43import uk.ac.ox.cs.rsacomb.util.{RSA, RDFoxUtil}
44 44
45/** Horn-ALCHOIQ to RDFox axiom converter. 45/** Horn-ALCHOIQ to RDFox axiom converter.
46 * 46 *
@@ -328,10 +328,7 @@ trait RDFoxConverter {
328 val (bind, term1) = skolem match { 328 val (bind, term1) = skolem match {
329 case NoSkolem => (None, varX) 329 case NoSkolem => (None, varX)
330 case c: Constant => (None, c.iri) 330 case c: Constant => (None, c.iri)
331 case s: Standard => { 331 case s: Standard => (Some(RDFoxUtil.skolem(s.name, term, varX)), varX)
332 val func = FunctionCall.create("SKOLEM", s.literal, term)
333 (Some(BindAtom.create(func, varX)), varX)
334 }
335 } 332 }
336 val (res, ext) = convert(cls, term1, unsafe, skolem, suffix) 333 val (res, ext) = convert(cls, term1, unsafe, skolem, suffix)
337 val prop = convert(role, term, term1, suffix) 334 val prop = convert(role, term, term1, suffix)
@@ -359,10 +356,7 @@ trait RDFoxConverter {
359 val (bind, term1) = skolem match { 356 val (bind, term1) = skolem match {
360 case NoSkolem => (None, varX) 357 case NoSkolem => (None, varX)
361 case c: Constant => (None, c.iri) 358 case c: Constant => (None, c.iri)
362 case s: Standard => { 359 case s: Standard => (Some(RDFoxUtil.skolem(s.name, term, varX)), varX)
363 val func = FunctionCall.create("SKOLEM", s.literal, term)
364 (Some(BindAtom.create(func, varX)), varX)
365 }
366 } 360 }
367 val prop = convert(role, term, term1, suffix) 361 val prop = convert(role, term, term1, suffix)
368 (List(prop), bind.toList) 362 (List(prop), bind.toList)
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxPropertyExprConverter.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxPropertyExprConverter.scala
deleted file mode 100644
index 46a70fa..0000000
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxPropertyExprConverter.scala
+++ /dev/null
@@ -1,45 +0,0 @@
1package uk.ac.ox.cs.rsacomb.converter
2
3import org.semanticweb.owlapi.model.{
4 OWLAnnotationProperty,
5 OWLDataProperty,
6 OWLObjectInverseOf,
7 OWLObjectProperty,
8 OWLPropertyExpression
9}
10import org.semanticweb.owlapi.model.OWLPropertyExpressionVisitorEx
11
12import tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom
13import tech.oxfordsemantic.jrdfox.logic.expression.{Term, IRI, Literal}
14
15import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Inverse}
16
17class RDFoxPropertyExprConverter(
18 term1: Term,
19 term2: Term,
20 suffix: RSASuffix
21) extends OWLPropertyExpressionVisitorEx[List[TupleTableAtom]] {
22
23 // Automatically converts OWLAPI types into RDFox equivalent types.
24 import uk.ac.ox.cs.rsacomb.implicits.RDFox._
25
26 override def visit(expr: OWLObjectProperty): List[TupleTableAtom] = {
27 val base = expr.getIRI.getIRIString
28 val pred = IRI.create(base :: suffix)
29 List(TupleTableAtom.rdf(term1, pred, term2))
30 }
31
32 override def visit(expr: OWLDataProperty): List[TupleTableAtom] = {
33 val base = expr.getIRI.getIRIString
34 val pred = IRI.create(base :: suffix)
35 List(TupleTableAtom.rdf(term1, pred, term2))
36 }
37
38 override def visit(expr: OWLObjectInverseOf): List[TupleTableAtom] = {
39 val visitor = new RDFoxPropertyExprConverter(term1, term2, suffix + Inverse)
40 expr.getInverse.accept(visitor)
41 }
42
43 def doDefault(expr: OWLPropertyExpression): List[TupleTableAtom] = List()
44
45} // class RDFoxPropertyExprConverter
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/SkolemStrategy.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/SkolemStrategy.scala
index 2142ff3..426a327 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/SkolemStrategy.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/SkolemStrategy.scala
@@ -53,8 +53,7 @@ case object NoSkolem extends SkolemStrategy {
53case class Standard(axiom: OWLAxiom)(implicit toString: (OWLAxiom) => String) 53case class Standard(axiom: OWLAxiom)(implicit toString: (OWLAxiom) => String)
54 extends SkolemStrategy { 54 extends SkolemStrategy {
55 def dup(_axiom: OWLAxiom): Standard = copy(axiom = _axiom)(toString) 55 def dup(_axiom: OWLAxiom): Standard = copy(axiom = _axiom)(toString)
56 lazy val literal = 56 lazy val name = s"f_${toString(axiom)}"
57 Literal.create(s"f_${toString(axiom)}", Datatype.XSD_STRING)
58} 57}
59 58
60/** Constant skolemization 59/** Constant skolemization
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala
index 615722b..9b04f0e 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala
@@ -1,17 +1,17 @@
1package uk.ac.ox.cs.rsacomb.implicits 1package uk.ac.ox.cs.rsacomb.implicits
2 2
3import tech.oxfordsemantic.jrdfox.logic.Datatype 3import tech.oxfordsemantic.jrdfox.logic.Datatype
4import tech.oxfordsemantic.jrdfox.logic.expression.{Literal, FunctionCall} 4import tech.oxfordsemantic.jrdfox.logic.expression.{Literal, FunctionCall, Term}
5import tech.oxfordsemantic.jrdfox.logic.datalog.{ 5import tech.oxfordsemantic.jrdfox.logic.datalog.{
6 BindAtom, 6 BindAtom,
7 TupleTableAtom, 7 TupleTableAtom,
8 TupleTableName 8 TupleTableName
9} 9}
10import tech.oxfordsemantic.jrdfox.logic.expression.{IRI} 10import tech.oxfordsemantic.jrdfox.logic.expression.{IRI}
11import scala.collection.JavaConverters._
12 11
13import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Nth}
14import uk.ac.ox.cs.rsacomb.RSAOntology 12import uk.ac.ox.cs.rsacomb.RSAOntology
13import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Nth}
14import uk.ac.ox.cs.rsacomb.util.RDFoxUtil
15 15
16/* Is this the best way to determine if an atom is an RDF triple? 16/* Is this the best way to determine if an atom is an RDF triple?
17 * Note that we can't use `getNumberOfArguments()` because is not 17 * Note that we can't use `getNumberOfArguments()` because is not
@@ -24,7 +24,7 @@ import uk.ac.ox.cs.rsacomb.RSAOntology
24 * This is probably because `Atom.rdf(...) is implemented as: 24 * This is probably because `Atom.rdf(...) is implemented as:
25 * ```scala 25 * ```scala
26 * def rdf(term1: Term, term2: Term, term3: Term): Atom = 26 * def rdf(term1: Term, term2: Term, term3: Term): Atom =
27 * Atom.create(TupleTableName.create("internal:triple"), term1, term2, term3) 27 * Atom.create(TupleTableName.create("rdfox:DefaultTriples"), term1, term2, term3)
28 * ``` 28 * ```
29 */ 29 */
30 30
@@ -33,10 +33,14 @@ object RSAAtom {
33 implicit class RSAAtom(val atom: TupleTableAtom) { 33 implicit class RSAAtom(val atom: TupleTableAtom) {
34 34
35 import RDFox._ 35 import RDFox._
36 import JavaCollections._
36 37
37 val name: String = atom.getTupleTableName.getName 38 val name: String = atom.getTupleTableName.getName
38 39
39 val isRDF: Boolean = name == "internal:triple" 40 val args: List[Term] = atom.getArguments
41
42 val isRDF: Boolean =
43 name == "http://oxfordsemantic.tech/RDFox#DefaultTriples"
40 44
41 val isClassAssertion: Boolean = { 45 val isClassAssertion: Boolean = {
42 isRDF && { 46 isRDF && {
@@ -70,19 +74,16 @@ object RSAAtom {
70 TupleTableAtom.create(ttname, atom.getArguments()) 74 TupleTableAtom.create(ttname, atom.getArguments())
71 } 75 }
72 76
73 lazy val reified: (Option[BindAtom], List[TupleTableAtom]) = 77 lazy val reified: (Option[TupleTableAtom], List[TupleTableAtom]) =
74 if (isRDF) { 78 if (isRDF) {
75 (None, List(atom)) 79 (None, List(atom))
76 } else { 80 } else {
77 val bvar = RSAOntology.genFreshVariable() 81 val varS = RSAOntology.genFreshVariable()
78 val str = Literal.create(name, Datatype.XSD_STRING) 82 val skolem = RDFoxUtil.skolem(name, (args :+ varS): _*)
79 val args = atom.getArguments.asScala.toList 83 val atom = TupleTableAtom.rdf(varS, IRI.RDF_TYPE, name)
80 val skolem = FunctionCall.create("SKOLEM", str :: args: _*)
81 val bind = BindAtom.create(skolem, bvar)
82 val atoms = args.zipWithIndex 84 val atoms = args.zipWithIndex
83 .map { case (t, i) => TupleTableAtom.rdf(bvar, name :: Nth(i), t) } 85 .map { case (a, i) => TupleTableAtom.rdf(varS, name :: Nth(i), a) }
84 (Some(bind), atoms) 86 (Some(skolem), atom :: atoms)
85 } 87 }
86 } 88 }
87
88} 89}
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxUtil.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxUtil.scala
index 76f720c..d072e48 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxUtil.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxUtil.scala
@@ -1,7 +1,6 @@
1package uk.ac.ox.cs.rsacomb.util 1package uk.ac.ox.cs.rsacomb.util
2 2
3import java.io.File 3import java.io.{OutputStream, File, StringReader}
4import java.io.StringReader
5import tech.oxfordsemantic.jrdfox.Prefixes 4import tech.oxfordsemantic.jrdfox.Prefixes
6import tech.oxfordsemantic.jrdfox.client.{ 5import tech.oxfordsemantic.jrdfox.client.{
7 ComponentInfo, 6 ComponentInfo,
@@ -11,6 +10,7 @@ import tech.oxfordsemantic.jrdfox.client.{
11 UpdateType 10 UpdateType
12} 11}
13import tech.oxfordsemantic.jrdfox.formats.SPARQLParser 12import tech.oxfordsemantic.jrdfox.formats.SPARQLParser
13import tech.oxfordsemantic.jrdfox.logic.Datatype
14import tech.oxfordsemantic.jrdfox.logic.datalog.{ 14import tech.oxfordsemantic.jrdfox.logic.datalog.{
15 Rule, 15 Rule,
16 BodyFormula, 16 BodyFormula,
@@ -18,7 +18,12 @@ import tech.oxfordsemantic.jrdfox.logic.datalog.{
18 TupleTableAtom, 18 TupleTableAtom,
19 TupleTableName 19 TupleTableName
20} 20}
21import tech.oxfordsemantic.jrdfox.logic.expression.{Resource} 21import tech.oxfordsemantic.jrdfox.logic.expression.{
22 Literal,
23 Resource,
24 Variable,
25 Term
26}
22import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery 27import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery
23import uk.ac.ox.cs.rsacomb.suffix.Nth 28import uk.ac.ox.cs.rsacomb.suffix.Nth
24import uk.ac.ox.cs.rsacomb.util.Logger 29import uk.ac.ox.cs.rsacomb.util.Logger
@@ -69,6 +74,13 @@ object RDFoxUtil {
69 (server, data) 74 (server, data)
70 } 75 }
71 76
77 /** Create a built-in `rdfox:SKOLEM` TupleTableAtom. */
78 def skolem(name: String, terms: Term*): TupleTableAtom =
79 TupleTableAtom.create(
80 TupleTableName.SKOLEM,
81 (Literal.create(name, Datatype.XSD_STRING) +: terms): _*
82 )
83
72 /** Prints statistics from RDFox datastore. 84 /** Prints statistics from RDFox datastore.
73 * 85 *
74 * Prints something only when Logger level is set to DEBUG or more. 86 * Prints something only when Logger level is set to DEBUG or more.
@@ -127,6 +139,26 @@ object RDFoxUtil {
127 query 139 query
128 } 140 }
129 141
142 /** Export data in `text/turtle`.
143 *
144 * @param data datastore connection from which to export data.
145 * @param rules output stream for rules
146 * @param facts output stream for facts
147 */
148 def export(
149 data: DataStoreConnection,
150 rules: OutputStream,
151 facts: OutputStream
152 ): Unit = {
153 data.exportData(Prefixes.s_emptyPrefixes, facts, "text/turtle", RDFoxOpts())
154 data.exportData(
155 Prefixes.s_emptyPrefixes,
156 rules,
157 "application/x.datalog",
158 RDFoxOpts()
159 )
160 }
161
130 /** Parse a SELECT query from a string in SPARQL format. 162 /** Parse a SELECT query from a string in SPARQL format.
131 * 163 *
132 * @param query the string containing the SPARQL query 164 * @param query the string containing the SPARQL query
@@ -218,7 +250,7 @@ object RDFoxUtil {
218 .map(i => s"?S rsa:${pred :: Nth(i)} ?X$i .") 250 .map(i => s"?S rsa:${pred :: Nth(i)} ?X$i .")
219 .mkString("WHERE {\n", "\n", "\n}") 251 .mkString("WHERE {\n", "\n", "\n}")
220 } else { 252 } else {
221 s"ASK { ?X a rsa:${pred :: Nth(0)} }" 253 s"ASK { ?X a rsa:$pred }"
222 } 254 }
223 } 255 }
224 256
@@ -231,11 +263,11 @@ object RDFoxUtil {
231 * built-in `SKOLEM` funtion of RDFox. 263 * built-in `SKOLEM` funtion of RDFox.
232 */ 264 */
233 def reify(rule: Rule): Rule = { 265 def reify(rule: Rule): Rule = {
234 val (bs, as) = rule.getHead.map(_.reified).unzip 266 val (sk, as) = rule.getHead.map(_.reified).unzip
235 val head: List[TupleTableAtom] = as.flatten 267 val head: List[TupleTableAtom] = as.flatten
236 val bind: List[BodyFormula] = bs.flatten 268 val skolem: List[BodyFormula] = sk.flatten
237 val body: List[BodyFormula] = rule.getBody.map(reify).flatten 269 val body: List[BodyFormula] = rule.getBody.map(reify).flatten
238 Rule.create(head, bind ::: body) 270 Rule.create(head, skolem ::: body)
239 } 271 }
240 272
241 /** Reify a [[tech.oxfordsemantic.jrdfox.logic.datalog.BodyFormula BodyFormula]]. 273 /** Reify a [[tech.oxfordsemantic.jrdfox.logic.datalog.BodyFormula BodyFormula]].
@@ -250,15 +282,16 @@ object RDFoxUtil {
250 formula match { 282 formula match {
251 case atom: TupleTableAtom => atom.reified._2 283 case atom: TupleTableAtom => atom.reified._2
252 case neg: Negation => { 284 case neg: Negation => {
253 val (bs, as) = neg.getNegatedAtoms 285 val (sk, as) = neg.getNegatedAtoms
254 .map({ 286 .map({
255 case a: TupleTableAtom => a.reified 287 case a: TupleTableAtom => a.reified
256 case a => (None, List(a)) 288 case a => (None, List(a))
257 }) 289 })
258 .unzip 290 .unzip
259 val bind = bs.flatten.map(_.getBoundVariable) 291 val skolem =
292 sk.flatten.map(_.getArguments.last).collect { case v: Variable => v }
260 val atoms = as.flatten 293 val atoms = as.flatten
261 List(Negation.create(bind, atoms)) 294 List(Negation.create(skolem, atoms))
262 } 295 }
263 case other => List(other) 296 case other => List(other)
264 } 297 }
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLAxiomSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLAxiomSpec.scala
index eb49c7d..62cda1d 100644
--- a/src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLAxiomSpec.scala
+++ b/src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLAxiomSpec.scala
@@ -1,336 +1,336 @@
1package uk.ac.ox.cs.rsacomb.converter 1package uk.ac.ox.cs.rsacomb.converter
2 2
3import java.util.{ArrayList => JList} 3// import java.util.{ArrayList => JList}
4import org.scalatest.LoneElement 4import org.scalatest.LoneElement
5import org.scalatest.flatspec.AnyFlatSpec 5import org.scalatest.flatspec.AnyFlatSpec
6import org.scalatest.matchers.should.Matchers 6import org.scalatest.matchers.should.Matchers
7 7
8import org.semanticweb.owlapi.model.OWLClassExpression 8// import org.semanticweb.owlapi.model.OWLClassExpression
9import uk.ac.manchester.cs.owl.owlapi.{OWLSubClassOfAxiomImpl} 9// import uk.ac.manchester.cs.owl.owlapi.{OWLSubClassOfAxiomImpl}
10import uk.ac.manchester.cs.owl.owlapi.{ 10// import uk.ac.manchester.cs.owl.owlapi.{
11 OWLClassImpl, 11// OWLClassImpl,
12 OWLObjectSomeValuesFromImpl, 12// OWLObjectSomeValuesFromImpl,
13 OWLObjectIntersectionOfImpl, 13// OWLObjectIntersectionOfImpl,
14 OWLObjectOneOfImpl, 14// OWLObjectOneOfImpl,
15 OWLObjectAllValuesFromImpl, 15// OWLObjectAllValuesFromImpl,
16 OWLObjectMaxCardinalityImpl, 16// OWLObjectMaxCardinalityImpl,
17 OWLNamedIndividualImpl 17// OWLNamedIndividualImpl
18} 18// }
19import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl} 19// import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl}
20import org.semanticweb.owlapi.model.{OWLAxiom} 20// import org.semanticweb.owlapi.model.{OWLAxiom}
21 21
22import tech.oxfordsemantic.jrdfox.logic.Datatype 22// import tech.oxfordsemantic.jrdfox.logic.Datatype
23import tech.oxfordsemantic.jrdfox.logic.datalog.{ 23// import tech.oxfordsemantic.jrdfox.logic.datalog.{
24 Rule, 24// Rule,
25 BindAtom, 25// BindAtom,
26 TupleTableAtom, 26// TupleTableAtom,
27 TupleTableName 27// TupleTableName
28} 28// }
29import tech.oxfordsemantic.jrdfox.logic.expression.{ 29// import tech.oxfordsemantic.jrdfox.logic.expression.{
30 FunctionCall, 30// FunctionCall,
31 Term, 31// Term,
32 Variable, 32// Variable,
33 Literal 33// Literal
34} 34// }
35 35
36import org.semanticweb.owlapi.model.{IRI => OWLIRI} 36// import org.semanticweb.owlapi.model.{IRI => OWLIRI}
37import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI} 37// import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI}
38 38
39import uk.ac.ox.cs.rsacomb.converter._ 39// import uk.ac.ox.cs.rsacomb.converter._
40import uk.ac.ox.cs.rsacomb.util.RSA 40// import uk.ac.ox.cs.rsacomb.util.RSA
41 41
42object OWLAxiomSpec { 42object OWLAxiomSpec {
43 43
44 // IRI 44 //// IRI
45 val iri_Professor = OWLIRI.create("univ:Professor") 45 //val iri_Professor = OWLIRI.create("univ:Professor")
46 val iri_Female = OWLIRI.create("std:Female") 46 //val iri_Female = OWLIRI.create("std:Female")
47 val iri_Student = OWLIRI.create("univ:Student") 47 //val iri_Student = OWLIRI.create("univ:Student")
48 val iri_PartTimeStudent = OWLIRI.create("univ:PartTimeStudent") 48 //val iri_PartTimeStudent = OWLIRI.create("univ:PartTimeStudent")
49 val iri_Worker = OWLIRI.create("univ:Worker") 49 //val iri_Worker = OWLIRI.create("univ:Worker")
50 val iri_alice = OWLIRI.create("univ:alice") 50 //val iri_alice = OWLIRI.create("univ:alice")
51 val iri_supervises = OWLIRI.create("univ:supervises") 51 //val iri_supervises = OWLIRI.create("univ:supervises")
52 val iri_hasSupervisor = OWLIRI.create("univ:hasSupervisor") 52 //val iri_hasSupervisor = OWLIRI.create("univ:hasSupervisor")
53 val iri_sameAs = OWLIRI.create("owl:sameAs") 53 //val iri_sameAs = OWLIRI.create("owl:sameAs")
54 54
55 // RDFox Terms 55 //// RDFox Terms
56 val term_x = Variable.create("x") 56 //val term_x = Variable.create("x")
57 val term_y = Variable.create("y") 57 //val term_y = Variable.create("y")
58 val term_z = Variable.create("z") 58 //val term_z = Variable.create("z")
59 val term_c1 = RSA("c_1") 59 //val term_c1 = RSA("c_1")
60 val term_c2 = RSA("c_2") 60 //val term_c2 = RSA("c_2")
61 val term_alice = RDFIRI.create("univ:alice") 61 //val term_alice = RDFIRI.create("univ:alice")
62 62
63 // RDFox Predicates 63 //// RDFox Predicates
64 val pred_sameAs = TupleTableName.create("owl:sameAs") 64 //val pred_sameAs = TupleTableName.create("owl:sameAs")
65 val pred_Professor = TupleTableName.create(iri_Professor.getIRIString) 65 //val pred_Professor = TupleTableName.create(iri_Professor.getIRIString)
66 val pred_hasSupervisor = TupleTableName.create(iri_hasSupervisor.getIRIString) 66 //val pred_hasSupervisor = TupleTableName.create(iri_hasSupervisor.getIRIString)
67 67
68 // OWL Classes 68 //// OWL Classes
69 // Name Class corresponding to 69 //// Name Class corresponding to
70 // 70 ////
71 // Professor 71 //// Professor
72 // 72 ////
73 val class_Professor = new OWLClassImpl(iri_Professor) 73 //val class_Professor = new OWLClassImpl(iri_Professor)
74 val class_Female = new OWLClassImpl(iri_Female) 74 //val class_Female = new OWLClassImpl(iri_Female)
75 val class_Student = new OWLClassImpl(iri_Student) 75 //val class_Student = new OWLClassImpl(iri_Student)
76 val class_PartTimeStudent = new OWLClassImpl(iri_PartTimeStudent) 76 //val class_PartTimeStudent = new OWLClassImpl(iri_PartTimeStudent)
77 val class_Worker = new OWLClassImpl(iri_Worker) 77 //val class_Worker = new OWLClassImpl(iri_Worker)
78 val class_OWLClass = class_Professor 78 //val class_OWLClass = class_Professor
79 // Class Conjunction corresponding to 79 //// Class Conjunction corresponding to
80 // 80 ////
81 // Student ∧ Worker 81 //// Student ∧ Worker
82 // 82 ////
83 val class_OWLObjectIntersectionOf = { 83 //val class_OWLObjectIntersectionOf = {
84 val conjuncts = new JList[OWLClassExpression]() 84 // val conjuncts = new JList[OWLClassExpression]()
85 conjuncts.add(class_Student) 85 // conjuncts.add(class_Student)
86 conjuncts.add(class_Worker) 86 // conjuncts.add(class_Worker)
87 new OWLObjectIntersectionOfImpl(conjuncts) 87 // new OWLObjectIntersectionOfImpl(conjuncts)
88 } 88 //}
89 // Singleton Class corresponding to 89 //// Singleton Class corresponding to
90 // 90 ////
91 // { alice } 91 //// { alice }
92 // 92 ////
93 val class_OWLObjectOneOf = 93 //val class_OWLObjectOneOf =
94 new OWLObjectOneOfImpl( 94 // new OWLObjectOneOfImpl(
95 new OWLNamedIndividualImpl(iri_alice) 95 // new OWLNamedIndividualImpl(iri_alice)
96 ) 96 // )
97 // Object Existential Restiction corresponding to 97 //// Object Existential Restiction corresponding to
98 // 98 ////
99 // ∃ hasSupervisor.Professor 99 //// ∃ hasSupervisor.Professor
100 // 100 ////
101 val class_OWLObjectSomeValuesFrom = 101 //val class_OWLObjectSomeValuesFrom =
102 new OWLObjectSomeValuesFromImpl( 102 // new OWLObjectSomeValuesFromImpl(
103 new OWLObjectPropertyImpl(iri_hasSupervisor), 103 // new OWLObjectPropertyImpl(iri_hasSupervisor),
104 class_Professor 104 // class_Professor
105 ) 105 // )
106 // Object Max Cardinality Restriction corresponding to 106 //// Object Max Cardinality Restriction corresponding to
107 // 107 ////
108 // ≤ 1 hasSupervisor . Professor 108 //// ≤ 1 hasSupervisor . Professor
109 val class_OWLObjectMaxCardinality = 109 //val class_OWLObjectMaxCardinality =
110 new OWLObjectMaxCardinalityImpl( 110 // new OWLObjectMaxCardinalityImpl(
111 new OWLObjectPropertyImpl(iri_hasSupervisor), 111 // new OWLObjectPropertyImpl(iri_hasSupervisor),
112 1, 112 // 1,
113 class_Professor 113 // class_Professor
114 ) 114 // )
115 115
116 // OWL Axioms 116 //// OWL Axioms
117 // Axiom SubClassOf corresponding to 117 //// Axiom SubClassOf corresponding to
118 // 118 ////
119 // Student ∧ Worker -> PartTimeStudent 119 //// Student ∧ Worker -> PartTimeStudent
120 // 120 ////
121 val axiom_OWLSubClassOf1 = 121 //val axiom_OWLSubClassOf1 =
122 new OWLSubClassOfAxiomImpl( 122 // new OWLSubClassOfAxiomImpl(
123 class_OWLObjectIntersectionOf, 123 // class_OWLObjectIntersectionOf,
124 class_PartTimeStudent, 124 // class_PartTimeStudent,
125 new JList() 125 // new JList()
126 ) 126 // )
127 127
128 // Axiom SubClassOf corresponding to 128 //// Axiom SubClassOf corresponding to
129 // 129 ////
130 // Student -> ∃ hasSupervisor.Professor 130 //// Student -> ∃ hasSupervisor.Professor
131 // 131 ////
132 val axiom_OWLSubClassOf2 = 132 //val axiom_OWLSubClassOf2 =
133 new OWLSubClassOfAxiomImpl( 133 // new OWLSubClassOfAxiomImpl(
134 class_Student, 134 // class_Student,
135 class_OWLObjectSomeValuesFrom, 135 // class_OWLObjectSomeValuesFrom,
136 new JList() 136 // new JList()
137 ) 137 // )
138 138
139 // Axiom SubClassOf corresponding to 139 //// Axiom SubClassOf corresponding to
140 // 140 ////
141 // ∃ hasSupervisor.Professor -> Student 141 //// ∃ hasSupervisor.Professor -> Student
142 // 142 ////
143 val axiom_OWLSubClassOf3 = 143 //val axiom_OWLSubClassOf3 =
144 new OWLSubClassOfAxiomImpl( 144 // new OWLSubClassOfAxiomImpl(
145 class_OWLObjectSomeValuesFrom, 145 // class_OWLObjectSomeValuesFrom,
146 class_Student, 146 // class_Student,
147 new JList() 147 // new JList()
148 ) 148 // )
149 149
150 // Axiom SubClassOf corresponding to 150 //// Axiom SubClassOf corresponding to
151 // 151 ////
152 // Student -> { alice } 152 //// Student -> { alice }
153 // 153 ////
154 val axiom_OWLSubClassOf4 = 154 //val axiom_OWLSubClassOf4 =
155 new OWLSubClassOfAxiomImpl( 155 // new OWLSubClassOfAxiomImpl(
156 class_Student, 156 // class_Student,
157 class_OWLObjectOneOf, 157 // class_OWLObjectOneOf,
158 new JList() 158 // new JList()
159 ) 159 // )
160 160
161 // Axiom SubClassOf corresponding to 161 //// Axiom SubClassOf corresponding to
162 // 162 ////
163 // Student -> ≤1 hasSupervisor.Professor 163 //// Student -> ≤1 hasSupervisor.Professor
164 // 164 ////
165 val axiom_OWLSubClassOf5 = 165 //val axiom_OWLSubClassOf5 =
166 new OWLSubClassOfAxiomImpl( 166 // new OWLSubClassOfAxiomImpl(
167 class_Student, 167 // class_Student,
168 class_OWLObjectMaxCardinality, 168 // class_OWLObjectMaxCardinality,
169 new JList() 169 // new JList()
170 ) 170 // )
171 171
172 def convertAxiom( 172 //def convertAxiom(
173 axiom: OWLAxiom, 173 // axiom: OWLAxiom,
174 term: Term, 174 // term: Term,
175 skolem: SkolemStrategy = NoSkolem 175 // skolem: SkolemStrategy = NoSkolem
176 ): List[Rule] = { 176 //): List[Rule] = {
177 axiom.accept(RDFoxAxiomConverter(term, List())) 177 // axiom.accept(RDFoxAxiomConverter(term, List()))
178 } 178 //}
179 179
180} // object OWLAxiomSpec 180} // object OWLAxiomSpec
181 181
182class OWLAxiomSpec extends AnyFlatSpec with Matchers with LoneElement { 182class OWLAxiomSpec extends AnyFlatSpec with Matchers with LoneElement {
183 183
184 // Import required data 184// // Import required data
185 import OWLAxiomSpec._ 185// import OWLAxiomSpec._
186 // Implicit convertion from IRI in OWLAPI to IRI in JRDFox 186// // Implicit convertion from IRI in OWLAPI to IRI in JRDFox
187 import uk.ac.ox.cs.rsacomb.implicits.RDFox._ 187// import uk.ac.ox.cs.rsacomb.implicits.RDFox._
188 188
189 // OWLSubClassOfAxiom #1 189// // OWLSubClassOfAxiom #1
190 axiom_OWLSubClassOf1.toString should "be converted into a singleton List[Rule]" in { 190// axiom_OWLSubClassOf1.toString should "be converted into a singleton List[Rule]" in {
191 val result = convertAxiom(axiom_OWLSubClassOf1, term_x) 191// val result = convertAxiom(axiom_OWLSubClassOf1, term_x)
192 result.loneElement shouldBe a[Rule] 192// result.loneElement shouldBe a[Rule]
193 } 193// }
194 194
195 it should "contain a conjuction of atoms (Student[?x],Worker[?x]) in the body of the rule" in { 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) 196// val result = convertAxiom(axiom_OWLSubClassOf1, term_x)
197 val body = List( 197// val body = List(
198 TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student), 198// TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student),
199 TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Worker) 199// TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Worker)
200 ) 200// )
201 result.loneElement.getBody should contain theSameElementsAs body 201// result.loneElement.getBody should contain theSameElementsAs body
202 } 202// }
203 203
204 it should "contain a single atom (PartTimeStudent[?x]) in the head of the rule" in { 204// it should "contain a single atom (PartTimeStudent[?x]) in the head of the rule" in {
205 val result = convertAxiom(axiom_OWLSubClassOf1, term_x) 205// val result = convertAxiom(axiom_OWLSubClassOf1, term_x)
206 val head = TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_PartTimeStudent) 206// val head = TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_PartTimeStudent)
207 result.loneElement.getHead.loneElement should be(head) 207// result.loneElement.getHead.loneElement should be(head)
208 } 208// }
209 209
210 // OWLSubClassOfAxiom #2 (w/ constant skolemization) 210// // OWLSubClassOfAxiom #2 (w/ constant skolemization)
211 (axiom_OWLSubClassOf2.toString + "\n(w/ constant skolemization)") should 211// (axiom_OWLSubClassOf2.toString + "\n(w/ constant skolemization)") should
212 "be converted into a singleton List[Rule]" in { 212// "be converted into a singleton List[Rule]" in {
213 val skolem = Constant(axiom_OWLSubClassOf2) 213// val skolem = Constant(axiom_OWLSubClassOf2)
214 val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) 214// val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem)
215 result.loneElement shouldBe a[Rule] 215// result.loneElement shouldBe a[Rule]
216 } 216// }
217 217
218 it should "contain a single atom (Student[?x]) in the body of the rule" in { 218// it should "contain a single atom (Student[?x]) in the body of the rule" in {
219 val skolem = Constant(axiom_OWLSubClassOf2) 219// val skolem = Constant(axiom_OWLSubClassOf2)
220 val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) 220// val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem)
221 val body = 221// val body =
222 TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student.getIRIString) 222// TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student.getIRIString)
223 result.loneElement.getBody.loneElement should equal(body) 223// result.loneElement.getBody.loneElement should equal(body)
224 } 224// }
225 225
226 // it should "contain a conjuction of atoms (hasSupervisor[?x,?c],Professor[?c]) in the head of the rule" in { 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) 227// // val skolem = SkolemStrategy.Constant(axiom_OWLSubClassOf2.toString)
228 // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) 228// // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem)
229 // val term_c = RSA.rsa(skolem.const.getIRI) 229// // val term_c = RSA.rsa(skolem.const.getIRI)
230 // val head = List( 230// // val head = List(
231 // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_c), 231// // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_c),
232 // TupleTableAtom.rdf(term_c, RDFIRI.RDF_TYPE, iri_Professor) 232// // TupleTableAtom.rdf(term_c, RDFIRI.RDF_TYPE, iri_Professor)
233 // ) 233// // )
234 // result.loneElement.getHead should contain theSameElementsAs (head) 234// // result.loneElement.getHead should contain theSameElementsAs (head)
235 // } 235// // }
236 236
237 // OWLSubClassOfAxiom #2 (w/ skolemization) 237// // OWLSubClassOfAxiom #2 (w/ skolemization)
238 (axiom_OWLSubClassOf2.toString + "\n(w/ skolemization)") should 238// (axiom_OWLSubClassOf2.toString + "\n(w/ skolemization)") should
239 "be converted into a singleton List[Rule]" in { 239// "be converted into a singleton List[Rule]" in {
240 val skolem = Standard(axiom_OWLSubClassOf2) 240// val skolem = Standard(axiom_OWLSubClassOf2)
241 val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) 241// val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem)
242 result.loneElement shouldBe a[Rule] 242// result.loneElement shouldBe a[Rule]
243 } 243// }
244 244
245 it should "contain an atom (Student[?x]) in the body of the rule" in { 245// it should "contain an atom (Student[?x]) in the body of the rule" in {
246 val skolem = Standard(axiom_OWLSubClassOf2) 246// val skolem = Standard(axiom_OWLSubClassOf2)
247 val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) 247// val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem)
248 val body = 248// val body =
249 TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student) 249// TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student)
250 result.loneElement.getBody should contain(body) 250// result.loneElement.getBody should contain(body)
251 } 251// }
252 252
253 // it should "contain a built-in function call (BIND(?y,SKOLEM(?f,?x))) in the body of the rule" in { 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) 254// // val skolem = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString)
255 // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) 255// // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem)
256 // val call = 256// // val call =
257 // BindAtom.create(BuiltinFunctionCall.create("SKOLEM", term_x), term_y) 257// // BindAtom.create(BuiltinFunctionCall.create("SKOLEM", term_x), term_y)
258 // result.loneElement.getBody should contain(call) 258// // result.loneElement.getBody should contain(call)
259 // } 259// // }
260 260
261 // it should "contain a conjuction of atom (hasSupervisor[?x,?y],Professor[?y]) in the head of the rule" in { 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) 262// // val skolem = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString)
263 // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) 263// // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem)
264 // val head = List( 264// // val head = List(
265 // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y), 265// // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y),
266 // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor) 266// // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor)
267 // ) 267// // )
268 // result.loneElement.getHead should contain theSameElementsAs head 268// // result.loneElement.getHead should contain theSameElementsAs head
269 // } 269// // }
270 270
271 // OWLSubClassOfAxiom #3 271// // OWLSubClassOfAxiom #3
272 axiom_OWLSubClassOf3.toString should "be converted into a singleton List[Rule]" in { 272// axiom_OWLSubClassOf3.toString should "be converted into a singleton List[Rule]" in {
273 val result = convertAxiom(axiom_OWLSubClassOf3, term_x) 273// val result = convertAxiom(axiom_OWLSubClassOf3, term_x)
274 result.loneElement shouldBe a[Rule] 274// result.loneElement shouldBe a[Rule]
275 } 275// }
276 276
277 // it should "contain a conjunction of atoms (hasSupervisor[?x,?y],Professor[?y]) in the body of the rule" in { 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) 278// // val result = convertAxiom(axiom_OWLSubClassOf3, term_x)
279 // val body = List( 279// // val body = List(
280 // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y), 280// // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y),
281 // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor) 281// // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor)
282 // ) 282// // )
283 // result.loneElement.getBody should contain theSameElementsAs body 283// // result.loneElement.getBody should contain theSameElementsAs body
284 // } 284// // }
285 285
286 it should "contain a single atom (Student[?x]) in the head of the rule" in { 286// it should "contain a single atom (Student[?x]) in the head of the rule" in {
287 val result = convertAxiom(axiom_OWLSubClassOf3, term_x) 287// val result = convertAxiom(axiom_OWLSubClassOf3, term_x)
288 val head = 288// val head =
289 TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student) 289// TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student)
290 result.loneElement.getHead.loneElement should be(head) 290// result.loneElement.getHead.loneElement should be(head)
291 } 291// }
292 292
293 // OWLSubClassOfAxiom #4 293// // OWLSubClassOfAxiom #4
294 axiom_OWLSubClassOf4.toString should "be converted into a singleton List[Rule]" in { 294// axiom_OWLSubClassOf4.toString should "be converted into a singleton List[Rule]" in {
295 val result = convertAxiom(axiom_OWLSubClassOf4, term_x) 295// val result = convertAxiom(axiom_OWLSubClassOf4, term_x)
296 result.loneElement shouldBe a[Rule] 296// result.loneElement shouldBe a[Rule]
297 } 297// }
298 298
299 it should "contain a single atoms (Student[?x]) in the body of the rule" in { 299// it should "contain a single atoms (Student[?x]) in the body of the rule" in {
300 val result = convertAxiom(axiom_OWLSubClassOf4, term_x) 300// val result = convertAxiom(axiom_OWLSubClassOf4, term_x)
301 val body = 301// val body =
302 TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student) 302// TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student)
303 result.loneElement.getBody.loneElement should be(body) 303// result.loneElement.getBody.loneElement should be(body)
304 } 304// }
305 305
306 it should "contain a single atom (sameAs[?x,alice])) in the head of the rule" in { 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) 307// val result = convertAxiom(axiom_OWLSubClassOf4, term_x)
308 val head = TupleTableAtom.rdf(term_x, RDFIRI.SAME_AS, term_alice) 308// val head = TupleTableAtom.rdf(term_x, RDFIRI.SAME_AS, term_alice)
309 result.loneElement.getHead.loneElement should be(head) 309// result.loneElement.getHead.loneElement should be(head)
310 } 310// }
311 311
312 // OWLSubClassOfAxiom #5 312// // OWLSubClassOfAxiom #5
313 axiom_OWLSubClassOf5.toString should "be converted into a singleton List[Rule]" in { 313// axiom_OWLSubClassOf5.toString should "be converted into a singleton List[Rule]" in {
314 val result = convertAxiom(axiom_OWLSubClassOf5, term_x) 314// val result = convertAxiom(axiom_OWLSubClassOf5, term_x)
315 result.loneElement shouldBe a[Rule] 315// result.loneElement shouldBe a[Rule]
316 } 316// }
317 317
318 // it should "contain a conjunction of atoms (...) in the body of the rule" in { 318// // it should "contain a conjunction of atoms (...) in the body of the rule" in {
319 // val result = convertAxiom(axiom_OWLSubClassOf5, term_x) 319// // val result = convertAxiom(axiom_OWLSubClassOf5, term_x)
320 // val body = List( 320// // val body = List(
321 // TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student), 321// // TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student),
322 // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y), 322// // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y),
323 // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor), 323// // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor),
324 // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_z), 324// // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_z),
325 // TupleTableAtom.rdf(term_z, RDFIRI.RDF_TYPE, iri_Professor) 325// // TupleTableAtom.rdf(term_z, RDFIRI.RDF_TYPE, iri_Professor)
326 // ) 326// // )
327 // result.loneElement.getBody should contain theSameElementsAs body 327// // result.loneElement.getBody should contain theSameElementsAs body
328 // } 328// // }
329 329
330 // it should "contain a single atom (sameAs[?x,?z])) in the head of the rule" in { 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) 331// // val result = convertAxiom(axiom_OWLSubClassOf5, term_x)
332 // val head = TupleTableAtom.rdf(term_y, RDFIRI.SAME_AS, term_z) 332// // val head = TupleTableAtom.rdf(term_y, RDFIRI.SAME_AS, term_z)
333 // result.loneElement.getHead.loneElement should be(head) 333// // result.loneElement.getHead.loneElement should be(head)
334 // } 334// // }
335 335
336} // class OWLAxiomSpec 336} // class OWLAxiomSpec
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLClassSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLClassSpec.scala
index fd13fc9..880c31a 100644
--- a/src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLClassSpec.scala
+++ b/src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLClassSpec.scala
@@ -1,204 +1,204 @@
1package uk.ac.ox.cs.rsacomb.converter 1package uk.ac.ox.cs.rsacomb.converter
2 2
3import java.util.{ArrayList => JList} 3// import java.util.{ArrayList => JList}
4 4
5import org.scalatest.LoneElement 5import org.scalatest.LoneElement
6import org.scalatest.flatspec.AnyFlatSpec 6import org.scalatest.flatspec.AnyFlatSpec
7import org.scalatest.matchers.should.Matchers 7import org.scalatest.matchers.should.Matchers
8 8
9import org.semanticweb.owlapi.model.OWLClassExpression 9// import org.semanticweb.owlapi.model.OWLClassExpression
10import uk.ac.manchester.cs.owl.owlapi.{ 10// import uk.ac.manchester.cs.owl.owlapi.{
11 OWLClassImpl, 11// OWLClassImpl,
12 OWLObjectSomeValuesFromImpl, 12// OWLObjectSomeValuesFromImpl,
13 OWLObjectIntersectionOfImpl, 13// OWLObjectIntersectionOfImpl,
14 OWLObjectOneOfImpl, 14// OWLObjectOneOfImpl,
15 OWLObjectAllValuesFromImpl, 15// OWLObjectAllValuesFromImpl,
16 OWLObjectMaxCardinalityImpl, 16// OWLObjectMaxCardinalityImpl,
17 OWLNamedIndividualImpl 17// OWLNamedIndividualImpl
18} 18// }
19import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl} 19// import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl}
20import org.semanticweb.owlapi.model.IRI 20// import org.semanticweb.owlapi.model.IRI
21import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI} 21// import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI}
22 22
23import tech.oxfordsemantic.jrdfox.logic.Datatype 23// import tech.oxfordsemantic.jrdfox.logic.Datatype
24import tech.oxfordsemantic.jrdfox.logic.datalog.{ 24// import tech.oxfordsemantic.jrdfox.logic.datalog.{
25 TupleTableAtom, 25// TupleTableAtom,
26 TupleTableName, 26// TupleTableName,
27 BindAtom 27// BindAtom
28} 28// }
29import tech.oxfordsemantic.jrdfox.logic.expression.{ 29// import tech.oxfordsemantic.jrdfox.logic.expression.{
30 FunctionCall, 30// FunctionCall,
31 Term, 31// Term,
32 Variable, 32// Variable,
33 Literal 33// Literal
34} 34// }
35 35
36import uk.ac.ox.cs.rsacomb.converter.{ 36// import uk.ac.ox.cs.rsacomb.converter.{
37 RDFoxRuleShards, 37// RDFoxRuleShards,
38 RDFoxClassExprConverter, 38// RDFoxClassExprConverter,
39 SkolemStrategy, 39// SkolemStrategy,
40 Standard, 40// Standard,
41 Constant 41// Constant
42} 42// }
43import uk.ac.ox.cs.rsacomb.util.RSA 43// import uk.ac.ox.cs.rsacomb.util.RSA
44 44
45object OWLClassSpec { 45object OWLClassSpec {
46 46
47 // IRI 47 //// IRI
48 val iri_Professor = IRI.create("univ:Professor") 48 //val iri_Professor = IRI.create("univ:Professor")
49 val iri_Female = IRI.create("std:Female") 49 //val iri_Female = IRI.create("std:Female")
50 val iri_Student = IRI.create("univ:Student") 50 //val iri_Student = IRI.create("univ:Student")
51 val iri_Worker = IRI.create("univ:Worker") 51 //val iri_Worker = IRI.create("univ:Worker")
52 val iri_alice = IRI.create("univ:alice") 52 //val iri_alice = IRI.create("univ:alice")
53 val iri_supervises = IRI.create("univ:supervises") 53 //val iri_supervises = IRI.create("univ:supervises")
54 val iri_hasSupervisor = IRI.create("univ:hasSupervisor") 54 //val iri_hasSupervisor = IRI.create("univ:hasSupervisor")
55 55
56 // RDFox Terms 56 //// RDFox Terms
57 val term_x = Variable.create("x") 57 //val term_x = Variable.create("x")
58 val term_y = Variable.create("y") 58 //val term_y = Variable.create("y")
59 val term_c1 = RSA("c_1") 59 //val term_c1 = RSA("c_1")
60 val term_c2 = RSA("c_2") 60 //val term_c2 = RSA("c_2")
61 val term_alice = RDFIRI.create("univ:alice") 61 //val term_alice = RDFIRI.create("univ:alice")
62 62
63 // RDFox Predicates 63 //// RDFox Predicates
64 val pred_sameAs = TupleTableName.create("owl:sameAs") 64 //val pred_sameAs = TupleTableName.create("owl:sameAs")
65 val pred_Professor = TupleTableName.create(iri_Professor.getIRIString) 65 //val pred_Professor = TupleTableName.create(iri_Professor.getIRIString)
66 val pred_hasSupervisor = TupleTableName.create(iri_hasSupervisor.getIRIString) 66 //val pred_hasSupervisor = TupleTableName.create(iri_hasSupervisor.getIRIString)
67 67
68 // OWL Classes 68 //// OWL Classes
69 // Name Class corresponding to 69 //// Name Class corresponding to
70 // 70 ////
71 // Professor 71 //// Professor
72 // 72 ////
73 val class_Professor = new OWLClassImpl(iri_Professor) 73 //val class_Professor = new OWLClassImpl(iri_Professor)
74 val class_Female = new OWLClassImpl(iri_Female) 74 //val class_Female = new OWLClassImpl(iri_Female)
75 val class_Student = new OWLClassImpl(iri_Student) 75 //val class_Student = new OWLClassImpl(iri_Student)
76 val class_Worker = new OWLClassImpl(iri_Worker) 76 //val class_Worker = new OWLClassImpl(iri_Worker)
77 val class_OWLClass = class_Professor 77 //val class_OWLClass = class_Professor
78 78
79 // Class Conjunction corresponding to 79 //// Class Conjunction corresponding to
80 // 80 ////
81 // Female ∧ Student ∧ Worker 81 //// Female ∧ Student ∧ Worker
82 // 82 ////
83 val class_OWLObjectIntersectionOf = { 83 //val class_OWLObjectIntersectionOf = {
84 val conjuncts = new JList[OWLClassExpression]() 84 // val conjuncts = new JList[OWLClassExpression]()
85 conjuncts.add(class_Female) 85 // conjuncts.add(class_Female)
86 conjuncts.add(class_Student) 86 // conjuncts.add(class_Student)
87 conjuncts.add(class_Worker) 87 // conjuncts.add(class_Worker)
88 new OWLObjectIntersectionOfImpl(conjuncts) 88 // new OWLObjectIntersectionOfImpl(conjuncts)
89 } 89 //}
90 // Singleton Class corresponding to 90 //// Singleton Class corresponding to
91 // 91 ////
92 // { alice } 92 //// { alice }
93 // 93 ////
94 val class_OWLObjectOneOf = 94 //val class_OWLObjectOneOf =
95 new OWLObjectOneOfImpl( 95 // new OWLObjectOneOfImpl(
96 new OWLNamedIndividualImpl(iri_alice) 96 // new OWLNamedIndividualImpl(iri_alice)
97 ) 97 // )
98 // Object Existential Restiction corresponding to 98 //// Object Existential Restiction corresponding to
99 // 99 ////
100 // ∃ hasSupervisor.Professor 100 //// ∃ hasSupervisor.Professor
101 // 101 ////
102 val class_OWLObjectSomeValuesFrom = 102 //val class_OWLObjectSomeValuesFrom =
103 new OWLObjectSomeValuesFromImpl( 103 // new OWLObjectSomeValuesFromImpl(
104 new OWLObjectPropertyImpl(iri_hasSupervisor), 104 // new OWLObjectPropertyImpl(iri_hasSupervisor),
105 class_Professor 105 // class_Professor
106 ) 106 // )
107 // Object Max Cardinality Restriction corresponding to 107 //// Object Max Cardinality Restriction corresponding to
108 // 108 ////
109 // ≤1 hasSupervisor.Professor 109 //// ≤1 hasSupervisor.Professor
110 val class_OWLObjectMaxCardinality = 110 //val class_OWLObjectMaxCardinality =
111 new OWLObjectMaxCardinalityImpl( 111 // new OWLObjectMaxCardinalityImpl(
112 new OWLObjectPropertyImpl(iri_hasSupervisor), 112 // new OWLObjectPropertyImpl(iri_hasSupervisor),
113 1, 113 // 1,
114 class_Professor 114 // class_Professor
115 ) 115 // )
116} // object OWLClassSpec 116} // object OWLClassSpec
117 117
118class OWLClassSpec extends AnyFlatSpec with Matchers with LoneElement { 118class OWLClassSpec extends AnyFlatSpec with Matchers with LoneElement {
119 // Import required data 119 // Import required data
120 import OWLClassSpec._ 120 import OWLClassSpec._
121 121
122 // OWLClass 122 //// OWLClass
123 class_OWLClass.toString should "be converted into a RDFoxRuleShards" in { 123 //class_OWLClass.toString should "be converted into a RDFoxRuleShards" in {
124 val visitor = RDFoxClassExprConverter(term_x) 124 // val visitor = RDFoxClassExprConverter(term_x)
125 val result = class_OWLClass.accept(visitor) 125 // val result = class_OWLClass.accept(visitor)
126 result shouldBe a[RDFoxRuleShards] 126 // result shouldBe a[RDFoxRuleShards]
127 } 127 //}
128 128
129 it should "have a single TupleTableAtom in its result list" in { 129 //it should "have a single TupleTableAtom in its result list" in {
130 val visitor = RDFoxClassExprConverter(term_x) 130 // val visitor = RDFoxClassExprConverter(term_x)
131 val result = class_OWLClass.accept(visitor) 131 // val result = class_OWLClass.accept(visitor)
132 result.res.loneElement shouldBe an[TupleTableAtom] 132 // result.res.loneElement shouldBe an[TupleTableAtom]
133 } 133 //}
134 134
135 it should "have an empty extension list" in { 135 //it should "have an empty extension list" in {
136 val visitor = RDFoxClassExprConverter(term_x) 136 // val visitor = RDFoxClassExprConverter(term_x)
137 val result = class_OWLClass.accept(visitor) 137 // val result = class_OWLClass.accept(visitor)
138 result.ext shouldBe empty 138 // result.ext shouldBe empty
139 } 139 //}
140 140
141 // OWLObjectIntersectionOf 141 //// OWLObjectIntersectionOf
142 class_OWLObjectIntersectionOf.toString should "be converted into a RDFoxRuleShards" in { 142 //class_OWLObjectIntersectionOf.toString should "be converted into a RDFoxRuleShards" in {
143 val visitor = RDFoxClassExprConverter(term_x) 143 // val visitor = RDFoxClassExprConverter(term_x)
144 val result = class_OWLObjectIntersectionOf.accept(visitor) 144 // val result = class_OWLObjectIntersectionOf.accept(visitor)
145 result shouldBe a[RDFoxRuleShards] 145 // result shouldBe a[RDFoxRuleShards]
146 } 146 //}
147
148 it should "be converted in the union of its converted conjuncts" in {
149 val visitor = RDFoxClassExprConverter(term_x)
150 val result1 = class_OWLObjectIntersectionOf.accept(visitor)
151 val result2 = RDFoxClassExprConverter.merge(
152 List(
153 class_Female.accept(visitor),
154 class_Student.accept(visitor),
155 class_Worker.accept(visitor)
156 )
157 )
158 result1.res should contain theSameElementsAs result2.res
159 result1.ext should contain theSameElementsAs result2.ext
160 }
161
162 // OWLObjectOneOf
163 class_OWLObjectOneOf.toString should "be converted into a RDFoxRuleShards" in {
164 val visitor = RDFoxClassExprConverter(term_x)
165 val result = class_OWLObjectOneOf.accept(visitor)
166 result shouldBe a[RDFoxRuleShards]
167 }
168
169 // it should "be converted into a single <owl:sameAs> TupleTableAtom" in {
170 // val visitor = RDFoxClassExprConverter(term_x)
171 // val result = class_OWLObjectOneOf.accept(visitor)
172 // result.res.loneElement should (be (a [TupleTableAtom]) and have ('tupleTableName (pred_sameAs)))
173 // }
174 147
175 it should "have an empty extension list" in { 148 //it should "be converted in the union of its converted conjuncts" in {
176 val visitor = RDFoxClassExprConverter(term_x) 149 // val visitor = RDFoxClassExprConverter(term_x)
177 val result = class_OWLObjectOneOf.accept(visitor) 150 // val result1 = class_OWLObjectIntersectionOf.accept(visitor)
178 result.ext shouldBe empty 151 // val result2 = RDFoxClassExprConverter.merge(
179 } 152 // List(
180 153 // class_Female.accept(visitor),
181 // OWLObjectSomeValuesFrom 154 // class_Student.accept(visitor),
182 (class_OWLObjectSomeValuesFrom.toString ++ " w/o skolemization") should 155 // class_Worker.accept(visitor)
183 "be converted into a RDFoxRuleShards" in { 156 // )
184 val visitor = RDFoxClassExprConverter(term_x) 157 // )
185 val result = class_OWLObjectSomeValuesFrom.accept(visitor) 158 // result1.res should contain theSameElementsAs result2.res
186 result shouldBe a[RDFoxRuleShards] 159 // result1.ext should contain theSameElementsAs result2.ext
187 } 160 //}
188 161
189 it should "have two TupleTableAtoms in its result list" in { 162 //// OWLObjectOneOf
190 val visitor = RDFoxClassExprConverter(term_x) 163 //class_OWLObjectOneOf.toString should "be converted into a RDFoxRuleShards" in {
191 val result = class_OWLObjectSomeValuesFrom.accept(visitor) 164 // val visitor = RDFoxClassExprConverter(term_x)
192 exactly(2, result.res) should (be(an[TupleTableAtom]) 165 // val result = class_OWLObjectOneOf.accept(visitor)
193 //and have('numberOfArguments (3)) 166 // result shouldBe a[RDFoxRuleShards]
194 ) 167 //}
195 } 168
196 169 //// it should "be converted into a single <owl:sameAs> TupleTableAtom" in {
197 it should "have an empty extension list" in { 170 //// val visitor = RDFoxClassExprConverter(term_x)
198 val visitor = RDFoxClassExprConverter(term_x) 171 //// val result = class_OWLObjectOneOf.accept(visitor)
199 val result = class_OWLObjectSomeValuesFrom.accept(visitor) 172 //// result.res.loneElement should (be (a [TupleTableAtom]) and have ('tupleTableName (pred_sameAs)))
200 result.ext shouldBe empty 173 //// }
201 } 174
175 //it should "have an empty extension list" in {
176 // val visitor = RDFoxClassExprConverter(term_x)
177 // val result = class_OWLObjectOneOf.accept(visitor)
178 // result.ext shouldBe empty
179 //}
180
181 //// OWLObjectSomeValuesFrom
182 //(class_OWLObjectSomeValuesFrom.toString ++ " w/o skolemization") should
183 // "be converted into a RDFoxRuleShards" in {
184 // val visitor = RDFoxClassExprConverter(term_x)
185 // val result = class_OWLObjectSomeValuesFrom.accept(visitor)
186 // result shouldBe a[RDFoxRuleShards]
187 // }
188
189 //it should "have two TupleTableAtoms in its result list" in {
190 // val visitor = RDFoxClassExprConverter(term_x)
191 // val result = class_OWLObjectSomeValuesFrom.accept(visitor)
192 // exactly(2, result.res) should (be(an[TupleTableAtom])
193 // //and have('numberOfArguments (3))
194 // )
195 //}
196
197 //it should "have an empty extension list" in {
198 // val visitor = RDFoxClassExprConverter(term_x)
199 // val result = class_OWLObjectSomeValuesFrom.accept(visitor)
200 // result.ext shouldBe empty
201 //}
202 202
203 //(class_OWLObjectSomeValuesFrom.toString ++ " w/ skolemization") should 203 //(class_OWLObjectSomeValuesFrom.toString ++ " w/ skolemization") should
204 // "be converted into a RDFoxRuleShards" in { 204 // "be converted into a RDFoxRuleShards" in {
@@ -252,13 +252,13 @@ class OWLClassSpec extends AnyFlatSpec with Matchers with LoneElement {
252 // result.ext shouldBe empty 252 // result.ext shouldBe empty
253 //} 253 //}
254 254
255 // OWLObjectMaxCardinalityImpl 255 // // OWLObjectMaxCardinalityImpl
256 class_OWLObjectMaxCardinality.toString should 256 // class_OWLObjectMaxCardinality.toString should
257 "be converted into a RDFoxRuleShards" in { 257 // "be converted into a RDFoxRuleShards" in {
258 val visitor = RDFoxClassExprConverter(term_x) 258 // val visitor = RDFoxClassExprConverter(term_x)
259 val result = class_OWLObjectMaxCardinality.accept(visitor) 259 // val result = class_OWLObjectMaxCardinality.accept(visitor)
260 result shouldBe a[RDFoxRuleShards] 260 // result shouldBe a[RDFoxRuleShards]
261 } 261 // }
262 262
263 // it should "have a single <owl:sameAs> TupleTableAtom in the result list" in { 263 // it should "have a single <owl:sameAs> TupleTableAtom in the result list" in {
264 // val visitor = RDFoxClassExprConverter(term_x) 264 // val visitor = RDFoxClassExprConverter(term_x)
@@ -268,12 +268,12 @@ class OWLClassSpec extends AnyFlatSpec with Matchers with LoneElement {
268 // )) 268 // ))
269 // } 269 // }
270 270
271 it should "have 4 TupleTableAtoms in its extension list" in { 271 //it should "have 4 TupleTableAtoms in its extension list" in {
272 val visitor = RDFoxClassExprConverter(term_x) 272 // val visitor = RDFoxClassExprConverter(term_x)
273 val result = class_OWLObjectMaxCardinality.accept(visitor) 273 // val result = class_OWLObjectMaxCardinality.accept(visitor)
274 exactly(4, result.ext) should (be(an[TupleTableAtom]) 274 // exactly(4, result.ext) should (be(an[TupleTableAtom])
275 //and have('numberOfArguments (3)) 275 // //and have('numberOfArguments (3))
276 ) 276 // )
277 } 277 //}
278 278
279} // class OWLClassSpec 279} // class OWLClassSpec
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 b2319bc..2b90f3b 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
@@ -16,25 +16,25 @@ object ConjunctiveQueryAnswerSpec {
16 val oneAnswer = new ConjunctiveQueryAnswers( 16 val oneAnswer = new ConjunctiveQueryAnswers(
17 false, 17 false,
18 Seq(varX, varY, varZ), 18 Seq(varX, varY, varZ),
19 Seq(Seq(iri1, iri2, iri3)) 19 Seq((4, Seq(iri1, iri2, iri3)))
20 ) 20 )
21 val multipleAnswers = 21 val multipleAnswers =
22 new ConjunctiveQueryAnswers( 22 new ConjunctiveQueryAnswers(
23 false, 23 false,
24 Seq(varY, varZ), 24 Seq(varY, varZ),
25 Seq(Seq(iri1, iri1), Seq(iri1, iri2), Seq(iri1, iri3)) 25 Seq((1, Seq(iri1, iri1)), (2, Seq(iri1, iri2)), (1, Seq(iri1, iri3)))
26 ) 26 )
27 val noAnswer = new ConjunctiveQueryAnswers(false, Seq(), Seq()) 27 val noAnswer = new ConjunctiveQueryAnswers(false, Seq(), Seq())
28 val emptyAnswer = 28 val emptyAnswer =
29 new ConjunctiveQueryAnswers(false, Seq(varX, varY), Seq(Seq())) 29 new ConjunctiveQueryAnswers(false, Seq(varX, varY), Seq((3, Seq())))
30 30
31 val falseAnswer = new ConjunctiveQueryAnswers(true, Seq(), Seq()) 31 val falseAnswer = new ConjunctiveQueryAnswers(true, Seq(), Seq())
32 val trueAnswer1 = new ConjunctiveQueryAnswers(true, Seq(), Seq(Seq())) 32 val trueAnswer1 = new ConjunctiveQueryAnswers(true, Seq(), Seq((1, Seq())))
33 val trueAnswer2 = 33 val trueAnswer2 =
34 new ConjunctiveQueryAnswers( 34 new ConjunctiveQueryAnswers(
35 true, 35 true,
36 Seq(varX, varY), 36 Seq(varX, varY),
37 Seq(Seq(iri1, iri1), Seq(iri1, iri2), Seq(iri1, iri3)) 37 Seq((5, Seq(iri1, iri1)), (2, Seq(iri1, iri2)), (1, Seq(iri1, iri3)))
38 ) 38 )
39} 39}
40 40
@@ -42,6 +42,49 @@ class ConjunctiveQueryAnswerSpec extends AnyFlatSpec with Matchers {
42 42
43 import ConjunctiveQueryAnswerSpec._ 43 import ConjunctiveQueryAnswerSpec._
44 44
45 "Test answer 1" should "have length 1 (4 with multiplicity)" in {
46 oneAnswer should have(
47 'length (1),
48 'lengthWithMultiplicity (4)
49 )
50 }
51 "Test answer 2" should "have length 3 (4 with multiplicity)" in {
52 multipleAnswers should have(
53 'length (3),
54 'lengthWithMultiplicity (4)
55 )
56 }
57 "Test answer 3" should "have length 0 (0 with multiplicity)" in {
58 noAnswer should have(
59 'length (0),
60 'lengthWithMultiplicity (0)
61 )
62 }
63 "Test answer 4" should "have length 1 (3 with multiplicity)" in {
64 emptyAnswer should have(
65 'length (1),
66 'lengthWithMultiplicity (3)
67 )
68 }
69 "Test boolean answer 1" should "have length 0 (0 with multiplicity)" in {
70 falseAnswer should have(
71 'length (0),
72 'lengthWithMultiplicity (0)
73 )
74 }
75 "Test boolean answer 2" should "have length 1 (1 with multiplicity)" in {
76 trueAnswer1 should have(
77 'length (0),
78 'lengthWithMultiplicity (1)
79 )
80 }
81 "Test boolean answer 3" should "have length 3 (8 with multiplicity)" in {
82 trueAnswer2 should have(
83 'length (0),
84 'lengthWithMultiplicity (8)
85 )
86 }
87
45 "A conjunctive query" should "print an header and a single line if it has a single answer" in { 88 "A conjunctive query" should "print an header and a single line if it has a single answer" in {
46 oneAnswer.toString shouldBe s"X\tY\tZ\n${iri1.getIRI}\t${iri2.getIRI}\t${iri3.getIRI}" 89 oneAnswer.toString shouldBe s"X\tY\tZ\n${iri1.getIRI}\t${iri2.getIRI}\t${iri3.getIRI}"
47 } 90 }