From 1efc189e90240c162b54cbc50362b46786643dad Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Wed, 18 Nov 2020 19:13:25 +0000 Subject: Reorganize project with Java-like folder structure --- src/test/scala/rsacomb/CanonicalModelSpec.scala | 369 ------------------- src/test/scala/rsacomb/FilteringProgramSpecs.scala | 397 -------------------- src/test/scala/rsacomb/OWLAxiomSpec.scala | 335 ----------------- src/test/scala/rsacomb/OWLClassSpec.scala | 273 -------------- .../uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala | 370 +++++++++++++++++++ .../ac/ox/cs/rsacomb/FilteringProgramSpecs.scala | 398 +++++++++++++++++++++ .../scala/uk/ac/ox/cs/rsacomb/OWLAxiomSpec.scala | 336 +++++++++++++++++ .../scala/uk/ac/ox/cs/rsacomb/OWLClassSpec.scala | 277 ++++++++++++++ 8 files changed, 1381 insertions(+), 1374 deletions(-) delete mode 100644 src/test/scala/rsacomb/CanonicalModelSpec.scala delete mode 100644 src/test/scala/rsacomb/FilteringProgramSpecs.scala delete mode 100644 src/test/scala/rsacomb/OWLAxiomSpec.scala delete mode 100644 src/test/scala/rsacomb/OWLClassSpec.scala create mode 100644 src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala create mode 100644 src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala create mode 100644 src/test/scala/uk/ac/ox/cs/rsacomb/OWLAxiomSpec.scala create mode 100644 src/test/scala/uk/ac/ox/cs/rsacomb/OWLClassSpec.scala (limited to 'src/test') diff --git a/src/test/scala/rsacomb/CanonicalModelSpec.scala b/src/test/scala/rsacomb/CanonicalModelSpec.scala deleted file mode 100644 index 06602e3..0000000 --- a/src/test/scala/rsacomb/CanonicalModelSpec.scala +++ /dev/null @@ -1,369 +0,0 @@ -package rsacomb - -import java.io.File -import org.scalatest.LoneElement -import org.scalatest.flatspec.AnyFlatSpec -import org.scalatest.matchers.should.Matchers - -import org.semanticweb.owlapi.model._ -import uk.ac.manchester.cs.owl.owlapi._ -import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer - -import tech.oxfordsemantic.jrdfox.logic.datalog.Rule -import tech.oxfordsemantic.jrdfox.logic.expression.Variable - -import scala.collection.JavaConverters._ - -import rsacomb.util.{RDFoxHelpers, RSA} - -object Ontology1_CanonicalModelSpec { - - /* Renderer to display OWL Axioms with DL syntax*/ - val renderer = new DLSyntaxObjectRenderer() - - def base(str: String): IRI = - IRI.create("http://example.com/rsa_example.owl#" + str) - - val ontology_path: File = new File("examples/example1.ttl") - val ontology = RSAOntology(ontology_path) - val program = ontology.canonicalModel - - val roleR = new OWLObjectPropertyImpl(base("R")) - val roleS = new OWLObjectPropertyImpl(base("S")) - val roleT = new OWLObjectPropertyImpl(base("T")) - val roleR_inv = roleR.getInverseProperty() - val roleS_inv = roleS.getInverseProperty() - val roleT_inv = roleT.getInverseProperty() - - val AsubClassOfD = new OWLSubClassOfAxiomImpl( - new OWLClassImpl(base("A")), - new OWLClassImpl(base("D")), - Seq().asJava - ) - - val DsomeValuesFromRB = new OWLSubClassOfAxiomImpl( - new OWLClassImpl(base("D")), - new OWLObjectSomeValuesFromImpl( - roleR, - new OWLClassImpl(base("B")) - ), - Seq().asJava - ) - - val BsomeValuesFromSD = new OWLSubClassOfAxiomImpl( - new OWLClassImpl(base("B")), - new OWLObjectSomeValuesFromImpl( - roleS, - new OWLClassImpl(base("D")) - ), - Seq().asJava - ) - - val AsomeValuesFromSiC = new OWLSubClassOfAxiomImpl( - new OWLClassImpl(base("A")), - new OWLObjectSomeValuesFromImpl( - roleS_inv, - new OWLClassImpl(base("C")) - ), - Seq().asJava - ) - - val SsubPropertyOfT = new OWLSubObjectPropertyOfAxiomImpl( - new OWLObjectPropertyImpl(base("S")), - new OWLObjectPropertyImpl(base("T")), - Seq().asJava - ) - -} - -class Ontology1_CanonicalModelSpec - extends AnyFlatSpec - with Matchers - with LoneElement { - - import Ontology1_CanonicalModelSpec._ - - "The program generated from Example #1" should "not be empty" in { - program.rules should not be empty - } - - renderer.render(AsubClassOfD) should "be converted into a single Rule" in { - val varX = Variable.create("X") - val visitor = program.RuleGenerator - val rules = AsubClassOfD.accept(visitor) - rules.loneElement shouldBe a[Rule] - } - - // Role R // - - renderer.render(roleR) should "be safe" in { - ontology.unsafeRoles should not contain roleR - } - - it should "have 3 elements in its conflict set" in { - ontology.confl(roleR) should have size 3 - } - - it should "contain S in its conflict set" in { - ontology.confl(roleR) should contain(roleS) - } - - it should "contain T in its conflict set" in { - ontology.confl(roleR) should contain(roleT) - } - - it should ("contain " + renderer.render( - roleR_inv - ) + " in its conflict set") in { - ontology.confl(roleR) should contain(roleR_inv) - } - - // Role S // - - renderer.render(roleS) should "be safe" in { - ontology.unsafeRoles should not contain roleS - } - - it should "have 3 elements in its conflict set" in { - ontology.confl(roleS) should have size 3 - } - - it should "contain R in its conflict set" in { - ontology.confl(roleS) should contain(roleR) - } - - it should ("contain " + renderer.render( - roleS_inv - ) + " in its conflict set") in { - ontology.confl(roleS) should contain(roleS_inv) - } - - it should ("contain " + renderer.render( - roleT_inv - ) + " in its conflict set") in { - ontology.confl(roleS) should contain(roleT_inv) - } - - // S⁻ - - renderer.render(roleS_inv) should "be unsafe" in { - ontology.unsafeRoles should contain(roleS_inv) - } - - renderer.render( - AsomeValuesFromSiC - ) should "produce 1 rule" in { - val varX = Variable.create("X") - val visitor = program.RuleGenerator - val rules = AsomeValuesFromSiC.accept(visitor) - rules should have length 1 - } - - renderer.render( - DsomeValuesFromRB - ) should "have a 'cycle' set of 48 elements" in { - // Cycle introduces a new constant for each possible triple (the - // order among triples is total). In this example there are 4 - // concept names and R has 3 safe roles in its conflict set (S, T, - // Inv(R)). Triples are - // (concept, role, concept) - // and hence we have 4*3*4=48 new constants introduced. - ontology.cycle(DsomeValuesFromRB) should have size 48 - } - - it should "produce 5 rules" in { - // Rule 1 provides 1 rule (split in 2) + 48 fact - // Rule 2 provides 0 rules - // Rule 3 provides 48 rule (split in 2) - // Then (1*2 + 48) + (0) + (48*2) = 146 - val varX = Variable.create("X") - val visitor = program.RuleGenerator - val rules = DsomeValuesFromRB.accept(visitor) - rules should have length 146 - } - - renderer.render( - BsomeValuesFromSD - ) should "have a 'cycle' set of 32 elements" in { - // Cycle introduces a new constant for each possible triple (the - // order among triples is total). In this example there are 4 - // concept names and S has 2 safe roles in its conflict set (R, - // Inv(T)). Triples are - // (concept, role, concept) - // and hence we have 4*2*4=32 new constants introduced. - ontology.cycle(BsomeValuesFromSD) should have size 32 - } - - it should "produce 5 rules" in { - // Rule 1 provides 1 rule (split in 2) + 32 fact - // Rule 2 provides 0 rules - // Rule 3 provides 32 rule (split in 2) - // Then (1*2 + 32) + (0) + (32*2) = 98 - val varX = Variable.create("X") - val visitor = program.RuleGenerator - val rules = DsomeValuesFromRB.accept(visitor) - rules should have length 146 - } - - renderer.render( - SsubPropertyOfT - ) should "produce 2 rules" in { - val varX = Variable.create("X") - val visitor = program.RuleGenerator - val rules = SsubPropertyOfT.accept(visitor) - rules should have length 2 - } - -} - -object Ontology2_CanonicalModelSpec { - - /* Renderer to display OWL Axioms with DL syntax*/ - val renderer = new DLSyntaxObjectRenderer() - - def base(str: String): IRI = - IRI.create("http://example.com/rsa_example.owl#" + str) - - val ontology_path: File = new File("examples/example2.owl") - val ontology = RSAOntology(ontology_path) - val program = ontology.canonicalModel - - val roleR = new OWLObjectPropertyImpl(base("R")) - val roleS = new OWLObjectPropertyImpl(base("S")) - val roleT = new OWLObjectPropertyImpl(base("T")) - val roleP = new OWLObjectPropertyImpl(base("P")) - val roleR_inv = roleR.getInverseProperty() - val roleS_inv = roleS.getInverseProperty() - val roleT_inv = roleT.getInverseProperty() - val roleP_inv = roleP.getInverseProperty() - - val AsomeValuesFromRB = new OWLSubClassOfAxiomImpl( - new OWLClassImpl(base("A")), - new OWLObjectSomeValuesFromImpl( - roleR, - new OWLClassImpl(base("B")) - ), - Seq().asJava - ) - - val BsomeValuesFromSC = new OWLSubClassOfAxiomImpl( - new OWLClassImpl(base("B")), - new OWLObjectSomeValuesFromImpl( - roleS, - new OWLClassImpl(base("C")) - ), - Seq().asJava - ) - - val CsomeValuesFromTD = new OWLSubClassOfAxiomImpl( - new OWLClassImpl(base("C")), - new OWLObjectSomeValuesFromImpl( - roleT, - new OWLClassImpl(base("D")) - ), - Seq().asJava - ) - - val DsomeValuesFromPA = new OWLSubClassOfAxiomImpl( - new OWLClassImpl(base("D")), - new OWLObjectSomeValuesFromImpl( - roleP, - new OWLClassImpl(base("A")) - ), - Seq().asJava - ) - -} - -class Ontology2_CanonicalModelSpec - extends AnyFlatSpec - with Matchers - with LoneElement { - - import Ontology2_CanonicalModelSpec._ - - "The program generated from Example #1" should "not be empty" in { - program.rules should not be empty - } - - // Role R // - - renderer.render(roleR) should "be unsafe" in { - ontology.unsafeRoles should contain(roleR) - } - - it should "have only its inverse in its conflict set" in { - ontology.confl(roleR).loneElement shouldBe roleR_inv - } - - // Role S // - - renderer.render(roleS) should "be unsafe" in { - ontology.unsafeRoles should contain(roleS) - } - - it should "have only its inverse in its conflict set" in { - ontology.confl(roleS).loneElement shouldBe roleS_inv - } - - // Role T // - - renderer.render(roleT) should "be unsafe" in { - ontology.unsafeRoles should contain(roleT) - } - - it should "have only its inverse in its conflict set" in { - ontology.confl(roleT).loneElement shouldBe roleT_inv - } - - // Role P // - - renderer.render(roleP) should "be unsafe" in { - ontology.unsafeRoles should contain(roleP) - } - - it should "have only its inverse in its conflict set" in { - ontology.confl(roleP).loneElement shouldBe roleP_inv - } - - // A ⊑ ∃ R.B - - renderer.render( - AsomeValuesFromRB - ) should "produce 1 rule" in { - val visitor = program.RuleGenerator - val rules = AsomeValuesFromRB.accept(visitor) - rules should have length 1 - } - - // B ⊑ ∃ S.C - - renderer.render( - BsomeValuesFromSC - ) should "produce 1 rule" in { - val visitor = program.RuleGenerator - val rules = BsomeValuesFromSC.accept(visitor) - rules should have length 1 - } - - // C ⊑ ∃ T.D - - renderer.render( - CsomeValuesFromTD - ) should "produce 1 rule" in { - val visitor = program.RuleGenerator - val rules = CsomeValuesFromTD.accept(visitor) - rules should have length 1 - } - - // D ⊑ ∃ P.A - - renderer.render( - DsomeValuesFromPA - ) should "produce 1 rule" in { - val visitor = program.RuleGenerator - val rules = DsomeValuesFromPA.accept(visitor) - rules should have length 1 - } - -} diff --git a/src/test/scala/rsacomb/FilteringProgramSpecs.scala b/src/test/scala/rsacomb/FilteringProgramSpecs.scala deleted file mode 100644 index 66c1cae..0000000 --- a/src/test/scala/rsacomb/FilteringProgramSpecs.scala +++ /dev/null @@ -1,397 +0,0 @@ -package rsacomb - -import java.io.File -import java.util.{ArrayList => JList} -import org.scalatest.LoneElement -import org.scalatest.Inspectors -import org.scalatest.flatspec.AnyFlatSpec -import org.scalatest.matchers.should.Matchers - -import tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom -import tech.oxfordsemantic.jrdfox.logic.expression.{Variable, IRI} -import tech.oxfordsemantic.jrdfox.logic.sparql.statement.{Query, SelectQuery} -import tech.oxfordsemantic.jrdfox.Prefixes - -import scala.collection.JavaConverters._ - -import rsacomb.util.RDFoxHelpers - -object FilteringProgramSpec { - - val prefixes = new Prefixes() - prefixes.declarePrefix( - ":", - "http://slegger.gitlab.io/slegge-obda/ontology/subsurface-exploration#" - ) - prefixes.declarePrefix("rdf:", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") - prefixes.declarePrefix("rdfs:", "http://www.w3.org/2000/01/rdf-schema#") - prefixes.declarePrefix("owl:", "http://www.w3.org/2002/07/owl#") - - // DEBUG: Quick helper functions - def v(v: String): Variable = Variable.create(v) - def c(c: String): IRI = IRI.create(":" + c) - - // QUERY 0 - - val query0 = RDFoxHelpers - .parseSelectQuery(""" - SELECT ?subj - WHERE { - ?subj ?pred ?obj - } - """, prefixes) - .get - - // val query0 = Query.create( - // QueryType.SELECT, - // false, - // List(v("subj")).asJava, - // Atom.rdf(v("subj"), v("pred"), v("obj")) - // ) - - // QUERY 1 - - val query1 = RDFoxHelpers - .parseSelectQuery(""" - SELECT * - WHERE { - ?w a :Wellbore - } - """, prefixes) - .get - - // val query1 = Query.create( - // QueryType.SELECT, - // false, - // List(v("w")).asJava, - // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")) - // ) - - // QUERY 2 - - val query2 = RDFoxHelpers - .parseSelectQuery( - """ - SELECT * - WHERE { - ?w a :Wellbore ; - :wellboreDocument ?doc . - ?doc :hasURL ?document_hyperlink - } - """, - prefixes - ) - .get - - // val query2 = Query.create( - // QueryType.SELECT, - // false, - // List(v("w"), v("doc"), v("document_hyperlink")).asJava, - // Conjunction.create( - // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), - // Atom.rdf(v("w"), c("wellboreDocument"), v("doc")), - // Atom.rdf(v("doc"), c("hasURL"), v("document_hyperlink")) - // ) - // ) - - // QUERY 3 - - val query3 = RDFoxHelpers - .parseSelectQuery( - """ - SELECT ?wellbore ?formation_pressure - WHERE { - ?w a :Wellbore ; - :name ?wellbore ; - :hasFormationPressure ?fp . - ?fp :valueInStandardUnit ?formation_pressure - } - """, - prefixes - ) - .get - - // val query3 = Query.create( - // QueryType.SELECT, - // false, - // List(v("wellbore"), v("formation_pressure")).asJava, - // Conjunction.create( - // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), - // Atom.rdf(v("w"), c("name"), v("wellbore")), - // Atom.rdf(v("w"), c("hasFormationPressure"), v("fp")), - // Atom.rdf(v("fp"), c("valueInStandardUnit"), v("formation_pressure")) - // ) - // ) - - // QUERY 4 - - val query4 = RDFoxHelpers - .parseSelectQuery( - """ - SELECT * - WHERE { - ?w a :Wellbore ; - :hasGeochemicalMeasurement ?measurement . - ?measurement :cgType ?cgtype ; - :peakName ?peakType ; - :peakHeight ?peak_height ; - :peakAmount ?peak_amount - } - """, - prefixes - ) - .get - - // val query4 = Query.create( - // QueryType.SELECT, - // false, - // List( - // v("w"), - // v("measurement"), - // v("cgtype"), - // v("peakType"), - // v("peak_height"), - // v("peak_amount") - // ).asJava, - // Conjunction.create( - // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), - // Atom.rdf(v("w"), c("hasGeochemicalMeasurement"), v("measurement")), - // Atom.rdf(v("measurement"), c("cgType"), v("cgtype")), - // Atom.rdf(v("measurement"), c("peakName"), v("peakType")), - // Atom.rdf(v("measurement"), c("peakHeight"), v("peak_height")), - // Atom.rdf(v("measurement"), c("peakAmount"), v("peak_amount")) - // ) - // ) - - // QUERY 5 - - val query5 = RDFoxHelpers - .parseSelectQuery( - """ - SELECT ?wellbore ?unit_name ?discovery - WHERE { - ?w a :Wellbore ; - :name ?wellbore ; - :hasWellboreInterval ?c_int ; - :hasWellboreInterval ?f_int . - ?c_int :hasUnit ?c_unit . - ?c_unit :name ?unit_name . - ?f_int a :FluidZone ; - :name ?discovery ; - :overlapsWellboreInterval ?c_int - } - """, - prefixes - ) - .get - - // val query5 = Query.create( - // QueryType.SELECT, - // false, - // List(v("wellbore"), v("unit_name"), v("discovery")).asJava, - // Conjunction.create( - // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), - // Atom.rdf(v("w"), c("name"), v("wellbore")), - // Atom.rdf(v("w"), c("hasWellboreInterval"), v("c_int")), - // Atom.rdf(v("w"), c("hasWellboreInterval"), v("f_int")), - // Atom.rdf(v("c_int"), c("hasUnit"), v("c_unit")), - // Atom.rdf(v("c_unit"), c("name"), v("unit_name")), - // Atom.rdf(v("f_int"), IRI.RDF_TYPE, c("FluidZone")), - // Atom.rdf(v("f_int"), c("name"), v("discovery")), - // Atom.rdf(v("f_int"), c("overlapsWellboreInterval"), v("c_int")) - // ) - // ) - - // QUERY 6 - - val query6 = RDFoxHelpers - .parseSelectQuery( - """ - SELECT DISTINCT ?wellbore ?content - WHERE { - ?w a :Wellbore ; - :name ?wellbore ; - :hasWellboreInterval ?int . - ?int a :FluidZone ; - :fluidZoneContent ?content - } - """, - prefixes - ) - .get - - // val query6 = Query.create( - // QueryType.SELECT, - // true, - // List(v("wellbore"), v("content")).asJava, - // Conjunction.create( - // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), - // Atom.rdf(v("w"), c("name"), v("wellbore")), - // Atom.rdf(v("w"), c("hasWellboreInterval"), v("int")), - // Atom.rdf(v("int"), IRI.RDF_TYPE, c("FluidZone")), - // Atom.rdf(v("int"), c("fluidZoneContent"), v("content")) - // ) - // ) - - // QUERY 7 - - val query7 = RDFoxHelpers - .parseSelectQuery( - """ - SELECT ?wName ?sample ?porosity ?top_depth_md ?bot_depth_md - WHERE { - ?w a :Wellbore ; - :name ?wName ; - :hasWellboreInterval ?z . - ?z :hasUnit ?u . - ?u :name ?strat_unit_name . - ?wellbore :hasWellboreInterval ?cored_int . - ?c :extractedFrom ?cored_int ; - :hasCoreSample ?sample . - ?sample :hasDepth ?sample_depth . - ?sample_depth - :inWellboreInterval ?z . - ?sample :hasPorosity ?p . - ?p :valueInStandardUnit ?porosity . - ?z :hasTopDepth ?top . - ?top a :MeasuredDepth ; - :valueInStandardUnit ?top_depth_md . - ?z :hasBottomDepth ?bot . - ?bot a :MeasuredDepth ; - :valueInStandardUnit ?bot_depth_md - } - """, - prefixes - ) - .get - - // val query7 = Query.create( - // QueryType.SELECT, - // false, - // List( - // v("wName"), - // v("sample"), - // v("porosity"), - // v("top_depth_md"), - // v("bot_depth_md") - // ).asJava, - // Conjunction.create( - // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), - // Atom.rdf(v("w"), c("name"), v("wName")), - // Atom.rdf(v("w"), c("hasWellboreInterval"), v("z")), - // Atom.rdf(v("z"), c("hasUnit"), v("u")), - // Atom.rdf(v("u"), c("name"), v("strat_unit_name")), - // Atom.rdf(v("wellbore"), c("hasWellboreInterval"), v("cored_int")), - // Atom.rdf(v("c"), c("extractedFrom"), v("cored_int")), - // Atom.rdf(v("c"), c("hasCoreSample"), v("sample")), - // Atom.rdf(v("sample"), c("hasDepth"), v("sample_depth")), - // Atom.rdf(v("sample_depth"), c("inWellboreInterval"), v("z")), - // Atom.rdf(v("sample"), c("hasPorosity"), v("p")), - // Atom.rdf(v("p"), c("valueInStandardUnit"), v("porosity")), - // Atom.rdf(v("z"), c("hasTopDepth"), v("top")), - // Atom.rdf(v("top"), IRI.RDF_TYPE, c("MeasuredDepth")), - // Atom.rdf(v("top"), c("valueInStandardUnit"), v("top_depth_md")), - // Atom.rdf(v("z"), c("hasBottomDepth"), v("bot")), - // Atom.rdf(v("bot"), IRI.RDF_TYPE, c("MeasuredDepth")), - // Atom.rdf(v("bot"), c("valueInStandardUnit"), v("bot_depth_md")) - // ) - // ) - - val queries = - List(query0, query1, query2, query3, query4, query5, query6, query7) -} - -class FilteringProgramSpec - extends AnyFlatSpec - with Matchers - with LoneElement - with Inspectors { - - import FilteringProgramSpec._ - - "Queries" should "have distinct answer and bounded variables" in { - for (query <- queries) { - val program = new FilteringProgram(query, List()) - forAll(program.answer) { v => program.bounded should not contain v } - forAll(program.bounded) { v => program.answer should not contain v } - } - } - - "Query 0" should "have {?obj, ?pred} as bounded variables" in { - val pred = Variable.create("obj") - val obj = Variable.create("pred") - val program = new FilteringProgram(query0, List()) - program.bounded should contain theSameElementsAs List(pred, obj) - } - - "Query 1" should "have no bounded variable" in { - val program = new FilteringProgram(query1, List()) - program.bounded shouldBe empty - } - - "Query 2" should "have no bounded variable" in { - val program = new FilteringProgram(query2, List()) - program.bounded shouldBe empty - } - - "Query 3" should "have {?w, ?fp} as bounded variables" in { - val w = Variable.create("w") - val fp = Variable.create("fp") - val program = new FilteringProgram(query3, List()) - program.bounded should contain theSameElementsAs List(w, fp) - } - - "Query 4" should "have no bounded variable" in { - val program = new FilteringProgram(query4, List()) - program.bounded shouldBe empty - } - - "Query 5" should "have a non-empty bounded set" in { - val w = Variable.create("w") - val c_int = Variable.create("c_int") - val f_int = Variable.create("f_int") - val c_unit = Variable.create("c_unit") - val program = new FilteringProgram(query5, List()) - program.bounded should contain theSameElementsAs List( - w, - c_int, - f_int, - c_unit - ) - } - - "Query 6" should "have a non-empty bounded set" in { - val w = Variable.create("w") - val int = Variable.create("int") - val program = new FilteringProgram(query6, List()) - program.bounded should contain theSameElementsAs List(w, int) - } - - "Query 7" should "have a non-empty bounded set" in { - val w = Variable.create("w") - val z = Variable.create("z") - val u = Variable.create("u") - val strat_unit_name = Variable.create("strat_unit_name") - val wellbore = Variable.create("wellbore") - val cored_int = Variable.create("cored_int") - val c = Variable.create("c") - val sample_depth = Variable.create("sample_depth") - val p = Variable.create("p") - val top = Variable.create("top") - val bot = Variable.create("bot") - val program = new FilteringProgram(query7, List()) - program.bounded should contain theSameElementsAs List( - w, - z, - u, - strat_unit_name, - wellbore, - cored_int, - c, - sample_depth, - p, - top, - bot - ) - } -} diff --git a/src/test/scala/rsacomb/OWLAxiomSpec.scala b/src/test/scala/rsacomb/OWLAxiomSpec.scala deleted file mode 100644 index 65333f5..0000000 --- a/src/test/scala/rsacomb/OWLAxiomSpec.scala +++ /dev/null @@ -1,335 +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 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 = SkolemStrategy.None - ): 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 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 = SkolemStrategy.Constant(axiom_OWLSubClassOf2.toString) - 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 = SkolemStrategy.Constant(axiom_OWLSubClassOf2.toString) - 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 = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString) - 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 = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString) - 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/rsacomb/OWLClassSpec.scala b/src/test/scala/rsacomb/OWLClassSpec.scala deleted file mode 100644 index 27e0872..0000000 --- a/src/test/scala/rsacomb/OWLClassSpec.scala +++ /dev/null @@ -1,273 +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 rsacomb.RDFoxRuleShards -import 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 = SkolemStrategy.Standard(class_OWLObjectSomeValuesFrom.toString) - 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 = SkolemStrategy.Standard(class_OWLObjectSomeValuesFrom.toString) - 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 = SkolemStrategy.Standard(class_OWLObjectSomeValuesFrom.toString) - 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 = SkolemStrategy.Constant(class_OWLObjectSomeValuesFrom.toString) - 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 = SkolemStrategy.Constant(class_OWLObjectSomeValuesFrom.toString) - 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 = SkolemStrategy.Constant(class_OWLObjectSomeValuesFrom.toString) - 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/CanonicalModelSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala new file mode 100644 index 0000000..376729c --- /dev/null +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala @@ -0,0 +1,370 @@ +package rsacomb + +import java.io.File +import org.scalatest.LoneElement +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers + +import org.semanticweb.owlapi.model._ +import uk.ac.manchester.cs.owl.owlapi._ +import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer + +import tech.oxfordsemantic.jrdfox.logic.datalog.Rule +import tech.oxfordsemantic.jrdfox.logic.expression.Variable + +import scala.collection.JavaConverters._ + +import uk.ac.ox.cs.rsacomb.RSAOntology +import uk.ac.ox.cs.rsacomb.util.{RDFoxHelpers, RSA} + +object Ontology1_CanonicalModelSpec { + + /* Renderer to display OWL Axioms with DL syntax*/ + val renderer = new DLSyntaxObjectRenderer() + + def base(str: String): IRI = + IRI.create("http://example.com/rsa_example.owl#" + str) + + val ontology_path: File = new File("examples/example1.ttl") + val ontology = RSAOntology(ontology_path) + val program = ontology.canonicalModel + + val roleR = new OWLObjectPropertyImpl(base("R")) + val roleS = new OWLObjectPropertyImpl(base("S")) + val roleT = new OWLObjectPropertyImpl(base("T")) + val roleR_inv = roleR.getInverseProperty() + val roleS_inv = roleS.getInverseProperty() + val roleT_inv = roleT.getInverseProperty() + + val AsubClassOfD = new OWLSubClassOfAxiomImpl( + new OWLClassImpl(base("A")), + new OWLClassImpl(base("D")), + Seq().asJava + ) + + val DsomeValuesFromRB = new OWLSubClassOfAxiomImpl( + new OWLClassImpl(base("D")), + new OWLObjectSomeValuesFromImpl( + roleR, + new OWLClassImpl(base("B")) + ), + Seq().asJava + ) + + val BsomeValuesFromSD = new OWLSubClassOfAxiomImpl( + new OWLClassImpl(base("B")), + new OWLObjectSomeValuesFromImpl( + roleS, + new OWLClassImpl(base("D")) + ), + Seq().asJava + ) + + val AsomeValuesFromSiC = new OWLSubClassOfAxiomImpl( + new OWLClassImpl(base("A")), + new OWLObjectSomeValuesFromImpl( + roleS_inv, + new OWLClassImpl(base("C")) + ), + Seq().asJava + ) + + val SsubPropertyOfT = new OWLSubObjectPropertyOfAxiomImpl( + new OWLObjectPropertyImpl(base("S")), + new OWLObjectPropertyImpl(base("T")), + Seq().asJava + ) + +} + +class Ontology1_CanonicalModelSpec + extends AnyFlatSpec + with Matchers + with LoneElement { + + import Ontology1_CanonicalModelSpec._ + + "The program generated from Example #1" should "not be empty" in { + program.rules should not be empty + } + + renderer.render(AsubClassOfD) should "be converted into a single Rule" in { + val varX = Variable.create("X") + val visitor = program.RuleGenerator + val rules = AsubClassOfD.accept(visitor) + rules.loneElement shouldBe a[Rule] + } + + // Role R // + + renderer.render(roleR) should "be safe" in { + ontology.unsafeRoles should not contain roleR + } + + it should "have 3 elements in its conflict set" in { + ontology.confl(roleR) should have size 3 + } + + it should "contain S in its conflict set" in { + ontology.confl(roleR) should contain(roleS) + } + + it should "contain T in its conflict set" in { + ontology.confl(roleR) should contain(roleT) + } + + it should ("contain " + renderer.render( + roleR_inv + ) + " in its conflict set") in { + ontology.confl(roleR) should contain(roleR_inv) + } + + // Role S // + + renderer.render(roleS) should "be safe" in { + ontology.unsafeRoles should not contain roleS + } + + it should "have 3 elements in its conflict set" in { + ontology.confl(roleS) should have size 3 + } + + it should "contain R in its conflict set" in { + ontology.confl(roleS) should contain(roleR) + } + + it should ("contain " + renderer.render( + roleS_inv + ) + " in its conflict set") in { + ontology.confl(roleS) should contain(roleS_inv) + } + + it should ("contain " + renderer.render( + roleT_inv + ) + " in its conflict set") in { + ontology.confl(roleS) should contain(roleT_inv) + } + + // S⁻ + + renderer.render(roleS_inv) should "be unsafe" in { + ontology.unsafeRoles should contain(roleS_inv) + } + + renderer.render( + AsomeValuesFromSiC + ) should "produce 1 rule" in { + val varX = Variable.create("X") + val visitor = program.RuleGenerator + val rules = AsomeValuesFromSiC.accept(visitor) + rules should have length 1 + } + + renderer.render( + DsomeValuesFromRB + ) should "have a 'cycle' set of 48 elements" in { + // Cycle introduces a new constant for each possible triple (the + // order among triples is total). In this example there are 4 + // concept names and R has 3 safe roles in its conflict set (S, T, + // Inv(R)). Triples are + // (concept, role, concept) + // and hence we have 4*3*4=48 new constants introduced. + ontology.cycle(DsomeValuesFromRB) should have size 48 + } + + it should "produce 5 rules" in { + // Rule 1 provides 1 rule (split in 2) + 48 fact + // Rule 2 provides 0 rules + // Rule 3 provides 48 rule (split in 2) + // Then (1*2 + 48) + (0) + (48*2) = 146 + val varX = Variable.create("X") + val visitor = program.RuleGenerator + val rules = DsomeValuesFromRB.accept(visitor) + rules should have length 146 + } + + renderer.render( + BsomeValuesFromSD + ) should "have a 'cycle' set of 32 elements" in { + // Cycle introduces a new constant for each possible triple (the + // order among triples is total). In this example there are 4 + // concept names and S has 2 safe roles in its conflict set (R, + // Inv(T)). Triples are + // (concept, role, concept) + // and hence we have 4*2*4=32 new constants introduced. + ontology.cycle(BsomeValuesFromSD) should have size 32 + } + + it should "produce 5 rules" in { + // Rule 1 provides 1 rule (split in 2) + 32 fact + // Rule 2 provides 0 rules + // Rule 3 provides 32 rule (split in 2) + // Then (1*2 + 32) + (0) + (32*2) = 98 + val varX = Variable.create("X") + val visitor = program.RuleGenerator + val rules = DsomeValuesFromRB.accept(visitor) + rules should have length 146 + } + + renderer.render( + SsubPropertyOfT + ) should "produce 2 rules" in { + val varX = Variable.create("X") + val visitor = program.RuleGenerator + val rules = SsubPropertyOfT.accept(visitor) + rules should have length 2 + } + +} + +object Ontology2_CanonicalModelSpec { + + /* Renderer to display OWL Axioms with DL syntax*/ + val renderer = new DLSyntaxObjectRenderer() + + def base(str: String): IRI = + IRI.create("http://example.com/rsa_example.owl#" + str) + + val ontology_path: File = new File("examples/example2.owl") + val ontology = RSAOntology(ontology_path) + val program = ontology.canonicalModel + + val roleR = new OWLObjectPropertyImpl(base("R")) + val roleS = new OWLObjectPropertyImpl(base("S")) + val roleT = new OWLObjectPropertyImpl(base("T")) + val roleP = new OWLObjectPropertyImpl(base("P")) + val roleR_inv = roleR.getInverseProperty() + val roleS_inv = roleS.getInverseProperty() + val roleT_inv = roleT.getInverseProperty() + val roleP_inv = roleP.getInverseProperty() + + val AsomeValuesFromRB = new OWLSubClassOfAxiomImpl( + new OWLClassImpl(base("A")), + new OWLObjectSomeValuesFromImpl( + roleR, + new OWLClassImpl(base("B")) + ), + Seq().asJava + ) + + val BsomeValuesFromSC = new OWLSubClassOfAxiomImpl( + new OWLClassImpl(base("B")), + new OWLObjectSomeValuesFromImpl( + roleS, + new OWLClassImpl(base("C")) + ), + Seq().asJava + ) + + val CsomeValuesFromTD = new OWLSubClassOfAxiomImpl( + new OWLClassImpl(base("C")), + new OWLObjectSomeValuesFromImpl( + roleT, + new OWLClassImpl(base("D")) + ), + Seq().asJava + ) + + val DsomeValuesFromPA = new OWLSubClassOfAxiomImpl( + new OWLClassImpl(base("D")), + new OWLObjectSomeValuesFromImpl( + roleP, + new OWLClassImpl(base("A")) + ), + Seq().asJava + ) + +} + +class Ontology2_CanonicalModelSpec + extends AnyFlatSpec + with Matchers + with LoneElement { + + import Ontology2_CanonicalModelSpec._ + + "The program generated from Example #1" should "not be empty" in { + program.rules should not be empty + } + + // Role R // + + renderer.render(roleR) should "be unsafe" in { + ontology.unsafeRoles should contain(roleR) + } + + it should "have only its inverse in its conflict set" in { + ontology.confl(roleR).loneElement shouldBe roleR_inv + } + + // Role S // + + renderer.render(roleS) should "be unsafe" in { + ontology.unsafeRoles should contain(roleS) + } + + it should "have only its inverse in its conflict set" in { + ontology.confl(roleS).loneElement shouldBe roleS_inv + } + + // Role T // + + renderer.render(roleT) should "be unsafe" in { + ontology.unsafeRoles should contain(roleT) + } + + it should "have only its inverse in its conflict set" in { + ontology.confl(roleT).loneElement shouldBe roleT_inv + } + + // Role P // + + renderer.render(roleP) should "be unsafe" in { + ontology.unsafeRoles should contain(roleP) + } + + it should "have only its inverse in its conflict set" in { + ontology.confl(roleP).loneElement shouldBe roleP_inv + } + + // A ⊑ ∃ R.B + + renderer.render( + AsomeValuesFromRB + ) should "produce 1 rule" in { + val visitor = program.RuleGenerator + val rules = AsomeValuesFromRB.accept(visitor) + rules should have length 1 + } + + // B ⊑ ∃ S.C + + renderer.render( + BsomeValuesFromSC + ) should "produce 1 rule" in { + val visitor = program.RuleGenerator + val rules = BsomeValuesFromSC.accept(visitor) + rules should have length 1 + } + + // C ⊑ ∃ T.D + + renderer.render( + CsomeValuesFromTD + ) should "produce 1 rule" in { + val visitor = program.RuleGenerator + val rules = CsomeValuesFromTD.accept(visitor) + rules should have length 1 + } + + // D ⊑ ∃ P.A + + renderer.render( + DsomeValuesFromPA + ) should "produce 1 rule" in { + val visitor = program.RuleGenerator + val rules = DsomeValuesFromPA.accept(visitor) + rules should have length 1 + } + +} diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala new file mode 100644 index 0000000..49abd48 --- /dev/null +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala @@ -0,0 +1,398 @@ +package rsacomb + +import java.io.File +import java.util.{ArrayList => JList} +import org.scalatest.LoneElement +import org.scalatest.Inspectors +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers + +import tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom +import tech.oxfordsemantic.jrdfox.logic.expression.{Variable, IRI} +import tech.oxfordsemantic.jrdfox.logic.sparql.statement.{Query, SelectQuery} +import tech.oxfordsemantic.jrdfox.Prefixes + +import scala.collection.JavaConverters._ + +import uk.ac.ox.cs.rsacomb.FilteringProgram +import uk.ac.ox.cs.rsacomb.util.RDFoxHelpers + +object FilteringProgramSpec { + + val prefixes = new Prefixes() + prefixes.declarePrefix( + ":", + "http://slegger.gitlab.io/slegge-obda/ontology/subsurface-exploration#" + ) + prefixes.declarePrefix("rdf:", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") + prefixes.declarePrefix("rdfs:", "http://www.w3.org/2000/01/rdf-schema#") + prefixes.declarePrefix("owl:", "http://www.w3.org/2002/07/owl#") + + // DEBUG: Quick helper functions + def v(v: String): Variable = Variable.create(v) + def c(c: String): IRI = IRI.create(":" + c) + + // QUERY 0 + + val query0 = RDFoxHelpers + .parseSelectQuery(""" + SELECT ?subj + WHERE { + ?subj ?pred ?obj + } + """, prefixes) + .get + + // val query0 = Query.create( + // QueryType.SELECT, + // false, + // List(v("subj")).asJava, + // Atom.rdf(v("subj"), v("pred"), v("obj")) + // ) + + // QUERY 1 + + val query1 = RDFoxHelpers + .parseSelectQuery(""" + SELECT * + WHERE { + ?w a :Wellbore + } + """, prefixes) + .get + + // val query1 = Query.create( + // QueryType.SELECT, + // false, + // List(v("w")).asJava, + // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")) + // ) + + // QUERY 2 + + val query2 = RDFoxHelpers + .parseSelectQuery( + """ + SELECT * + WHERE { + ?w a :Wellbore ; + :wellboreDocument ?doc . + ?doc :hasURL ?document_hyperlink + } + """, + prefixes + ) + .get + + // val query2 = Query.create( + // QueryType.SELECT, + // false, + // List(v("w"), v("doc"), v("document_hyperlink")).asJava, + // Conjunction.create( + // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), + // Atom.rdf(v("w"), c("wellboreDocument"), v("doc")), + // Atom.rdf(v("doc"), c("hasURL"), v("document_hyperlink")) + // ) + // ) + + // QUERY 3 + + val query3 = RDFoxHelpers + .parseSelectQuery( + """ + SELECT ?wellbore ?formation_pressure + WHERE { + ?w a :Wellbore ; + :name ?wellbore ; + :hasFormationPressure ?fp . + ?fp :valueInStandardUnit ?formation_pressure + } + """, + prefixes + ) + .get + + // val query3 = Query.create( + // QueryType.SELECT, + // false, + // List(v("wellbore"), v("formation_pressure")).asJava, + // Conjunction.create( + // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), + // Atom.rdf(v("w"), c("name"), v("wellbore")), + // Atom.rdf(v("w"), c("hasFormationPressure"), v("fp")), + // Atom.rdf(v("fp"), c("valueInStandardUnit"), v("formation_pressure")) + // ) + // ) + + // QUERY 4 + + val query4 = RDFoxHelpers + .parseSelectQuery( + """ + SELECT * + WHERE { + ?w a :Wellbore ; + :hasGeochemicalMeasurement ?measurement . + ?measurement :cgType ?cgtype ; + :peakName ?peakType ; + :peakHeight ?peak_height ; + :peakAmount ?peak_amount + } + """, + prefixes + ) + .get + + // val query4 = Query.create( + // QueryType.SELECT, + // false, + // List( + // v("w"), + // v("measurement"), + // v("cgtype"), + // v("peakType"), + // v("peak_height"), + // v("peak_amount") + // ).asJava, + // Conjunction.create( + // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), + // Atom.rdf(v("w"), c("hasGeochemicalMeasurement"), v("measurement")), + // Atom.rdf(v("measurement"), c("cgType"), v("cgtype")), + // Atom.rdf(v("measurement"), c("peakName"), v("peakType")), + // Atom.rdf(v("measurement"), c("peakHeight"), v("peak_height")), + // Atom.rdf(v("measurement"), c("peakAmount"), v("peak_amount")) + // ) + // ) + + // QUERY 5 + + val query5 = RDFoxHelpers + .parseSelectQuery( + """ + SELECT ?wellbore ?unit_name ?discovery + WHERE { + ?w a :Wellbore ; + :name ?wellbore ; + :hasWellboreInterval ?c_int ; + :hasWellboreInterval ?f_int . + ?c_int :hasUnit ?c_unit . + ?c_unit :name ?unit_name . + ?f_int a :FluidZone ; + :name ?discovery ; + :overlapsWellboreInterval ?c_int + } + """, + prefixes + ) + .get + + // val query5 = Query.create( + // QueryType.SELECT, + // false, + // List(v("wellbore"), v("unit_name"), v("discovery")).asJava, + // Conjunction.create( + // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), + // Atom.rdf(v("w"), c("name"), v("wellbore")), + // Atom.rdf(v("w"), c("hasWellboreInterval"), v("c_int")), + // Atom.rdf(v("w"), c("hasWellboreInterval"), v("f_int")), + // Atom.rdf(v("c_int"), c("hasUnit"), v("c_unit")), + // Atom.rdf(v("c_unit"), c("name"), v("unit_name")), + // Atom.rdf(v("f_int"), IRI.RDF_TYPE, c("FluidZone")), + // Atom.rdf(v("f_int"), c("name"), v("discovery")), + // Atom.rdf(v("f_int"), c("overlapsWellboreInterval"), v("c_int")) + // ) + // ) + + // QUERY 6 + + val query6 = RDFoxHelpers + .parseSelectQuery( + """ + SELECT DISTINCT ?wellbore ?content + WHERE { + ?w a :Wellbore ; + :name ?wellbore ; + :hasWellboreInterval ?int . + ?int a :FluidZone ; + :fluidZoneContent ?content + } + """, + prefixes + ) + .get + + // val query6 = Query.create( + // QueryType.SELECT, + // true, + // List(v("wellbore"), v("content")).asJava, + // Conjunction.create( + // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), + // Atom.rdf(v("w"), c("name"), v("wellbore")), + // Atom.rdf(v("w"), c("hasWellboreInterval"), v("int")), + // Atom.rdf(v("int"), IRI.RDF_TYPE, c("FluidZone")), + // Atom.rdf(v("int"), c("fluidZoneContent"), v("content")) + // ) + // ) + + // QUERY 7 + + val query7 = RDFoxHelpers + .parseSelectQuery( + """ + SELECT ?wName ?sample ?porosity ?top_depth_md ?bot_depth_md + WHERE { + ?w a :Wellbore ; + :name ?wName ; + :hasWellboreInterval ?z . + ?z :hasUnit ?u . + ?u :name ?strat_unit_name . + ?wellbore :hasWellboreInterval ?cored_int . + ?c :extractedFrom ?cored_int ; + :hasCoreSample ?sample . + ?sample :hasDepth ?sample_depth . + ?sample_depth + :inWellboreInterval ?z . + ?sample :hasPorosity ?p . + ?p :valueInStandardUnit ?porosity . + ?z :hasTopDepth ?top . + ?top a :MeasuredDepth ; + :valueInStandardUnit ?top_depth_md . + ?z :hasBottomDepth ?bot . + ?bot a :MeasuredDepth ; + :valueInStandardUnit ?bot_depth_md + } + """, + prefixes + ) + .get + + // val query7 = Query.create( + // QueryType.SELECT, + // false, + // List( + // v("wName"), + // v("sample"), + // v("porosity"), + // v("top_depth_md"), + // v("bot_depth_md") + // ).asJava, + // Conjunction.create( + // Atom.rdf(v("w"), IRI.RDF_TYPE, c("Wellbore")), + // Atom.rdf(v("w"), c("name"), v("wName")), + // Atom.rdf(v("w"), c("hasWellboreInterval"), v("z")), + // Atom.rdf(v("z"), c("hasUnit"), v("u")), + // Atom.rdf(v("u"), c("name"), v("strat_unit_name")), + // Atom.rdf(v("wellbore"), c("hasWellboreInterval"), v("cored_int")), + // Atom.rdf(v("c"), c("extractedFrom"), v("cored_int")), + // Atom.rdf(v("c"), c("hasCoreSample"), v("sample")), + // Atom.rdf(v("sample"), c("hasDepth"), v("sample_depth")), + // Atom.rdf(v("sample_depth"), c("inWellboreInterval"), v("z")), + // Atom.rdf(v("sample"), c("hasPorosity"), v("p")), + // Atom.rdf(v("p"), c("valueInStandardUnit"), v("porosity")), + // Atom.rdf(v("z"), c("hasTopDepth"), v("top")), + // Atom.rdf(v("top"), IRI.RDF_TYPE, c("MeasuredDepth")), + // Atom.rdf(v("top"), c("valueInStandardUnit"), v("top_depth_md")), + // Atom.rdf(v("z"), c("hasBottomDepth"), v("bot")), + // Atom.rdf(v("bot"), IRI.RDF_TYPE, c("MeasuredDepth")), + // Atom.rdf(v("bot"), c("valueInStandardUnit"), v("bot_depth_md")) + // ) + // ) + + val queries = + List(query0, query1, query2, query3, query4, query5, query6, query7) +} + +class FilteringProgramSpec + extends AnyFlatSpec + with Matchers + with LoneElement + with Inspectors { + + import FilteringProgramSpec._ + + "Queries" should "have distinct answer and bounded variables" in { + for (query <- queries) { + val program = new FilteringProgram(query, List()) + forAll(program.answer) { v => program.bounded should not contain v } + forAll(program.bounded) { v => program.answer should not contain v } + } + } + + "Query 0" should "have {?obj, ?pred} as bounded variables" in { + val pred = Variable.create("obj") + val obj = Variable.create("pred") + val program = new FilteringProgram(query0, List()) + program.bounded should contain theSameElementsAs List(pred, obj) + } + + "Query 1" should "have no bounded variable" in { + val program = new FilteringProgram(query1, List()) + program.bounded shouldBe empty + } + + "Query 2" should "have no bounded variable" in { + val program = new FilteringProgram(query2, List()) + program.bounded shouldBe empty + } + + "Query 3" should "have {?w, ?fp} as bounded variables" in { + val w = Variable.create("w") + val fp = Variable.create("fp") + val program = new FilteringProgram(query3, List()) + program.bounded should contain theSameElementsAs List(w, fp) + } + + "Query 4" should "have no bounded variable" in { + val program = new FilteringProgram(query4, List()) + program.bounded shouldBe empty + } + + "Query 5" should "have a non-empty bounded set" in { + val w = Variable.create("w") + val c_int = Variable.create("c_int") + val f_int = Variable.create("f_int") + val c_unit = Variable.create("c_unit") + val program = new FilteringProgram(query5, List()) + program.bounded should contain theSameElementsAs List( + w, + c_int, + f_int, + c_unit + ) + } + + "Query 6" should "have a non-empty bounded set" in { + val w = Variable.create("w") + val int = Variable.create("int") + val program = new FilteringProgram(query6, List()) + program.bounded should contain theSameElementsAs List(w, int) + } + + "Query 7" should "have a non-empty bounded set" in { + val w = Variable.create("w") + val z = Variable.create("z") + val u = Variable.create("u") + val strat_unit_name = Variable.create("strat_unit_name") + val wellbore = Variable.create("wellbore") + val cored_int = Variable.create("cored_int") + val c = Variable.create("c") + val sample_depth = Variable.create("sample_depth") + val p = Variable.create("p") + val top = Variable.create("top") + val bot = Variable.create("bot") + val program = new FilteringProgram(query7, List()) + program.bounded should contain theSameElementsAs List( + w, + z, + u, + strat_unit_name, + wellbore, + cored_int, + c, + sample_depth, + p, + top, + bot + ) + } +} diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/OWLAxiomSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/OWLAxiomSpec.scala new file mode 100644 index 0000000..8aee03d --- /dev/null +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/OWLAxiomSpec.scala @@ -0,0 +1,336 @@ +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.{RDFoxAxiomConverter, SkolemStrategy} +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 = SkolemStrategy.None + ): 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 = SkolemStrategy.Constant(axiom_OWLSubClassOf2.toString) + 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 = SkolemStrategy.Constant(axiom_OWLSubClassOf2.toString) + 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 = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString) + 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 = SkolemStrategy.Standard(axiom_OWLSubClassOf2.toString) + 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 new file mode 100644 index 0000000..459fe21 --- /dev/null +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/OWLClassSpec.scala @@ -0,0 +1,277 @@ +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 +} +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 = SkolemStrategy.Standard(class_OWLObjectSomeValuesFrom.toString) + 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 = SkolemStrategy.Standard(class_OWLObjectSomeValuesFrom.toString) + 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 = SkolemStrategy.Standard(class_OWLObjectSomeValuesFrom.toString) + 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 = SkolemStrategy.Constant(class_OWLObjectSomeValuesFrom.toString) + 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 = SkolemStrategy.Constant(class_OWLObjectSomeValuesFrom.toString) + 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 = SkolemStrategy.Constant(class_OWLObjectSomeValuesFrom.toString) + 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 -- cgit v1.2.3