diff options
13 files changed, 668 insertions, 943 deletions
| @@ -1,6 +1,6 @@ | |||
| 1 | #!/bin/sh | 1 | #!/bin/sh |
| 2 | 2 | ||
| 3 | VERSION="4.0.0" | 3 | VERSION="4.1.0" |
| 4 | NAME="RDFox-linux-$VERSION" | 4 | NAME="RDFox-linux-$VERSION" |
| 5 | LINK="https://rdfox-distribution.s3.eu-west-2.amazonaws.com/release/v$VERSION/$NAME.zip" | 5 | LINK="https://rdfox-distribution.s3.eu-west-2.amazonaws.com/release/v$VERSION/$NAME.zip" |
| 6 | DEST="./lib/" | 6 | DEST="./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 | |||
| 24 | import org.semanticweb.owlapi.model.{IRI => OWLIRI} | 24 | import org.semanticweb.owlapi.model.{IRI => OWLIRI} |
| 25 | import uk.ac.manchester.cs.owl.owlapi.OWLObjectPropertyImpl | 25 | import uk.ac.manchester.cs.owl.owlapi.OWLObjectPropertyImpl |
| 26 | 26 | ||
| 27 | import tech.oxfordsemantic.jrdfox.client.{UpdateType, DataStoreConnection} | 27 | import tech.oxfordsemantic.jrdfox.client.{ |
| 28 | DataStoreConnection, | ||
| 29 | TransactionType, | ||
| 30 | UpdateType | ||
| 31 | } | ||
| 28 | import tech.oxfordsemantic.jrdfox.Prefixes | 32 | import tech.oxfordsemantic.jrdfox.Prefixes |
| 29 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ | 33 | import 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 @@ | |||
| 1 | package uk.ac.ox.cs.rsacomb.converter | ||
| 2 | |||
| 3 | import org.semanticweb.owlapi.model.{ | ||
| 4 | OWLAxiom, | ||
| 5 | OWLSubClassOfAxiom, | ||
| 6 | OWLEquivalentClassesAxiom, | ||
| 7 | OWLObjectPropertyExpression, | ||
| 8 | OWLObjectPropertyDomainAxiom, | ||
| 9 | OWLObjectPropertyRangeAxiom, | ||
| 10 | OWLDataPropertyDomainAxiom, | ||
| 11 | OWLDataPropertyRangeAxiom, | ||
| 12 | OWLInverseObjectPropertiesAxiom | ||
| 13 | } | ||
| 14 | import org.semanticweb.owlapi.model.OWLAxiomVisitorEx | ||
| 15 | |||
| 16 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ | ||
| 17 | Rule, | ||
| 18 | BodyFormula, | ||
| 19 | TupleTableAtom, | ||
| 20 | TupleTableName | ||
| 21 | } | ||
| 22 | import tech.oxfordsemantic.jrdfox.logic.expression.{ | ||
| 23 | Term, | ||
| 24 | IRI => RDFoxIRI, | ||
| 25 | Variable, | ||
| 26 | Literal | ||
| 27 | } | ||
| 28 | |||
| 29 | import scala.collection.JavaConverters._ | ||
| 30 | |||
| 31 | import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom | ||
| 32 | import org.semanticweb.owlapi.model.OWLObjectProperty | ||
| 33 | import org.semanticweb.owlapi.model.OWLClassAssertionAxiom | ||
| 34 | |||
| 35 | import uk.ac.ox.cs.rsacomb.RSAOntology | ||
| 36 | import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Empty} | ||
| 37 | import uk.ac.manchester.cs.owl.owlapi.OWLSubClassOfAxiomImpl | ||
| 38 | import uk.ac.manchester.cs.owl.owlapi.OWLObjectSomeValuesFromImpl | ||
| 39 | import uk.ac.manchester.cs.owl.owlapi.OWLClassImpl | ||
| 40 | import org.semanticweb.owlapi.model.IRI | ||
| 41 | |||
| 42 | object 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 | |||
| 54 | class 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 @@ | |||
| 1 | package uk.ac.ox.cs.rsacomb.converter | ||
| 2 | |||
| 3 | import scala.collection.JavaConverters._ | ||
| 4 | import java.util.stream.{Stream, Collectors} | ||
| 5 | |||
| 6 | import org.semanticweb.owlapi.model.{ | ||
| 7 | OWLClassExpression, | ||
| 8 | OWLClass, | ||
| 9 | OWLObjectSomeValuesFrom, | ||
| 10 | OWLDataSomeValuesFrom, | ||
| 11 | OWLObjectIntersectionOf, | ||
| 12 | OWLObjectOneOf, | ||
| 13 | OWLObjectMaxCardinality | ||
| 14 | } | ||
| 15 | import org.semanticweb.owlapi.model.OWLClassExpressionVisitorEx | ||
| 16 | import tech.oxfordsemantic.jrdfox.logic.Datatype | ||
| 17 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ | ||
| 18 | BindAtom, | ||
| 19 | TupleTableName, | ||
| 20 | TupleTableAtom | ||
| 21 | } | ||
| 22 | import tech.oxfordsemantic.jrdfox.logic.expression.{ | ||
| 23 | Term, | ||
| 24 | Literal, | ||
| 25 | Variable, | ||
| 26 | FunctionCall, | ||
| 27 | IRI | ||
| 28 | } | ||
| 29 | |||
| 30 | import org.semanticweb.owlapi.model.OWLObjectPropertyExpression | ||
| 31 | import org.semanticweb.owlapi.model.OWLObjectProperty | ||
| 32 | |||
| 33 | import uk.ac.ox.cs.rsacomb.RSAOntology | ||
| 34 | import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Empty} | ||
| 35 | import uk.ac.ox.cs.rsacomb.util.RSA | ||
| 36 | |||
| 37 | object 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 | |||
| 58 | class 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.{ | |||
| 40 | import tech.oxfordsemantic.jrdfox.logic.expression.{Term, IRI, FunctionCall} | 40 | import tech.oxfordsemantic.jrdfox.logic.expression.{Term, IRI, FunctionCall} |
| 41 | import uk.ac.ox.cs.rsacomb.RSAOntology | 41 | import uk.ac.ox.cs.rsacomb.RSAOntology |
| 42 | import uk.ac.ox.cs.rsacomb.suffix.{Empty, Inverse, RSASuffix} | 42 | import uk.ac.ox.cs.rsacomb.suffix.{Empty, Inverse, RSASuffix} |
| 43 | import uk.ac.ox.cs.rsacomb.util.RSA | 43 | import 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 @@ | |||
| 1 | package uk.ac.ox.cs.rsacomb.converter | ||
| 2 | |||
| 3 | import org.semanticweb.owlapi.model.{ | ||
| 4 | OWLAnnotationProperty, | ||
| 5 | OWLDataProperty, | ||
| 6 | OWLObjectInverseOf, | ||
| 7 | OWLObjectProperty, | ||
| 8 | OWLPropertyExpression | ||
| 9 | } | ||
| 10 | import org.semanticweb.owlapi.model.OWLPropertyExpressionVisitorEx | ||
| 11 | |||
| 12 | import tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom | ||
| 13 | import tech.oxfordsemantic.jrdfox.logic.expression.{Term, IRI, Literal} | ||
| 14 | |||
| 15 | import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Inverse} | ||
| 16 | |||
| 17 | class 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 { | |||
| 53 | case class Standard(axiom: OWLAxiom)(implicit toString: (OWLAxiom) => String) | 53 | case 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 @@ | |||
| 1 | package uk.ac.ox.cs.rsacomb.implicits | 1 | package uk.ac.ox.cs.rsacomb.implicits |
| 2 | 2 | ||
| 3 | import tech.oxfordsemantic.jrdfox.logic.Datatype | 3 | import tech.oxfordsemantic.jrdfox.logic.Datatype |
| 4 | import tech.oxfordsemantic.jrdfox.logic.expression.{Literal, FunctionCall} | 4 | import tech.oxfordsemantic.jrdfox.logic.expression.{Literal, FunctionCall, Term} |
| 5 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ | 5 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ |
| 6 | BindAtom, | 6 | BindAtom, |
| 7 | TupleTableAtom, | 7 | TupleTableAtom, |
| 8 | TupleTableName | 8 | TupleTableName |
| 9 | } | 9 | } |
| 10 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI} | 10 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI} |
| 11 | import scala.collection.JavaConverters._ | ||
| 12 | 11 | ||
| 13 | import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Nth} | ||
| 14 | import uk.ac.ox.cs.rsacomb.RSAOntology | 12 | import uk.ac.ox.cs.rsacomb.RSAOntology |
| 13 | import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Nth} | ||
| 14 | import 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 @@ | |||
| 1 | package uk.ac.ox.cs.rsacomb.util | 1 | package uk.ac.ox.cs.rsacomb.util |
| 2 | 2 | ||
| 3 | import java.io.File | 3 | import java.io.{OutputStream, File, StringReader} |
| 4 | import java.io.StringReader | ||
| 5 | import tech.oxfordsemantic.jrdfox.Prefixes | 4 | import tech.oxfordsemantic.jrdfox.Prefixes |
| 6 | import tech.oxfordsemantic.jrdfox.client.{ | 5 | import tech.oxfordsemantic.jrdfox.client.{ |
| 7 | ComponentInfo, | 6 | ComponentInfo, |
| @@ -11,6 +10,7 @@ import tech.oxfordsemantic.jrdfox.client.{ | |||
| 11 | UpdateType | 10 | UpdateType |
| 12 | } | 11 | } |
| 13 | import tech.oxfordsemantic.jrdfox.formats.SPARQLParser | 12 | import tech.oxfordsemantic.jrdfox.formats.SPARQLParser |
| 13 | import tech.oxfordsemantic.jrdfox.logic.Datatype | ||
| 14 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ | 14 | import 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 | } |
| 21 | import tech.oxfordsemantic.jrdfox.logic.expression.{Resource} | 21 | import tech.oxfordsemantic.jrdfox.logic.expression.{ |
| 22 | Literal, | ||
| 23 | Resource, | ||
| 24 | Variable, | ||
| 25 | Term | ||
| 26 | } | ||
| 22 | import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery | 27 | import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery |
| 23 | import uk.ac.ox.cs.rsacomb.suffix.Nth | 28 | import uk.ac.ox.cs.rsacomb.suffix.Nth |
| 24 | import uk.ac.ox.cs.rsacomb.util.Logger | 29 | import 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 @@ | |||
| 1 | package uk.ac.ox.cs.rsacomb.converter | 1 | package uk.ac.ox.cs.rsacomb.converter |
| 2 | 2 | ||
| 3 | import java.util.{ArrayList => JList} | 3 | // import java.util.{ArrayList => JList} |
| 4 | import org.scalatest.LoneElement | 4 | import org.scalatest.LoneElement |
| 5 | import org.scalatest.flatspec.AnyFlatSpec | 5 | import org.scalatest.flatspec.AnyFlatSpec |
| 6 | import org.scalatest.matchers.should.Matchers | 6 | import org.scalatest.matchers.should.Matchers |
| 7 | 7 | ||
| 8 | import org.semanticweb.owlapi.model.OWLClassExpression | 8 | // import org.semanticweb.owlapi.model.OWLClassExpression |
| 9 | import uk.ac.manchester.cs.owl.owlapi.{OWLSubClassOfAxiomImpl} | 9 | // import uk.ac.manchester.cs.owl.owlapi.{OWLSubClassOfAxiomImpl} |
| 10 | import 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 | // } |
| 19 | import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl} | 19 | // import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl} |
| 20 | import org.semanticweb.owlapi.model.{OWLAxiom} | 20 | // import org.semanticweb.owlapi.model.{OWLAxiom} |
| 21 | 21 | ||
| 22 | import tech.oxfordsemantic.jrdfox.logic.Datatype | 22 | // import tech.oxfordsemantic.jrdfox.logic.Datatype |
| 23 | import 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 | // } |
| 29 | import 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 | ||
| 36 | import org.semanticweb.owlapi.model.{IRI => OWLIRI} | 36 | // import org.semanticweb.owlapi.model.{IRI => OWLIRI} |
| 37 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI} | 37 | // import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI} |
| 38 | 38 | ||
| 39 | import uk.ac.ox.cs.rsacomb.converter._ | 39 | // import uk.ac.ox.cs.rsacomb.converter._ |
| 40 | import uk.ac.ox.cs.rsacomb.util.RSA | 40 | // import uk.ac.ox.cs.rsacomb.util.RSA |
| 41 | 41 | ||
| 42 | object OWLAxiomSpec { | 42 | object 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 | ||
| 182 | class OWLAxiomSpec extends AnyFlatSpec with Matchers with LoneElement { | 182 | class 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 @@ | |||
| 1 | package uk.ac.ox.cs.rsacomb.converter | 1 | package uk.ac.ox.cs.rsacomb.converter |
| 2 | 2 | ||
| 3 | import java.util.{ArrayList => JList} | 3 | // import java.util.{ArrayList => JList} |
| 4 | 4 | ||
| 5 | import org.scalatest.LoneElement | 5 | import org.scalatest.LoneElement |
| 6 | import org.scalatest.flatspec.AnyFlatSpec | 6 | import org.scalatest.flatspec.AnyFlatSpec |
| 7 | import org.scalatest.matchers.should.Matchers | 7 | import org.scalatest.matchers.should.Matchers |
| 8 | 8 | ||
| 9 | import org.semanticweb.owlapi.model.OWLClassExpression | 9 | // import org.semanticweb.owlapi.model.OWLClassExpression |
| 10 | import 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 | // } |
| 19 | import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl} | 19 | // import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl} |
| 20 | import org.semanticweb.owlapi.model.IRI | 20 | // import org.semanticweb.owlapi.model.IRI |
| 21 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI} | 21 | // import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI} |
| 22 | 22 | ||
| 23 | import tech.oxfordsemantic.jrdfox.logic.Datatype | 23 | // import tech.oxfordsemantic.jrdfox.logic.Datatype |
| 24 | import 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 | // } |
| 29 | import 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 | ||
| 36 | import 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 | // } |
| 43 | import uk.ac.ox.cs.rsacomb.util.RSA | 43 | // import uk.ac.ox.cs.rsacomb.util.RSA |
| 44 | 44 | ||
| 45 | object OWLClassSpec { | 45 | object 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 | ||
| 118 | class OWLClassSpec extends AnyFlatSpec with Matchers with LoneElement { | 118 | class 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 | } |
