diff options
Diffstat (limited to 'src/main/scala')
| -rw-r--r-- | src/main/scala/rsacomb/CanonicalModel.scala | 52 | ||||
| -rw-r--r-- | src/main/scala/rsacomb/Main.scala | 14 | ||||
| -rw-r--r-- | src/main/scala/rsacomb/RSAAxiom.scala | 8 | ||||
| -rw-r--r-- | src/main/scala/rsacomb/RSAOntology.scala | 34 |
4 files changed, 75 insertions, 33 deletions
diff --git a/src/main/scala/rsacomb/CanonicalModel.scala b/src/main/scala/rsacomb/CanonicalModel.scala index c957940..95eb556 100644 --- a/src/main/scala/rsacomb/CanonicalModel.scala +++ b/src/main/scala/rsacomb/CanonicalModel.scala | |||
| @@ -29,12 +29,12 @@ object ProgramGenerator { | |||
| 29 | new ProgramGenerator(ontology, term, unsafe) | 29 | new ProgramGenerator(ontology, term, unsafe) |
| 30 | 30 | ||
| 31 | def generateRoleRules( | 31 | def generateRoleRules( |
| 32 | roles: List[OWLObjectPropertyExpression] | 32 | roles: Set[OWLObjectProperty] |
| 33 | ): List[Rule] = { | 33 | ): List[Rule] = { |
| 34 | def additional(pred: String): Seq[Rule] = { | 34 | def additional(pred: String): Seq[Rule] = { |
| 35 | val varX = Variable.create("X") | 35 | val varX = Variable.create("X") |
| 36 | val varY = Variable.create("Y") | 36 | val varY = Variable.create("Y") |
| 37 | Seq( | 37 | List( |
| 38 | Rule.create( | 38 | Rule.create( |
| 39 | Atom.rdf(varX, IRI.create(pred), varY), | 39 | Atom.rdf(varX, IRI.create(pred), varY), |
| 40 | Atom.rdf(varX, IRI.create(pred ++ RSASuffix.Forward.getSuffix), varY) | 40 | Atom.rdf(varX, IRI.create(pred ++ RSASuffix.Forward.getSuffix), varY) |
| @@ -62,10 +62,14 @@ object ProgramGenerator { | |||
| 62 | ) | 62 | ) |
| 63 | } | 63 | } |
| 64 | roles | 64 | roles |
| 65 | .filter(_.isInstanceOf[OWLObjectProperty]) // Can we avoid this? | 65 | .map(_.getIRI.getIRIString) |
| 66 | .map(_.asInstanceOf[OWLObjectProperty].getIRI.getIRIString) | ||
| 67 | .flatMap(additional) | 66 | .flatMap(additional) |
| 67 | .toList | ||
| 68 | } | 68 | } |
| 69 | |||
| 70 | def NIs(individuals: List[IRI]): List[Atom] = | ||
| 71 | individuals.map(Atom.rdf(_, IRI.RDF_TYPE, RSA.internal("NI"))) | ||
| 72 | |||
| 69 | } | 73 | } |
| 70 | 74 | ||
| 71 | class ProgramGenerator( | 75 | class ProgramGenerator( |
| @@ -78,7 +82,7 @@ class ProgramGenerator( | |||
| 78 | 82 | ||
| 79 | import RDFoxUtil._ | 83 | import RDFoxUtil._ |
| 80 | 84 | ||
| 81 | def rules1(axiom: OWLSubClassOfAxiom): (List[Rule], List[Atom]) = { | 85 | def rules1(axiom: OWLSubClassOfAxiom): List[Rule] = { |
| 82 | val unfold = ontology.cycle(axiom).toList | 86 | val unfold = ontology.cycle(axiom).toList |
| 83 | // Fresh Variables | 87 | // Fresh Variables |
| 84 | val v0 = IRI.create("v0_" ++ axiom.hashCode.toString) | 88 | val v0 = IRI.create("v0_" ++ axiom.hashCode.toString) |
| @@ -112,13 +116,16 @@ class ProgramGenerator( | |||
| 112 | .getIRI | 116 | .getIRI |
| 113 | Atom.rdf(v0, IRI.RDF_TYPE, cls) | 117 | Atom.rdf(v0, IRI.RDF_TYPE, cls) |
| 114 | } | 118 | } |
| 115 | ( | 119 | // TODO: To be consistent with the specifics of the visitor we are |
| 116 | List( | 120 | // returning facts as `Rule`s with true body. While this is correct |
| 117 | Rule.create(roleRf, atomA, notIn(varX)), | 121 | // there is an easier way to import facts into RDFox. Are we able to |
| 118 | Rule.create(atomB, atomA, notIn(varX)) | 122 | // do that? |
| 119 | ), | 123 | val facts = unfold.map(x => Rule.create(notIn(x))) |
| 120 | unfold map notIn | 124 | val rules = List( |
| 125 | Rule.create(roleRf, atomA, notIn(varX)), | ||
| 126 | Rule.create(atomB, atomA, notIn(varX)) | ||
| 121 | ) | 127 | ) |
| 128 | facts ++ rules | ||
| 122 | } | 129 | } |
| 123 | 130 | ||
| 124 | def rules2(axiom: OWLSubClassOfAxiom): List[Rule] = { | 131 | def rules2(axiom: OWLSubClassOfAxiom): List[Rule] = { |
| @@ -209,10 +216,7 @@ class ProgramGenerator( | |||
| 209 | ) | 216 | ) |
| 210 | axiom.accept(visitor) | 217 | axiom.accept(visitor) |
| 211 | } else { | 218 | } else { |
| 212 | val (r1, f1) = rules1(axiom) | 219 | rules1(axiom) ++ rules2(axiom) ++ rules3(axiom) |
| 213 | val r2 = rules2(axiom) | ||
| 214 | val r3 = rules3(axiom) | ||
| 215 | r1 ++ r2 ++ r3 | ||
| 216 | } | 220 | } |
| 217 | } else { | 221 | } else { |
| 218 | // Fallback to standard OWL to LP translation | 222 | // Fallback to standard OWL to LP translation |
| @@ -221,9 +225,21 @@ class ProgramGenerator( | |||
| 221 | } | 225 | } |
| 222 | 226 | ||
| 223 | override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = { | 227 | override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = { |
| 224 | // TODO: Generate additional rules for role inclusion | 228 | val varX = Variable.create("X") |
| 225 | val additional = List() | 229 | val varY = Variable.create("Y") |
| 226 | super.visit(axiom) ++ additional | 230 | val visitorF = new RDFoxAxiomConverter( |
| 231 | term, | ||
| 232 | unsafe, | ||
| 233 | SkolemStrategy.None, | ||
| 234 | RSASuffix.Forward | ||
| 235 | ) | ||
| 236 | val visitorB = new RDFoxAxiomConverter( | ||
| 237 | term, | ||
| 238 | unsafe, | ||
| 239 | SkolemStrategy.None, | ||
| 240 | RSASuffix.Backward | ||
| 241 | ) | ||
| 242 | axiom.accept(visitorB) ++ axiom.accept(visitorF) | ||
| 227 | } | 243 | } |
| 228 | 244 | ||
| 229 | } | 245 | } |
diff --git a/src/main/scala/rsacomb/Main.scala b/src/main/scala/rsacomb/Main.scala index 7900e19..5d92061 100644 --- a/src/main/scala/rsacomb/Main.scala +++ b/src/main/scala/rsacomb/Main.scala | |||
| @@ -54,19 +54,7 @@ object RSAComb extends App { | |||
| 54 | 54 | ||
| 55 | // DEBUG: print program to generate canonical model | 55 | // DEBUG: print program to generate canonical model |
| 56 | { | 56 | { |
| 57 | import tech.oxfordsemantic.jrdfox.logic.{Variable} | 57 | ontology.canonicalModel.foreach(println) |
| 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 | } | 58 | } |
| 71 | 59 | ||
| 72 | /* Load query */ | 60 | /* Load query */ |
diff --git a/src/main/scala/rsacomb/RSAAxiom.scala b/src/main/scala/rsacomb/RSAAxiom.scala index 50dc37e..aca44b1 100644 --- a/src/main/scala/rsacomb/RSAAxiom.scala +++ b/src/main/scala/rsacomb/RSAAxiom.scala | |||
| @@ -8,6 +8,7 @@ import org.semanticweb.owlapi.model.{ | |||
| 8 | } | 8 | } |
| 9 | import org.semanticweb.owlapi.model.{ | 9 | import org.semanticweb.owlapi.model.{ |
| 10 | OWLObjectPropertyExpression, | 10 | OWLObjectPropertyExpression, |
| 11 | OWLSubObjectPropertyOfAxiom, | ||
| 11 | OWLClass, | 12 | OWLClass, |
| 12 | OWLClassExpression, | 13 | OWLClassExpression, |
| 13 | OWLObjectSomeValuesFrom, | 14 | OWLObjectSomeValuesFrom, |
| @@ -148,11 +149,16 @@ trait RSAAxiom { | |||
| 148 | List() | 149 | List() |
| 149 | } | 150 | } |
| 150 | 151 | ||
| 152 | override def visit( | ||
| 153 | axiom: OWLSubObjectPropertyOfAxiom | ||
| 154 | ): List[OWLObjectPropertyExpression] = | ||
| 155 | List(axiom.getSubProperty(), axiom.getSuperProperty()) | ||
| 156 | |||
| 151 | def doDefault(axiom: OWLAxiom): List[OWLObjectPropertyExpression] = List() | 157 | def doDefault(axiom: OWLAxiom): List[OWLObjectPropertyExpression] = List() |
| 152 | } | 158 | } |
| 153 | 159 | ||
| 154 | /* Exposed methods */ | 160 | /* Exposed methods */ |
| 155 | def objectPropertyExpressionsInSignature | 161 | lazy val objectPropertyExpressionsInSignature |
| 156 | : List[OWLObjectPropertyExpression] = { | 162 | : List[OWLObjectPropertyExpression] = { |
| 157 | val visitor = new RSAAxiomRoleExtractor() | 163 | val visitor = new RSAAxiomRoleExtractor() |
| 158 | axiom.accept(visitor) | 164 | axiom.accept(visitor) |
diff --git a/src/main/scala/rsacomb/RSAOntology.scala b/src/main/scala/rsacomb/RSAOntology.scala index 0acf2a6..e4348d8 100644 --- a/src/main/scala/rsacomb/RSAOntology.scala +++ b/src/main/scala/rsacomb/RSAOntology.scala | |||
| @@ -46,12 +46,13 @@ trait RSAOntology { | |||
| 46 | .toList | 46 | .toList |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | private lazy val roles: Set[OWLObjectPropertyExpression] = | 49 | private val roles: Set[OWLObjectPropertyExpression] = { |
| 50 | ontology | 50 | ontology |
| 51 | .rboxAxioms(Imports.INCLUDED) | 51 | .rboxAxioms(Imports.INCLUDED) |
| 52 | .collect(Collectors.toSet()) | 52 | .collect(Collectors.toSet()) |
| 53 | .asScala | 53 | .asScala |
| 54 | .flatMap(_.objectPropertyExpressionsInSignature) | 54 | .flatMap(_.objectPropertyExpressionsInSignature) |
| 55 | } | ||
| 55 | 56 | ||
| 56 | // OWLAPI reasoner for same easier tasks | 57 | // OWLAPI reasoner for same easier tasks |
| 57 | private val reasoner = | 58 | private val reasoner = |
| @@ -199,6 +200,37 @@ trait RSAOntology { | |||
| 199 | (unsafe1 ++ unsafe2).toList | 200 | (unsafe1 ++ unsafe2).toList |
| 200 | } | 201 | } |
| 201 | 202 | ||
| 203 | lazy val canonicalModel: List[Rule] = { | ||
| 204 | // Compute program to generate canonical model | ||
| 205 | val tbox = | ||
| 206 | ontology | ||
| 207 | .tboxAxioms(Imports.INCLUDED) | ||
| 208 | .collect(Collectors.toList()) | ||
| 209 | .asScala | ||
| 210 | .toList | ||
| 211 | val rbox = | ||
| 212 | ontology | ||
| 213 | .rboxAxioms(Imports.INCLUDED) | ||
| 214 | .collect(Collectors.toList()) | ||
| 215 | .asScala | ||
| 216 | .toList | ||
| 217 | val axioms = tbox ++ rbox | ||
| 218 | val varX = Variable.create("X") | ||
| 219 | val visitor = ProgramGenerator(ontology, varX, unsafeRoles) | ||
| 220 | val facts = ProgramGenerator.NIs(individuals) | ||
| 221 | val rules1 = ProgramGenerator.generateRoleRules( | ||
| 222 | axioms | ||
| 223 | .flatMap( | ||
| 224 | _.objectPropertiesInSignature.collect(Collectors.toSet()).asScala | ||
| 225 | ) | ||
| 226 | .toSet | ||
| 227 | ) | ||
| 228 | val rules2 = axioms.flatMap(_.accept(visitor)) | ||
| 229 | |||
| 230 | rules1 ++ rules2 | ||
| 231 | // Call RDFox to generate the canonical model | ||
| 232 | } | ||
| 233 | |||
| 202 | private def rsaGraph( | 234 | private def rsaGraph( |
| 203 | data: DataStoreConnection | 235 | data: DataStoreConnection |
| 204 | ): Graph[Resource, UnDiEdge] = { | 236 | ): Graph[Resource, UnDiEdge] = { |
