aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/scala/rsacomb/CanonicalModel.scala28
-rw-r--r--src/main/scala/rsacomb/Main.scala17
-rw-r--r--src/main/scala/rsacomb/RDFoxAxiomConverter.scala16
-rw-r--r--src/main/scala/rsacomb/RDFoxClassExprConverter.scala21
-rw-r--r--src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala15
-rw-r--r--src/main/scala/rsacomb/RSAOntology.scala5
-rw-r--r--src/main/scala/rsacomb/RSASuffix.scala20
7 files changed, 88 insertions, 34 deletions
diff --git a/src/main/scala/rsacomb/CanonicalModel.scala b/src/main/scala/rsacomb/CanonicalModel.scala
index 49c0c24..162bea1 100644
--- a/src/main/scala/rsacomb/CanonicalModel.scala
+++ b/src/main/scala/rsacomb/CanonicalModel.scala
@@ -25,19 +25,27 @@ object ProgramGenerator {
25 Seq( 25 Seq(
26 Rule.create( 26 Rule.create(
27 Atom.rdf(varX, IRI.create(pred), varY), 27 Atom.rdf(varX, IRI.create(pred), varY),
28 Atom.rdf(varX, IRI.create(pred ++ "_f"), varY) 28 Atom.rdf(varX, IRI.create(pred ++ RSASuffix.Forward.getSuffix), varY)
29 ), 29 ),
30 Rule.create( 30 Rule.create(
31 Atom.rdf(varX, IRI.create(pred), varY), 31 Atom.rdf(varX, IRI.create(pred), varY),
32 Atom.rdf(varX, IRI.create(pred ++ "_b"), varY) 32 Atom.rdf(varX, IRI.create(pred ++ RSASuffix.Backward.getSuffix), varY)
33 ), 33 ),
34 Rule.create( 34 Rule.create(
35 Atom.rdf(varY, IRI.create(pred ++ "_b" ++ "_inv"), varX), 35 Atom.rdf(
36 Atom.rdf(varX, IRI.create(pred ++ "_f"), varY) 36 varY,
37 IRI.create(pred ++ RSASuffix.Backward.getSuffix ++ "_inv"),
38 varX
39 ),
40 Atom.rdf(varX, IRI.create(pred ++ RSASuffix.Forward.getSuffix), varY)
37 ), 41 ),
38 Rule.create( 42 Rule.create(
39 Atom.rdf(varY, IRI.create(pred ++ "_f" ++ "_inv"), varX), 43 Atom.rdf(
40 Atom.rdf(varX, IRI.create(pred ++ "_b"), varY) 44 varY,
45 IRI.create(pred ++ RSASuffix.Forward.getSuffix ++ "_inv"),
46 varX
47 ),
48 Atom.rdf(varX, IRI.create(pred ++ RSASuffix.Backward.getSuffix), varY)
41 ) 49 )
42 ) 50 )
43 } 51 }
@@ -51,7 +59,7 @@ object ProgramGenerator {
51class ProgramGenerator( 59class ProgramGenerator(
52 term: Term, 60 term: Term,
53 unsafe: List[OWLObjectPropertyExpression] 61 unsafe: List[OWLObjectPropertyExpression]
54) extends RDFoxAxiomConverter(term, SkolemStrategy.None, unsafe) 62) extends RDFoxAxiomConverter(term, unsafe, SkolemStrategy.None, RSASuffix.None)
55 with RSAAxiom { 63 with RSAAxiom {
56 64
57 override def visit(axiom: OWLSubClassOfAxiom): List[Rule] = { 65 override def visit(axiom: OWLSubClassOfAxiom): List[Rule] = {
@@ -63,18 +71,18 @@ class ProgramGenerator(
63 val visitor = 71 val visitor =
64 new RDFoxAxiomConverter( 72 new RDFoxAxiomConverter(
65 term, 73 term,
74 unsafe,
66 SkolemStrategy.Standard(axiom.toString), 75 SkolemStrategy.Standard(axiom.toString),
67 unsafe 76 RSASuffix.Forward
68 ) 77 )
69 axiom.accept(visitor) 78 axiom.accept(visitor)
70 } else { 79 } else {
71 // TODO; Handle forks 80 List()
72 } 81 }
73 } else { 82 } else {
74 // Fallback to standard OWL to LP translation 83 // Fallback to standard OWL to LP translation
75 super.visit(axiom) 84 super.visit(axiom)
76 } 85 }
77 List()
78 } 86 }
79 87
80 override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = { 88 override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = {
diff --git a/src/main/scala/rsacomb/Main.scala b/src/main/scala/rsacomb/Main.scala
index c6bd6a1..7900e19 100644
--- a/src/main/scala/rsacomb/Main.scala
+++ b/src/main/scala/rsacomb/Main.scala
@@ -52,6 +52,23 @@ object RSAComb extends App {
52 /* Build canonical model */ 52 /* Build canonical model */
53 //val tboxCanon = rsa.canonicalModel() 53 //val tboxCanon = rsa.canonicalModel()
54 54
55 // DEBUG: print program to generate canonical model
56 {
57 import tech.oxfordsemantic.jrdfox.logic.{Variable}
58 import org.semanticweb.owlapi.model.parameters.Imports
59 import java.util.stream.{Collectors}
60 import scala.collection.JavaConverters._
61
62 val visitor = ProgramGenerator(Variable.create("x"), ontology.unsafeRoles)
63 val axioms =
64 ontology
65 .tboxAxioms(Imports.INCLUDED)
66 .collect(Collectors.toList())
67 .asScala
68 println("Program to generate the canonical model:")
69 axioms.flatMap(_.accept(visitor)).foreach(println)
70 }
71
55 /* Load query */ 72 /* Load query */
56 val query = RDFoxUtil.parseQuery( 73 val query = RDFoxUtil.parseQuery(
57 "SELECT ?X WHERE {?X ?Y ?Z}" 74 "SELECT ?X WHERE {?X ?Y ?Z}"
diff --git a/src/main/scala/rsacomb/RDFoxAxiomConverter.scala b/src/main/scala/rsacomb/RDFoxAxiomConverter.scala
index d90c966..dab6765 100644
--- a/src/main/scala/rsacomb/RDFoxAxiomConverter.scala
+++ b/src/main/scala/rsacomb/RDFoxAxiomConverter.scala
@@ -23,24 +23,26 @@ object RDFoxAxiomConverter {
23 23
24 def apply( 24 def apply(
25 term: Term, 25 term: Term,
26 unsafe: List[OWLObjectPropertyExpression],
26 skolem: SkolemStrategy = SkolemStrategy.None, 27 skolem: SkolemStrategy = SkolemStrategy.None,
27 unsafe: List[OWLObjectPropertyExpression] = List() 28 suffix: RSASuffix = RSASuffix.None
28 ): RDFoxAxiomConverter = 29 ): RDFoxAxiomConverter =
29 new RDFoxAxiomConverter(term, skolem, unsafe) 30 new RDFoxAxiomConverter(term, unsafe, skolem, suffix)
30 31
31} // object RDFoxAxiomConverter 32} // object RDFoxAxiomConverter
32 33
33class RDFoxAxiomConverter( 34class RDFoxAxiomConverter(
34 term: Term, 35 term: Term,
36 unsafe: List[OWLObjectPropertyExpression],
35 skolem: SkolemStrategy, 37 skolem: SkolemStrategy,
36 unsafe: List[OWLObjectPropertyExpression] 38 suffix: RSASuffix
37) extends OWLAxiomVisitorEx[List[Rule]] { 39) extends OWLAxiomVisitorEx[List[Rule]] {
38 40
39 override def visit(axiom: OWLSubClassOfAxiom): List[Rule] = { 41 override def visit(axiom: OWLSubClassOfAxiom): List[Rule] = {
40 // Skolemization is needed only for the head of an axiom 42 // Skolemization is needed only for the head of an axiom
41 val subVisitor = 43 val subVisitor =
42 new RDFoxClassExprConverter(term, SkolemStrategy.None, unsafe) 44 new RDFoxClassExprConverter(term, unsafe, SkolemStrategy.None, suffix)
43 val superVisitor = new RDFoxClassExprConverter(term, skolem, unsafe) 45 val superVisitor = new RDFoxClassExprConverter(term, unsafe, skolem, suffix)
44 // Each visitor returns a `RDFoxRuleShards`, a tuple (res,ext): 46 // Each visitor returns a `RDFoxRuleShards`, a tuple (res,ext):
45 // - the `res` List is a list of atoms resulting from the conversion 47 // - the `res` List is a list of atoms resulting from the conversion
46 // of the axiom. 48 // of the axiom.
@@ -66,8 +68,8 @@ class RDFoxAxiomConverter(
66 override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = { 68 override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = {
67 val term1 = RSA.getFreshVariable() 69 val term1 = RSA.getFreshVariable()
68 val subVisitor = 70 val subVisitor =
69 new RDFoxPropertyExprConverter(term, term1, SkolemStrategy.None) 71 new RDFoxPropertyExprConverter(term, term1, suffix)
70 val superVisitor = new RDFoxPropertyExprConverter(term, term1, skolem) 72 val superVisitor = new RDFoxPropertyExprConverter(term, term1, suffix)
71 val body: List[BodyFormula] = axiom.getSubProperty.accept(subVisitor) 73 val body: List[BodyFormula] = axiom.getSubProperty.accept(subVisitor)
72 val head: List[Atom] = axiom.getSuperProperty.accept(superVisitor) 74 val head: List[Atom] = axiom.getSuperProperty.accept(superVisitor)
73 List(Rule.create(head.asJava, body.asJava)) 75 List(Rule.create(head.asJava, body.asJava))
diff --git a/src/main/scala/rsacomb/RDFoxClassExprConverter.scala b/src/main/scala/rsacomb/RDFoxClassExprConverter.scala
index a319d86..2029f0b 100644
--- a/src/main/scala/rsacomb/RDFoxClassExprConverter.scala
+++ b/src/main/scala/rsacomb/RDFoxClassExprConverter.scala
@@ -35,10 +35,11 @@ object RDFoxClassExprConverter {
35 35
36 def apply( 36 def apply(
37 term: Term, 37 term: Term,
38 unsafe: List[OWLObjectPropertyExpression],
38 skolem: SkolemStrategy = SkolemStrategy.None, 39 skolem: SkolemStrategy = SkolemStrategy.None,
39 unsafe: List[OWLObjectPropertyExpression] = List() 40 suffix: RSASuffix = RSASuffix.None
40 ): RDFoxClassExprConverter = 41 ): RDFoxClassExprConverter =
41 new RDFoxClassExprConverter(term, skolem, unsafe) 42 new RDFoxClassExprConverter(term, unsafe, skolem, suffix)
42 43
43 def merge(rules: List[RDFoxRuleShards]): RDFoxRuleShards = { 44 def merge(rules: List[RDFoxRuleShards]): RDFoxRuleShards = {
44 rules.foldLeft(RDFoxRuleShards(List(), List())) { (r1, r2) => 45 rules.foldLeft(RDFoxRuleShards(List(), List())) { (r1, r2) =>
@@ -53,8 +54,9 @@ object RDFoxClassExprConverter {
53 54
54class RDFoxClassExprConverter( 55class RDFoxClassExprConverter(
55 term: Term, 56 term: Term,
57 unsafe: List[OWLObjectPropertyExpression],
56 skolem: SkolemStrategy, 58 skolem: SkolemStrategy,
57 unsafe: List[OWLObjectPropertyExpression] 59 suffix: RSASuffix
58) extends OWLClassExpressionVisitorEx[RDFoxRuleShards] { 60) extends OWLClassExpressionVisitorEx[RDFoxRuleShards] {
59 61
60 import RDFoxUtil.owlapi2rdfox; 62 import RDFoxUtil.owlapi2rdfox;
@@ -68,7 +70,7 @@ class RDFoxClassExprConverter(
68 70
69 // OWLObjectIntersectionOf 71 // OWLObjectIntersectionOf
70 override def visit(expr: OWLObjectIntersectionOf): RDFoxRuleShards = { 72 override def visit(expr: OWLObjectIntersectionOf): RDFoxRuleShards = {
71 val visitor = new RDFoxClassExprConverter(term, skolem, unsafe) 73 val visitor = new RDFoxClassExprConverter(term, unsafe, skolem, suffix)
72 // TODO: maybe using `flatMap` instead of `merge` + `map` works as well 74 // TODO: maybe using `flatMap` instead of `merge` + `map` works as well
73 RDFoxClassExprConverter.merge( 75 RDFoxClassExprConverter.merge(
74 expr.asConjunctSet.asScala.toList 76 expr.asConjunctSet.asScala.toList
@@ -78,7 +80,7 @@ class RDFoxClassExprConverter(
78 80
79 // OWLObjectOneOf 81 // OWLObjectOneOf
80 override def visit(expr: OWLObjectOneOf): RDFoxRuleShards = { 82 override def visit(expr: OWLObjectOneOf): RDFoxRuleShards = {
81 val visitor = RDFoxClassExprConverter(term, skolem) 83 val visitor = RDFoxClassExprConverter(term, unsafe, skolem, suffix)
82 // TODO: review nominal handling. Here we are taking "just" one 84 // TODO: review nominal handling. Here we are taking "just" one
83 val ind = expr.individuals 85 val ind = expr.individuals
84 .collect(Collectors.toList()) 86 .collect(Collectors.toList())
@@ -126,9 +128,10 @@ class RDFoxClassExprConverter(
126 y 128 y
127 ) 129 )
128 } 130 }
129 val classVisitor = new RDFoxClassExprConverter(term1, skolem, unsafe) 131 val classVisitor =
132 new RDFoxClassExprConverter(term1, unsafe, skolem, suffix)
130 val classResult = expr.getFiller.accept(classVisitor) 133 val classResult = expr.getFiller.accept(classVisitor)
131 val propertyVisitor = new RDFoxPropertyExprConverter(term, term1, skolem) 134 val propertyVisitor = new RDFoxPropertyExprConverter(term, term1, suffix)
132 val propertyResult = expr.getProperty.accept(propertyVisitor) 135 val propertyResult = expr.getProperty.accept(propertyVisitor)
133 RDFoxRuleShards( 136 RDFoxRuleShards(
134 classResult.res ++ propertyResult ++ head, 137 classResult.res ++ propertyResult ++ head,
@@ -142,12 +145,12 @@ class RDFoxClassExprConverter(
142 val vars = List(RSA.getFreshVariable(), RSA.getFreshVariable()) 145 val vars = List(RSA.getFreshVariable(), RSA.getFreshVariable())
143 val classResult = RDFoxClassExprConverter.merge( 146 val classResult = RDFoxClassExprConverter.merge(
144 vars 147 vars
145 .map(new RDFoxClassExprConverter(_, skolem, unsafe)) 148 .map(new RDFoxClassExprConverter(_, unsafe, skolem, suffix))
146 .map(expr.getFiller.accept(_)) 149 .map(expr.getFiller.accept(_))
147 ) 150 )
148 val propertyResult = 151 val propertyResult =
149 vars 152 vars
150 .map(new RDFoxPropertyExprConverter(term, _, skolem)) 153 .map(new RDFoxPropertyExprConverter(term, _, suffix))
151 .map(expr.getProperty.accept(_)) 154 .map(expr.getProperty.accept(_))
152 .flatten 155 .flatten
153 RDFoxRuleShards( 156 RDFoxRuleShards(
diff --git a/src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala b/src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala
index 6eecdbf..ba151d0 100644
--- a/src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala
+++ b/src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala
@@ -5,24 +5,27 @@ import org.semanticweb.owlapi.model.OWLPropertyExpressionVisitorEx
5 5
6import tech.oxfordsemantic.jrdfox.logic.{Atom, Term, IRI, Literal} 6import tech.oxfordsemantic.jrdfox.logic.{Atom, Term, IRI, Literal}
7 7
8import rsacomb.SkolemStrategy
9import org.semanticweb.owlapi.model.OWLObjectInverseOf 8import org.semanticweb.owlapi.model.OWLObjectInverseOf
10 9
11class RDFoxPropertyExprConverter( 10class RDFoxPropertyExprConverter(
12 term1: Term, 11 term1: Term,
13 term2: Term, 12 term2: Term,
14 skolem: SkolemStrategy 13 suffix: RSASuffix
15) extends OWLPropertyExpressionVisitorEx[List[Atom]] { 14) extends OWLPropertyExpressionVisitorEx[List[Atom]] {
16 15
17 // Automatically converts OWLAPI types into RDFox equivalent types. 16 // Automatically converts OWLAPI types into RDFox equivalent types.
18 import RDFoxUtil.owlapi2rdfox; 17 import RDFoxUtil.owlapi2rdfox;
19 18
20 override def visit(expr: OWLObjectProperty): List[Atom] = 19 override def visit(expr: OWLObjectProperty): List[Atom] = {
21 List(Atom.rdf(term1, expr.getIRI, term2)) 20 val pred = IRI.create(expr.getIRI.getIRIString ++ suffix.getSuffix)
21 List(Atom.rdf(term1, pred, term2))
22 }
22 23
23 override def visit(expr: OWLObjectInverseOf): List[Atom] = { 24 override def visit(expr: OWLObjectInverseOf): List[Atom] = {
24 val name = expr.getInverse.getNamedProperty.getIRI.getIRIString; 25 val pred = IRI.create(
25 List(Atom.rdf(term1, IRI.create(name ++ "_inv"), term2)) 26 expr.getInverse.getNamedProperty.getIRI.getIRIString ++ suffix.getSuffix ++ "_inv"
27 )
28 List(Atom.rdf(term1, pred, term2))
26 } 29 }
27 30
28 def doDefault(expr: OWLPropertyExpression): List[Atom] = List() 31 def doDefault(expr: OWLPropertyExpression): List[Atom] = List()
diff --git a/src/main/scala/rsacomb/RSAOntology.scala b/src/main/scala/rsacomb/RSAOntology.scala
index 4b872e5..79b8632 100644
--- a/src/main/scala/rsacomb/RSAOntology.scala
+++ b/src/main/scala/rsacomb/RSAOntology.scala
@@ -73,8 +73,9 @@ trait RSAOntology {
73 axiom <- axioms 73 axiom <- axioms
74 visitor = new RDFoxAxiomConverter( 74 visitor = new RDFoxAxiomConverter(
75 RSA.getFreshVariable(), 75 RSA.getFreshVariable(),
76 unsafe,
76 SkolemStrategy.ConstantRSA(axiom.toString), 77 SkolemStrategy.ConstantRSA(axiom.toString),
77 unsafe 78 RSASuffix.None
78 ) 79 )
79 rule <- axiom.accept(visitor) 80 rule <- axiom.accept(visitor)
80 } yield rule 81 } yield rule
@@ -124,7 +125,7 @@ trait RSAOntology {
124 graph.isAcyclic 125 graph.isAcyclic
125 } 126 }
126 127
127 private def unsafeRoles: List[OWLObjectPropertyExpression] = { 128 lazy val unsafeRoles: List[OWLObjectPropertyExpression] = {
128 // The reasoner is used to check unsafety condition for the ontology roles 129 // The reasoner is used to check unsafety condition for the ontology roles
129 val factory = new StructuralReasonerFactory() 130 val factory = new StructuralReasonerFactory()
130 val reasoner = factory.createReasoner(ontology) 131 val reasoner = factory.createReasoner(ontology)
diff --git a/src/main/scala/rsacomb/RSASuffix.scala b/src/main/scala/rsacomb/RSASuffix.scala
new file mode 100644
index 0000000..f15d01b
--- /dev/null
+++ b/src/main/scala/rsacomb/RSASuffix.scala
@@ -0,0 +1,20 @@
1package rsacomb
2
3sealed trait RSASuffix {
4 def getSuffix: String;
5}
6
7object RSASuffix {
8
9 case object None extends RSASuffix {
10 def getSuffix: String = ""
11 }
12
13 case object Forward extends RSASuffix {
14 def getSuffix: String = "_f"
15 }
16
17 case object Backward extends RSASuffix {
18 def getSuffix: String = "_b"
19 }
20}