diff options
Diffstat (limited to 'src/main/scala')
| -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 | } | ||
