diff options
author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-10-05 18:51:52 +0200 |
---|---|---|
committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-10-05 18:51:52 +0200 |
commit | 4cae6afabb48cf5f77d9826881f7e41ffb57baaf (patch) | |
tree | 28a916c97513a3ebc833e32591289d6d1042c40c | |
parent | 78966faa10b2ca4f93724e062ba6984a4a4ba956 (diff) | |
download | RSAComb-4cae6afabb48cf5f77d9826881f7e41ffb57baaf.tar.gz RSAComb-4cae6afabb48cf5f77d9826881f7e41ffb57baaf.zip |
Add generation of rules for safe T5 axioms
-rw-r--r-- | src/main/scala/rsacomb/CanonicalModel.scala | 143 |
1 files changed, 139 insertions, 4 deletions
diff --git a/src/main/scala/rsacomb/CanonicalModel.scala b/src/main/scala/rsacomb/CanonicalModel.scala index 162bea1..c957940 100644 --- a/src/main/scala/rsacomb/CanonicalModel.scala +++ b/src/main/scala/rsacomb/CanonicalModel.scala | |||
@@ -1,20 +1,32 @@ | |||
1 | package rsacomb | 1 | package rsacomb |
2 | 2 | ||
3 | import org.semanticweb.owlapi.model.{ | 3 | import org.semanticweb.owlapi.model.{ |
4 | OWLOntology, | ||
5 | OWLClass, | ||
4 | OWLSubObjectPropertyOfAxiom, | 6 | OWLSubObjectPropertyOfAxiom, |
5 | OWLSubClassOfAxiom, | 7 | OWLSubClassOfAxiom, |
6 | OWLObjectProperty, | 8 | OWLObjectProperty, |
7 | OWLObjectPropertyExpression | 9 | OWLObjectPropertyExpression, |
10 | OWLObjectSomeValuesFrom | ||
8 | } | 11 | } |
9 | import tech.oxfordsemantic.jrdfox.logic.{IRI, Atom, Rule, Term, Variable} | 12 | import tech.oxfordsemantic.jrdfox.logic.{ |
13 | IRI, | ||
14 | BodyFormula, | ||
15 | Atom, | ||
16 | Rule, | ||
17 | Term, | ||
18 | Variable | ||
19 | } | ||
20 | import scala.collection.JavaConverters._ | ||
10 | 21 | ||
11 | object ProgramGenerator { | 22 | object ProgramGenerator { |
12 | 23 | ||
13 | def apply( | 24 | def apply( |
25 | ontology: OWLOntology, | ||
14 | term: Term, | 26 | term: Term, |
15 | unsafe: List[OWLObjectPropertyExpression] = List() | 27 | unsafe: List[OWLObjectPropertyExpression] = List() |
16 | ): RDFoxAxiomConverter = | 28 | ): RDFoxAxiomConverter = |
17 | new ProgramGenerator(term, unsafe) | 29 | new ProgramGenerator(ontology, term, unsafe) |
18 | 30 | ||
19 | def generateRoleRules( | 31 | def generateRoleRules( |
20 | roles: List[OWLObjectPropertyExpression] | 32 | roles: List[OWLObjectPropertyExpression] |
@@ -57,11 +69,131 @@ object ProgramGenerator { | |||
57 | } | 69 | } |
58 | 70 | ||
59 | class ProgramGenerator( | 71 | class ProgramGenerator( |
72 | ontology: OWLOntology, | ||
60 | term: Term, | 73 | term: Term, |
61 | unsafe: List[OWLObjectPropertyExpression] | 74 | unsafe: List[OWLObjectPropertyExpression] |
62 | ) extends RDFoxAxiomConverter(term, unsafe, SkolemStrategy.None, RSASuffix.None) | 75 | ) extends RDFoxAxiomConverter(term, unsafe, SkolemStrategy.None, RSASuffix.None) |
76 | with RSAOntology | ||
63 | with RSAAxiom { | 77 | with RSAAxiom { |
64 | 78 | ||
79 | import RDFoxUtil._ | ||
80 | |||
81 | def rules1(axiom: OWLSubClassOfAxiom): (List[Rule], List[Atom]) = { | ||
82 | val unfold = ontology.cycle(axiom).toList | ||
83 | // Fresh Variables | ||
84 | val v0 = IRI.create("v0_" ++ axiom.hashCode.toString) | ||
85 | val varX = Variable.create("x") | ||
86 | // Predicates | ||
87 | val atomA: Atom = { | ||
88 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI | ||
89 | Atom.rdf(varX, IRI.RDF_TYPE, cls) | ||
90 | } | ||
91 | def notIn(t: Term): Atom = { | ||
92 | Atom.rdf( | ||
93 | t, | ||
94 | RSA.internal("notIn"), | ||
95 | RSA.internal(unfold.hashCode.toString) | ||
96 | ) | ||
97 | } | ||
98 | val roleRf: Atom = { | ||
99 | val visitor = | ||
100 | new RDFoxPropertyExprConverter(varX, v0, RSASuffix.Forward) | ||
101 | axiom.getSuperClass | ||
102 | .asInstanceOf[OWLObjectSomeValuesFrom] | ||
103 | .getProperty | ||
104 | .accept(visitor) | ||
105 | .head | ||
106 | } | ||
107 | val atomB: Atom = { | ||
108 | val cls = axiom.getSuperClass | ||
109 | .asInstanceOf[OWLObjectSomeValuesFrom] | ||
110 | .getFiller | ||
111 | .asInstanceOf[OWLClass] | ||
112 | .getIRI | ||
113 | Atom.rdf(v0, IRI.RDF_TYPE, cls) | ||
114 | } | ||
115 | ( | ||
116 | List( | ||
117 | Rule.create(roleRf, atomA, notIn(varX)), | ||
118 | Rule.create(atomB, atomA, notIn(varX)) | ||
119 | ), | ||
120 | unfold map notIn | ||
121 | ) | ||
122 | } | ||
123 | |||
124 | def rules2(axiom: OWLSubClassOfAxiom): List[Rule] = { | ||
125 | val roleR = | ||
126 | axiom.getSuperClass | ||
127 | .asInstanceOf[OWLObjectSomeValuesFrom] | ||
128 | .getProperty | ||
129 | if (ontology.confl(roleR) contains roleR) { | ||
130 | // Fresh Variables | ||
131 | val v0 = IRI.create("v0_" ++ axiom.hashCode.toString) | ||
132 | val v1 = IRI.create("v1_" ++ axiom.hashCode.toString) | ||
133 | val v2 = IRI.create("v2_" ++ axiom.hashCode.toString) | ||
134 | // Predicates | ||
135 | def atomA(t: Term): Atom = { | ||
136 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI | ||
137 | Atom.rdf(t, IRI.RDF_TYPE, cls) | ||
138 | } | ||
139 | def roleRf(t1: Term, t2: Term): Atom = { | ||
140 | val visitor = new RDFoxPropertyExprConverter(t1, t2, RSASuffix.Forward) | ||
141 | roleR.accept(visitor).head | ||
142 | } | ||
143 | def atomB(t: Term): Atom = { | ||
144 | val cls = axiom.getSuperClass | ||
145 | .asInstanceOf[OWLObjectSomeValuesFrom] | ||
146 | .getFiller | ||
147 | .asInstanceOf[OWLClass] | ||
148 | .getIRI | ||
149 | Atom.rdf(t, IRI.RDF_TYPE, cls) | ||
150 | } | ||
151 | //Rules | ||
152 | List( | ||
153 | Rule.create(roleRf(v0, v1), atomA(v0)), | ||
154 | Rule.create(atomB(v1), atomA(v0)), | ||
155 | Rule.create(roleRf(v1, v2), atomA(v1)), | ||
156 | Rule.create(atomB(v2), atomA(v1)) | ||
157 | ) | ||
158 | } else { | ||
159 | List() | ||
160 | } | ||
161 | } | ||
162 | |||
163 | def rules3(axiom: OWLSubClassOfAxiom): List[Rule] = { | ||
164 | val cycle = ontology.cycle(axiom).toList | ||
165 | val roleR = | ||
166 | axiom.getSuperClass | ||
167 | .asInstanceOf[OWLObjectSomeValuesFrom] | ||
168 | .getProperty | ||
169 | // Fresh Variables | ||
170 | val v1 = IRI.create("v1_" ++ axiom.hashCode.toString) | ||
171 | // Predicates | ||
172 | def atomA(t: Term): Atom = { | ||
173 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI | ||
174 | Atom.rdf(t, IRI.RDF_TYPE, cls) | ||
175 | } | ||
176 | def roleRf(t: Term): Atom = { | ||
177 | val visitor = | ||
178 | new RDFoxPropertyExprConverter(t, v1, RSASuffix.Forward) | ||
179 | roleR.accept(visitor).head | ||
180 | } | ||
181 | val atomB: Atom = { | ||
182 | val cls = axiom.getSuperClass | ||
183 | .asInstanceOf[OWLObjectSomeValuesFrom] | ||
184 | .getFiller | ||
185 | .asInstanceOf[OWLClass] | ||
186 | .getIRI | ||
187 | Atom.rdf(v1, IRI.RDF_TYPE, cls) | ||
188 | } | ||
189 | cycle.flatMap { x => | ||
190 | List( | ||
191 | Rule.create(roleRf(x), atomA(x)), | ||
192 | Rule.create(atomB, atomA(x)) | ||
193 | ) | ||
194 | } | ||
195 | } | ||
196 | |||
65 | override def visit(axiom: OWLSubClassOfAxiom): List[Rule] = { | 197 | override def visit(axiom: OWLSubClassOfAxiom): List[Rule] = { |
66 | if (axiom.isT5) { | 198 | if (axiom.isT5) { |
67 | // TODO: get role in T5 axiom | 199 | // TODO: get role in T5 axiom |
@@ -77,7 +209,10 @@ class ProgramGenerator( | |||
77 | ) | 209 | ) |
78 | axiom.accept(visitor) | 210 | axiom.accept(visitor) |
79 | } else { | 211 | } else { |
80 | List() | 212 | val (r1, f1) = rules1(axiom) |
213 | val r2 = rules2(axiom) | ||
214 | val r3 = rules3(axiom) | ||
215 | r1 ++ r2 ++ r3 | ||
81 | } | 216 | } |
82 | } else { | 217 | } else { |
83 | // Fallback to standard OWL to LP translation | 218 | // Fallback to standard OWL to LP translation |