aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Igne <federico.igne@cs.ox.ac.uk>2020-09-07 13:08:31 +0200
committerFederico Igne <federico.igne@cs.ox.ac.uk>2020-09-07 13:08:31 +0200
commit2b661f3ac6fdb5156168b6775ede24e4c7b53758 (patch)
tree0e3514c38fedf41febff82e9bf93aea2ab4d7a7f
parent7e126824e9a6cb456295d2f1535aef975bb63237 (diff)
downloadRSAComb-2b661f3ac6fdb5156168b6775ede24e4c7b53758.tar.gz
RSAComb-2b661f3ac6fdb5156168b6775ede24e4c7b53758.zip
Add setup code to compute the RSA filtering program
Not all rules of the filtering program have been implemented, but the code for the generation and reification of the rules seems to work.
-rw-r--r--src/main/scala/rsacomb/Main.scala18
-rw-r--r--src/main/scala/rsacomb/RDFoxClassExprConverter.scala4
-rw-r--r--src/main/scala/rsacomb/RDFoxUtil.scala6
-rw-r--r--src/main/scala/rsacomb/RSA.scala24
-rw-r--r--src/main/scala/rsacomb/RSAAxiom.scala92
-rw-r--r--src/main/scala/rsacomb/RSAOntology.scala165
6 files changed, 261 insertions, 48 deletions
diff --git a/src/main/scala/rsacomb/Main.scala b/src/main/scala/rsacomb/Main.scala
index 9cd6680..d2bc2a8 100644
--- a/src/main/scala/rsacomb/Main.scala
+++ b/src/main/scala/rsacomb/Main.scala
@@ -48,18 +48,20 @@ object RSAComb {
48 */ 48 */
49 49
50 val ontology = RSA.loadOntology(ontoPath) 50 val ontology = RSA.loadOntology(ontoPath)
51 ontology.isRSA 51 if (ontology.isRSA) {
52 52
53 /* Build canonical model */ 53 /* Build canonical model */
54 //val tboxCanon = rsa.canonicalModel() 54 //val tboxCanon = rsa.canonicalModel()
55 55
56 /* Load query */ 56 /* Load query */
57 //val query = ... 57 val query = RSA.test_query
58 58
59 /* Compute the filtering program from the given query */ 59 /* Compute the filtering program from the given query */
60 //val tboxFilter = rsa.filteringProgram(query) 60 val filter = ontology.getFilteringProgram(query)
61 61
62 /* ... */ 62 /* ... */
63
64 }
63 65
64 /* DEBUG ONLY */ 66 /* DEBUG ONLY */
65 println("Ok!") 67 println("Ok!")
diff --git a/src/main/scala/rsacomb/RDFoxClassExprConverter.scala b/src/main/scala/rsacomb/RDFoxClassExprConverter.scala
index b9d3ea2..467b3f1 100644
--- a/src/main/scala/rsacomb/RDFoxClassExprConverter.scala
+++ b/src/main/scala/rsacomb/RDFoxClassExprConverter.scala
@@ -61,7 +61,8 @@ class RDFoxClassExprConverter(
61 61
62 // OWLClass 62 // OWLClass
63 override def visit(expr: OWLClass): RDFoxRuleShards = { 63 override def visit(expr: OWLClass): RDFoxRuleShards = {
64 val atom = List(Atom.rdf(term, IRI.RDF_TYPE, expr.getIRI())) 64 val iri: IRI = if (expr.isTopEntity()) IRI.THING else expr.getIRI()
65 val atom = List(Atom.rdf(term, IRI.RDF_TYPE, iri))
65 RDFoxRuleShards(atom, List()) 66 RDFoxRuleShards(atom, List())
66 } 67 }
67 68
@@ -97,6 +98,7 @@ class RDFoxClassExprConverter(
97 // TODO: variables needs to be handled at visitor level. Hardcoding 98 // TODO: variables needs to be handled at visitor level. Hardcoding
98 // the name of the varibles might lead to errors for complex cases. 99 // the name of the varibles might lead to errors for complex cases.
99 val y = Variable.create("y") 100 val y = Variable.create("y")
101 // Here we are assuming a role name
100 val prop = expr.getProperty() 102 val prop = expr.getProperty()
101 // Computes the result of rule skolemization. Depending on the used 103 // Computes the result of rule skolemization. Depending on the used
102 // technique it might involve the introduction of additional atoms, 104 // technique it might involve the introduction of additional atoms,
diff --git a/src/main/scala/rsacomb/RDFoxUtil.scala b/src/main/scala/rsacomb/RDFoxUtil.scala
index 4cefd83..9699fb4 100644
--- a/src/main/scala/rsacomb/RDFoxUtil.scala
+++ b/src/main/scala/rsacomb/RDFoxUtil.scala
@@ -15,6 +15,10 @@ object RDFoxUtil {
15 IRI.create(iri.getIRIString()) 15 IRI.create(iri.getIRIString())
16 } 16 }
17 17
18 implicit def owlapi2rdfox(iri: String): IRI = {
19 IRI.create(iri)
20 }
21
18 def openConnection( 22 def openConnection(
19 dataStore: String 23 dataStore: String
20 ): (ServerConnection, DataStoreConnection) = { 24 ): (ServerConnection, DataStoreConnection) = {
@@ -37,7 +41,7 @@ object RDFoxUtil {
37 (server, data) 41 (server, data)
38 } 42 }
39 43
40 def query( 44 def submitQuery(
41 data: DataStoreConnection, 45 data: DataStoreConnection,
42 prefixes: Prefixes, 46 prefixes: Prefixes,
43 query: String 47 query: String
diff --git a/src/main/scala/rsacomb/RSA.scala b/src/main/scala/rsacomb/RSA.scala
index 79617c7..c0d4e51 100644
--- a/src/main/scala/rsacomb/RSA.scala
+++ b/src/main/scala/rsacomb/RSA.scala
@@ -8,6 +8,18 @@ import tech.oxfordsemantic.jrdfox.Prefixes
8import tech.oxfordsemantic.jrdfox.logic.IRI 8import tech.oxfordsemantic.jrdfox.logic.IRI
9import org.semanticweb.owlapi.apibinding.OWLManager 9import org.semanticweb.owlapi.apibinding.OWLManager
10import org.semanticweb.owlapi.model.OWLOntology 10import org.semanticweb.owlapi.model.OWLOntology
11import rsacomb.RSAOntology
12
13// Debug only
14import tech.oxfordsemantic.jrdfox.logic.{
15 Formula,
16 Atom,
17 Variable,
18 Query,
19 QueryType,
20 Conjunction
21}
22import scala.collection.JavaConverters._
11 23
12object RSA extends RSAOntology { 24object RSA extends RSAOntology {
13 25
@@ -18,6 +30,18 @@ object RSA extends RSAOntology {
18 Prefixes.declarePrefix("rdfs:", "http://www.w3.org/2000/01/rdf-schema#") 30 Prefixes.declarePrefix("rdfs:", "http://www.w3.org/2000/01/rdf-schema#")
19 Prefixes.declarePrefix("owl:", "http://www.w3.org/2002/07/owl#") 31 Prefixes.declarePrefix("owl:", "http://www.w3.org/2002/07/owl#")
20 32
33 val varX = Variable.create("X")
34 val varY = Variable.create("Y")
35 val varZ = Variable.create("Z")
36 val testAnswerVars = List[Variable](varX, varY, varZ).asJava;
37 val testFormula: Formula =
38 Conjunction.create(
39 Atom.rdf(varX, IRI.TOP_OBJECT_PROPERTY, varY),
40 Atom.rdf(varY, IRI.TOP_OBJECT_PROPERTY, varZ)
41 )
42 val test_query =
43 Query.create(QueryType.SELECT, false, testAnswerVars, testFormula)
44
21 def internal(name: String): IRI = 45 def internal(name: String): IRI =
22 IRI.create( 46 IRI.create(
23 Prefixes.getPrefixIRIsByPrefixName.get("internal:").getIRI + name 47 Prefixes.getPrefixIRIsByPrefixName.get("internal:").getIRI + name
diff --git a/src/main/scala/rsacomb/RSAAxiom.scala b/src/main/scala/rsacomb/RSAAxiom.scala
index 9e9a016..50dc37e 100644
--- a/src/main/scala/rsacomb/RSAAxiom.scala
+++ b/src/main/scala/rsacomb/RSAAxiom.scala
@@ -1,10 +1,23 @@
1package rsacomb 1package rsacomb
2 2
3/* Java imports */ 3/* Java imports */
4import org.semanticweb.owlapi.model.{OWLAxiom,OWLSubClassOfAxiom, OWLEquivalentClassesAxiom} 4import org.semanticweb.owlapi.model.{
5import org.semanticweb.owlapi.model.{OWLObjectPropertyExpression,OWLClass,OWLClassExpression,OWLObjectSomeValuesFrom,OWLObjectMaxCardinality} 5 OWLAxiom,
6 OWLSubClassOfAxiom,
7 OWLEquivalentClassesAxiom
8}
9import org.semanticweb.owlapi.model.{
10 OWLObjectPropertyExpression,
11 OWLClass,
12 OWLClassExpression,
13 OWLObjectSomeValuesFrom,
14 OWLObjectMaxCardinality
15}
6import org.semanticweb.owlapi.model.ClassExpressionType 16import org.semanticweb.owlapi.model.ClassExpressionType
7import org.semanticweb.owlapi.model.{OWLAxiomVisitorEx,OWLClassExpressionVisitorEx} 17import org.semanticweb.owlapi.model.{
18 OWLAxiomVisitorEx,
19 OWLClassExpressionVisitorEx
20}
8 21
9/* Wrapper trait for the implicit class `RSAAxiom`. 22/* Wrapper trait for the implicit class `RSAAxiom`.
10 */ 23 */
@@ -16,10 +29,10 @@ trait RSAAxiom {
16 */ 29 */
17 private sealed trait RSAAxiomType 30 private sealed trait RSAAxiomType
18 private object RSAAxiomType { 31 private object RSAAxiomType {
19 case object T3 extends RSAAxiomType // ∃R.A ⊑ B 32 case object T3 extends RSAAxiomType // ∃R.A ⊑ B
20 case object T3top extends RSAAxiomType // ∃R.⊤ ⊑ B 33 case object T3top extends RSAAxiomType // ∃R.⊤ ⊑ B
21 case object T4 extends RSAAxiomType // A ⊑ ≤1R.B 34 case object T4 extends RSAAxiomType // A ⊑ ≤1R.B
22 case object T5 extends RSAAxiomType // A ⊑ ∃R.B 35 case object T5 extends RSAAxiomType // A ⊑ ∃R.B
23 } 36 }
24 37
25 /* Implements additional features on top of `OWLAxiom` from 38 /* Implements additional features on top of `OWLAxiom` from
@@ -32,20 +45,22 @@ trait RSAAxiom {
32 * In order to reason about role unsafety in Horn-ALCHOIQ 45 * In order to reason about role unsafety in Horn-ALCHOIQ
33 * ontologies we need to detect and filter axioms by their 46 * ontologies we need to detect and filter axioms by their
34 * "type". 47 * "type".
35 * 48 *
36 * This is a simple implementation following the Visitor 49 * This is a simple implementation following the Visitor
37 * pattern imposed by the OWLAPI. 50 * pattern imposed by the OWLAPI.
38 */ 51 */
39 private class RSAAxiomTypeDetector(t: RSAAxiomType) 52 private class RSAAxiomTypeDetector(t: RSAAxiomType)
40 extends OWLAxiomVisitorEx[Boolean] 53 extends OWLAxiomVisitorEx[Boolean] {
41 { 54 override def visit(axiom: OWLSubClassOfAxiom): Boolean = {
42 override
43 def visit(axiom: OWLSubClassOfAxiom): Boolean = {
44 val sub = axiom.getSubClass().getClassExpressionType() 55 val sub = axiom.getSubClass().getClassExpressionType()
45 val sup = axiom.getSuperClass().getClassExpressionType() 56 val sup = axiom.getSuperClass().getClassExpressionType()
46 t match { 57 t match {
47 case RSAAxiomType.T3top => // ∃R.⊤ ⊑ B 58 case RSAAxiomType.T3top => // ∃R.⊤ ⊑ B
48 axiom.isT5 && axiom.getSubClass().asInstanceOf[OWLObjectSomeValuesFrom].getFiller.isOWLThing 59 axiom.isT3 && axiom
60 .getSubClass()
61 .asInstanceOf[OWLObjectSomeValuesFrom]
62 .getFiller
63 .isOWLThing
49 case RSAAxiomType.T3 => // ∃R.A ⊑ B 64 case RSAAxiomType.T3 => // ∃R.A ⊑ B
50 sub == ClassExpressionType.OBJECT_SOME_VALUES_FROM && sup == ClassExpressionType.OWL_CLASS 65 sub == ClassExpressionType.OBJECT_SOME_VALUES_FROM && sup == ClassExpressionType.OWL_CLASS
51 case RSAAxiomType.T4 => // A ⊑ ≤1R.B 66 case RSAAxiomType.T4 => // A ⊑ ≤1R.B
@@ -55,13 +70,12 @@ trait RSAAxiom {
55 } 70 }
56 } 71 }
57 72
58 override 73 override def visit(axiom: OWLEquivalentClassesAxiom): Boolean = {
59 def visit(axiom: OWLEquivalentClassesAxiom): Boolean = {
60 // TODO 74 // TODO
61 false 75 false
62 } 76 }
63 77
64 def doDefault(axiom : OWLAxiom): Boolean = false 78 def doDefault(axiom: OWLAxiom): Boolean = false
65 } 79 }
66 80
67 private def isOfType(t: RSAAxiomType): Boolean = { 81 private def isOfType(t: RSAAxiomType): Boolean = {
@@ -74,13 +88,13 @@ trait RSAAxiom {
74 def isT3: Boolean = isOfType(RSAAxiomType.T3) 88 def isT3: Boolean = isOfType(RSAAxiomType.T3)
75 def isT4: Boolean = isOfType(RSAAxiomType.T4) 89 def isT4: Boolean = isOfType(RSAAxiomType.T4)
76 def isT5: Boolean = isOfType(RSAAxiomType.T5) 90 def isT5: Boolean = isOfType(RSAAxiomType.T5)
77 91
78 /* Extracting ObjectPropertyExpressions from axioms 92 /* Extracting ObjectPropertyExpressions from axioms
79 * 93 *
80 * This extracts all ObjectPropertyExpressions from a given 94 * This extracts all ObjectPropertyExpressions from a given
81 * axiom. While the implementation is generic we use it on axioms 95 * axiom. While the implementation is generic we use it on axioms
82 * of specific types (see above). 96 * of specific types (see above).
83 * 97 *
84 * NOTE: it is not possible to use the `objectPropertyInSignature` 98 * NOTE: it is not possible to use the `objectPropertyInSignature`
85 * method of `OWLAxiom` because it returns all "role names" involved 99 * method of `OWLAxiom` because it returns all "role names" involved
86 * in the signature of an axiom. In particular we won't get the inverse 100 * in the signature of an axiom. In particular we won't get the inverse
@@ -88,55 +102,61 @@ trait RSAAxiom {
88 * itself instead). 102 * itself instead).
89 */ 103 */
90 private class RSAAxiomRoleExtractor() 104 private class RSAAxiomRoleExtractor()
91 extends OWLAxiomVisitorEx[List[OWLObjectPropertyExpression]] 105 extends OWLAxiomVisitorEx[List[OWLObjectPropertyExpression]] {
92 {
93 106
94 private class RSAExprRoleExtractor() 107 private class RSAExprRoleExtractor()
95 extends OWLClassExpressionVisitorEx[List[OWLObjectPropertyExpression]] 108 extends OWLClassExpressionVisitorEx[
96 { 109 List[OWLObjectPropertyExpression]
97 override 110 ] {
98 def visit(expr: OWLObjectSomeValuesFrom): List[OWLObjectPropertyExpression] = 111 override def visit(
112 expr: OWLObjectSomeValuesFrom
113 ): List[OWLObjectPropertyExpression] =
99 List(expr.getProperty) 114 List(expr.getProperty)
100 115
101 override 116 override def visit(
102 def visit(expr: OWLObjectMaxCardinality): List[OWLObjectPropertyExpression] = 117 expr: OWLObjectMaxCardinality
118 ): List[OWLObjectPropertyExpression] =
103 List(expr.getProperty) 119 List(expr.getProperty)
104 120
105 /* NOTE: this instance of `visit` for `OWLClass` shouldn't be necessary. However 121 /* NOTE: this instance of `visit` for `OWLClass` shouldn't be necessary. However
106 * if missing, the code throws a `NullPointerException`. It seems like, for some 122 * if missing, the code throws a `NullPointerException`. It seems like, for some
107 * reason, `OWLClass` is not really a subinterface of `OWLClassExpression`, as 123 * reason, `OWLClass` is not really a subinterface of `OWLClassExpression`, as
108 * stated in the JavaDocs. 124 * stated in the JavaDocs.
109 */ 125 */
110 override 126 override def visit(expr: OWLClass): List[OWLObjectPropertyExpression] =
111 def visit(expr: OWLClass): List[OWLObjectPropertyExpression] =
112 List() 127 List()
113 128
114 def doDefault(expr: OWLClassExpression): List[OWLObjectPropertyExpression] = 129 def doDefault(
130 expr: OWLClassExpression
131 ): List[OWLObjectPropertyExpression] =
115 List() 132 List()
116 } 133 }
117 134
118 override 135 override def visit(
119 def visit(axiom: OWLSubClassOfAxiom): List[OWLObjectPropertyExpression] = { 136 axiom: OWLSubClassOfAxiom
137 ): List[OWLObjectPropertyExpression] = {
120 val visitor = new RSAExprRoleExtractor() 138 val visitor = new RSAExprRoleExtractor()
121 val sub = axiom.getSubClass.accept(visitor) 139 val sub = axiom.getSubClass.accept(visitor)
122 val sup = axiom.getSuperClass.accept(visitor) 140 val sup = axiom.getSuperClass.accept(visitor)
123 sub ++ sup 141 sub ++ sup
124 } 142 }
125 143
126 override 144 override def visit(
127 def visit(axiom: OWLEquivalentClassesAxiom): List[OWLObjectPropertyExpression] = { 145 axiom: OWLEquivalentClassesAxiom
146 ): List[OWLObjectPropertyExpression] = {
128 // TODO 147 // TODO
129 List() 148 List()
130 } 149 }
131 150
132 def doDefault(axiom : OWLAxiom): List[OWLObjectPropertyExpression] = List() 151 def doDefault(axiom: OWLAxiom): List[OWLObjectPropertyExpression] = List()
133 } 152 }
134 153
135 /* Exposed methods */ 154 /* Exposed methods */
136 def objectPropertyExpressionsInSignature: List[OWLObjectPropertyExpression] = { 155 def objectPropertyExpressionsInSignature
156 : List[OWLObjectPropertyExpression] = {
137 val visitor = new RSAAxiomRoleExtractor() 157 val visitor = new RSAAxiomRoleExtractor()
138 axiom.accept(visitor) 158 axiom.accept(visitor)
139 } 159 }
140 } 160 }
141 161
142} // trait RSAAxiom \ No newline at end of file 162} // trait RSAAxiom
diff --git a/src/main/scala/rsacomb/RSAOntology.scala b/src/main/scala/rsacomb/RSAOntology.scala
index 3d9210e..9d52612 100644
--- a/src/main/scala/rsacomb/RSAOntology.scala
+++ b/src/main/scala/rsacomb/RSAOntology.scala
@@ -19,6 +19,7 @@ import scalax.collection.GraphEdge.UnDiEdge
19 19
20/* Debug only */ 20/* Debug only */
21import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer 21import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer
22import tech.oxfordsemantic.jrdfox.logic._
22 23
23/* Wrapper trait for the implicit class `RSAOntology`. 24/* Wrapper trait for the implicit class `RSAOntology`.
24 */ 25 */
@@ -163,8 +164,9 @@ trait RSAOntology {
163 } yield role1 164 } yield role1
164 165
165 /* TODO: We should be able to avoid this last conversion to List. 166 /* TODO: We should be able to avoid this last conversion to List.
166 * Maybe we should just move everything to Sets instead of Lists, since 167 * Maybe we should just move everything to Sets instead of Lists,
167 * they have a more straightforward conversion from Java collections. 168 * since they have a more straightforward conversion from Java
169 * collections.
168 */ 170 */
169 (unsafe1 ++ unsafe2).toList 171 (unsafe1 ++ unsafe2).toList
170 } 172 }
@@ -184,6 +186,165 @@ trait RSAOntology {
184 Graph(edges: _*) 186 Graph(edges: _*)
185 } 187 }
186 188
189 def getFilteringProgram(query: Query): List[Rule] = {
190
191 // Import implicit conversion to RDFox IRI
192 import RDFoxUtil._
193
194 sealed trait Reified;
195 case class ReifiedHead(bind: BindAtom, atoms: List[Atom]) extends Reified
196 case class ReifiedBody(atoms: List[Atom]) extends Reified
197 case class Unaltered(formula: BodyFormula) extends Reified
198
199 def getBindAtom(atom: Atom): BindAtom = {
200 // TODO: We need to implement another way to introduce fresh
201 // variables.
202 val varA = Variable.create("A")
203 val args = atom
204 .getArguments()
205 .asScala
206 .toSeq
207 //.prepended(atom.getTupleTableName.getIRI)
208 BindAtom.create(
209 BuiltinFunctionCall
210 .create("SKOLEM", args: _*),
211 varA
212 )
213 }
214
215 def reifyAtom(atom: Atom, variable: Variable): List[Atom] = {
216 def iri(i: Int) = atom.getTupleTableName().getIRI() ++ s"_$i"
217 atom
218 .getArguments()
219 .asScala
220 .zipWithIndex
221 .map { case (t, i) => Atom.rdf(variable, iri(i), t) }
222 .toList
223 }
224
225 // Is this the best way to determine if an atom is an RDF triple?
226 // Note that we can't use `getNumberOfArguments()` because is not
227 // "consistent":
228 // - for an atom created with `rdf(<term1>, <term2>, <term3>)`,
229 // `getNumberOfArguments` returns 3
230 // - for an atom created with `Atom.create(<tupletablename>, <term1>,
231 // <term2>, <term3>)`, `getNumberOfArguments()` returns 3
232 //
233 // This is probably because `Atom.rdf(...) is implemented as:
234 // ```scala
235 // def rdf(term1: Term, term2: Term, term3: Term): Atom =
236 // Atom.create(TupleTableName.create("internal:triple"), term1, term2, term3)
237 // ```
238 def isRdfTriple(atom: Atom): Boolean =
239 atom.getTupleTableName.getIRI.equals("internal:triple")
240
241 def reify(
242 formula: BodyFormula,
243 head: Boolean
244 ): Reified = {
245 def default[A <: BodyFormula](x: A) = Unaltered(x)
246 formula match {
247 case a: Atom => {
248 if (!isRdfTriple(a)) {
249 if (head) {
250 val b = getBindAtom(a)
251 ReifiedHead(b, reifyAtom(a, b.getBoundVariable))
252 } else {
253 val varA = Variable.create("A")
254 ReifiedBody(reifyAtom(a, varA))
255 }
256 } else {
257 default(a)
258 }
259 }
260 case a => default(a)
261 }
262 }
263
264 def skolemizeRule(rule: Rule): Rule = {
265 // Rule body
266 val body =
267 rule.getBody.asScala.map(reify(_, false)).flatMap {
268 case ReifiedHead(_, _) => List(); /* handle impossible case */
269 case ReifiedBody(x) => x;
270 case Unaltered(x) => List(x)
271 }
272 // Rule head
273 val reified = rule.getHead.asScala.map(reify(_, true))
274 val skols = reified.flatMap {
275 case ReifiedHead(x, _) => Some(x);
276 case ReifiedBody(_) => None; /* handle impossible case */
277 case Unaltered(_) => None
278 }
279 val head = reified.flatMap {
280 case ReifiedHead(_, x) => x;
281 case ReifiedBody(_) => List(); /* handle impossible case */
282 case Unaltered(x) =>
283 List(x.asInstanceOf[Atom]) /* Can we do better that a cast? */
284 }
285 Rule.create(head.asJava, (skols ++ body).asJava)
286 }
287
288 def formulaToRuleBody(body: Formula): List[BodyFormula] = {
289 body match {
290 case a: BodyFormula => List(a);
291 case a: Conjunction =>
292 a.getConjuncts().asScala.toList.flatMap(formulaToRuleBody(_));
293 case _ => List() /* We don't handle this for now */
294 }
295 }
296
297 val body = formulaToRuleBody(query.getQueryFormula)
298 val vars: List[Term] = query.getAnswerVariables.asScala.toList
299 def id(t1: Term, t2: Term) =
300 Atom.create(
301 TupleTableName.create("http://127.0.0.1/ID"),
302 vars.appendedAll(List(t1, t2)).asJava
303 )
304 val qm = Atom.create(TupleTableName.create("QM"), vars.asJava)
305
306 /* Filtering program */
307 val rule1 = Rule.create(qm, body.asJava)
308 val rule3a =
309 for ((v, i) <- vars.zipWithIndex)
310 yield Rule.create(
311 id(
312 IRI.create(s"http://127.0.0.1/$i"),
313 IRI.create(s"http://127.0.0.1/$i")
314 ),
315 List(
316 qm,
317 Negation.create(
318 Atom.rdf(v, IRI.RDF_TYPE, IRI.create("http://127.0.0.1/NI"))
319 )
320 ).asJava
321 )
322 val rule3b = Rule.create(
323 id(Variable.create("V"), Variable.create("U")),
324 id(Variable.create("U"), Variable.create("V"))
325 )
326 val rule3c = Rule.create(
327 id(Variable.create("U"), Variable.create("W")),
328 List[BodyFormula](
329 id(Variable.create("U"), Variable.create("V")),
330 id(Variable.create("V"), Variable.create("W"))
331 ).asJava
332 )
333
334 var rules: List[Rule] =
335 List.empty
336 .prepended(rule3c)
337 .prepended(rule3b)
338 .prependedAll(rule3a)
339 .prepended(rule1)
340
341 // DEBUG
342 println("FILTERING PROGRAM:")
343 rules.map(skolemizeRule(_)).foreach(println(_))
344
345 List()
346 }
347
187 } // implicit class RSAOntology 348 } // implicit class RSAOntology
188 349
189} // trait RSAOntology 350} // trait RSAOntology