diff options
-rw-r--r-- | src/main/scala/rsacomb/CanonicalModel.scala | 28 | ||||
-rw-r--r-- | src/main/scala/rsacomb/Main.scala | 17 | ||||
-rw-r--r-- | src/main/scala/rsacomb/RDFoxAxiomConverter.scala | 16 | ||||
-rw-r--r-- | src/main/scala/rsacomb/RDFoxClassExprConverter.scala | 21 | ||||
-rw-r--r-- | src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala | 15 | ||||
-rw-r--r-- | src/main/scala/rsacomb/RSAOntology.scala | 5 | ||||
-rw-r--r-- | src/main/scala/rsacomb/RSASuffix.scala | 20 |
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 { | |||
51 | class ProgramGenerator( | 59 | class 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 | ||
33 | class RDFoxAxiomConverter( | 34 | class 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 | ||
54 | class RDFoxClassExprConverter( | 55 | class 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 | ||
6 | import tech.oxfordsemantic.jrdfox.logic.{Atom, Term, IRI, Literal} | 6 | import tech.oxfordsemantic.jrdfox.logic.{Atom, Term, IRI, Literal} |
7 | 7 | ||
8 | import rsacomb.SkolemStrategy | ||
9 | import org.semanticweb.owlapi.model.OWLObjectInverseOf | 8 | import org.semanticweb.owlapi.model.OWLObjectInverseOf |
10 | 9 | ||
11 | class RDFoxPropertyExprConverter( | 10 | class 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 @@ | |||
1 | package rsacomb | ||
2 | |||
3 | sealed trait RSASuffix { | ||
4 | def getSuffix: String; | ||
5 | } | ||
6 | |||
7 | object 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 | } | ||