diff options
| author | Federico Igne <git@federicoigne.com> | 2021-10-01 16:16:31 +0100 |
|---|---|---|
| committer | Federico Igne <git@federicoigne.com> | 2021-10-01 16:16:31 +0100 |
| commit | 360e10e686d144b918825939f48004aebc31b7f3 (patch) | |
| tree | 38ab63b1da462bc683d526c22cd323ce8c0cbad4 /src/main/scala | |
| parent | bc37ee9293d8a4098edce2a77db6efa3d87b6dd2 (diff) | |
| download | RSAComb-360e10e686d144b918825939f48004aebc31b7f3.tar.gz RSAComb-360e10e686d144b918825939f48004aebc31b7f3.zip | |
Rework naive filtering program computation to use named graphs
Diffstat (limited to 'src/main/scala')
7 files changed, 298 insertions, 166 deletions
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala index 5a89bf9..6a3dca2 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | |||
| @@ -111,12 +111,13 @@ object RSAOntology { | |||
| 111 | * @param query the query to derive the filtering program | 111 | * @param query the query to derive the filtering program |
| 112 | * @return the filtering program for the given query | 112 | * @return the filtering program for the given query |
| 113 | */ | 113 | */ |
| 114 | def filteringProgram( | 114 | def filteringProgram(query: ConjunctiveQuery): FilteringProgram = |
| 115 | graph: String, | ||
| 116 | query: ConjunctiveQuery | ||
| 117 | ): FilteringProgram = | ||
| 118 | Logger.timed( | 115 | Logger.timed( |
| 119 | FilteringProgram(FilterType.REVISED)(query), | 116 | { |
| 117 | val filter = | ||
| 118 | FilteringProgram(FilterType.REVISED, CanonGraph, FilterGraph(query)) | ||
| 119 | filter(query) | ||
| 120 | }, | ||
| 120 | "Generating filtering program", | 121 | "Generating filtering program", |
| 121 | Logger.DEBUG | 122 | Logger.DEBUG |
| 122 | ) | 123 | ) |
| @@ -568,9 +569,8 @@ class RSAOntology(axioms: List[OWLLogicalAxiom], datafiles: List[File]) | |||
| 568 | 569 | ||
| 569 | queries map { query => | 570 | queries map { query => |
| 570 | { | 571 | { |
| 571 | val filterNamedGraph = | 572 | //val graph = RSAOntology.FilterGraph(query) |
| 572 | s"http://cs.ox.ac.uk/isg/RSAComb#Filter${query.id}" | 573 | val filter = RSAOntology.filteringProgram(query) |
| 573 | val filter = RSAOntology.filteringProgram(filterNamedGraph, query) | ||
| 574 | /* Add filtering program */ | 574 | /* Add filtering program */ |
| 575 | Logger print s"Filtering program rules: ${filter.rules.length}" | 575 | Logger print s"Filtering program rules: ${filter.rules.length}" |
| 576 | RDFoxUtil.addRules(data, filter.rules) | 576 | RDFoxUtil.addRules(data, filter.rules) |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/FilteringProgram.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/FilteringProgram.scala index d6ad8c5..3015def 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/FilteringProgram.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/FilteringProgram.scala | |||
| @@ -17,25 +17,43 @@ | |||
| 17 | package uk.ac.ox.cs.rsacomb.filtering | 17 | package uk.ac.ox.cs.rsacomb.filtering |
| 18 | 18 | ||
| 19 | import tech.oxfordsemantic.jrdfox.logic.datalog.Rule | 19 | import tech.oxfordsemantic.jrdfox.logic.datalog.Rule |
| 20 | import tech.oxfordsemantic.jrdfox.logic.expression.IRI | ||
| 20 | import uk.ac.ox.cs.rsacomb.sparql.ConjunctiveQuery | 21 | import uk.ac.ox.cs.rsacomb.sparql.ConjunctiveQuery |
| 21 | import uk.ac.ox.cs.rsacomb.util.Versioned | 22 | import uk.ac.ox.cs.rsacomb.util.Versioned |
| 22 | 23 | ||
| 24 | /** Type of filtering strategy. | ||
| 25 | * | ||
| 26 | * Mainly for testing different approaches and techniques. | ||
| 27 | */ | ||
| 23 | sealed trait FilterType | 28 | sealed trait FilterType |
| 24 | object FilterType { | 29 | object FilterType { |
| 25 | case object NAIVE extends FilterType | 30 | case object NAIVE extends FilterType |
| 26 | case object REVISED extends FilterType | 31 | case object REVISED extends FilterType |
| 27 | } | 32 | } |
| 28 | 33 | ||
| 34 | /** Filtering program trait */ | ||
| 29 | object FilteringProgram extends Versioned[FilterType] { | 35 | object FilteringProgram extends Versioned[FilterType] { |
| 30 | 36 | ||
| 31 | import FilterType._ | 37 | import FilterType._ |
| 32 | 38 | ||
| 33 | type Result = (ConjunctiveQuery) => FilteringProgram | 39 | type Result = (ConjunctiveQuery) => FilteringProgram |
| 34 | 40 | ||
| 35 | def apply(t: FilterType): (ConjunctiveQuery) => FilteringProgram = | 41 | /** Returns the right type of filtering program builder. |
| 36 | t match { | 42 | * |
| 37 | case NAIVE => NaiveFilteringProgram(_) | 43 | * @param filter type of filtering program. |
| 38 | case REVISED => RevisedFilteringProgram(_) | 44 | * @param source source named graph for the filtering program. |
| 45 | * @param target target named graph for the filtering program. | ||
| 46 | * | ||
| 47 | * @return the right type of filtering program builder. | ||
| 48 | */ | ||
| 49 | def apply( | ||
| 50 | filter: FilterType, | ||
| 51 | source: IRI, | ||
| 52 | target: IRI | ||
| 53 | ): (ConjunctiveQuery) => FilteringProgram = | ||
| 54 | filter match { | ||
| 55 | case NAIVE => NaiveFilteringProgram(source, target, _) | ||
| 56 | case REVISED => RevisedFilteringProgram(source, target, _) | ||
| 39 | } | 57 | } |
| 40 | } | 58 | } |
| 41 | 59 | ||
| @@ -46,8 +64,11 @@ object FilteringProgram extends Versioned[FilterType] { | |||
| 46 | */ | 64 | */ |
| 47 | trait FilteringProgram { | 65 | trait FilteringProgram { |
| 48 | 66 | ||
| 49 | /** Named graph used for filtering process */ | 67 | /** Source named graph for the filtering process */ |
| 50 | val graph: String | 68 | val source: IRI |
| 69 | |||
| 70 | /** Target named graph for the filtering process */ | ||
| 71 | val target: IRI | ||
| 51 | 72 | ||
| 52 | /** Query from which the filtering program is generated */ | 73 | /** Query from which the filtering program is generated */ |
| 53 | val query: ConjunctiveQuery | 74 | val query: ConjunctiveQuery |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/NaiveFilteringProgram.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/NaiveFilteringProgram.scala index 3d9717c..1777713 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/NaiveFilteringProgram.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/filtering/NaiveFilteringProgram.scala | |||
| @@ -21,23 +21,35 @@ import tech.oxfordsemantic.jrdfox.logic.Datatype | |||
| 21 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ | 21 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ |
| 22 | Rule, | 22 | Rule, |
| 23 | TupleTableAtom, | 23 | TupleTableAtom, |
| 24 | TupleTableName, | ||
| 24 | BodyFormula, | 25 | BodyFormula, |
| 25 | Negation | 26 | Negation |
| 26 | } | 27 | } |
| 27 | import tech.oxfordsemantic.jrdfox.logic.expression.{Term, Variable} | 28 | import tech.oxfordsemantic.jrdfox.logic.expression.{ |
| 29 | IRI, | ||
| 30 | Literal, | ||
| 31 | Term, | ||
| 32 | Variable | ||
| 33 | } | ||
| 28 | import uk.ac.ox.cs.rsacomb.sparql.ConjunctiveQuery | 34 | import uk.ac.ox.cs.rsacomb.sparql.ConjunctiveQuery |
| 29 | import uk.ac.ox.cs.rsacomb.suffix.{Forward, Backward} | 35 | import uk.ac.ox.cs.rsacomb.suffix.{Forward, Backward, Nth} |
| 30 | import uk.ac.ox.cs.rsacomb.util.{RSA, RDFoxUtil} | 36 | import uk.ac.ox.cs.rsacomb.util.{DataFactory, RSA, RDFoxUtil} |
| 31 | 37 | ||
| 32 | /** Factory for [[uk.ac.ox.cs.rsacomb.FilteringProgram FilteringProgram]] */ | 38 | /** Factory for [[uk.ac.ox.cs.rsacomb.FilteringProgram FilteringProgram]] */ |
| 33 | object NaiveFilteringProgram { | 39 | object NaiveFilteringProgram { |
| 34 | 40 | ||
| 35 | /** Create a new FilteringProgram instance. | 41 | /** Create a new FilteringProgram instance. |
| 36 | * | 42 | * |
| 43 | * @param source source named graph for the filtering program. | ||
| 44 | * @param target target named graph for the filtering program. | ||
| 37 | * @param query CQ to be converted into logic rules. | 45 | * @param query CQ to be converted into logic rules. |
| 38 | */ | 46 | */ |
| 39 | def apply(graph: String, query: ConjunctiveQuery): FilteringProgram = | 47 | def apply( |
| 40 | new NaiveFilteringProgram(graph, query) | 48 | source: IRI, |
| 49 | target: IRI, | ||
| 50 | query: ConjunctiveQuery | ||
| 51 | ): FilteringProgram = | ||
| 52 | new NaiveFilteringProgram(source, target, query) | ||
| 41 | } | 53 | } |
| 42 | 54 | ||
| 43 | /** Filtering Program generator | 55 | /** Filtering Program generator |
| @@ -47,14 +59,23 @@ object NaiveFilteringProgram { | |||
| 47 | * | 59 | * |
| 48 | * Instances can be created using the companion object. | 60 | * Instances can be created using the companion object. |
| 49 | */ | 61 | */ |
| 50 | class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | 62 | class NaiveFilteringProgram( |
| 51 | extends FilteringProgram { | 63 | val source: IRI, |
| 64 | val target: IRI, | ||
| 65 | val query: ConjunctiveQuery | ||
| 66 | ) extends FilteringProgram { | ||
| 52 | 67 | ||
| 53 | /** Extends capabilities of | 68 | /** Extends capabilities of |
| 54 | * [[tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom TupleTableAtom]] | 69 | * [[tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom TupleTableAtom]] |
| 55 | */ | 70 | */ |
| 56 | import uk.ac.ox.cs.rsacomb.implicits.RSAAtom._ | 71 | import uk.ac.ox.cs.rsacomb.implicits.RSAAtom._ |
| 57 | 72 | ||
| 73 | /** Simplify conversion to RDFox specific types */ | ||
| 74 | import uk.ac.ox.cs.rsacomb.implicits.RDFox._ | ||
| 75 | |||
| 76 | /** Simplify conversion between Java and Scala `List`s */ | ||
| 77 | import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ | ||
| 78 | |||
| 58 | /** Implicit parameter used in RSA internal predicates. | 79 | /** Implicit parameter used in RSA internal predicates. |
| 59 | * | 80 | * |
| 60 | * @see [[uk.ac.ox.cs.rsacomb.util.RSA]] for more information. | 81 | * @see [[uk.ac.ox.cs.rsacomb.util.RSA]] for more information. |
| @@ -72,6 +93,13 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 72 | private val varU = Variable.create("U") | 93 | private val varU = Variable.create("U") |
| 73 | private val varW = Variable.create("W") | 94 | private val varW = Variable.create("W") |
| 74 | 95 | ||
| 96 | /** `TupleTableName`s for the source/targer named graphs */ | ||
| 97 | val tts: TupleTableName = TupleTableName.create(source.getIRI) | ||
| 98 | implicit val ttt: TupleTableName = TupleTableName.create(target.getIRI) | ||
| 99 | |||
| 100 | /** Set of atoms in the body of the query */ | ||
| 101 | val queryBody: List[TupleTableAtom] = query.atoms(tts) | ||
| 102 | |||
| 75 | /** Rule generating the instances of the predicate `rsa:NI`. | 103 | /** Rule generating the instances of the predicate `rsa:NI`. |
| 76 | * | 104 | * |
| 77 | * According to the original paper, the set of `rsa:NI` is defined as | 105 | * According to the original paper, the set of `rsa:NI` is defined as |
| @@ -88,7 +116,11 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 88 | * generate in the filtering program using a logic rule. | 116 | * generate in the filtering program using a logic rule. |
| 89 | */ | 117 | */ |
| 90 | val nis: Rule = | 118 | val nis: Rule = |
| 91 | Rule.create(RSA.NI(varX), RSA.Congruent(varX, varY), RSA.Named(varY)) | 119 | Rule.create( |
| 120 | RSA.NI(varX), | ||
| 121 | RSA.Congruent(varX, varY)(tts), | ||
| 122 | RSA.Named(varY)(tts) | ||
| 123 | ) | ||
| 92 | 124 | ||
| 93 | /** Collection of filtering program rules. */ | 125 | /** Collection of filtering program rules. */ |
| 94 | val rules: List[Rule] = | 126 | val rules: List[Rule] = |
| @@ -101,7 +133,7 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 101 | * | 133 | * |
| 102 | * @note corresponds to rule 1 in Table 3 in the paper. | 134 | * @note corresponds to rule 1 in Table 3 in the paper. |
| 103 | */ | 135 | */ |
| 104 | val r1 = Rule.create(RSA.QM, query.atoms: _*) | 136 | val r1 = Rule.create(RSA.QM, queryBody: _*) |
| 105 | 137 | ||
| 106 | /** Initializes instances of `rsa:ID`. | 138 | /** Initializes instances of `rsa:ID`. |
| 107 | * | 139 | * |
| @@ -123,10 +155,10 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 123 | * @note corresponds to rules 4x in Table 3. | 155 | * @note corresponds to rules 4x in Table 3. |
| 124 | */ | 156 | */ |
| 125 | val r4a = for { | 157 | val r4a = for { |
| 126 | role1 <- query.atoms filter (_.isRoleAssertion) | 158 | role1 <- queryBody filter (_.isRoleAssertion) |
| 127 | index1 = query.bounded indexOf (role1.getArguments get 2) | 159 | index1 = query.bounded indexOf (role1.getArguments get 2) |
| 128 | if index1 >= 0 | 160 | if index1 >= 0 |
| 129 | role2 <- query.atoms filter (_.isRoleAssertion) | 161 | role2 <- queryBody filter (_.isRoleAssertion) |
| 130 | index2 = query.bounded indexOf (role2.getArguments get 2) | 162 | index2 = query.bounded indexOf (role2.getArguments get 2) |
| 131 | if index2 >= 0 | 163 | if index2 >= 0 |
| 132 | } yield Rule.create( | 164 | } yield Rule.create( |
| @@ -134,13 +166,20 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 134 | RSA.ID(RSA(index1), RSA(index2)), | 166 | RSA.ID(RSA(index1), RSA(index2)), |
| 135 | role1 << Forward, | 167 | role1 << Forward, |
| 136 | role2 << Forward, | 168 | role2 << Forward, |
| 137 | not(RSA.Congruent(role1.getArguments get 0, role2.getArguments get 0)) | 169 | not( |
| 170 | TupleTableAtom.create( | ||
| 171 | tts, | ||
| 172 | role1.getArguments get 0, | ||
| 173 | RSA.CONGRUENT, | ||
| 174 | role2.getArguments get 0 | ||
| 175 | ) | ||
| 176 | ) | ||
| 138 | ) | 177 | ) |
| 139 | val r4b = for { | 178 | val r4b = for { |
| 140 | role1 <- query.atoms filter (_.isRoleAssertion) | 179 | role1 <- queryBody filter (_.isRoleAssertion) |
| 141 | index1 = query.bounded indexOf (role1.getArguments get 2) | 180 | index1 = query.bounded indexOf (role1.getArguments get 2) |
| 142 | if index1 >= 0 | 181 | if index1 >= 0 |
| 143 | role2 <- query.atoms filter (_.isRoleAssertion) | 182 | role2 <- queryBody filter (_.isRoleAssertion) |
| 144 | index2 = query.bounded indexOf (role2.getArguments get 0) | 183 | index2 = query.bounded indexOf (role2.getArguments get 0) |
| 145 | if index2 >= 0 | 184 | if index2 >= 0 |
| 146 | } yield Rule.create( | 185 | } yield Rule.create( |
| @@ -148,13 +187,20 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 148 | RSA.ID(RSA(index1), RSA(index2)), | 187 | RSA.ID(RSA(index1), RSA(index2)), |
| 149 | role1 << Forward, | 188 | role1 << Forward, |
| 150 | role2 << Backward, | 189 | role2 << Backward, |
| 151 | not(RSA.Congruent(role1.getArguments get 0, role2.getArguments get 2)) | 190 | not( |
| 191 | TupleTableAtom.create( | ||
| 192 | tts, | ||
| 193 | role1.getArguments get 0, | ||
| 194 | RSA.CONGRUENT, | ||
| 195 | role2.getArguments get 2 | ||
| 196 | ) | ||
| 197 | ) | ||
| 152 | ) | 198 | ) |
| 153 | val r4c = for { | 199 | val r4c = for { |
| 154 | role1 <- query.atoms filter (_.isRoleAssertion) | 200 | role1 <- queryBody filter (_.isRoleAssertion) |
| 155 | index1 = query.bounded indexOf (role1.getArguments get 0) | 201 | index1 = query.bounded indexOf (role1.getArguments get 0) |
| 156 | if index1 >= 0 | 202 | if index1 >= 0 |
| 157 | role2 <- query.atoms filter (_.isRoleAssertion) | 203 | role2 <- queryBody filter (_.isRoleAssertion) |
| 158 | index2 = query.bounded indexOf (role2.getArguments get 0) | 204 | index2 = query.bounded indexOf (role2.getArguments get 0) |
| 159 | if index2 >= 0 | 205 | if index2 >= 0 |
| 160 | } yield Rule.create( | 206 | } yield Rule.create( |
| @@ -162,7 +208,14 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 162 | RSA.ID(RSA(index1), RSA(index2)), | 208 | RSA.ID(RSA(index1), RSA(index2)), |
| 163 | role1 << Backward, | 209 | role1 << Backward, |
| 164 | role2 << Backward, | 210 | role2 << Backward, |
| 165 | not(RSA.Congruent(role1.getArguments get 2, role2.getArguments get 2)) | 211 | not( |
| 212 | TupleTableAtom.create( | ||
| 213 | tts, | ||
| 214 | role1.getArguments get 2, | ||
| 215 | RSA.CONGRUENT, | ||
| 216 | role2.getArguments get 2 | ||
| 217 | ) | ||
| 218 | ) | ||
| 166 | ) | 219 | ) |
| 167 | 220 | ||
| 168 | /** Recursively propagates `rsa:ID` predicate. | 221 | /** Recursively propagates `rsa:ID` predicate. |
| @@ -170,12 +223,12 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 170 | * @note corresponds to rules 5x in Table 3. | 223 | * @note corresponds to rules 5x in Table 3. |
| 171 | */ | 224 | */ |
| 172 | val r5a = for { | 225 | val r5a = for { |
| 173 | role1 <- query.atoms filter (_.isRoleAssertion) | 226 | role1 <- queryBody filter (_.isRoleAssertion) |
| 174 | r1arg0 = role1.getArguments get 0 | 227 | r1arg0 = role1.getArguments get 0 |
| 175 | if query.bounded contains r1arg0 | 228 | if query.bounded contains r1arg0 |
| 176 | r1arg2 = role1.getArguments get 2 | 229 | r1arg2 = role1.getArguments get 2 |
| 177 | if query.bounded contains r1arg2 | 230 | if query.bounded contains r1arg2 |
| 178 | role2 <- query.atoms filter (_.isRoleAssertion) | 231 | role2 <- queryBody filter (_.isRoleAssertion) |
| 179 | r2arg0 = role2.getArguments get 0 | 232 | r2arg0 = role2.getArguments get 0 |
| 180 | if query.bounded contains r2arg0 | 233 | if query.bounded contains r2arg0 |
| 181 | r2arg2 = role2.getArguments get 2 | 234 | r2arg2 = role2.getArguments get 2 |
| @@ -189,18 +242,18 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 189 | RSA(query.bounded indexOf r1arg2), | 242 | RSA(query.bounded indexOf r1arg2), |
| 190 | RSA(query.bounded indexOf r2arg2) | 243 | RSA(query.bounded indexOf r2arg2) |
| 191 | ), | 244 | ), |
| 192 | RSA.Congruent(r1arg0, r2arg0), | 245 | TupleTableAtom.create(tts, r1arg0, RSA.CONGRUENT, r2arg0), |
| 193 | role1 << Forward, | 246 | role1 << Forward, |
| 194 | role2 << Forward, | 247 | role2 << Forward, |
| 195 | not(RSA.NI(r1arg0)) | 248 | not(RSA.NI(r1arg0)) |
| 196 | ) | 249 | ) |
| 197 | val r5b = for { | 250 | val r5b = for { |
| 198 | role1 <- query.atoms filter (_.isRoleAssertion) | 251 | role1 <- queryBody filter (_.isRoleAssertion) |
| 199 | r1arg0 = role1.getArguments get 0 | 252 | r1arg0 = role1.getArguments get 0 |
| 200 | if query.bounded contains r1arg0 | 253 | if query.bounded contains r1arg0 |
| 201 | r1arg2 = role1.getArguments get 2 | 254 | r1arg2 = role1.getArguments get 2 |
| 202 | if query.bounded contains r1arg2 | 255 | if query.bounded contains r1arg2 |
| 203 | role2 <- query.atoms filter (_.isRoleAssertion) | 256 | role2 <- queryBody filter (_.isRoleAssertion) |
| 204 | r2arg0 = role2.getArguments get 0 | 257 | r2arg0 = role2.getArguments get 0 |
| 205 | if query.bounded contains r2arg0 | 258 | if query.bounded contains r2arg0 |
| 206 | r2arg2 = role2.getArguments get 2 | 259 | r2arg2 = role2.getArguments get 2 |
| @@ -214,18 +267,18 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 214 | RSA(query.bounded indexOf r1arg2), | 267 | RSA(query.bounded indexOf r1arg2), |
| 215 | RSA(query.bounded indexOf r2arg0) | 268 | RSA(query.bounded indexOf r2arg0) |
| 216 | ), | 269 | ), |
| 217 | RSA.Congruent(r1arg0, r2arg2), | 270 | TupleTableAtom.create(tts, r1arg0, RSA.CONGRUENT, r2arg2), |
| 218 | role1 << Forward, | 271 | role1 << Forward, |
| 219 | role2 << Backward, | 272 | role2 << Backward, |
| 220 | not(RSA.NI(r1arg0)) | 273 | not(RSA.NI(r1arg0)) |
| 221 | ) | 274 | ) |
| 222 | val r5c = for { | 275 | val r5c = for { |
| 223 | role1 <- query.atoms filter (_.isRoleAssertion) | 276 | role1 <- queryBody filter (_.isRoleAssertion) |
| 224 | r1arg0 = role1.getArguments get 0 | 277 | r1arg0 = role1.getArguments get 0 |
| 225 | if query.bounded contains r1arg0 | 278 | if query.bounded contains r1arg0 |
| 226 | r1arg2 = role1.getArguments get 2 | 279 | r1arg2 = role1.getArguments get 2 |
| 227 | if query.bounded contains r1arg2 | 280 | if query.bounded contains r1arg2 |
| 228 | role2 <- query.atoms filter (_.isRoleAssertion) | 281 | role2 <- queryBody filter (_.isRoleAssertion) |
| 229 | r2arg0 = role2.getArguments get 0 | 282 | r2arg0 = role2.getArguments get 0 |
| 230 | if query.bounded contains r2arg0 | 283 | if query.bounded contains r2arg0 |
| 231 | r2arg2 = role2.getArguments get 2 | 284 | r2arg2 = role2.getArguments get 2 |
| @@ -239,7 +292,7 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 239 | RSA(query.bounded indexOf r1arg0), | 292 | RSA(query.bounded indexOf r1arg0), |
| 240 | RSA(query.bounded indexOf r2arg0) | 293 | RSA(query.bounded indexOf r2arg0) |
| 241 | ), | 294 | ), |
| 242 | RSA.Congruent(r1arg2, r2arg2), | 295 | TupleTableAtom.create(tts, r1arg2, RSA.CONGRUENT, r2arg2), |
| 243 | role1 << Backward, | 296 | role1 << Backward, |
| 244 | role2 << Backward, | 297 | role2 << Backward, |
| 245 | not(RSA.NI(r1arg2)) | 298 | not(RSA.NI(r1arg2)) |
| @@ -254,14 +307,14 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 254 | * @note corresponds to rules 6,7x in Table 3. | 307 | * @note corresponds to rules 6,7x in Table 3. |
| 255 | */ | 308 | */ |
| 256 | val r6 = for { | 309 | val r6 = for { |
| 257 | role <- query.atoms filter (_.isRoleAssertion) | 310 | role <- queryBody filter (_.isRoleAssertion) |
| 258 | index0 = query.bounded indexOf (role.getArguments get 0) | 311 | index0 = query.bounded indexOf (role.getArguments get 0) |
| 259 | if index0 >= 0 | 312 | if index0 >= 0 |
| 260 | index2 = query.bounded indexOf (role.getArguments get 2) | 313 | index2 = query.bounded indexOf (role.getArguments get 2) |
| 261 | if index2 >= 0 | 314 | if index2 >= 0 |
| 262 | suffix <- Seq(Forward, Backward) | 315 | suffix <- Seq(Forward, Backward) |
| 263 | } yield Rule.create( | 316 | } yield Rule.create( |
| 264 | RSA.AQ(varV, varW, suffix), | 317 | RSA.AQ(suffix, varV, varW), |
| 265 | role << suffix, | 318 | role << suffix, |
| 266 | RSA.ID(RSA(index0), varV), | 319 | RSA.ID(RSA(index0), varV), |
| 267 | RSA.ID(RSA(index2), varW) | 320 | RSA.ID(RSA(index2), varW) |
| @@ -269,15 +322,15 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 269 | val r7a = | 322 | val r7a = |
| 270 | for (suffix <- List(Forward, Backward)) | 323 | for (suffix <- List(Forward, Backward)) |
| 271 | yield Rule.create( | 324 | yield Rule.create( |
| 272 | RSA.TQ(varU, varV, suffix), | 325 | RSA.TQ(suffix, varU, varV), |
| 273 | RSA.AQ(varU, varV, suffix) | 326 | RSA.AQ(suffix, varU, varV) |
| 274 | ) | 327 | ) |
| 275 | val r7b = | 328 | val r7b = |
| 276 | for (suffix <- List(Forward, Backward)) | 329 | for (suffix <- List(Forward, Backward)) |
| 277 | yield Rule.create( | 330 | yield Rule.create( |
| 278 | RSA.TQ(varU, varW, suffix), | 331 | RSA.TQ(suffix, varU, varW), |
| 279 | RSA.AQ(varU, varV, suffix), | 332 | RSA.AQ(suffix, varU, varV), |
| 280 | RSA.TQ(varV, varW, suffix) | 333 | RSA.TQ(suffix, varV, varW) |
| 281 | ) | 334 | ) |
| 282 | 335 | ||
| 283 | /** Flag spurious answers. | 336 | /** Flag spurious answers. |
| @@ -286,13 +339,19 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 286 | */ | 339 | */ |
| 287 | val r8a = | 340 | val r8a = |
| 288 | for (v <- query.answer) | 341 | for (v <- query.answer) |
| 289 | yield Rule.create(RSA.SP, RSA.QM, not(RSA.Named(v))) | 342 | yield Rule.create( |
| 343 | RSA.SP, | ||
| 344 | RSA.QM, | ||
| 345 | not( | ||
| 346 | TupleTableAtom.create(tts, v, IRI.RDF_TYPE, RSA.NAMED) | ||
| 347 | ) | ||
| 348 | ) | ||
| 290 | val r8b = Rule.create(RSA.SP, RSA.FK) | 349 | val r8b = Rule.create(RSA.SP, RSA.FK) |
| 291 | val r8c = | 350 | val r8c = |
| 292 | for (suffix <- List(Forward, Backward)) | 351 | for (suffix <- List(Forward, Backward)) |
| 293 | yield Rule.create( | 352 | yield Rule.create( |
| 294 | RSA.SP, | 353 | RSA.SP, |
| 295 | RSA.TQ(varV, varV, suffix) | 354 | RSA.TQ(suffix, varV, varV) |
| 296 | ) | 355 | ) |
| 297 | 356 | ||
| 298 | /** Determine answers to the query | 357 | /** Determine answers to the query |
| @@ -318,9 +377,70 @@ class NaiveFilteringProgram(val graph: String, val query: ConjunctiveQuery) | |||
| 318 | r5a ::: r5b ::: r5c ::: | 377 | r5a ::: r5b ::: r5c ::: |
| 319 | r6 ::: r7b ::: r7a ::: | 378 | r6 ::: r7b ::: r7a ::: |
| 320 | r8a ::: r8b :: r8c ::: | 379 | r8a ::: r8b :: r8c ::: |
| 321 | r9 :: List()) map RDFoxUtil.reify | 380 | r9 :: List()) map reify |
| 322 | } | 381 | } |
| 323 | 382 | ||
| 383 | /** Reify a [[tech.oxfordsemantic.jrdfox.logic.datalog.Rule Rule]]. | ||
| 384 | * | ||
| 385 | * This is needed because RDFox supports only predicates of arity 1 | ||
| 386 | * or 2, but the filtering program uses predicates with higher arity. | ||
| 387 | * | ||
| 388 | * @note we can perform a reification of the atoms thanks to the | ||
| 389 | * built-in `SKOLEM` funtion of RDFox. | ||
| 390 | */ | ||
| 391 | def reify(rule: Rule): Rule = { | ||
| 392 | val (sk, as) = rule.getHead.map(reify).unzip | ||
| 393 | val head: List[TupleTableAtom] = as.flatten | ||
| 394 | val skolem: List[BodyFormula] = sk.flatten | ||
| 395 | val body: List[BodyFormula] = rule.getBody.map(reify).flatten | ||
| 396 | Rule.create(head, skolem ::: body) | ||
| 397 | } | ||
| 398 | |||
| 399 | /** Reify a [[tech.oxfordsemantic.jrdfox.logic.datalog.BodyFormula BodyFormula]]. */ | ||
| 400 | private def reify(formula: BodyFormula): List[BodyFormula] = { | ||
| 401 | formula match { | ||
| 402 | case atom: TupleTableAtom => reify(atom)._2 | ||
| 403 | case neg: Negation => { | ||
| 404 | val (sk, as) = neg.getNegatedAtoms | ||
| 405 | .map({ | ||
| 406 | case a: TupleTableAtom => reify(a) | ||
| 407 | case a => (None, List(a)) | ||
| 408 | }) | ||
| 409 | .unzip | ||
| 410 | val skolem = | ||
| 411 | sk.flatten.map(_.getArguments.last).collect { case v: Variable => v } | ||
| 412 | val atoms = as.flatten | ||
| 413 | List(Negation.create(skolem, atoms)) | ||
| 414 | } | ||
| 415 | case other => List(other) | ||
| 416 | } | ||
| 417 | } | ||
| 418 | |||
| 419 | /** Reify a [[tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom TupleTableAtom]]. */ | ||
| 420 | private def reify(atom: TupleTableAtom)(implicit | ||
| 421 | fresh: DataFactory | ||
| 422 | ): (Option[TupleTableAtom], List[TupleTableAtom]) = { | ||
| 423 | if (atom.getArguments.length == 3) { | ||
| 424 | (None, List(atom)) | ||
| 425 | } else { | ||
| 426 | val varS: Variable = fresh.getVariable | ||
| 427 | val (pred :: args): List[Term] = atom.getArguments | ||
| 428 | val name = pred.asInstanceOf[IRI].getIRI | ||
| 429 | val skolem = TupleTableAtom.create( | ||
| 430 | TupleTableName.SKOLEM, | ||
| 431 | Literal.create(name, Datatype.XSD_STRING) +: args :+ varS | ||
| 432 | ) | ||
| 433 | val triple = | ||
| 434 | TupleTableAtom.create(atom.getTupleTableName, varS, IRI.RDF_TYPE, pred) | ||
| 435 | val triples = args.zipWithIndex | ||
| 436 | .map { case (a, i) => | ||
| 437 | TupleTableAtom.create(atom.getTupleTableName, varS, name :: Nth(i), a) | ||
| 438 | } | ||
| 439 | (Some(skolem), triple :: triples) | ||
| 440 | } | ||
| 441 | } | ||
| 442 | |||
| 324 | val answerQuery = | 443 | val answerQuery = |
| 325 | RDFoxUtil.buildDescriptionQuery(graph, "Ans", query.answer.size) | 444 | RDFoxUtil.buildDescriptionQuery(target, RSA.ANS, query.answer.size) |
| 445 | |||
| 326 | } | 446 | } |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala index ff48f1f..37c70df 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala | |||
| @@ -82,18 +82,18 @@ object RSAAtom { | |||
| 82 | } | 82 | } |
| 83 | } else atom | 83 | } else atom |
| 84 | 84 | ||
| 85 | def reified(implicit | 85 | // def reified(implicit |
| 86 | fresh: DataFactory | 86 | // fresh: DataFactory |
| 87 | ): (Option[TupleTableAtom], List[TupleTableAtom]) = | 87 | // ): (Option[TupleTableAtom], List[TupleTableAtom]) = |
| 88 | if (isRDF) { | 88 | // if (isRDF) { |
| 89 | (None, List(atom)) | 89 | // (None, List(atom)) |
| 90 | } else { | 90 | // } else { |
| 91 | val varS = fresh.getVariable | 91 | // val varS = fresh.getVariable |
| 92 | val skolem = RDFoxUtil.skolem(name, (args :+ varS): _*) | 92 | // val skolem = RDFoxUtil.skolem(name, (args :+ varS): _*) |
| 93 | val atom = TupleTableAtom.rdf(varS, IRI.RDF_TYPE, name) | 93 | // val atom = TupleTableAtom.rdf(varS, IRI.RDF_TYPE, name) |
| 94 | val atoms = args.zipWithIndex | 94 | // val atoms = args.zipWithIndex |
| 95 | .map { case (a, i) => TupleTableAtom.rdf(varS, name :: Nth(i), a) } | 95 | // .map { case (a, i) => TupleTableAtom.rdf(varS, name :: Nth(i), a) } |
| 96 | (Some(skolem), atom :: atoms) | 96 | // (Some(skolem), atom :: atoms) |
| 97 | } | 97 | // } |
| 98 | } | 98 | } |
| 99 | } | 99 | } |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuery.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuery.scala index c405008..73da80f 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuery.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuery.scala | |||
| @@ -19,7 +19,7 @@ package uk.ac.ox.cs.rsacomb.sparql | |||
| 19 | import java.util.{Map => JMap, HashMap => JHashMap} | 19 | import java.util.{Map => JMap, HashMap => JHashMap} |
| 20 | import tech.oxfordsemantic.jrdfox.Prefixes | 20 | import tech.oxfordsemantic.jrdfox.Prefixes |
| 21 | import tech.oxfordsemantic.jrdfox.client.DataStoreConnection | 21 | import tech.oxfordsemantic.jrdfox.client.DataStoreConnection |
| 22 | import tech.oxfordsemantic.jrdfox.logic.datalog.TupleTableAtom | 22 | import tech.oxfordsemantic.jrdfox.logic.datalog.{TupleTableAtom, TupleTableName} |
| 23 | import tech.oxfordsemantic.jrdfox.logic.expression.Variable | 23 | import tech.oxfordsemantic.jrdfox.logic.expression.Variable |
| 24 | import tech.oxfordsemantic.jrdfox.logic.sparql.pattern.{ | 24 | import tech.oxfordsemantic.jrdfox.logic.sparql.pattern.{ |
| 25 | ConjunctionPattern, | 25 | ConjunctionPattern, |
| @@ -99,37 +99,51 @@ class ConjunctiveQuery( | |||
| 99 | val bcq: Boolean = select.isEmpty && !query.getAllPossibleVariables | 99 | val bcq: Boolean = select.isEmpty && !query.getAllPossibleVariables |
| 100 | 100 | ||
| 101 | /** Returns the query body as a sequence of atoms (triples). */ | 101 | /** Returns the query body as a sequence of atoms (triples). */ |
| 102 | val atoms: List[TupleTableAtom] = | 102 | def atoms(graph: TupleTableName): List[TupleTableAtom] = |
| 103 | where match { | 103 | where.collect { case c: ConjunctionPattern => |
| 104 | case b: ConjunctionPattern => { | 104 | c.getConjuncts.collect { case t: TriplePattern => |
| 105 | b.getConjuncts.toList.flatMap { conj: QueryPattern => | 105 | TupleTableAtom |
| 106 | conj match { | 106 | .create(graph, t.getSubject, t.getPredicate, t.getObject) |
| 107 | case c: TriplePattern => | ||
| 108 | Seq( | ||
| 109 | TupleTableAtom.rdf(c.getSubject, c.getPredicate, c.getObject) | ||
| 110 | ) | ||
| 111 | case _ => List() | ||
| 112 | } | ||
| 113 | } | ||
| 114 | } | 107 | } |
| 115 | case _ => List() | 108 | }.flatten |
| 116 | } | 109 | // where match { |
| 110 | // case b: ConjunctionPattern => { | ||
| 111 | // b.getConjuncts.toList.flatMap { conj: QueryPattern => | ||
| 112 | // conj match { | ||
| 113 | // case c: TriplePattern => | ||
| 114 | // Seq( | ||
| 115 | // TupleTableAtom.rdf(c.getSubject, c.getPredicate, c.getObject) | ||
| 116 | // ) | ||
| 117 | // case _ => List() | ||
| 118 | // } | ||
| 119 | // } | ||
| 120 | // } | ||
| 121 | // case _ => List() | ||
| 122 | // } | ||
| 117 | 123 | ||
| 118 | /** Returns the full collection of variables involved in the query. */ | 124 | /** Returns the full collection of variables involved in the query. */ |
| 119 | val variables: List[Variable] = (where match { | 125 | val variables: List[Variable] = |
| 120 | case b: ConjunctionPattern => { | 126 | where.collect { case c: ConjunctionPattern => |
| 121 | b.getConjuncts.toList.flatMap { conj: QueryPattern => | 127 | c.getConjuncts.collect { case t: TriplePattern => |
| 122 | conj match { | 128 | Set(t.getSubject, t.getPredicate, t.getObject).collect { |
| 123 | case c: TriplePattern => | 129 | case v: Variable => v |
| 124 | Set(c.getSubject, c.getPredicate, c.getObject).collect { | ||
| 125 | case v: Variable => v | ||
| 126 | } | ||
| 127 | case _ => List() | ||
| 128 | } | 130 | } |
| 129 | } | 131 | } |
| 130 | } | 132 | }.distinct |
| 131 | case _ => List() | 133 | // (where match { |
| 132 | }).distinct | 134 | // case b: ConjunctionPattern => { |
| 135 | // b.getConjuncts.toList.flatMap { conj: QueryPattern => | ||
| 136 | // conj match { | ||
| 137 | // case c: TriplePattern => | ||
| 138 | // Set(c.getSubject, c.getPredicate, c.getObject).collect { | ||
| 139 | // case v: Variable => v | ||
| 140 | // } | ||
| 141 | // case _ => List() | ||
| 142 | // } | ||
| 143 | // } | ||
| 144 | // } | ||
| 145 | // case _ => List() | ||
| 146 | // }).distinct | ||
| 133 | 147 | ||
| 134 | /** Returns the collection of answer variables in the query. */ | 148 | /** Returns the collection of answer variables in the query. */ |
| 135 | val answer: List[Variable] = | 149 | val answer: List[Variable] = |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxUtil.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxUtil.scala index 568858c..217fa7f 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxUtil.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RDFoxUtil.scala | |||
| @@ -342,8 +342,8 @@ object RDFoxUtil { | |||
| 342 | * @return a string containing a SPARQL query. | 342 | * @return a string containing a SPARQL query. |
| 343 | */ | 343 | */ |
| 344 | def buildDescriptionQuery( | 344 | def buildDescriptionQuery( |
| 345 | graph: String, | 345 | graph: IRI, |
| 346 | pred: String, | 346 | pred: IRI, |
| 347 | arity: Int | 347 | arity: Int |
| 348 | ): String = { | 348 | ): String = { |
| 349 | if (arity > 0) { | 349 | if (arity > 0) { |
| @@ -351,55 +351,12 @@ object RDFoxUtil { | |||
| 351 | s""" | 351 | s""" |
| 352 | SELECT $variables | 352 | SELECT $variables |
| 353 | WHERE { | 353 | WHERE { |
| 354 | GRAPH <$graph> { ?K a rsa:$pred }. | 354 | GRAPH $graph { ?K a $pred }. |
| 355 | TT <http://oxfordsemantic.tech/RDFox#SKOLEM> { $variables ?K } . | 355 | TT ${TupleTableName.SKOLEM} { $variables ?K } . |
| 356 | } | 356 | } |
| 357 | """ | 357 | """ |
| 358 | } else { | 358 | } else { |
| 359 | s"ASK { GRAPH <$graph> { ?X a rsa:Ans } }" | 359 | s"ASK { GRAPH $graph { ?X a $pred } }" |
| 360 | } | ||
| 361 | } | ||
| 362 | |||
| 363 | /** Reify a [[tech.oxfordsemantic.jrdfox.logic.datalog.Rule Rule]]. | ||
| 364 | * | ||
| 365 | * This is needed because RDFox supports only predicates of arity 1 | ||
| 366 | * or 2, but the filtering program uses predicates with higher arity. | ||
| 367 | * | ||
| 368 | * @note we can perform a reification of the atoms thanks to the | ||
| 369 | * built-in `SKOLEM` funtion of RDFox. | ||
| 370 | */ | ||
| 371 | def reify(rule: Rule): Rule = { | ||
| 372 | val (sk, as) = rule.getHead.map(_.reified).unzip | ||
| 373 | val head: List[TupleTableAtom] = as.flatten | ||
| 374 | val skolem: List[BodyFormula] = sk.flatten | ||
| 375 | val body: List[BodyFormula] = rule.getBody.map(reify).flatten | ||
| 376 | Rule.create(head, skolem ::: body) | ||
| 377 | } | ||
| 378 | |||
| 379 | /** Reify a [[tech.oxfordsemantic.jrdfox.logic.datalog.BodyFormula BodyFormula]]. | ||
| 380 | * | ||
| 381 | * This is needed because RDFox supports only predicates of arity 1 | ||
| 382 | * or 2, but the filtering program uses predicates with higher arity. | ||
| 383 | * | ||
| 384 | * @note we can perform a reification of the atoms thanks to the | ||
| 385 | * built-in `SKOLEM` funtion of RDFox. | ||
| 386 | */ | ||
| 387 | private def reify(formula: BodyFormula): List[BodyFormula] = { | ||
| 388 | formula match { | ||
| 389 | case atom: TupleTableAtom => atom.reified._2 | ||
| 390 | case neg: Negation => { | ||
| 391 | val (sk, as) = neg.getNegatedAtoms | ||
| 392 | .map({ | ||
| 393 | case a: TupleTableAtom => a.reified | ||
| 394 | case a => (None, List(a)) | ||
| 395 | }) | ||
| 396 | .unzip | ||
| 397 | val skolem = | ||
| 398 | sk.flatten.map(_.getArguments.last).collect { case v: Variable => v } | ||
| 399 | val atoms = as.flatten | ||
| 400 | List(Negation.create(skolem, atoms)) | ||
| 401 | } | ||
| 402 | case other => List(other) | ||
| 403 | } | 360 | } |
| 404 | } | 361 | } |
| 405 | 362 | ||
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RSA.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RSA.scala index 96d3aa8..40c5ced 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/util/RSA.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/util/RSA.scala | |||
| @@ -42,6 +42,9 @@ import scala.collection.JavaConverters._ | |||
| 42 | 42 | ||
| 43 | object RSA { | 43 | object RSA { |
| 44 | 44 | ||
| 45 | /** Simplify conversion between Java and Scala `List`s */ | ||
| 46 | import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ | ||
| 47 | |||
| 45 | /** Set of default prefixes to be included in all datastore operations */ | 48 | /** Set of default prefixes to be included in all datastore operations */ |
| 46 | val Prefixes: Prefixes = new Prefixes() | 49 | val Prefixes: Prefixes = new Prefixes() |
| 47 | Prefixes.declarePrefix("rsacomb:", "http://www.cs.ox.ac.uk/isg/RSAComb#") | 50 | Prefixes.declarePrefix("rsacomb:", "http://www.cs.ox.ac.uk/isg/RSAComb#") |
| @@ -54,52 +57,69 @@ object RSA { | |||
| 54 | Prefixes.getPrefixIRIsByPrefixName.get("rsacomb:").getIRI + name.toString | 57 | Prefixes.getPrefixIRIsByPrefixName.get("rsacomb:").getIRI + name.toString |
| 55 | ) | 58 | ) |
| 56 | 59 | ||
| 57 | val NAMED = RSA("Named") | 60 | val ANS = RSA("Ans") |
| 58 | val CONGRUENT = RSA("congruent") | 61 | val CONGRUENT = RSA("congruent") |
| 59 | val IN = RSA("In") | 62 | val IN = RSA("In") |
| 63 | val NAMED = RSA("Named") | ||
| 60 | 64 | ||
| 61 | // def In(t: Term)(implicit set: Term) = | 65 | // def In(t: Term)(implicit set: Term) = |
| 62 | // TupleTableAtom.rdf(t, RSA("In"), set) | 66 | // TupleTableAtom.rdf(t, RSA("In"), set) |
| 63 | 67 | ||
| 64 | // def NotIn(t: Term)(implicit set: Term) = Negation.create(In(t)(set)) | 68 | // def NotIn(t: Term)(implicit set: Term) = Negation.create(In(t)(set)) |
| 65 | 69 | ||
| 66 | // def Congruent(t1: Term, t2: Term) = | 70 | def Congruent(t1: Term, t2: Term)(implicit graph: TupleTableName) = |
| 67 | // TupleTableAtom.rdf(t1, RSA("congruent"), t2) | 71 | TupleTableAtom.create(graph, t1, RSA.CONGRUENT, t2) |
| 68 | 72 | ||
| 69 | def QM(implicit q: ConjunctiveQuery) = | 73 | def Named(term: Term)(implicit graph: TupleTableName) = |
| 70 | atom(RSA("QM"), q.answer ::: q.bounded) | 74 | TupleTableAtom.create(graph, term, IRI.RDF_TYPE, RSA.NAMED) |
| 71 | 75 | ||
| 72 | def ID(t1: Term, t2: Term)(implicit q: ConjunctiveQuery) = { | 76 | def QM(implicit query: ConjunctiveQuery, graph: TupleTableName) = |
| 73 | atom(RSA("ID"), (q.answer ::: q.bounded) :+ t1 :+ t2) | 77 | TupleTableAtom.create(graph, RSA("QM") :: query.answer ::: query.bounded) |
| 74 | } | ||
| 75 | 78 | ||
| 76 | def Named(t: Term) = | 79 | def ID(t1: Term, t2: Term)(implicit |
| 77 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, RSA("Named")) | 80 | query: ConjunctiveQuery, |
| 81 | graph: TupleTableName | ||
| 82 | ) = | ||
| 83 | TupleTableAtom.create( | ||
| 84 | graph, | ||
| 85 | RSA("ID") +: (query.answer ::: query.bounded) :+ t1 :+ t2 | ||
| 86 | ) | ||
| 78 | 87 | ||
| 79 | def Thing(t: Term) = | 88 | // def Thing(t: Term) = |
| 80 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, IRI.THING) | 89 | // TupleTableAtom.rdf(t, IRI.RDF_TYPE, IRI.THING) |
| 81 | 90 | ||
| 82 | def NI(t: Term) = | 91 | def NI(term: Term)(implicit graph: TupleTableName) = |
| 83 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, RSA("NI")) | 92 | TupleTableAtom.create(graph, term, IRI.RDF_TYPE, RSA("NI")) |
| 84 | 93 | ||
| 85 | def TQ(t1: Term, t2: Term, sx: RSASuffix)(implicit q: ConjunctiveQuery) = | 94 | def TQ(sx: RSASuffix, t1: Term, t2: Term)(implicit |
| 86 | atom(RSA("TQ" :: sx), (q.answer ::: q.bounded) :+ t1 :+ t2) | 95 | query: ConjunctiveQuery, |
| 96 | graph: TupleTableName | ||
| 97 | ) = | ||
| 98 | TupleTableAtom.create( | ||
| 99 | graph, | ||
| 100 | RSA("TQ" :: sx) +: (query.answer ::: query.bounded) :+ t1 :+ t2 | ||
| 101 | ) | ||
| 87 | 102 | ||
| 88 | def AQ(t1: Term, t2: Term, sx: RSASuffix)(implicit q: ConjunctiveQuery) = | 103 | def AQ(sx: RSASuffix, t1: Term, t2: Term)(implicit |
| 89 | atom(RSA("AQ" :: sx), (q.answer ::: q.bounded) :+ t1 :+ t2) | 104 | query: ConjunctiveQuery, |
| 105 | graph: TupleTableName | ||
| 106 | ) = | ||
| 107 | TupleTableAtom.create( | ||
| 108 | graph, | ||
| 109 | RSA("AQ" :: sx) +: (query.answer ::: query.bounded) :+ t1 :+ t2 | ||
| 110 | ) | ||
| 90 | 111 | ||
| 91 | def FK(implicit q: ConjunctiveQuery) = | 112 | def FK(implicit query: ConjunctiveQuery, graph: TupleTableName) = |
| 92 | atom(RSA("FK"), q.answer ::: q.bounded) | 113 | TupleTableAtom.create(graph, RSA("FK") :: query.answer ::: query.bounded) |
| 93 | 114 | ||
| 94 | def SP(implicit q: ConjunctiveQuery) = | 115 | def SP(implicit q: ConjunctiveQuery, graph: TupleTableName) = |
| 95 | atom(RSA("SP"), q.answer ::: q.bounded) | 116 | TupleTableAtom.create(graph, RSA("SP") :: q.answer ::: q.bounded) |
| 96 | 117 | ||
| 97 | def Ans(implicit q: ConjunctiveQuery) = { | 118 | def Ans(implicit q: ConjunctiveQuery, graph: TupleTableName) = |
| 98 | if (q.bcq) | 119 | if (q.bcq) |
| 99 | TupleTableAtom.rdf(RSA("blank"), IRI.RDF_TYPE, RSA("Ans")) | 120 | TupleTableAtom.create(graph, RSA("blank"), IRI.RDF_TYPE, RSA.ANS) |
| 100 | else | 121 | else |
| 101 | atom(RSA("Ans"), q.answer) | 122 | TupleTableAtom.create(graph, RSA.ANS :: q.answer) |
| 102 | } | ||
| 103 | 123 | ||
| 104 | /* TODO: review after reworking the dependency graph construction */ | 124 | /* TODO: review after reworking the dependency graph construction */ |
| 105 | 125 | ||
