aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala
diff options
context:
space:
mode:
authorFederico Igne <federico.igne@cs.ox.ac.uk>2021-01-26 14:31:43 +0000
committerFederico Igne <federico.igne@cs.ox.ac.uk>2021-01-26 14:34:37 +0000
commit87b180f1de0e1c30a4624e546825b77c2edf9bbe (patch)
tree8cf5cbb5651548c156f3d5b6d600101f0255de97 /src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala
parenta3b33898b4a595c212fffb66b89cf573adbfe69d (diff)
downloadRSAComb-87b180f1de0e1c30a4624e546825b77c2edf9bbe.tar.gz
RSAComb-87b180f1de0e1c30a4624e546825b77c2edf9bbe.zip
Simplify top axiomatization as shown in #7
Diffstat (limited to 'src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala')
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala127
1 files changed, 84 insertions, 43 deletions
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala
index 5001c8a..96a953f 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala
@@ -24,68 +24,109 @@ import tech.oxfordsemantic.jrdfox.logic.expression.{
24 IRI 24 IRI
25} 25}
26 26
27import implicits.JavaCollections._
28
27import uk.ac.ox.cs.rsacomb.converter._ 29import uk.ac.ox.cs.rsacomb.converter._
28import uk.ac.ox.cs.rsacomb.suffix._ 30import uk.ac.ox.cs.rsacomb.suffix._
29import uk.ac.ox.cs.rsacomb.util.RSA 31import uk.ac.ox.cs.rsacomb.util.RSA
30 32
33/** Canonical model generator
34 *
35 * Converts the input axioms in a given ontology into logic rules that
36 * can then be passed to RDFox to compute the actual canonical model
37 * (via materialization).
38 *
39 * @param ontology the RSA ontology the canonical model is targeting.
40 */
31class CanonicalModel(val ontology: RSAOntology) { 41class CanonicalModel(val ontology: RSAOntology) {
32 42
43 /** Simplify conversion between OWLAPI and RDFox concepts */
33 import implicits.RDFox._ 44 import implicits.RDFox._
34 import implicits.JavaCollections._ 45
46 /** Extends capabilities of
47 * [[tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom TupleTableAtom]]
48 */
35 import uk.ac.ox.cs.rsacomb.implicits.RSAAxiom._ 49 import uk.ac.ox.cs.rsacomb.implicits.RSAAxiom._
36 50
51 /** Introduce additional rules for each role.
52 *
53 * Some relations between roles and their inverse or their "suffixed"
54 * versions need to be explicitly stated in terms of logic rules.
55 */
37 val rolesAdditionalRules: List[Rule] = { 56 val rolesAdditionalRules: List[Rule] = {
38 // Given a role (predicate) compute additional logic rules
39 def additional(pred: String): Seq[Rule] = {
40 val varX = Variable.create("X")
41 val varY = Variable.create("Y")
42 for (
43 (hSuffix, bSuffix) <- List(
44 (Empty, Forward),
45 (Empty, Backward),
46 (Inverse, Forward + Inverse),
47 (Inverse, Backward + Inverse),
48 (Backward + Inverse, Forward),
49 (Forward + Inverse, Backward),
50 (Backward, Forward + Inverse),
51 (Forward, Backward + Inverse)
52 )
53 )
54 yield Rule.create(
55 TupleTableAtom.rdf(varX, pred :: hSuffix, varY),
56 TupleTableAtom.rdf(varX, pred :: bSuffix, varY)
57 )
58 }
59 // Compute additional rules per role
60 ontology.roles 57 ontology.roles
61 .collect { case prop: OWLObjectProperty => prop } 58 .collect { case prop: OWLObjectProperty => prop }
62 .map(_.getIRI.getIRIString) 59 .flatMap((pred) => {
63 .flatMap(additional) 60 val iri = pred.getIRI.getIRIString
61 val (varX, varY) = (Variable.create("X"), Variable.create("Y"))
62 for (
63 (hSuffix, bSuffix) <- Seq(
64 (Empty, Forward),
65 (Empty, Backward),
66 (Inverse, Forward + Inverse),
67 (Inverse, Backward + Inverse),
68 (Backward + Inverse, Forward),
69 (Forward + Inverse, Backward),
70 (Backward, Forward + Inverse),
71 (Forward, Backward + Inverse)
72 )
73 )
74 yield Rule.create(
75 TupleTableAtom.rdf(varX, iri :: hSuffix, varY),
76 TupleTableAtom.rdf(varX, iri :: bSuffix, varY)
77 )
78 })
64 } 79 }
65 80
66 private lazy val topAxioms: List[Rule] = { 81 /** Top axiomatization
67 val varX = Variable.create("X") 82 *
68 val varY = Variable.create("Y") 83 * Corresponding to the following rules:
69 val concepts = ontology.concepts.map(c => { 84 *
85 * ```
86 * [?a, rdf:type, owl:Thing] :- [?a, rdf:type, ?b] .
87 * [?a, rdf:type, owl:Thing], [?b, rdf:type, owl:Thing] :- [?a, ?r, ?b], FILTER(?r != rdf:type).
88 * ```
89 *
90 * @note this is a naïve implementation of top axiomatization and
91 * might change in the future. The ideal solution would be for RDFox
92 * to take care of this, but at the time of writing this is not
93 * compatible with the way we are using the tool.
94 */
95 private val topAxioms: List[Rule] = {
96 val varA = Variable.create("A")
97 val varR = Variable.create("R")
98 val varB = Variable.create("B")
99 List(
70 Rule.create( 100 Rule.create(
71 RSA.Thing(varX), 101 RSA.Thing(varA),
72 TupleTableAtom.rdf(varX, IRI.RDF_TYPE, c.getIRI) 102 TupleTableAtom.rdf(varA, IRI.RDF_TYPE, varB)
73 ) 103 ),
74 })
75 val roles = ontology.roles.map(r => {
76 val name = r match {
77 case x: OWLObjectProperty => x.getIRI.getIRIString
78 case x: OWLObjectInverseOf =>
79 x.getInverse.getNamedProperty.getIRI.getIRIString :: Inverse
80 }
81 Rule.create( 104 Rule.create(
82 List(RSA.Thing(varX), RSA.Thing(varY)), 105 List(RSA.Thing(varA), RSA.Thing(varB)),
83 List(TupleTableAtom.rdf(varX, name, varY)) 106 List(
107 TupleTableAtom.rdf(varA, varR, varB),
108 FilterAtom.create(FunctionCall.notEqual(varR, IRI.RDF_TYPE))
109 )
84 ) 110 )
85 }) 111 )
86 concepts ::: roles
87 } 112 }
88 113
114 /** Equality axiomatization
115 *
116 * Introduce reflexivity, simmetry and transitivity rules for a naïve
117 * equality axiomatization.
118 *
119 * @note that we are using a custom `congruent` predicate to indicate
120 * equality. This is to avoid interfering with the standard
121 * `owl:sameAs`.
122 *
123 * @note RDFox is able to handle equality in a "smart" way, but this
124 * behaviour is incompatible with other needed features like
125 * negation-as-failure and aggregates.
126 *
127 * @todo to complete the equality axiomatization we need to introduce
128 * substitution rules to explicate a complete "equality" semantics.
129 */
89 private val equalityAxioms: List[Rule] = { 130 private val equalityAxioms: List[Rule] = {
90 val varX = Variable.create("X") 131 val varX = Variable.create("X")
91 val varY = Variable.create("Y") 132 val varY = Variable.create("Y")