diff options
| author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-09-08 18:43:40 +0200 |
|---|---|---|
| committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-09-08 18:43:40 +0200 |
| commit | 932b0a794c06a224a96b265935a38a4c7b851c5e (patch) | |
| tree | 2ea7562eefaf710ec6f685865ae7e466af70531d /src/main/scala | |
| parent | cb5f08f7dc9c811488c499d5b5fa65e3451aff5e (diff) | |
| download | RSAComb-932b0a794c06a224a96b265935a38a4c7b851c5e.tar.gz RSAComb-932b0a794c06a224a96b265935a38a4c7b851c5e.zip | |
Add full set of rules for filtering program
Diffstat (limited to 'src/main/scala')
| -rw-r--r-- | src/main/scala/rsacomb/FilteringProgram.scala | 295 | ||||
| -rw-r--r-- | src/main/scala/rsacomb/RDFTriple.scala | 60 | ||||
| -rw-r--r-- | src/main/scala/rsacomb/RSA.scala | 5 | ||||
| -rw-r--r-- | src/main/scala/rsacomb/RSAOntology.scala | 105 |
4 files changed, 363 insertions, 102 deletions
diff --git a/src/main/scala/rsacomb/FilteringProgram.scala b/src/main/scala/rsacomb/FilteringProgram.scala new file mode 100644 index 0000000..91c98d8 --- /dev/null +++ b/src/main/scala/rsacomb/FilteringProgram.scala | |||
| @@ -0,0 +1,295 @@ | |||
| 1 | package rsacomb | ||
| 2 | |||
| 3 | import tech.oxfordsemantic.jrdfox.logic._ | ||
| 4 | import scala.collection.JavaConverters._ | ||
| 5 | |||
| 6 | class FilteringProgram(query: Query, constants: List[Term]) extends RDFTriple { | ||
| 7 | |||
| 8 | private val bounded: List[Term] = this.getBoundedVariables | ||
| 9 | private val answer: List[Term] = query.getAnswerVariables.asScala.toList | ||
| 10 | |||
| 11 | val facts: List[Atom] = constants.map(named) | ||
| 12 | val rules: List[Rule] = this.generateFilteringProgram() | ||
| 13 | |||
| 14 | private def named(t: Term): Atom = | ||
| 15 | Atom.rdf(t, IRI.RDF_TYPE, RSA.internal("NAMED")) | ||
| 16 | |||
| 17 | private def getBoundedVariables: List[Variable] = List() | ||
| 18 | |||
| 19 | private def generateFilteringProgram(): List[Rule] = { | ||
| 20 | // Query formula as a rule body | ||
| 21 | val body = queryToBody(query.getQueryFormula) | ||
| 22 | // Auxiliar predicates/helpers | ||
| 23 | def not(atom: Atom): BodyFormula = Negation.create(atom) | ||
| 24 | val predQM = | ||
| 25 | Atom.create( | ||
| 26 | TupleTableName.create(RSA.internal("QM").getIRI), | ||
| 27 | (answer ++ bounded): _* | ||
| 28 | ) | ||
| 29 | def predID(t1: Term, t2: Term) = | ||
| 30 | Atom.create( | ||
| 31 | TupleTableName.create(RSA.internal("ID").getIRI), | ||
| 32 | (answer ++ bounded).appended(t1).appended(t2): _* | ||
| 33 | ) | ||
| 34 | def predNI(t1: Term): Atom = | ||
| 35 | Atom.rdf(t1, IRI.RDF_TYPE, RSA.internal("NI")) | ||
| 36 | def predTQ(sx: String, t1: Term, t2: Term) = | ||
| 37 | Atom.create( | ||
| 38 | TupleTableName.create(RSA.internal(s"TQ_$sx").getIRI), | ||
| 39 | (answer ++ bounded).appended(t1).appended(t2): _* | ||
| 40 | ) | ||
| 41 | def predAQ(sx: String, t1: Term, t2: Term) = | ||
| 42 | Atom.create( | ||
| 43 | TupleTableName.create(RSA.internal(s"AQ_$sx").getIRI), | ||
| 44 | (answer ++ bounded).appended(t1).appended(t2): _* | ||
| 45 | ) | ||
| 46 | val predFK = | ||
| 47 | Atom.create( | ||
| 48 | TupleTableName.create(RSA.internal("FK").getIRI), | ||
| 49 | (answer ++ bounded): _* | ||
| 50 | ) | ||
| 51 | val predSP = | ||
| 52 | Atom.create( | ||
| 53 | TupleTableName.create(RSA.internal("SP").getIRI), | ||
| 54 | (answer ++ bounded): _* | ||
| 55 | ) | ||
| 56 | val predANS = | ||
| 57 | Atom.create( | ||
| 58 | TupleTableName.create(RSA.internal("ANS").getIRI), | ||
| 59 | answer: _* | ||
| 60 | ) | ||
| 61 | |||
| 62 | /* Rule 1 */ | ||
| 63 | val r1 = Rule.create(predQM, body: _*) | ||
| 64 | |||
| 65 | /* Rules 3x */ | ||
| 66 | val r3a = | ||
| 67 | for ((v, i) <- bounded.zipWithIndex) | ||
| 68 | yield Rule.create( | ||
| 69 | predID(RSA.internal(i), RSA.internal(i)), | ||
| 70 | predQM, | ||
| 71 | not(predNI(v)) | ||
| 72 | ) | ||
| 73 | val r3b = Rule.create( | ||
| 74 | predID(Variable.create("V"), Variable.create("U")), | ||
| 75 | predID(Variable.create("U"), Variable.create("V")) | ||
| 76 | ) | ||
| 77 | val r3c = Rule.create( | ||
| 78 | predID(Variable.create("U"), Variable.create("W")), | ||
| 79 | predID(Variable.create("U"), Variable.create("V")), | ||
| 80 | predID(Variable.create("V"), Variable.create("W")) | ||
| 81 | ) | ||
| 82 | |||
| 83 | /* Rules 4x */ | ||
| 84 | val r4a = for { | ||
| 85 | role1 <- body.filter(_.isRoleAssertion) | ||
| 86 | if bounded contains (role1 getArgument 2) | ||
| 87 | role2 <- body.filter(_.isRoleAssertion) | ||
| 88 | if bounded contains (role2 getArgument 2) | ||
| 89 | } yield Rule.create( | ||
| 90 | predFK, | ||
| 91 | role1 suffix "_f", | ||
| 92 | role2 suffix "_f", | ||
| 93 | predID( | ||
| 94 | RSA.internal(bounded.indexOf(role1 getArgument 2)), | ||
| 95 | RSA.internal(bounded.indexOf(role2 getArgument 2)) | ||
| 96 | ), | ||
| 97 | not(Atom.rdf(role1 getArgument 0, IRI.SAME_AS, role2 getArgument 0)) | ||
| 98 | ) | ||
| 99 | val r4b = for { | ||
| 100 | role1 <- body.filter(_.isRoleAssertion) | ||
| 101 | if bounded contains (role1 getArgument 2) | ||
| 102 | role2 <- body.filter(_.isRoleAssertion) | ||
| 103 | if bounded contains (role2 getArgument 0) | ||
| 104 | } yield Rule.create( | ||
| 105 | predFK, | ||
| 106 | role1 suffix "_f", | ||
| 107 | role2 suffix "_b", | ||
| 108 | predID( | ||
| 109 | RSA.internal(bounded.indexOf(role1 getArgument 2)), | ||
| 110 | RSA.internal(bounded.indexOf(role2 getArgument 0)) | ||
| 111 | ), | ||
| 112 | not(Atom.rdf(role1 getArgument 0, IRI.SAME_AS, role2 getArgument 2)) | ||
| 113 | ) | ||
| 114 | val r4c = for { | ||
| 115 | role1 <- body.filter(_.isRoleAssertion) | ||
| 116 | if bounded contains (role1 getArgument 0) | ||
| 117 | role2 <- body.filter(_.isRoleAssertion) | ||
| 118 | if bounded contains (role2 getArgument 0) | ||
| 119 | } yield Rule.create( | ||
| 120 | predFK, | ||
| 121 | role1 suffix "_b", | ||
| 122 | role2 suffix "_b", | ||
| 123 | predID( | ||
| 124 | RSA.internal(bounded.indexOf(role1 getArgument 0)), | ||
| 125 | RSA.internal(bounded.indexOf(role2 getArgument 0)) | ||
| 126 | ), | ||
| 127 | not(Atom.rdf(role1 getArgument 2, IRI.SAME_AS, role2 getArgument 2)) | ||
| 128 | ) | ||
| 129 | |||
| 130 | /* Rules 5x */ | ||
| 131 | val r5a = for { | ||
| 132 | role1 <- body.filter(_.isRoleAssertion) | ||
| 133 | role1arg0 = role1 getArgument 0 | ||
| 134 | role1arg2 = role1 getArgument 2 | ||
| 135 | if bounded contains role1arg0 | ||
| 136 | if bounded contains role1arg2 | ||
| 137 | role2 <- body.filter(_.isRoleAssertion) | ||
| 138 | role2arg0 = role2 getArgument 0 | ||
| 139 | role2arg2 = role2 getArgument 2 | ||
| 140 | if bounded contains role2arg0 | ||
| 141 | if bounded contains role2arg2 | ||
| 142 | } yield Rule.create( | ||
| 143 | predID( | ||
| 144 | RSA.internal(bounded indexOf role1arg0), | ||
| 145 | RSA.internal(bounded indexOf role2arg0) | ||
| 146 | ), | ||
| 147 | role1 suffix "_f", | ||
| 148 | role2 suffix "_f", | ||
| 149 | predID( | ||
| 150 | RSA.internal(bounded indexOf role1arg2), | ||
| 151 | RSA.internal(bounded indexOf role2arg2) | ||
| 152 | ), | ||
| 153 | Atom.rdf(role1arg0, IRI.SAME_AS, role2arg0), | ||
| 154 | not(predNI(role1arg0)) | ||
| 155 | ) | ||
| 156 | val r5b = for { | ||
| 157 | role1 <- body.filter(_.isRoleAssertion) | ||
| 158 | role1arg0 = role1 getArgument 0 | ||
| 159 | role1arg2 = role1 getArgument 2 | ||
| 160 | if bounded contains role1arg0 | ||
| 161 | if bounded contains role1arg2 | ||
| 162 | role2 <- body.filter(_.isRoleAssertion) | ||
| 163 | role2arg0 = role2 getArgument 0 | ||
| 164 | role2arg2 = role2 getArgument 2 | ||
| 165 | if bounded contains role2arg0 | ||
| 166 | if bounded contains role2arg2 | ||
| 167 | } yield Rule.create( | ||
| 168 | predID( | ||
| 169 | RSA.internal(bounded indexOf role1arg0), | ||
| 170 | RSA.internal(bounded indexOf role2arg2) | ||
| 171 | ), | ||
| 172 | role1 suffix "_f", | ||
| 173 | role2 suffix "_b", | ||
| 174 | predID( | ||
| 175 | RSA.internal(bounded indexOf role1arg2), | ||
| 176 | RSA.internal(bounded indexOf role2arg0) | ||
| 177 | ), | ||
| 178 | Atom.rdf(role1arg0, IRI.SAME_AS, role2arg2), | ||
| 179 | not(predNI(role1arg0)) | ||
| 180 | ) | ||
| 181 | val r5c = for { | ||
| 182 | role1 <- body.filter(_.isRoleAssertion) | ||
| 183 | role1arg0 = role1 getArgument 0 | ||
| 184 | role1arg2 = role1 getArgument 2 | ||
| 185 | if bounded contains role1arg0 | ||
| 186 | if bounded contains role1arg2 | ||
| 187 | role2 <- body.filter(_.isRoleAssertion) | ||
| 188 | role2arg0 = role2 getArgument 0 | ||
| 189 | role2arg2 = role2 getArgument 2 | ||
| 190 | if bounded contains role2arg0 | ||
| 191 | if bounded contains role2arg2 | ||
| 192 | } yield Rule.create( | ||
| 193 | predID( | ||
| 194 | RSA.internal(bounded indexOf role1arg2), | ||
| 195 | RSA.internal(bounded indexOf role2arg2) | ||
| 196 | ), | ||
| 197 | role1 suffix "_b", | ||
| 198 | role2 suffix "_b", | ||
| 199 | predID( | ||
| 200 | RSA.internal(bounded indexOf role1arg0), | ||
| 201 | RSA.internal(bounded indexOf role2arg0) | ||
| 202 | ), | ||
| 203 | Atom.rdf(role1arg2, IRI.SAME_AS, role2arg2), | ||
| 204 | not(predNI(role1arg2)) | ||
| 205 | ) | ||
| 206 | |||
| 207 | /* Rules 6 */ | ||
| 208 | val r6 = for { | ||
| 209 | role <- body.filter(_.isRoleAssertion) | ||
| 210 | arg0 = role getArgument 0 | ||
| 211 | arg2 = role getArgument 2 | ||
| 212 | if bounded contains arg0 | ||
| 213 | if bounded contains arg2 | ||
| 214 | sx <- List("_f", "_b") | ||
| 215 | } yield Rule.create( | ||
| 216 | predAQ(sx, Variable.create("V"), Variable.create("W")), | ||
| 217 | role suffix sx, | ||
| 218 | predID( | ||
| 219 | RSA.internal(bounded indexOf arg0), | ||
| 220 | RSA.internal(Variable.create("V")) | ||
| 221 | ), | ||
| 222 | predID( | ||
| 223 | RSA.internal(bounded indexOf arg2), | ||
| 224 | RSA.internal(Variable.create("W")) | ||
| 225 | ) | ||
| 226 | ) | ||
| 227 | |||
| 228 | /* Rules 7x */ | ||
| 229 | val r7a = | ||
| 230 | for (sx <- List("f", "b")) | ||
| 231 | yield Rule.create( | ||
| 232 | predTQ(sx, Variable.create("U"), Variable.create("V")), | ||
| 233 | predAQ(sx, Variable.create("U"), Variable.create("V")) | ||
| 234 | ) | ||
| 235 | val r7b = | ||
| 236 | for (r <- List("f", "b")) | ||
| 237 | yield Rule.create( | ||
| 238 | predTQ(r, Variable.create("U"), Variable.create("W")), | ||
| 239 | predAQ(r, Variable.create("U"), Variable.create("V")), | ||
| 240 | predTQ(r, Variable.create("V"), Variable.create("W")) | ||
| 241 | ) | ||
| 242 | |||
| 243 | /* Rules 8x */ | ||
| 244 | val r8a = | ||
| 245 | for (v <- answer) yield Rule.create(predSP, predQM, not(named(v))) | ||
| 246 | val r8b = | ||
| 247 | Rule.create(predSP, predFK) | ||
| 248 | val r8c = | ||
| 249 | for (sx <- List("_f", "_b")) | ||
| 250 | yield Rule.create( | ||
| 251 | predSP, | ||
| 252 | predTQ(sx, Variable.create("V"), Variable.create("V")) | ||
| 253 | ) | ||
| 254 | |||
| 255 | /* Rule 9 */ | ||
| 256 | val r9 = Rule.create(predANS, predQM, not(predSP)) | ||
| 257 | |||
| 258 | List.empty | ||
| 259 | .prepended(r9) | ||
| 260 | .prependedAll(r8c) | ||
| 261 | .prepended(r8b) | ||
| 262 | .prependedAll(r8a) | ||
| 263 | .prependedAll(r7b) | ||
| 264 | .prependedAll(r7a) | ||
| 265 | .prependedAll(r6) | ||
| 266 | .prependedAll(r5c) | ||
| 267 | .prependedAll(r5b) | ||
| 268 | .prependedAll(r5a) | ||
| 269 | .prependedAll(r4c) | ||
| 270 | .prependedAll(r4b) | ||
| 271 | .prependedAll(r4a) | ||
| 272 | .prepended(r3c) | ||
| 273 | .prepended(r3b) | ||
| 274 | .prependedAll(r3a) | ||
| 275 | .prepended(r1) | ||
| 276 | } | ||
| 277 | |||
| 278 | /* NOTE: we are restricting to queries that contain conjunctions of | ||
| 279 | * atoms for the time being. This might need to be reviewed in the | ||
| 280 | * future. | ||
| 281 | */ | ||
| 282 | private def queryToBody(body: Formula): List[Atom] = | ||
| 283 | body match { | ||
| 284 | case a: Atom => List(a); | ||
| 285 | case a: Conjunction => | ||
| 286 | a.getConjuncts.asScala.toList.flatMap(queryToBody); | ||
| 287 | case _ => List() | ||
| 288 | } | ||
| 289 | |||
| 290 | } // class FilteringProgram | ||
| 291 | |||
| 292 | object FilteringProgram { | ||
| 293 | def apply(query: Query, constants: List[Term]): FilteringProgram = | ||
| 294 | new FilteringProgram(query, constants) | ||
| 295 | } | ||
diff --git a/src/main/scala/rsacomb/RDFTriple.scala b/src/main/scala/rsacomb/RDFTriple.scala new file mode 100644 index 0000000..11ad6d4 --- /dev/null +++ b/src/main/scala/rsacomb/RDFTriple.scala | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | package rsacomb | ||
| 2 | |||
| 3 | import tech.oxfordsemantic.jrdfox.logic.{Atom, IRI, TupleTableName} | ||
| 4 | |||
| 5 | trait RDFTriple { | ||
| 6 | |||
| 7 | implicit class RDFTriple(atom: Atom) { | ||
| 8 | |||
| 9 | /* Is this the best way to determine if an atom is an RDF triple? | ||
| 10 | * Note that we can't use `getNumberOfArguments()` because is not | ||
| 11 | * "consistent": | ||
| 12 | * - for an atom created with `rdf(<term1>, <term2>, <term3>)`, | ||
| 13 | * `getNumberOfArguments` returns 3 | ||
| 14 | * - for an atom created with `Atom.create(<tupletablename>, <term1>, | ||
| 15 | * <term2>, <term3>)`, `getNumberOfArguments()` returns 3 | ||
| 16 | * | ||
| 17 | * This is probably because `Atom.rdf(...) is implemented as: | ||
| 18 | * ```scala | ||
| 19 | * def rdf(term1: Term, term2: Term, term3: Term): Atom = | ||
| 20 | * Atom.create(TupleTableName.create("internal:triple"), term1, term2, term3) | ||
| 21 | * ``` | ||
| 22 | */ | ||
| 23 | def isRdfTriple: Boolean = | ||
| 24 | atom.getTupleTableName.getIRI.equals("internal:triple") | ||
| 25 | |||
| 26 | def isClassAssertion: Boolean = | ||
| 27 | atom.isRdfTriple && atom.getArgument(1).equals(IRI.RDF_TYPE) | ||
| 28 | |||
| 29 | def isRoleAssertion: Boolean = | ||
| 30 | atom.isRdfTriple && !atom.getArgument(1).equals(IRI.RDF_TYPE) | ||
| 31 | |||
| 32 | def suffix(sx: String): Atom = | ||
| 33 | if (this.isClassAssertion) { | ||
| 34 | val newclass = atom.getArgument(2) match { | ||
| 35 | case iri: IRI => IRI.create(iri.getIRI.appendedAll(sx)) | ||
| 36 | case other => other | ||
| 37 | } | ||
| 38 | Atom.rdf( | ||
| 39 | atom getArgument 0, | ||
| 40 | atom getArgument 1, | ||
| 41 | newclass | ||
| 42 | ) | ||
| 43 | } else if (this.isRoleAssertion) { | ||
| 44 | val newrole = atom.getArgument(1) match { | ||
| 45 | case iri: IRI => IRI.create(iri.getIRI.appendedAll(sx)) | ||
| 46 | case other => other | ||
| 47 | } | ||
| 48 | Atom.rdf( | ||
| 49 | atom getArgument 0, | ||
| 50 | newrole, | ||
| 51 | atom getArgument 2 | ||
| 52 | ) | ||
| 53 | } else { | ||
| 54 | val newname = | ||
| 55 | TupleTableName.create(atom.getTupleTableName.getIRI.appendedAll(sx)) | ||
| 56 | Atom.create(newname, atom.getArguments()) | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | } | ||
diff --git a/src/main/scala/rsacomb/RSA.scala b/src/main/scala/rsacomb/RSA.scala index edd3758..9125f9f 100644 --- a/src/main/scala/rsacomb/RSA.scala +++ b/src/main/scala/rsacomb/RSA.scala | |||
| @@ -50,9 +50,10 @@ object RSA extends RSAOntology { | |||
| 50 | val test_query = | 50 | val test_query = |
| 51 | Query.create(QueryType.SELECT, false, testAnswerVars, testFormula) | 51 | Query.create(QueryType.SELECT, false, testAnswerVars, testFormula) |
| 52 | 52 | ||
| 53 | def internal(name: String): IRI = | 53 | def internal(name: Any): IRI = |
| 54 | IRI.create( | 54 | IRI.create( |
| 55 | Prefixes.getPrefixIRIsByPrefixName.get("internal:").getIRI + name | 55 | Prefixes.getPrefixIRIsByPrefixName.get("internal:").getIRI |
| 56 | + name.toString | ||
| 56 | ) | 57 | ) |
| 57 | 58 | ||
| 58 | // TODO: move this somewhere else... maybe an OntoUtils class or something. | 59 | // TODO: move this somewhere else... maybe an OntoUtils class or something. |
diff --git a/src/main/scala/rsacomb/RSAOntology.scala b/src/main/scala/rsacomb/RSAOntology.scala index e49d4ac..efd6e7f 100644 --- a/src/main/scala/rsacomb/RSAOntology.scala +++ b/src/main/scala/rsacomb/RSAOntology.scala | |||
| @@ -28,7 +28,9 @@ trait RSAOntology { | |||
| 28 | /* Implements additional features to reason about RSA ontologies | 28 | /* Implements additional features to reason about RSA ontologies |
| 29 | * on top of `OWLOntology` from the OWLAPI. | 29 | * on top of `OWLOntology` from the OWLAPI. |
| 30 | */ | 30 | */ |
| 31 | implicit class RSAOntology(ontology: OWLOntology) extends RSAAxiom { | 31 | implicit class RSAOntology(ontology: OWLOntology) |
| 32 | extends RSAAxiom | ||
| 33 | with RDFTriple { | ||
| 32 | 34 | ||
| 33 | /* Steps for RSA check | 35 | /* Steps for RSA check |
| 34 | * 1) convert ontology axioms into LP rules | 36 | * 1) convert ontology axioms into LP rules |
| @@ -224,28 +226,6 @@ trait RSAOntology { | |||
| 224 | .toList | 226 | .toList |
| 225 | } | 227 | } |
| 226 | 228 | ||
| 227 | // Is this the best way to determine if an atom is an RDF triple? | ||
| 228 | // Note that we can't use `getNumberOfArguments()` because is not | ||
| 229 | // "consistent": | ||
| 230 | // - for an atom created with `rdf(<term1>, <term2>, <term3>)`, | ||
| 231 | // `getNumberOfArguments` returns 3 | ||
| 232 | // - for an atom created with `Atom.create(<tupletablename>, <term1>, | ||
| 233 | // <term2>, <term3>)`, `getNumberOfArguments()` returns 3 | ||
| 234 | // | ||
| 235 | // This is probably because `Atom.rdf(...) is implemented as: | ||
| 236 | // ```scala | ||
| 237 | // def rdf(term1: Term, term2: Term, term3: Term): Atom = | ||
| 238 | // Atom.create(TupleTableName.create("internal:triple"), term1, term2, term3) | ||
| 239 | // ``` | ||
| 240 | def isRdfTriple(atom: Atom): Boolean = | ||
| 241 | atom.getTupleTableName.getIRI.equals("internal:triple") | ||
| 242 | |||
| 243 | def isClassAssertion(atom: Atom): Boolean = | ||
| 244 | isRdfTriple(atom) && atom.getArgument(1).equals(IRI.RDF_TYPE) | ||
| 245 | |||
| 246 | def isRoleAssertion(atom: Atom): Boolean = | ||
| 247 | isRdfTriple(atom) && !atom.getArgument(1).equals(IRI.RDF_TYPE) | ||
| 248 | |||
| 249 | def reify( | 229 | def reify( |
| 250 | formula: BodyFormula, | 230 | formula: BodyFormula, |
| 251 | head: Boolean | 231 | head: Boolean |
| @@ -253,7 +233,7 @@ trait RSAOntology { | |||
| 253 | def default[A <: BodyFormula](x: A) = Unaltered(x) | 233 | def default[A <: BodyFormula](x: A) = Unaltered(x) |
| 254 | formula match { | 234 | formula match { |
| 255 | case a: Atom => { | 235 | case a: Atom => { |
| 256 | if (!isRdfTriple(a)) { | 236 | if (!a.isRdfTriple) { |
| 257 | if (head) { | 237 | if (head) { |
| 258 | val b = getBindAtom(a) | 238 | val b = getBindAtom(a) |
| 259 | ReifiedHead(b, reifyAtom(a, b.getBoundVariable)) | 239 | ReifiedHead(b, reifyAtom(a, b.getBoundVariable)) |
| @@ -293,83 +273,8 @@ trait RSAOntology { | |||
| 293 | Rule.create(head.asJava, (skols ++ body).asJava) | 273 | Rule.create(head.asJava, (skols ++ body).asJava) |
| 294 | } | 274 | } |
| 295 | 275 | ||
| 296 | def formulaToRuleBody(body: Formula): List[BodyFormula] = { | ||
| 297 | body match { | ||
| 298 | case a: BodyFormula => List(a); | ||
| 299 | case a: Conjunction => | ||
| 300 | a.getConjuncts().asScala.toList.flatMap(formulaToRuleBody(_)); | ||
| 301 | case _ => List() /* We don't handle this for now */ | ||
| 302 | } | ||
| 303 | } | ||
| 304 | |||
| 305 | val body = formulaToRuleBody(query.getQueryFormula) | ||
| 306 | val bounded: List[Term] = List() | ||
| 307 | val answer: List[Term] = query.getAnswerVariables.asScala.toList | ||
| 308 | def id(t1: Term, t2: Term) = | ||
| 309 | Atom.create( | ||
| 310 | TupleTableName.create("http://127.0.0.1/ID"), | ||
| 311 | (bounded ++ answer).appendedAll(List(t1, t2)).asJava | ||
| 312 | ) | ||
| 313 | def tq(suffix: String, t1: Term, t2: Term) = | ||
| 314 | Atom.create( | ||
| 315 | TupleTableName.create(s"http://127.0.0.1/TQ$suffix"), | ||
| 316 | (bounded ++ answer).appendedAll(List(t1, t2)).asJava | ||
| 317 | ) | ||
| 318 | def aq(suffix: String, t1: Term, t2: Term) = | ||
| 319 | Atom.create( | ||
| 320 | TupleTableName.create(s"http://127.0.0.1/AQ$suffix"), | ||
| 321 | (bounded ++ answer).appendedAll(List(t1, t2)).asJava | ||
| 322 | ) | ||
| 323 | val qm = | ||
| 324 | Atom.create(TupleTableName.create("QM"), (bounded ++ answer).asJava) | ||
| 325 | |||
| 326 | /* Filtering program */ | ||
| 327 | val rule1 = Rule.create(qm, body.asJava) | ||
| 328 | val rule3a = | ||
| 329 | for ((v, i) <- answer.zipWithIndex) | ||
| 330 | yield Rule.create( | ||
| 331 | id( | ||
| 332 | IRI.create(s"http://127.0.0.1/$i"), | ||
| 333 | IRI.create(s"http://127.0.0.1/$i") | ||
| 334 | ), | ||
| 335 | qm, | ||
| 336 | Negation.create( | ||
| 337 | Atom.rdf(v, IRI.RDF_TYPE, IRI.create("http://127.0.0.1/NI")) | ||
| 338 | ) | ||
| 339 | ) | ||
| 340 | val rule3b = Rule.create( | ||
| 341 | id(Variable.create("V"), Variable.create("U")), | ||
| 342 | id(Variable.create("U"), Variable.create("V")) | ||
| 343 | ) | ||
| 344 | val rule3c = Rule.create( | ||
| 345 | id(Variable.create("U"), Variable.create("W")), | ||
| 346 | id(Variable.create("U"), Variable.create("V")), | ||
| 347 | id(Variable.create("V"), Variable.create("W")) | ||
| 348 | ) | ||
| 349 | val rule7a = | ||
| 350 | for (r <- Seq("f", "b")) | ||
| 351 | yield Rule.create( | ||
| 352 | tq(r, Variable.create("U"), Variable.create("V")), | ||
| 353 | aq(r, Variable.create("U"), Variable.create("V")) | ||
| 354 | ) | ||
| 355 | val rule7b = | ||
| 356 | for (r <- Seq("f", "b")) | ||
| 357 | yield Rule.create( | ||
| 358 | tq(r, Variable.create("U"), Variable.create("W")), | ||
| 359 | aq(r, Variable.create("U"), Variable.create("V")), | ||
| 360 | tq(r, Variable.create("V"), Variable.create("W")) | ||
| 361 | ) | ||
| 362 | |||
| 363 | var rules: List[Rule] = | ||
| 364 | List.empty | ||
| 365 | .prependedAll(rule7b) | ||
| 366 | .prependedAll(rule7a) | ||
| 367 | .prepended(rule3c) | ||
| 368 | .prepended(rule3b) | ||
| 369 | .prependedAll(rule3a) | ||
| 370 | .prepended(rule1) | ||
| 371 | |||
| 372 | // DEBUG | 276 | // DEBUG |
| 277 | val rules = FilteringProgram(query, List()).rules | ||
| 373 | println("FILTERING PROGRAM:") | 278 | println("FILTERING PROGRAM:") |
| 374 | rules.map(skolemizeRule(_)).foreach(println(_)) | 279 | rules.map(skolemizeRule(_)).foreach(println(_)) |
| 375 | 280 | ||
