From 6bd0b51aade6ad82dfa4e4d9c78db347bcaaa3a2 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Mon, 7 Dec 2020 20:04:15 +0000 Subject: Fix bug for data property translation --- src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') 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 6c83caf..6193296 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 @@ -225,7 +225,7 @@ trait RDFoxConverter { * @see [[org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom OWLDataPropertyAssertionAxiom]] */ case a: OWLDataPropertyAssertionAxiom => - if (!a.getSubject.isNamed || !a.getObject.isNamed) + if (!a.getSubject.isNamed) Result() else { val subj = a.getSubject.asOWLNamedIndividual.getIRI -- cgit v1.2.3 From 1421dae96ea7b8be1678944229d4912037ba8821 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Mon, 7 Dec 2020 20:12:44 +0000 Subject: Reorganize tests --- .../uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala | 2 +- .../ac/ox/cs/rsacomb/FilteringProgramSpecs.scala | 2 +- .../scala/uk/ac/ox/cs/rsacomb/OWLAxiomSpec.scala | 336 --------------------- .../scala/uk/ac/ox/cs/rsacomb/OWLClassSpec.scala | 279 ----------------- .../uk/ac/ox/cs/rsacomb/RDFoxConverterSpec.scala | 108 ------- .../ac/ox/cs/rsacomb/converter/OWLAxiomSpec.scala | 336 +++++++++++++++++++++ .../ac/ox/cs/rsacomb/converter/OWLClassSpec.scala | 279 +++++++++++++++++ .../cs/rsacomb/converter/RDFoxConverterSpec.scala | 108 +++++++ 8 files changed, 725 insertions(+), 725 deletions(-) delete mode 100644 src/test/scala/uk/ac/ox/cs/rsacomb/OWLAxiomSpec.scala delete mode 100644 src/test/scala/uk/ac/ox/cs/rsacomb/OWLClassSpec.scala delete mode 100644 src/test/scala/uk/ac/ox/cs/rsacomb/RDFoxConverterSpec.scala create mode 100644 src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLAxiomSpec.scala create mode 100644 src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLClassSpec.scala create mode 100644 src/test/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverterSpec.scala (limited to 'src') diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala index a7d7f27..a588ae8 100644 --- a/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala @@ -1,4 +1,4 @@ -package rsacomb +package uk.ac.ox.cs.rsacomb import java.io.File import org.scalatest.LoneElement diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala index 93e312c..e627bf7 100644 --- a/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala @@ -1,4 +1,4 @@ -package rsacomb +package uk.ac.ox.cs.rsacomb import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/OWLAxiomSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/OWLAxiomSpec.scala deleted file mode 100644 index e1ece62..0000000 --- a/src/test/scala/uk/ac/ox/cs/rsacomb/OWLAxiomSpec.scala +++ /dev/null @@ -1,336 +0,0 @@ -package rsacomb - -import java.util.{ArrayList => JList} -import org.scalatest.LoneElement -import org.scalatest.flatspec.AnyFlatSpec -import org.scalatest.matchers.should.Matchers - -import org.semanticweb.owlapi.model.OWLClassExpression -import uk.ac.manchester.cs.owl.owlapi.{OWLSubClassOfAxiomImpl} -import uk.ac.manchester.cs.owl.owlapi.{ - OWLClassImpl, - OWLObjectSomeValuesFromImpl, - OWLObjectIntersectionOfImpl, - OWLObjectOneOfImpl, - OWLObjectAllValuesFromImpl, - OWLObjectMaxCardinalityImpl, - OWLNamedIndividualImpl -} -import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl} -import org.semanticweb.owlapi.model.{OWLAxiom} - -import tech.oxfordsemantic.jrdfox.logic.Datatype -import tech.oxfordsemantic.jrdfox.logic.datalog.{ - Rule, - BindAtom, - TupleTableAtom, - TupleTableName -} -import tech.oxfordsemantic.jrdfox.logic.expression.{ - FunctionCall, - Term, - Variable, - Literal -} - -import org.semanticweb.owlapi.model.{IRI => OWLIRI} -import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI} - -import uk.ac.ox.cs.rsacomb.converter._ -import uk.ac.ox.cs.rsacomb.util.RSA - -object OWLAxiomSpec { - - // IRI - val iri_Professor = OWLIRI.create("univ:Professor") - val iri_Female = OWLIRI.create("std:Female") - val iri_Student = OWLIRI.create("univ:Student") - val iri_PartTimeStudent = OWLIRI.create("univ:PartTimeStudent") - val iri_Worker = OWLIRI.create("univ:Worker") - val iri_alice = OWLIRI.create("univ:alice") - val iri_supervises = OWLIRI.create("univ:supervises") - val iri_hasSupervisor = OWLIRI.create("univ:hasSupervisor") - val iri_sameAs = OWLIRI.create("owl:sameAs") - - // RDFox Terms - val term_x = Variable.create("x") - val term_y = Variable.create("y") - val term_z = Variable.create("z") - val term_c1 = RSA("c_1") - val term_c2 = RSA("c_2") - val term_alice = RDFIRI.create("univ:alice") - - // RDFox Predicates - val pred_sameAs = TupleTableName.create("owl:sameAs") - val pred_Professor = TupleTableName.create(iri_Professor.getIRIString) - val pred_hasSupervisor = TupleTableName.create(iri_hasSupervisor.getIRIString) - - // OWL Classes - // Name Class corresponding to - // - // Professor - // - val class_Professor = new OWLClassImpl(iri_Professor) - val class_Female = new OWLClassImpl(iri_Female) - val class_Student = new OWLClassImpl(iri_Student) - val class_PartTimeStudent = new OWLClassImpl(iri_PartTimeStudent) - val class_Worker = new OWLClassImpl(iri_Worker) - val class_OWLClass = class_Professor - // Class Conjunction corresponding to - // - // Student ∧ Worker - // - val class_OWLObjectIntersectionOf = { - val conjuncts = new JList[OWLClassExpression]() - conjuncts.add(class_Student) - conjuncts.add(class_Worker) - new OWLObjectIntersectionOfImpl(conjuncts) - } - // Singleton Class corresponding to - // - // { alice } - // - val class_OWLObjectOneOf = - new OWLObjectOneOfImpl( - new OWLNamedIndividualImpl(iri_alice) - ) - // Object Existential Restiction corresponding to - // - // ∃ hasSupervisor.Professor - // - val class_OWLObjectSomeValuesFrom = - new OWLObjectSomeValuesFromImpl( - new OWLObjectPropertyImpl(iri_hasSupervisor), - class_Professor - ) - // Object Max Cardinality Restriction corresponding to - // - // ≤ 1 hasSupervisor . Professor - val class_OWLObjectMaxCardinality = - new OWLObjectMaxCardinalityImpl( - new OWLObjectPropertyImpl(iri_hasSupervisor), - 1, - class_Professor - ) - - // OWL Axioms - // Axiom SubClassOf corresponding to - // - // Student ∧ Worker -> PartTimeStudent - // - val axiom_OWLSubClassOf1 = - new OWLSubClassOfAxiomImpl( - class_OWLObjectIntersectionOf, - class_PartTimeStudent, - new JList() - ) - - // Axiom SubClassOf corresponding to - // - // Student -> ∃ hasSupervisor.Professor - // - val axiom_OWLSubClassOf2 = - new OWLSubClassOfAxiomImpl( - class_Student, - class_OWLObjectSomeValuesFrom, - new JList() - ) - - // Axiom SubClassOf corresponding to - // - // ∃ hasSupervisor.Professor -> Student - // - val axiom_OWLSubClassOf3 = - new OWLSubClassOfAxiomImpl( - class_OWLObjectSomeValuesFrom, - class_Student, - new JList() - ) - - // Axiom SubClassOf corresponding to - // - // Student -> { alice } - // - val axiom_OWLSubClassOf4 = - new OWLSubClassOfAxiomImpl( - class_Student, - class_OWLObjectOneOf, - new JList() - ) - - // Axiom SubClassOf corresponding to - // - // Student -> ≤1 hasSupervisor.Professor - // - val axiom_OWLSubClassOf5 = - new OWLSubClassOfAxiomImpl( - class_Student, - class_OWLObjectMaxCardinality, - new JList() - ) - - def convertAxiom( - axiom: OWLAxiom, - term: Term, - skolem: SkolemStrategy = NoSkolem - ): List[Rule] = { - axiom.accept(RDFoxAxiomConverter(term, List())) - } - -} // object OWLAxiomSpec - -class OWLAxiomSpec extends AnyFlatSpec with Matchers with LoneElement { - - // Import required data - import OWLAxiomSpec._ - // Implicit convertion from IRI in OWLAPI to IRI in JRDFox - import uk.ac.ox.cs.rsacomb.implicits.RDFox._ - - // OWLSubClassOfAxiom #1 - axiom_OWLSubClassOf1.toString should "be converted into a singleton List[Rule]" in { - val result = convertAxiom(axiom_OWLSubClassOf1, term_x) - result.loneElement shouldBe a[Rule] - } - - it should "contain a conjuction of atoms (Student[?x],Worker[?x]) in the body of the rule" in { - val result = convertAxiom(axiom_OWLSubClassOf1, term_x) - val body = List( - TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student), - TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Worker) - ) - result.loneElement.getBody should contain theSameElementsAs body - } - - it should "contain a single atom (PartTimeStudent[?x]) in the head of the rule" in { - val result = convertAxiom(axiom_OWLSubClassOf1, term_x) - val head = TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_PartTimeStudent) - result.loneElement.getHead.loneElement should be(head) - } - - // OWLSubClassOfAxiom #2 (w/ constant skolemization) - (axiom_OWLSubClassOf2.toString + "\n(w/ constant skolemization)") should - "be converted into a singleton List[Rule]" in { - val skolem = Constant(axiom_OWLSubClassOf2) - val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) - result.loneElement shouldBe a[Rule] - } - - it should "contain a single atom (Student[?x]) in the body of the rule" in { - val skolem = Constant(axiom_OWLSubClassOf2) - val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) - val body = - TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student.getIRIString) - result.loneElement.getBody.loneElement should equal(body) - } - - // it should "contain a conjuction of atoms (hasSupervisor[?x,?c],Professor[?c]) in the head of the rule" in { - // val skolem = SkolemStrategy.Constant(axiom_OWLSubClassOf2.toString) - // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) - // val term_c = RSA.rsa(skolem.const.getIRI) - // val head = List( - // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_c), - // TupleTableAtom.rdf(term_c, RDFIRI.RDF_TYPE, iri_Professor) - // ) - // result.loneElement.getHead should contain theSameElementsAs (head) - // } - - // OWLSubClassOfAxiom #2 (w/ skolemization) - (axiom_OWLSubClassOf2.toString + "\n(w/ skolemization)") should - "be converted into a singleton List[Rule]" in { - val skolem = Standard(axiom_OWLSubClassOf2) - val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) - result.loneElement shouldBe a[Rule] - } - - it should "contain an atom (Student[?x]) in the body of the rule" in { - val skolem = Standard(axiom_OWLSubClassOf2) - val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) - val body = - TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student) - result.loneElement.getBody should contain(body) - } - - // it should "contain a built-in function call (BIND(?y,SKOLEM(?f,?x))) in the body of the rule" in { - // val skolem = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString) - // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) - // val call = - // BindAtom.create(BuiltinFunctionCall.create("SKOLEM", term_x), term_y) - // result.loneElement.getBody should contain(call) - // } - - // it should "contain a conjuction of atom (hasSupervisor[?x,?y],Professor[?y]) in the head of the rule" in { - // val skolem = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString) - // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) - // val head = List( - // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y), - // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor) - // ) - // result.loneElement.getHead should contain theSameElementsAs head - // } - - // OWLSubClassOfAxiom #3 - axiom_OWLSubClassOf3.toString should "be converted into a singleton List[Rule]" in { - val result = convertAxiom(axiom_OWLSubClassOf3, term_x) - result.loneElement shouldBe a[Rule] - } - - // it should "contain a conjunction of atoms (hasSupervisor[?x,?y],Professor[?y]) in the body of the rule" in { - // val result = convertAxiom(axiom_OWLSubClassOf3, term_x) - // val body = List( - // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y), - // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor) - // ) - // result.loneElement.getBody should contain theSameElementsAs body - // } - - it should "contain a single atom (Student[?x]) in the head of the rule" in { - val result = convertAxiom(axiom_OWLSubClassOf3, term_x) - val head = - TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student) - result.loneElement.getHead.loneElement should be(head) - } - - // OWLSubClassOfAxiom #4 - axiom_OWLSubClassOf4.toString should "be converted into a singleton List[Rule]" in { - val result = convertAxiom(axiom_OWLSubClassOf4, term_x) - result.loneElement shouldBe a[Rule] - } - - it should "contain a single atoms (Student[?x]) in the body of the rule" in { - val result = convertAxiom(axiom_OWLSubClassOf4, term_x) - val body = - TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student) - result.loneElement.getBody.loneElement should be(body) - } - - it should "contain a single atom (sameAs[?x,alice])) in the head of the rule" in { - val result = convertAxiom(axiom_OWLSubClassOf4, term_x) - val head = TupleTableAtom.rdf(term_x, RDFIRI.SAME_AS, term_alice) - result.loneElement.getHead.loneElement should be(head) - } - - // OWLSubClassOfAxiom #5 - axiom_OWLSubClassOf5.toString should "be converted into a singleton List[Rule]" in { - val result = convertAxiom(axiom_OWLSubClassOf5, term_x) - result.loneElement shouldBe a[Rule] - } - - // it should "contain a conjunction of atoms (...) in the body of the rule" in { - // val result = convertAxiom(axiom_OWLSubClassOf5, term_x) - // val body = List( - // TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student), - // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y), - // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor), - // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_z), - // TupleTableAtom.rdf(term_z, RDFIRI.RDF_TYPE, iri_Professor) - // ) - // result.loneElement.getBody should contain theSameElementsAs body - // } - - // it should "contain a single atom (sameAs[?x,?z])) in the head of the rule" in { - // val result = convertAxiom(axiom_OWLSubClassOf5, term_x) - // val head = TupleTableAtom.rdf(term_y, RDFIRI.SAME_AS, term_z) - // result.loneElement.getHead.loneElement should be(head) - // } - -} // class OWLAxiomSpec diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/OWLClassSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/OWLClassSpec.scala deleted file mode 100644 index def864b..0000000 --- a/src/test/scala/uk/ac/ox/cs/rsacomb/OWLClassSpec.scala +++ /dev/null @@ -1,279 +0,0 @@ -package rsacomb - -import java.util.{ArrayList => JList} - -import org.scalatest.LoneElement -import org.scalatest.flatspec.AnyFlatSpec -import org.scalatest.matchers.should.Matchers - -import org.semanticweb.owlapi.model.OWLClassExpression -import uk.ac.manchester.cs.owl.owlapi.{ - OWLClassImpl, - OWLObjectSomeValuesFromImpl, - OWLObjectIntersectionOfImpl, - OWLObjectOneOfImpl, - OWLObjectAllValuesFromImpl, - OWLObjectMaxCardinalityImpl, - OWLNamedIndividualImpl -} -import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl} -import org.semanticweb.owlapi.model.IRI -import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI} - -import tech.oxfordsemantic.jrdfox.logic.Datatype -import tech.oxfordsemantic.jrdfox.logic.datalog.{ - TupleTableAtom, - TupleTableName, - BindAtom -} -import tech.oxfordsemantic.jrdfox.logic.expression.{ - FunctionCall, - Term, - Variable, - Literal -} - -import uk.ac.ox.cs.rsacomb.converter.{ - RDFoxRuleShards, - RDFoxClassExprConverter, - SkolemStrategy, - Standard, - Constant -} -import uk.ac.ox.cs.rsacomb.util.RSA - -object OWLClassSpec { - - // IRI - val iri_Professor = IRI.create("univ:Professor") - val iri_Female = IRI.create("std:Female") - val iri_Student = IRI.create("univ:Student") - val iri_Worker = IRI.create("univ:Worker") - val iri_alice = IRI.create("univ:alice") - val iri_supervises = IRI.create("univ:supervises") - val iri_hasSupervisor = IRI.create("univ:hasSupervisor") - - // RDFox Terms - val term_x = Variable.create("x") - val term_y = Variable.create("y") - val term_c1 = RSA("c_1") - val term_c2 = RSA("c_2") - val term_alice = RDFIRI.create("univ:alice") - - // RDFox Predicates - val pred_sameAs = TupleTableName.create("owl:sameAs") - val pred_Professor = TupleTableName.create(iri_Professor.getIRIString) - val pred_hasSupervisor = TupleTableName.create(iri_hasSupervisor.getIRIString) - - // OWL Classes - // Name Class corresponding to - // - // Professor - // - val class_Professor = new OWLClassImpl(iri_Professor) - val class_Female = new OWLClassImpl(iri_Female) - val class_Student = new OWLClassImpl(iri_Student) - val class_Worker = new OWLClassImpl(iri_Worker) - val class_OWLClass = class_Professor - - // Class Conjunction corresponding to - // - // Female ∧ Student ∧ Worker - // - val class_OWLObjectIntersectionOf = { - val conjuncts = new JList[OWLClassExpression]() - conjuncts.add(class_Female) - conjuncts.add(class_Student) - conjuncts.add(class_Worker) - new OWLObjectIntersectionOfImpl(conjuncts) - } - // Singleton Class corresponding to - // - // { alice } - // - val class_OWLObjectOneOf = - new OWLObjectOneOfImpl( - new OWLNamedIndividualImpl(iri_alice) - ) - // Object Existential Restiction corresponding to - // - // ∃ hasSupervisor.Professor - // - val class_OWLObjectSomeValuesFrom = - new OWLObjectSomeValuesFromImpl( - new OWLObjectPropertyImpl(iri_hasSupervisor), - class_Professor - ) - // Object Max Cardinality Restriction corresponding to - // - // ≤1 hasSupervisor.Professor - val class_OWLObjectMaxCardinality = - new OWLObjectMaxCardinalityImpl( - new OWLObjectPropertyImpl(iri_hasSupervisor), - 1, - class_Professor - ) -} // object OWLClassSpec - -class OWLClassSpec extends AnyFlatSpec with Matchers with LoneElement { - // Import required data - import OWLClassSpec._ - - // OWLClass - class_OWLClass.toString should "be converted into a RDFoxRuleShards" in { - val visitor = RDFoxClassExprConverter(term_x) - val result = class_OWLClass.accept(visitor) - result shouldBe a[RDFoxRuleShards] - } - - it should "have a single TupleTableAtom in its result list" in { - val visitor = RDFoxClassExprConverter(term_x) - val result = class_OWLClass.accept(visitor) - result.res.loneElement shouldBe an[TupleTableAtom] - } - - it should "have an empty extension list" in { - val visitor = RDFoxClassExprConverter(term_x) - val result = class_OWLClass.accept(visitor) - result.ext shouldBe empty - } - - // OWLObjectIntersectionOf - class_OWLObjectIntersectionOf.toString should "be converted into a RDFoxRuleShards" in { - val visitor = RDFoxClassExprConverter(term_x) - val result = class_OWLObjectIntersectionOf.accept(visitor) - result shouldBe a[RDFoxRuleShards] - } - - it should "be converted in the union of its converted conjuncts" in { - val visitor = RDFoxClassExprConverter(term_x) - val result1 = class_OWLObjectIntersectionOf.accept(visitor) - val result2 = RDFoxClassExprConverter.merge( - List( - class_Female.accept(visitor), - class_Student.accept(visitor), - class_Worker.accept(visitor) - ) - ) - result1.res should contain theSameElementsAs result2.res - result1.ext should contain theSameElementsAs result2.ext - } - - // OWLObjectOneOf - class_OWLObjectOneOf.toString should "be converted into a RDFoxRuleShards" in { - val visitor = RDFoxClassExprConverter(term_x) - val result = class_OWLObjectOneOf.accept(visitor) - result shouldBe a[RDFoxRuleShards] - } - - // it should "be converted into a single TupleTableAtom" in { - // val visitor = RDFoxClassExprConverter(term_x) - // val result = class_OWLObjectOneOf.accept(visitor) - // result.res.loneElement should (be (a [TupleTableAtom]) and have ('tupleTableName (pred_sameAs))) - // } - - it should "have an empty extension list" in { - val visitor = RDFoxClassExprConverter(term_x) - val result = class_OWLObjectOneOf.accept(visitor) - result.ext shouldBe empty - } - - // OWLObjectSomeValuesFrom - (class_OWLObjectSomeValuesFrom.toString ++ " w/o skolemization") should - "be converted into a RDFoxRuleShards" in { - val visitor = RDFoxClassExprConverter(term_x) - val result = class_OWLObjectSomeValuesFrom.accept(visitor) - result shouldBe a[RDFoxRuleShards] - } - - it should "have two TupleTableAtoms in its result list" in { - val visitor = RDFoxClassExprConverter(term_x) - val result = class_OWLObjectSomeValuesFrom.accept(visitor) - exactly(2, result.res) should (be(an[TupleTableAtom]) - //and have('numberOfArguments (3)) - ) - } - - it should "have an empty extension list" in { - val visitor = RDFoxClassExprConverter(term_x) - val result = class_OWLObjectSomeValuesFrom.accept(visitor) - result.ext shouldBe empty - } - - //(class_OWLObjectSomeValuesFrom.toString ++ " w/ skolemization") should - // "be converted into a RDFoxRuleShards" in { - // val skolem = Standard(class_OWLObjectSomeValuesFrom) - // val visitor = RDFoxClassExprConverter(term_x, List(), skolem) - // val result = class_OWLObjectSomeValuesFrom.accept(visitor) - // result shouldBe a[RDFoxRuleShards] - // } - - //it should "have exactly two TupleTableAtoms in its result list" in { - // val skolem = Standard(class_OWLObjectSomeValuesFrom) - // val visitor = RDFoxClassExprConverter(term_x, List(), skolem) - // val result = class_OWLObjectSomeValuesFrom.accept(visitor) - // exactly(2, result.res) should (be(an[TupleTableAtom]) - // //and have('numberOfArguments (3)) - // ) - //} - - //it should "should have a single SKOLEM call in the extension list" in { - // val skolem = Standard(class_OWLObjectSomeValuesFrom) - // val visitor = RDFoxClassExprConverter(term_x, List(), skolem) - // val result = class_OWLObjectSomeValuesFrom.accept(visitor) - // result.ext.loneElement shouldBe a[BindAtom] - // val builtin = result.ext.head.asInstanceOf[BindAtom].getExpression - // builtin should (be(a[FunctionCall]) and have( - // 'functionName ("SKOLEM") - // )) - //} - - //(class_OWLObjectSomeValuesFrom.toString ++ " w/ constant skolemization") should - // "be converted into a RDFoxRuleShards" in { - // val skolem = Constant(class_OWLObjectSomeValuesFrom) - // val visitor = RDFoxClassExprConverter(term_x, List(), skolem) - // val result = class_OWLObjectSomeValuesFrom.accept(visitor) - // result shouldBe a[RDFoxRuleShards] - // } - - //it should "have exactly two TupleTableAtoms in its result list" in { - // val skolem = Constant(class_OWLObjectSomeValuesFrom) - // val visitor = RDFoxClassExprConverter(term_x, List(), skolem) - // val result = class_OWLObjectSomeValuesFrom.accept(visitor) - // exactly(2, result.res) should (be(an[TupleTableAtom]) - // //and have('numberOfArguments (3)) - // ) - //} - - //it should "have an empty extension list" in { - // val skolem = Constant(class_OWLObjectSomeValuesFrom) - // val visitor = RDFoxClassExprConverter(term_x, List(), skolem) - // val result = class_OWLObjectSomeValuesFrom.accept(visitor) - // result.ext shouldBe empty - //} - - // OWLObjectMaxCardinalityImpl - class_OWLObjectMaxCardinality.toString should - "be converted into a RDFoxRuleShards" in { - val visitor = RDFoxClassExprConverter(term_x) - val result = class_OWLObjectMaxCardinality.accept(visitor) - result shouldBe a[RDFoxRuleShards] - } - - // it should "have a single TupleTableAtom in the result list" in { - // val visitor = RDFoxClassExprConverter(term_x) - // val result = class_OWLObjectMaxCardinality.accept(visitor) - // result.res.loneElement should (be(an[TupleTableAtom]) and have( - // 'tupleTableName (pred_sameAs) - // )) - // } - - it should "have 4 TupleTableAtoms in its extension list" in { - val visitor = RDFoxClassExprConverter(term_x) - val result = class_OWLObjectMaxCardinality.accept(visitor) - exactly(4, result.ext) should (be(an[TupleTableAtom]) - //and have('numberOfArguments (3)) - ) - } - -} // class OWLClassSpec diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/RDFoxConverterSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/RDFoxConverterSpec.scala deleted file mode 100644 index 5c9fa96..0000000 --- a/src/test/scala/uk/ac/ox/cs/rsacomb/RDFoxConverterSpec.scala +++ /dev/null @@ -1,108 +0,0 @@ -package rsacomb - -import org.scalatest.LoneElement -import org.scalatest.flatspec.AnyFlatSpec -import org.scalatest.matchers.should.Matchers -import org.semanticweb.owlapi.apibinding.OWLManager -import org.semanticweb.owlapi.model.OWLOntologyManager - -import tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom -import tech.oxfordsemantic.jrdfox.logic.expression.{Variable, IRI} -import uk.ac.ox.cs.rsacomb.converter.RDFoxConverter -import uk.ac.ox.cs.rsacomb.suffix.{Empty, Forward, Backward, Inverse} -import uk.ac.ox.cs.rsacomb.converter.{SkolemStrategy, NoSkolem} - -object RDFoxConverterSpec { - - val manager = OWLManager.createOWLOntologyManager() - val factory = manager.getOWLDataFactory - - val term0 = Variable.create("X") - val term1 = Variable.create("Y") - val iriString0 = "http://example.com/rsacomb/iri0" - val iriString1 = "http://example.com/rsacomb/iri1" - val iriString2 = "http://example.com/rsacomb/iri2" - val suffixes = Seq( - Empty, - Forward, - Backward, - Inverse, - Forward + Inverse, - Backward + Inverse - ) -} - -class RDFoxConverterSpec - extends AnyFlatSpec - with Matchers - with LoneElement - with RDFoxConverter { - - import RDFoxConverterSpec._ - - "A class name" should "be converted into a single atom" in { - val cls = factory.getOWLClass(iriString0) - val atom = TupleTableAtom.rdf(term0, IRI.RDF_TYPE, IRI.create(iriString0)) - val (res, ext) = - convert(cls, term0, List(), NoSkolem, Empty) - res.loneElement shouldEqual atom - ext shouldBe empty - } - - "A intersection of classes" should "be converted into the union of the conversion of the classes" in { - val cls0 = factory.getOWLClass(iriString0) - val cls1 = factory.getOWLClass(iriString1) - val cls2 = factory.getOWLClass(iriString2) - val conj = factory.getOWLObjectIntersectionOf(cls0, cls1, cls2) - val (res0, ext0) = - convert(cls0, term0, List(), NoSkolem, Empty) - val (res1, ext1) = - convert(cls1, term0, List(), NoSkolem, Empty) - val (res2, ext2) = - convert(cls2, term0, List(), NoSkolem, Empty) - val (res, ext) = - convert(conj, term0, List(), NoSkolem, Empty) - res should contain theSameElementsAs (res0 ::: res1 ::: res2) - ext should contain theSameElementsAs (ext0 ::: ext1 ::: ext2) - } - - "A singleton intersection" should "correspond to the conversion of the internal class" in { - val cls0 = factory.getOWLClass(iriString0) - val conj = factory.getOWLObjectIntersectionOf(cls0) - val (res0, ext0) = - convert(cls0, term0, List(), NoSkolem, Empty) - val (res, ext) = - convert(conj, term0, List(), NoSkolem, Empty) - res should contain theSameElementsAs res0 - ext should contain theSameElementsAs ext0 - } - - "An object property" should "be converted into an atom with matching predicate" in { - val prop = factory.getOWLObjectProperty(iriString0) - for (sx <- suffixes) { - val atom = - TupleTableAtom.rdf(term0, IRI.create(iriString0 :: sx), term1) - convert(prop, term0, term1, sx) shouldEqual atom - } - } - - "The inverse of an object property" should "be converted into an atom with matching negated predicate" in { - val prop = factory.getOWLObjectProperty(iriString0) - val inv = factory.getOWLObjectInverseOf(prop) - for (sx <- Seq(Empty, Forward, Backward)) { - val atom = - TupleTableAtom.rdf(term0, IRI.create(iriString0 :: sx + Inverse), term1) - convert(inv, term0, term1, sx) shouldEqual atom - } - } - - "A data property" should "be converted into an atom with matching predicate" in { - val prop = factory.getOWLDataProperty(iriString0) - for (suffix <- suffixes) { - val atom = - TupleTableAtom.rdf(term0, IRI.create(iriString0 :: suffix), term1) - convert(prop, term0, term1, suffix) shouldEqual atom - } - } - -} 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 new file mode 100644 index 0000000..eb49c7d --- /dev/null +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLAxiomSpec.scala @@ -0,0 +1,336 @@ +package uk.ac.ox.cs.rsacomb.converter + +import java.util.{ArrayList => JList} +import org.scalatest.LoneElement +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers + +import org.semanticweb.owlapi.model.OWLClassExpression +import uk.ac.manchester.cs.owl.owlapi.{OWLSubClassOfAxiomImpl} +import uk.ac.manchester.cs.owl.owlapi.{ + OWLClassImpl, + OWLObjectSomeValuesFromImpl, + OWLObjectIntersectionOfImpl, + OWLObjectOneOfImpl, + OWLObjectAllValuesFromImpl, + OWLObjectMaxCardinalityImpl, + OWLNamedIndividualImpl +} +import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl} +import org.semanticweb.owlapi.model.{OWLAxiom} + +import tech.oxfordsemantic.jrdfox.logic.Datatype +import tech.oxfordsemantic.jrdfox.logic.datalog.{ + Rule, + BindAtom, + TupleTableAtom, + TupleTableName +} +import tech.oxfordsemantic.jrdfox.logic.expression.{ + FunctionCall, + Term, + Variable, + Literal +} + +import org.semanticweb.owlapi.model.{IRI => OWLIRI} +import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI} + +import uk.ac.ox.cs.rsacomb.converter._ +import uk.ac.ox.cs.rsacomb.util.RSA + +object OWLAxiomSpec { + + // IRI + val iri_Professor = OWLIRI.create("univ:Professor") + val iri_Female = OWLIRI.create("std:Female") + val iri_Student = OWLIRI.create("univ:Student") + val iri_PartTimeStudent = OWLIRI.create("univ:PartTimeStudent") + val iri_Worker = OWLIRI.create("univ:Worker") + val iri_alice = OWLIRI.create("univ:alice") + val iri_supervises = OWLIRI.create("univ:supervises") + val iri_hasSupervisor = OWLIRI.create("univ:hasSupervisor") + val iri_sameAs = OWLIRI.create("owl:sameAs") + + // RDFox Terms + val term_x = Variable.create("x") + val term_y = Variable.create("y") + val term_z = Variable.create("z") + val term_c1 = RSA("c_1") + val term_c2 = RSA("c_2") + val term_alice = RDFIRI.create("univ:alice") + + // RDFox Predicates + val pred_sameAs = TupleTableName.create("owl:sameAs") + val pred_Professor = TupleTableName.create(iri_Professor.getIRIString) + val pred_hasSupervisor = TupleTableName.create(iri_hasSupervisor.getIRIString) + + // OWL Classes + // Name Class corresponding to + // + // Professor + // + val class_Professor = new OWLClassImpl(iri_Professor) + val class_Female = new OWLClassImpl(iri_Female) + val class_Student = new OWLClassImpl(iri_Student) + val class_PartTimeStudent = new OWLClassImpl(iri_PartTimeStudent) + val class_Worker = new OWLClassImpl(iri_Worker) + val class_OWLClass = class_Professor + // Class Conjunction corresponding to + // + // Student ∧ Worker + // + val class_OWLObjectIntersectionOf = { + val conjuncts = new JList[OWLClassExpression]() + conjuncts.add(class_Student) + conjuncts.add(class_Worker) + new OWLObjectIntersectionOfImpl(conjuncts) + } + // Singleton Class corresponding to + // + // { alice } + // + val class_OWLObjectOneOf = + new OWLObjectOneOfImpl( + new OWLNamedIndividualImpl(iri_alice) + ) + // Object Existential Restiction corresponding to + // + // ∃ hasSupervisor.Professor + // + val class_OWLObjectSomeValuesFrom = + new OWLObjectSomeValuesFromImpl( + new OWLObjectPropertyImpl(iri_hasSupervisor), + class_Professor + ) + // Object Max Cardinality Restriction corresponding to + // + // ≤ 1 hasSupervisor . Professor + val class_OWLObjectMaxCardinality = + new OWLObjectMaxCardinalityImpl( + new OWLObjectPropertyImpl(iri_hasSupervisor), + 1, + class_Professor + ) + + // OWL Axioms + // Axiom SubClassOf corresponding to + // + // Student ∧ Worker -> PartTimeStudent + // + val axiom_OWLSubClassOf1 = + new OWLSubClassOfAxiomImpl( + class_OWLObjectIntersectionOf, + class_PartTimeStudent, + new JList() + ) + + // Axiom SubClassOf corresponding to + // + // Student -> ∃ hasSupervisor.Professor + // + val axiom_OWLSubClassOf2 = + new OWLSubClassOfAxiomImpl( + class_Student, + class_OWLObjectSomeValuesFrom, + new JList() + ) + + // Axiom SubClassOf corresponding to + // + // ∃ hasSupervisor.Professor -> Student + // + val axiom_OWLSubClassOf3 = + new OWLSubClassOfAxiomImpl( + class_OWLObjectSomeValuesFrom, + class_Student, + new JList() + ) + + // Axiom SubClassOf corresponding to + // + // Student -> { alice } + // + val axiom_OWLSubClassOf4 = + new OWLSubClassOfAxiomImpl( + class_Student, + class_OWLObjectOneOf, + new JList() + ) + + // Axiom SubClassOf corresponding to + // + // Student -> ≤1 hasSupervisor.Professor + // + val axiom_OWLSubClassOf5 = + new OWLSubClassOfAxiomImpl( + class_Student, + class_OWLObjectMaxCardinality, + new JList() + ) + + def convertAxiom( + axiom: OWLAxiom, + term: Term, + skolem: SkolemStrategy = NoSkolem + ): List[Rule] = { + axiom.accept(RDFoxAxiomConverter(term, List())) + } + +} // object OWLAxiomSpec + +class OWLAxiomSpec extends AnyFlatSpec with Matchers with LoneElement { + + // Import required data + import OWLAxiomSpec._ + // Implicit convertion from IRI in OWLAPI to IRI in JRDFox + import uk.ac.ox.cs.rsacomb.implicits.RDFox._ + + // OWLSubClassOfAxiom #1 + axiom_OWLSubClassOf1.toString should "be converted into a singleton List[Rule]" in { + val result = convertAxiom(axiom_OWLSubClassOf1, term_x) + result.loneElement shouldBe a[Rule] + } + + it should "contain a conjuction of atoms (Student[?x],Worker[?x]) in the body of the rule" in { + val result = convertAxiom(axiom_OWLSubClassOf1, term_x) + val body = List( + TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student), + TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Worker) + ) + result.loneElement.getBody should contain theSameElementsAs body + } + + it should "contain a single atom (PartTimeStudent[?x]) in the head of the rule" in { + val result = convertAxiom(axiom_OWLSubClassOf1, term_x) + val head = TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_PartTimeStudent) + result.loneElement.getHead.loneElement should be(head) + } + + // OWLSubClassOfAxiom #2 (w/ constant skolemization) + (axiom_OWLSubClassOf2.toString + "\n(w/ constant skolemization)") should + "be converted into a singleton List[Rule]" in { + val skolem = Constant(axiom_OWLSubClassOf2) + val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) + result.loneElement shouldBe a[Rule] + } + + it should "contain a single atom (Student[?x]) in the body of the rule" in { + val skolem = Constant(axiom_OWLSubClassOf2) + val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) + val body = + TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student.getIRIString) + result.loneElement.getBody.loneElement should equal(body) + } + + // it should "contain a conjuction of atoms (hasSupervisor[?x,?c],Professor[?c]) in the head of the rule" in { + // val skolem = SkolemStrategy.Constant(axiom_OWLSubClassOf2.toString) + // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) + // val term_c = RSA.rsa(skolem.const.getIRI) + // val head = List( + // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_c), + // TupleTableAtom.rdf(term_c, RDFIRI.RDF_TYPE, iri_Professor) + // ) + // result.loneElement.getHead should contain theSameElementsAs (head) + // } + + // OWLSubClassOfAxiom #2 (w/ skolemization) + (axiom_OWLSubClassOf2.toString + "\n(w/ skolemization)") should + "be converted into a singleton List[Rule]" in { + val skolem = Standard(axiom_OWLSubClassOf2) + val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) + result.loneElement shouldBe a[Rule] + } + + it should "contain an atom (Student[?x]) in the body of the rule" in { + val skolem = Standard(axiom_OWLSubClassOf2) + val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) + val body = + TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student) + result.loneElement.getBody should contain(body) + } + + // it should "contain a built-in function call (BIND(?y,SKOLEM(?f,?x))) in the body of the rule" in { + // val skolem = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString) + // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) + // val call = + // BindAtom.create(BuiltinFunctionCall.create("SKOLEM", term_x), term_y) + // result.loneElement.getBody should contain(call) + // } + + // it should "contain a conjuction of atom (hasSupervisor[?x,?y],Professor[?y]) in the head of the rule" in { + // val skolem = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString) + // val result = convertAxiom(axiom_OWLSubClassOf2, term_x, skolem) + // val head = List( + // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y), + // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor) + // ) + // result.loneElement.getHead should contain theSameElementsAs head + // } + + // OWLSubClassOfAxiom #3 + axiom_OWLSubClassOf3.toString should "be converted into a singleton List[Rule]" in { + val result = convertAxiom(axiom_OWLSubClassOf3, term_x) + result.loneElement shouldBe a[Rule] + } + + // it should "contain a conjunction of atoms (hasSupervisor[?x,?y],Professor[?y]) in the body of the rule" in { + // val result = convertAxiom(axiom_OWLSubClassOf3, term_x) + // val body = List( + // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y), + // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor) + // ) + // result.loneElement.getBody should contain theSameElementsAs body + // } + + it should "contain a single atom (Student[?x]) in the head of the rule" in { + val result = convertAxiom(axiom_OWLSubClassOf3, term_x) + val head = + TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student) + result.loneElement.getHead.loneElement should be(head) + } + + // OWLSubClassOfAxiom #4 + axiom_OWLSubClassOf4.toString should "be converted into a singleton List[Rule]" in { + val result = convertAxiom(axiom_OWLSubClassOf4, term_x) + result.loneElement shouldBe a[Rule] + } + + it should "contain a single atoms (Student[?x]) in the body of the rule" in { + val result = convertAxiom(axiom_OWLSubClassOf4, term_x) + val body = + TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student) + result.loneElement.getBody.loneElement should be(body) + } + + it should "contain a single atom (sameAs[?x,alice])) in the head of the rule" in { + val result = convertAxiom(axiom_OWLSubClassOf4, term_x) + val head = TupleTableAtom.rdf(term_x, RDFIRI.SAME_AS, term_alice) + result.loneElement.getHead.loneElement should be(head) + } + + // OWLSubClassOfAxiom #5 + axiom_OWLSubClassOf5.toString should "be converted into a singleton List[Rule]" in { + val result = convertAxiom(axiom_OWLSubClassOf5, term_x) + result.loneElement shouldBe a[Rule] + } + + // it should "contain a conjunction of atoms (...) in the body of the rule" in { + // val result = convertAxiom(axiom_OWLSubClassOf5, term_x) + // val body = List( + // TupleTableAtom.rdf(term_x, RDFIRI.RDF_TYPE, iri_Student), + // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_y), + // TupleTableAtom.rdf(term_y, RDFIRI.RDF_TYPE, iri_Professor), + // TupleTableAtom.rdf(term_x, iri_hasSupervisor, term_z), + // TupleTableAtom.rdf(term_z, RDFIRI.RDF_TYPE, iri_Professor) + // ) + // result.loneElement.getBody should contain theSameElementsAs body + // } + + // it should "contain a single atom (sameAs[?x,?z])) in the head of the rule" in { + // val result = convertAxiom(axiom_OWLSubClassOf5, term_x) + // val head = TupleTableAtom.rdf(term_y, RDFIRI.SAME_AS, term_z) + // result.loneElement.getHead.loneElement should be(head) + // } + +} // 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 new file mode 100644 index 0000000..09ab6eb --- /dev/null +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/converter/OWLClassSpec.scala @@ -0,0 +1,279 @@ +package uk.ox.ac.cs.rsacomb.converter + +import java.util.{ArrayList => JList} + +import org.scalatest.LoneElement +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers + +import org.semanticweb.owlapi.model.OWLClassExpression +import uk.ac.manchester.cs.owl.owlapi.{ + OWLClassImpl, + OWLObjectSomeValuesFromImpl, + OWLObjectIntersectionOfImpl, + OWLObjectOneOfImpl, + OWLObjectAllValuesFromImpl, + OWLObjectMaxCardinalityImpl, + OWLNamedIndividualImpl +} +import uk.ac.manchester.cs.owl.owlapi.{OWLObjectPropertyImpl} +import org.semanticweb.owlapi.model.IRI +import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFIRI} + +import tech.oxfordsemantic.jrdfox.logic.Datatype +import tech.oxfordsemantic.jrdfox.logic.datalog.{ + TupleTableAtom, + TupleTableName, + BindAtom +} +import tech.oxfordsemantic.jrdfox.logic.expression.{ + FunctionCall, + Term, + Variable, + Literal +} + +import uk.ac.ox.cs.rsacomb.converter.{ + RDFoxRuleShards, + RDFoxClassExprConverter, + SkolemStrategy, + Standard, + Constant +} +import uk.ac.ox.cs.rsacomb.util.RSA + +object OWLClassSpec { + + // IRI + val iri_Professor = IRI.create("univ:Professor") + val iri_Female = IRI.create("std:Female") + val iri_Student = IRI.create("univ:Student") + val iri_Worker = IRI.create("univ:Worker") + val iri_alice = IRI.create("univ:alice") + val iri_supervises = IRI.create("univ:supervises") + val iri_hasSupervisor = IRI.create("univ:hasSupervisor") + + // RDFox Terms + val term_x = Variable.create("x") + val term_y = Variable.create("y") + val term_c1 = RSA("c_1") + val term_c2 = RSA("c_2") + val term_alice = RDFIRI.create("univ:alice") + + // RDFox Predicates + val pred_sameAs = TupleTableName.create("owl:sameAs") + val pred_Professor = TupleTableName.create(iri_Professor.getIRIString) + val pred_hasSupervisor = TupleTableName.create(iri_hasSupervisor.getIRIString) + + // OWL Classes + // Name Class corresponding to + // + // Professor + // + val class_Professor = new OWLClassImpl(iri_Professor) + val class_Female = new OWLClassImpl(iri_Female) + val class_Student = new OWLClassImpl(iri_Student) + val class_Worker = new OWLClassImpl(iri_Worker) + val class_OWLClass = class_Professor + + // Class Conjunction corresponding to + // + // Female ∧ Student ∧ Worker + // + val class_OWLObjectIntersectionOf = { + val conjuncts = new JList[OWLClassExpression]() + conjuncts.add(class_Female) + conjuncts.add(class_Student) + conjuncts.add(class_Worker) + new OWLObjectIntersectionOfImpl(conjuncts) + } + // Singleton Class corresponding to + // + // { alice } + // + val class_OWLObjectOneOf = + new OWLObjectOneOfImpl( + new OWLNamedIndividualImpl(iri_alice) + ) + // Object Existential Restiction corresponding to + // + // ∃ hasSupervisor.Professor + // + val class_OWLObjectSomeValuesFrom = + new OWLObjectSomeValuesFromImpl( + new OWLObjectPropertyImpl(iri_hasSupervisor), + class_Professor + ) + // Object Max Cardinality Restriction corresponding to + // + // ≤1 hasSupervisor.Professor + val class_OWLObjectMaxCardinality = + new OWLObjectMaxCardinalityImpl( + new OWLObjectPropertyImpl(iri_hasSupervisor), + 1, + class_Professor + ) +} // object OWLClassSpec + +class OWLClassSpec extends AnyFlatSpec with Matchers with LoneElement { + // Import required data + import OWLClassSpec._ + + // OWLClass + class_OWLClass.toString should "be converted into a RDFoxRuleShards" in { + val visitor = RDFoxClassExprConverter(term_x) + val result = class_OWLClass.accept(visitor) + result shouldBe a[RDFoxRuleShards] + } + + it should "have a single TupleTableAtom in its result list" in { + val visitor = RDFoxClassExprConverter(term_x) + val result = class_OWLClass.accept(visitor) + result.res.loneElement shouldBe an[TupleTableAtom] + } + + it should "have an empty extension list" in { + val visitor = RDFoxClassExprConverter(term_x) + val result = class_OWLClass.accept(visitor) + result.ext shouldBe empty + } + + // OWLObjectIntersectionOf + class_OWLObjectIntersectionOf.toString should "be converted into a RDFoxRuleShards" in { + val visitor = RDFoxClassExprConverter(term_x) + val result = class_OWLObjectIntersectionOf.accept(visitor) + result shouldBe a[RDFoxRuleShards] + } + + it should "be converted in the union of its converted conjuncts" in { + val visitor = RDFoxClassExprConverter(term_x) + val result1 = class_OWLObjectIntersectionOf.accept(visitor) + val result2 = RDFoxClassExprConverter.merge( + List( + class_Female.accept(visitor), + class_Student.accept(visitor), + class_Worker.accept(visitor) + ) + ) + result1.res should contain theSameElementsAs result2.res + result1.ext should contain theSameElementsAs result2.ext + } + + // OWLObjectOneOf + class_OWLObjectOneOf.toString should "be converted into a RDFoxRuleShards" in { + val visitor = RDFoxClassExprConverter(term_x) + val result = class_OWLObjectOneOf.accept(visitor) + result shouldBe a[RDFoxRuleShards] + } + + // it should "be converted into a single TupleTableAtom" in { + // val visitor = RDFoxClassExprConverter(term_x) + // val result = class_OWLObjectOneOf.accept(visitor) + // result.res.loneElement should (be (a [TupleTableAtom]) and have ('tupleTableName (pred_sameAs))) + // } + + it should "have an empty extension list" in { + val visitor = RDFoxClassExprConverter(term_x) + val result = class_OWLObjectOneOf.accept(visitor) + result.ext shouldBe empty + } + + // OWLObjectSomeValuesFrom + (class_OWLObjectSomeValuesFrom.toString ++ " w/o skolemization") should + "be converted into a RDFoxRuleShards" in { + val visitor = RDFoxClassExprConverter(term_x) + val result = class_OWLObjectSomeValuesFrom.accept(visitor) + result shouldBe a[RDFoxRuleShards] + } + + it should "have two TupleTableAtoms in its result list" in { + val visitor = RDFoxClassExprConverter(term_x) + val result = class_OWLObjectSomeValuesFrom.accept(visitor) + exactly(2, result.res) should (be(an[TupleTableAtom]) + //and have('numberOfArguments (3)) + ) + } + + it should "have an empty extension list" in { + val visitor = RDFoxClassExprConverter(term_x) + val result = class_OWLObjectSomeValuesFrom.accept(visitor) + result.ext shouldBe empty + } + + //(class_OWLObjectSomeValuesFrom.toString ++ " w/ skolemization") should + // "be converted into a RDFoxRuleShards" in { + // val skolem = Standard(class_OWLObjectSomeValuesFrom) + // val visitor = RDFoxClassExprConverter(term_x, List(), skolem) + // val result = class_OWLObjectSomeValuesFrom.accept(visitor) + // result shouldBe a[RDFoxRuleShards] + // } + + //it should "have exactly two TupleTableAtoms in its result list" in { + // val skolem = Standard(class_OWLObjectSomeValuesFrom) + // val visitor = RDFoxClassExprConverter(term_x, List(), skolem) + // val result = class_OWLObjectSomeValuesFrom.accept(visitor) + // exactly(2, result.res) should (be(an[TupleTableAtom]) + // //and have('numberOfArguments (3)) + // ) + //} + + //it should "should have a single SKOLEM call in the extension list" in { + // val skolem = Standard(class_OWLObjectSomeValuesFrom) + // val visitor = RDFoxClassExprConverter(term_x, List(), skolem) + // val result = class_OWLObjectSomeValuesFrom.accept(visitor) + // result.ext.loneElement shouldBe a[BindAtom] + // val builtin = result.ext.head.asInstanceOf[BindAtom].getExpression + // builtin should (be(a[FunctionCall]) and have( + // 'functionName ("SKOLEM") + // )) + //} + + //(class_OWLObjectSomeValuesFrom.toString ++ " w/ constant skolemization") should + // "be converted into a RDFoxRuleShards" in { + // val skolem = Constant(class_OWLObjectSomeValuesFrom) + // val visitor = RDFoxClassExprConverter(term_x, List(), skolem) + // val result = class_OWLObjectSomeValuesFrom.accept(visitor) + // result shouldBe a[RDFoxRuleShards] + // } + + //it should "have exactly two TupleTableAtoms in its result list" in { + // val skolem = Constant(class_OWLObjectSomeValuesFrom) + // val visitor = RDFoxClassExprConverter(term_x, List(), skolem) + // val result = class_OWLObjectSomeValuesFrom.accept(visitor) + // exactly(2, result.res) should (be(an[TupleTableAtom]) + // //and have('numberOfArguments (3)) + // ) + //} + + //it should "have an empty extension list" in { + // val skolem = Constant(class_OWLObjectSomeValuesFrom) + // val visitor = RDFoxClassExprConverter(term_x, List(), skolem) + // val result = class_OWLObjectSomeValuesFrom.accept(visitor) + // result.ext shouldBe empty + //} + + // OWLObjectMaxCardinalityImpl + class_OWLObjectMaxCardinality.toString should + "be converted into a RDFoxRuleShards" in { + val visitor = RDFoxClassExprConverter(term_x) + val result = class_OWLObjectMaxCardinality.accept(visitor) + result shouldBe a[RDFoxRuleShards] + } + + // it should "have a single TupleTableAtom in the result list" in { + // val visitor = RDFoxClassExprConverter(term_x) + // val result = class_OWLObjectMaxCardinality.accept(visitor) + // result.res.loneElement should (be(an[TupleTableAtom]) and have( + // 'tupleTableName (pred_sameAs) + // )) + // } + + it should "have 4 TupleTableAtoms in its extension list" in { + val visitor = RDFoxClassExprConverter(term_x) + val result = class_OWLObjectMaxCardinality.accept(visitor) + exactly(4, result.ext) should (be(an[TupleTableAtom]) + //and have('numberOfArguments (3)) + ) + } + +} // class OWLClassSpec diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverterSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverterSpec.scala new file mode 100644 index 0000000..a401abf --- /dev/null +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverterSpec.scala @@ -0,0 +1,108 @@ +package uk.ac.ox.cs.rsacomb.converter + +import org.scalatest.LoneElement +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers +import org.semanticweb.owlapi.apibinding.OWLManager +import org.semanticweb.owlapi.model.OWLOntologyManager + +import tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom +import tech.oxfordsemantic.jrdfox.logic.expression.{Variable, IRI} +import uk.ac.ox.cs.rsacomb.converter.RDFoxConverter +import uk.ac.ox.cs.rsacomb.suffix.{Empty, Forward, Backward, Inverse} +import uk.ac.ox.cs.rsacomb.converter.{SkolemStrategy, NoSkolem} + +object RDFoxConverterSpec { + + val manager = OWLManager.createOWLOntologyManager() + val factory = manager.getOWLDataFactory + + val term0 = Variable.create("X") + val term1 = Variable.create("Y") + val iriString0 = "http://example.com/rsacomb/iri0" + val iriString1 = "http://example.com/rsacomb/iri1" + val iriString2 = "http://example.com/rsacomb/iri2" + val suffixes = Seq( + Empty, + Forward, + Backward, + Inverse, + Forward + Inverse, + Backward + Inverse + ) +} + +class RDFoxConverterSpec + extends AnyFlatSpec + with Matchers + with LoneElement + with RDFoxConverter { + + import RDFoxConverterSpec._ + + "A class name" should "be converted into a single atom" in { + val cls = factory.getOWLClass(iriString0) + val atom = TupleTableAtom.rdf(term0, IRI.RDF_TYPE, IRI.create(iriString0)) + val (res, ext) = + convert(cls, term0, List(), NoSkolem, Empty) + res.loneElement shouldEqual atom + ext shouldBe empty + } + + "A intersection of classes" should "be converted into the union of the conversion of the classes" in { + val cls0 = factory.getOWLClass(iriString0) + val cls1 = factory.getOWLClass(iriString1) + val cls2 = factory.getOWLClass(iriString2) + val conj = factory.getOWLObjectIntersectionOf(cls0, cls1, cls2) + val (res0, ext0) = + convert(cls0, term0, List(), NoSkolem, Empty) + val (res1, ext1) = + convert(cls1, term0, List(), NoSkolem, Empty) + val (res2, ext2) = + convert(cls2, term0, List(), NoSkolem, Empty) + val (res, ext) = + convert(conj, term0, List(), NoSkolem, Empty) + res should contain theSameElementsAs (res0 ::: res1 ::: res2) + ext should contain theSameElementsAs (ext0 ::: ext1 ::: ext2) + } + + "A singleton intersection" should "correspond to the conversion of the internal class" in { + val cls0 = factory.getOWLClass(iriString0) + val conj = factory.getOWLObjectIntersectionOf(cls0) + val (res0, ext0) = + convert(cls0, term0, List(), NoSkolem, Empty) + val (res, ext) = + convert(conj, term0, List(), NoSkolem, Empty) + res should contain theSameElementsAs res0 + ext should contain theSameElementsAs ext0 + } + + "An object property" should "be converted into an atom with matching predicate" in { + val prop = factory.getOWLObjectProperty(iriString0) + for (sx <- suffixes) { + val atom = + TupleTableAtom.rdf(term0, IRI.create(iriString0 :: sx), term1) + convert(prop, term0, term1, sx) shouldEqual atom + } + } + + "The inverse of an object property" should "be converted into an atom with matching negated predicate" in { + val prop = factory.getOWLObjectProperty(iriString0) + val inv = factory.getOWLObjectInverseOf(prop) + for (sx <- Seq(Empty, Forward, Backward)) { + val atom = + TupleTableAtom.rdf(term0, IRI.create(iriString0 :: sx + Inverse), term1) + convert(inv, term0, term1, sx) shouldEqual atom + } + } + + "A data property" should "be converted into an atom with matching predicate" in { + val prop = factory.getOWLDataProperty(iriString0) + for (suffix <- suffixes) { + val atom = + TupleTableAtom.rdf(term0, IRI.create(iriString0 :: suffix), term1) + convert(prop, term0, term1, suffix) shouldEqual atom + } + } + +} -- cgit v1.2.3 From c3ff5305c30cdf31755972df4c3dc554d5246ae9 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Tue, 8 Dec 2020 12:22:56 +0000 Subject: Include literals in instances of `Named` internal predicate --- src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | 12 ++++++++++-- .../uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswers.scala | 12 +++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'src') 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 7b4b142..0fb6c96 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala @@ -11,6 +11,7 @@ import org.semanticweb.owlapi.model.{OWLOntology, OWLAxiom, OWLLogicalAxiom} import org.semanticweb.owlapi.model.{ OWLClass, OWLClassExpression, + OWLDataPropertyAssertionAxiom, OWLObjectProperty, OWLSubObjectPropertyOfAxiom, OWLObjectPropertyExpression, @@ -35,7 +36,8 @@ import tech.oxfordsemantic.jrdfox.logic.expression.{ Term, Variable, IRI, - Resource + Resource, + Literal } import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery @@ -117,6 +119,12 @@ class RSAOntology(val ontology: OWLOntology) { .map(implicits.RDFox.owlapiToRdfoxIri) .toList + val literals: List[Literal] = + abox + .collect { case a: OWLDataPropertyAssertionAxiom => a } + .map(_.getObject) + .map(implicits.RDFox.owlapiToRdfoxLiteral) + val concepts: List[OWLClass] = ontology.getClassesInSignature().asScala.toList @@ -288,7 +296,7 @@ class RSAOntology(val ontology: OWLOntology) { } def filteringProgram(query: ConjunctiveQuery): FilteringProgram = - new FilteringProgram(query, individuals) + new FilteringProgram(query, individuals ++ literals) lazy val canonicalModel = new CanonicalModel(this) diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswers.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswers.scala index 327ae8e..3db5500 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswers.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswers.scala @@ -1,6 +1,11 @@ package uk.ac.ox.cs.rsacomb.sparql -import tech.oxfordsemantic.jrdfox.logic.expression.{IRI, Resource, Variable} +import tech.oxfordsemantic.jrdfox.logic.expression.{ + IRI, + Literal, + Resource, + Variable +} /** A collections of answers to a query. * @@ -27,8 +32,9 @@ class ConjunctiveQueryAnswers( val header = variables map (_.getName) mkString "\t" val body = answers .map(_.map { - case x: IRI => x.getIRI - case x => x.toString + case x: IRI => x.getIRI + case x: Literal => x.getLexicalForm + case x => x.toString }.mkString("\t")) .mkString("\n") s"$header\n$body" -- cgit v1.2.3 From f8e612288f3a604ee1bd60016b7320f00b763e6b Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Tue, 8 Dec 2020 13:16:30 +0000 Subject: Fix bug for OWLObjectSubPropertyOfAxiom A version of the rule with an empty suffix was missing. Note that this is not completely clear from the paper. --- src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala | 9 ++++----- src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala index c605e51..5001c8a 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala @@ -247,11 +247,10 @@ class CanonicalModel(val ontology: RSAOntology) { } case a: OWLSubObjectPropertyOfAxiom => { - val (factsF, rulesF) = - super.convert(a, term, unsafe, NoSkolem, Forward) - val (factsB, rulesB) = - super.convert(a, term, unsafe, NoSkolem, Backward) - (factsF ::: factsB, rulesF ::: rulesB) + val (facts, rules) = List(Empty, Forward, Backward) + .map(super.convert(a, term, unsafe, NoSkolem, _)) + .unzip + (facts.flatten, rules.flatten) } case a => super.convert(a, term, unsafe, skolem, suffix) diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala index a588ae8..0d18e66 100644 --- a/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala @@ -218,13 +218,13 @@ class Ontology1_CanonicalModelSpec renderer.render( SsubPropertyOfT - ) should "produce 2 rules" in { + ) should "produce 3 rules" in { val term = Variable.create("X") val unsafe = ontology.unsafeRoles val (facts, rules) = converter.convert(SsubPropertyOfT, term, unsafe, NoSkolem, Empty) facts shouldBe empty - rules should have length 2 + rules should have length 3 } } -- cgit v1.2.3