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 | |
parent | bc37ee9293d8a4098edce2a77db6efa3d87b6dd2 (diff) | |
download | RSAComb-360e10e686d144b918825939f48004aebc31b7f3.tar.gz RSAComb-360e10e686d144b918825939f48004aebc31b7f3.zip |
Rework naive filtering program computation to use named graphs
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 | ||