aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala')
-rw-r--r--src/main/scala/rsacomb/RDFoxAxiomConverter.scala46
-rw-r--r--src/main/scala/rsacomb/RDFoxClassExprConverter.scala54
-rw-r--r--src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala7
-rw-r--r--src/main/scala/rsacomb/RSAComb.scala31
-rw-r--r--src/main/scala/rsacomb/SkolemStrategy.scala18
5 files changed, 117 insertions, 39 deletions
diff --git a/src/main/scala/rsacomb/RDFoxAxiomConverter.scala b/src/main/scala/rsacomb/RDFoxAxiomConverter.scala
index 675ca7d..0a79823 100644
--- a/src/main/scala/rsacomb/RDFoxAxiomConverter.scala
+++ b/src/main/scala/rsacomb/RDFoxAxiomConverter.scala
@@ -1,35 +1,39 @@
1package rsacomb 1package rsacomb
2 2
3import org.semanticweb.owlapi.model.{OWLAxiom, OWLSubClassOfAxiom, OWLEquivalentClassesAxiom} 3import org.semanticweb.owlapi.model.{OWLAxiom, OWLSubClassOfAxiom, OWLEquivalentClassesAxiom, OWLObjectPropertyExpression}
4import org.semanticweb.owlapi.model.OWLAxiomVisitorEx 4import org.semanticweb.owlapi.model.OWLAxiomVisitorEx
5 5
6import tech.oxfordsemantic.jrdfox.logic.{Rule, BodyFormula} 6import tech.oxfordsemantic.jrdfox.logic.{Rule, BodyFormula}
7import tech.oxfordsemantic.jrdfox.logic.{Atom, Term, Literal} 7import tech.oxfordsemantic.jrdfox.logic.{Atom, Term, Variable, Literal}
8import tech.oxfordsemantic.jrdfox.logic.{TupleTableName}
8 9
9import scala.collection.JavaConverters._ 10import scala.collection.JavaConverters._
10 11
11import rsacomb.SkolemStrategy 12import rsacomb.SkolemStrategy
12import rsacomb.RDFoxRuleShards 13import rsacomb.RDFoxRuleShards
14import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom
15import org.semanticweb.owlapi.model.OWLObjectProperty
13 16
14object RDFoxAxiomConverter { 17object RDFoxAxiomConverter {
15 18
16 def apply(term : Term, skolem : SkolemStrategy) : RDFoxAxiomConverter = 19 def apply(
17 new RDFoxAxiomConverter(term, skolem) 20 term : Term = Variable.create("x"),
18 21 skolem : SkolemStrategy = SkolemStrategy.None,
19 def apply(term : Term) : RDFoxAxiomConverter = 22 unsafe : List[OWLObjectPropertyExpression] = List()
20 new RDFoxAxiomConverter(term, SkolemStrategy.None) 23 ) : RDFoxAxiomConverter =
24 new RDFoxAxiomConverter(term, skolem, unsafe)
21 25
22} // object RDFoxAxiomConverter 26} // object RDFoxAxiomConverter
23 27
24class RDFoxAxiomConverter(term : Term, skolem : SkolemStrategy) 28class RDFoxAxiomConverter(term : Term, skolem : SkolemStrategy, unsafe : List[OWLObjectPropertyExpression])
25 extends OWLAxiomVisitorEx[List[Rule]] 29 extends OWLAxiomVisitorEx[List[Rule]]
26{ 30{
27 31
28 override 32 override
29 def visit(axiom : OWLSubClassOfAxiom) : List[Rule] = { 33 def visit(axiom : OWLSubClassOfAxiom) : List[Rule] = {
30 // Skolemization is needed only for the head of an axiom 34 // Skolemization is needed only for the head of an axiom
31 val subVisitor = new RDFoxClassExprConverter(term,SkolemStrategy.None) 35 val subVisitor = new RDFoxClassExprConverter(term,SkolemStrategy.None, unsafe)
32 val superVisitor = new RDFoxClassExprConverter(term, skolem) 36 val superVisitor = new RDFoxClassExprConverter(term, skolem, unsafe)
33 // Each visitor returns a `RDFoxRuleShards`, a tuple (res,ext): 37 // Each visitor returns a `RDFoxRuleShards`, a tuple (res,ext):
34 // - the `res` List is a list of atoms resulting from the conversion 38 // - the `res` List is a list of atoms resulting from the conversion
35 // of the axiom. 39 // of the axiom.
@@ -46,11 +50,23 @@ class RDFoxAxiomConverter(term : Term, skolem : SkolemStrategy)
46 50
47 override 51 override
48 def visit(axiom : OWLEquivalentClassesAxiom) : List[Rule] = { 52 def visit(axiom : OWLEquivalentClassesAxiom) : List[Rule] = {
49 for { 53 for {
50 axiom1 <- axiom.asPairwiseAxioms.asScala.toList 54 axiom1 <- axiom.asPairwiseAxioms.asScala.toList
51 axiom2 <- axiom1.asOWLSubClassOfAxioms.asScala.toList 55 axiom2 <- axiom1.asOWLSubClassOfAxioms.asScala.toList
52 rule <- axiom2.accept(this) 56 rule <- axiom2.accept(this)
53 } yield rule 57 } yield rule
58 }
59
60 override
61 def visit(axiom : OWLSubObjectPropertyOfAxiom) : List[Rule] = {
62 // TODO: variables needs to be handled at visitor level. Hardcoding
63 // the name of the varibles might lead to errors for complex cases.
64 val term1 = Variable.create("y")
65 val subVisitor = new RDFoxPropertyExprConverter(term,term1,SkolemStrategy.None)
66 val superVisitor = new RDFoxPropertyExprConverter(term,term1,skolem)
67 val body: List[BodyFormula] = axiom.getSubProperty.accept(subVisitor)
68 val head: List[Atom] = axiom.getSuperProperty.accept(superVisitor)
69 List(Rule.create(head.asJava,body.asJava))
54 } 70 }
55 71
56 def doDefault(axiom : OWLAxiom) : List[Rule] = List() 72 def doDefault(axiom : OWLAxiom) : List[Rule] = List()
diff --git a/src/main/scala/rsacomb/RDFoxClassExprConverter.scala b/src/main/scala/rsacomb/RDFoxClassExprConverter.scala
index bf026c3..227c25b 100644
--- a/src/main/scala/rsacomb/RDFoxClassExprConverter.scala
+++ b/src/main/scala/rsacomb/RDFoxClassExprConverter.scala
@@ -10,14 +10,17 @@ import tech.oxfordsemantic.jrdfox.logic.{Atom, Term, Variable, Literal, Datatype
10 10
11import rsacomb.SkolemStrategy 11import rsacomb.SkolemStrategy
12import rsacomb.RDFoxRuleShards 12import rsacomb.RDFoxRuleShards
13import org.semanticweb.owlapi.model.OWLObjectPropertyExpression
14import org.semanticweb.owlapi.model.OWLObjectProperty
13 15
14object RDFoxClassExprConverter { 16object RDFoxClassExprConverter {
15 17
16 def apply(term : Term, skolem : SkolemStrategy) : RDFoxClassExprConverter = 18 def apply(
17 new RDFoxClassExprConverter(term, skolem) 19 term : Term = Variable.create("x"),
18 20 skolem : SkolemStrategy = SkolemStrategy.None,
19 def apply(term : Term) : RDFoxClassExprConverter = 21 unsafe : List[OWLObjectPropertyExpression] = List()
20 new RDFoxClassExprConverter(term, SkolemStrategy.None) 22 ) : RDFoxClassExprConverter =
23 new RDFoxClassExprConverter(term, skolem, unsafe)
21 24
22 def merge(rules : List[RDFoxRuleShards]) : RDFoxRuleShards = { 25 def merge(rules : List[RDFoxRuleShards]) : RDFoxRuleShards = {
23 rules.foldLeft(RDFoxRuleShards(List(),List())) { 26 rules.foldLeft(RDFoxRuleShards(List(),List())) {
@@ -31,7 +34,7 @@ object RDFoxClassExprConverter {
31 34
32} // object RDFoxClassExprConverter 35} // object RDFoxClassExprConverter
33 36
34class RDFoxClassExprConverter(term : Term, skolem : SkolemStrategy) 37class RDFoxClassExprConverter(term : Term, skolem : SkolemStrategy, unsafe : List[OWLObjectPropertyExpression])
35 extends OWLClassExpressionVisitorEx[RDFoxRuleShards] 38 extends OWLClassExpressionVisitorEx[RDFoxRuleShards]
36{ 39{
37 40
@@ -46,7 +49,7 @@ class RDFoxClassExprConverter(term : Term, skolem : SkolemStrategy)
46 // OWLObjectIntersectionOf 49 // OWLObjectIntersectionOf
47 override 50 override
48 def visit(expr : OWLObjectIntersectionOf) : RDFoxRuleShards = { 51 def visit(expr : OWLObjectIntersectionOf) : RDFoxRuleShards = {
49 val visitor = new RDFoxClassExprConverter(term,skolem) 52 val visitor = new RDFoxClassExprConverter(term, skolem, unsafe)
50 // TODO: maybe using `flatMap` instead of `merge` + `map` works as well 53 // TODO: maybe using `flatMap` instead of `merge` + `map` works as well
51 RDFoxClassExprConverter.merge ( 54 RDFoxClassExprConverter.merge (
52 expr.asConjunctSet.asScala.toList 55 expr.asConjunctSet.asScala.toList
@@ -75,22 +78,33 @@ class RDFoxClassExprConverter(term : Term, skolem : SkolemStrategy)
75 // TODO: variables needs to be handled at visitor level. Hardcoding 78 // TODO: variables needs to be handled at visitor level. Hardcoding
76 // the name of the varibles might lead to errors for complex cases. 79 // the name of the varibles might lead to errors for complex cases.
77 val y = Variable.create("y") 80 val y = Variable.create("y")
78 val (fun,term1) = skolem match { 81 val prop = expr.getProperty()
79 case SkolemStrategy.None => (List(),y) 82 // Computes the result of rule skolemization. Depending on the used
80 case SkolemStrategy.Constant(c) => (List(), Literal.create(c, Datatype.IRI_REFERENCE)) 83 // technique it might involve the introduction of additional atoms,
81 case SkolemStrategy.Standard(f) => 84 // and/or fresh constants and variables.
82 // At the time of writing the RDFox library does not have a 85 val (head, body, term1) = skolem match {
83 // particular class for the "SKOLEM" operator and it is instead 86 case SkolemStrategy.None => (List(), List(), y)
84 // a simple builtin function with a special name. 87 case SkolemStrategy.Constant(c) => (List(), List(), Literal.create(c, Datatype.IRI_REFERENCE))
85 (List(BindAtom.create(BuiltinFunctionCall.create("SKOLEM",term),y)),y) 88 case SkolemStrategy.ConstantRSA(c) => {
86 } 89 val lit = Literal.create(c, Datatype.IRI_REFERENCE)
87 val classVisitor = new RDFoxClassExprConverter(term1,skolem) 90 if (unsafe.contains(prop))
91 (List(Atom.create(TupleTableName.create("internal:PE"),term,lit), Atom.create(TupleTableName.create("internal:U"),lit)), List(), lit)
92 else
93 (List(), List(), lit)
94 }
95 case SkolemStrategy.Standard(f) =>
96 // At the time of writing the RDFox library does not have a
97 // particular class for the "SKOLEM" operator and it is instead
98 // a simple builtin function with a "special" name.
99 (List(),List(BindAtom.create(BuiltinFunctionCall.create("SKOLEM",term),y)),y)
100 }
101 val classVisitor = new RDFoxClassExprConverter(term1, skolem, unsafe)
88 val classResult = expr.getFiller.accept(classVisitor) 102 val classResult = expr.getFiller.accept(classVisitor)
89 val propertyVisitor = new RDFoxPropertyExprConverter(term, term1, skolem) 103 val propertyVisitor = new RDFoxPropertyExprConverter(term, term1, skolem)
90 val propertyResult = expr.getProperty.accept(propertyVisitor) 104 val propertyResult = expr.getProperty.accept(propertyVisitor)
91 RDFoxRuleShards( 105 RDFoxRuleShards(
92 classResult.res ++ propertyResult, 106 classResult.res ++ propertyResult ++ head,
93 fun ++ classResult.ext 107 classResult.ext ++ body
94 ) 108 )
95 } 109 }
96 110
@@ -100,7 +114,7 @@ class RDFoxClassExprConverter(term : Term, skolem : SkolemStrategy)
100 // TODO: again, no hardcoded variables 114 // TODO: again, no hardcoded variables
101 val vars = List(Variable.create("y"),Variable.create("z")) 115 val vars = List(Variable.create("y"),Variable.create("z"))
102 val classResult = RDFoxClassExprConverter.merge( 116 val classResult = RDFoxClassExprConverter.merge(
103 vars.map(new RDFoxClassExprConverter(_,skolem)) 117 vars.map(new RDFoxClassExprConverter(_,skolem, unsafe))
104 .map(expr.getFiller.accept(_)) 118 .map(expr.getFiller.accept(_))
105 ) 119 )
106 val propertyResult = 120 val propertyResult =
diff --git a/src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala b/src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala
index 8d472bf..78ac98c 100644
--- a/src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala
+++ b/src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala
@@ -7,6 +7,7 @@ import tech.oxfordsemantic.jrdfox.logic.{TupleTableName}
7import tech.oxfordsemantic.jrdfox.logic.{Atom, Term, Variable, Literal} 7import tech.oxfordsemantic.jrdfox.logic.{Atom, Term, Variable, Literal}
8 8
9import rsacomb.SkolemStrategy 9import rsacomb.SkolemStrategy
10import org.semanticweb.owlapi.model.OWLObjectInverseOf
10 11
11class RDFoxPropertyExprConverter(term1 : Term, term2 : Term, skolem : SkolemStrategy) 12class RDFoxPropertyExprConverter(term1 : Term, term2 : Term, skolem : SkolemStrategy)
12 extends OWLPropertyExpressionVisitorEx[List[Atom]] 13 extends OWLPropertyExpressionVisitorEx[List[Atom]]
@@ -18,6 +19,12 @@ class RDFoxPropertyExprConverter(term1 : Term, term2 : Term, skolem : SkolemStra
18 List(Atom.create(TupleTableName.create(name), term1, term2)) 19 List(Atom.create(TupleTableName.create(name), term1, term2))
19 } 20 }
20 21
22 override
23 def visit(expr : OWLObjectInverseOf) : List[Atom] = {
24 val name = expr.getInverse.getNamedProperty.getIRI.getIRIString;
25 List(Atom.create(TupleTableName.create(name ++ "_inv"), term1, term2))
26 }
27
21 def doDefault(expr : OWLPropertyExpression) : List[Atom] = List() 28 def doDefault(expr : OWLPropertyExpression) : List[Atom] = List()
22 29
23} // class RDFoxPropertyExprConverter 30} // class RDFoxPropertyExprConverter
diff --git a/src/main/scala/rsacomb/RSAComb.scala b/src/main/scala/rsacomb/RSAComb.scala
index 16d7a04..62414e9 100644
--- a/src/main/scala/rsacomb/RSAComb.scala
+++ b/src/main/scala/rsacomb/RSAComb.scala
@@ -10,7 +10,9 @@ import org.semanticweb.owlapi.model.{OWLAxiom, OWLSubClassOfAxiom, OWLEquivalent
10import org.semanticweb.owlapi.model.OWLClassExpression 10import org.semanticweb.owlapi.model.OWLClassExpression
11import org.semanticweb.owlapi.model.OWLOntology 11import org.semanticweb.owlapi.model.OWLOntology
12import org.semanticweb.owlapi.model.OWLOntologyManager 12import org.semanticweb.owlapi.model.OWLOntologyManager
13import org.semanticweb.owlapi.model.IRI
13import org.semanticweb.owlapi.model.parameters.Imports 14import org.semanticweb.owlapi.model.parameters.Imports
15import uk.ac.manchester.cs.owl.owlapi.OWLObjectPropertyImpl
14 16
15import tech.oxfordsemantic.jrdfox.Prefixes 17import tech.oxfordsemantic.jrdfox.Prefixes
16import tech.oxfordsemantic.jrdfox.client.{ConnectionFactory, ServerConnection, DataStoreConnection} 18import tech.oxfordsemantic.jrdfox.client.{ConnectionFactory, ServerConnection, DataStoreConnection}
@@ -22,6 +24,7 @@ import tech.oxfordsemantic.jrdfox.logic.{LogicFormat}
22import scala.collection.JavaConverters._ 24import scala.collection.JavaConverters._
23 25
24import rsacomb.SkolemStrategy 26import rsacomb.SkolemStrategy
27import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer
25 28
26class RSA(ontology : OWLOntology) { 29class RSA(ontology : OWLOntology) {
27 30
@@ -52,12 +55,34 @@ object RSA {
52 * step of approximation of an Horn-ALCHOIQ to RSA 55 * step of approximation of an Horn-ALCHOIQ to RSA
53 */ 56 */
54 57
58 val renderer = new DLSyntaxObjectRenderer()
59
60 // Here we need to compute the unsafe roles. This is hardcoded for now.
61 val unsafe = List(
62 new OWLObjectPropertyImpl(IRI.create("http://example.com/rsa_example.owl#S")).getInverseProperty()
63 )
64
65 /* Print TBox axioms */
66 println("TBox/RBox:")
67 for {
68 axiom <- onto.tboxAxioms(Imports.EXCLUDED).collect(Collectors.toList()).asScala
69 } yield println(renderer.render(axiom))
70 for {
71 axiom <- onto.rboxAxioms(Imports.EXCLUDED).collect(Collectors.toList()).asScala
72 } yield println(renderer.render(axiom))
73
55 /* Ontology axiom convertion into LP rules */ 74 /* Ontology axiom convertion into LP rules */
56 for { 75 println("Logic rules:")
76 for {
57 axiom <- onto.tboxAxioms(Imports.EXCLUDED).collect(Collectors.toList()).asScala 77 axiom <- onto.tboxAxioms(Imports.EXCLUDED).collect(Collectors.toList()).asScala
58 visitor = new RDFoxAxiomConverter(Variable.create("x"), SkolemStrategy.Constant(axiom.toString)) 78 visitor = new RDFoxAxiomConverter(Variable.create("x"), SkolemStrategy.ConstantRSA(axiom.toString), unsafe)
79 rule <- axiom.accept(visitor)
80 } yield println(rule)
81 for {
82 axiom <- onto.rboxAxioms(Imports.EXCLUDED).collect(Collectors.toList()).asScala
83 visitor = new RDFoxAxiomConverter(Variable.create("x"), SkolemStrategy.ConstantRSA(axiom.toString), unsafe)
59 rule <- axiom.accept(visitor) 84 rule <- axiom.accept(visitor)
60 } yield println(rule) 85 } yield println(rule)
61 86
62 /* Return true for now... */ 87 /* Return true for now... */
63 true 88 true
diff --git a/src/main/scala/rsacomb/SkolemStrategy.scala b/src/main/scala/rsacomb/SkolemStrategy.scala
index 9df167f..bcf6828 100644
--- a/src/main/scala/rsacomb/SkolemStrategy.scala
+++ b/src/main/scala/rsacomb/SkolemStrategy.scala
@@ -29,7 +29,7 @@ object SkolemStrategy {
29 def genFunctionString(str : String) = "f_" ++ str.hashCode.toString 29 def genFunctionString(str : String) = "f_" ++ str.hashCode.toString
30 } 30 }
31 31
32 /* Functional skolemization 32 /* Constant skolemization
33 * 33 *
34 * From 34 * From
35 * A ⊑ ∃R.B 35 * A ⊑ ∃R.B
@@ -42,5 +42,21 @@ object SkolemStrategy {
42 def apply(axiom : String) = new Constant(genConstantString(axiom)) 42 def apply(axiom : String) = new Constant(genConstantString(axiom))
43 def genConstantString(str : String) = "internal:c_" ++ str.hashCode.toString 43 def genConstantString(str : String) = "internal:c_" ++ str.hashCode.toString
44 } 44 }
45
46 /* (RSA) Constant skolemization
47 * This is a special skolemization option to introduce additional atoms for RSA
48 * checking algorithm.
49 *
50 * From
51 * A ⊑ ∃R.B
52 * to
53 * A(y) -> R(x,c), PE(x,c), B(c)
54 * for c, fresh constant associated with the input axiom and PE an internal predicate.
55 */
56 case class ConstantRSA(const : String) extends SkolemStrategy
57 object ConstantRSA {
58 def apply(axiom : String) = new ConstantRSA(genConstantString(axiom))
59 def genConstantString(str : String) = "internal:c_" ++ str.hashCode.toString
60 }
45} 61}
46 62