Coverage report: /development/source/library/org/datagraph/spocq-shard/src/store/rlmdb/bgp-filters.lisp
| Kind | Covered | All | % |
| expression | 0 | 1418 | 0.0 |
| branch | 0 | 240 | 0.0 |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;; -*- Mode: lisp; Syntax: ansi-common-lisp; Base: 10; Package: org.datagraph.spocq.implementation; -*-
3
(in-package :org.datagraph.spocq.implementation)
5
(:documentation "Implements comparison logic and compilation
6
for temporal constraints within a bgp.
7
Supports both ordinal and temporal-id visibility maps.")
10
(defun variable-type-information (name env)
11
(multiple-value-bind (type local-p declarations)
12
(variable-information name env)
13
(declare (ignore local-p))
15
(:lexical (rest (assoc 'type declarations))))))
19
(defvar *temporal-continue* )
20
(defvar *temporal-map* )
22
;;; does not all compiler macro
27
(macrolet ((def-version-operator (stem arglist)
28
(let ((ordinal-name (cons-symbol *package* :cw-ordinal-map- stem))
29
(timestamp-name (cons-symbol *package* :cw-timestamp-map- stem))
30
(generic-name (cons-symbol *package* :continue-with-version- stem)))
32
(defgeneric ,generic-name ,arglist
33
(:argument-precedence-order ,(second arglist) ,(first arglist) ,@(cddr arglist))
34
(:method (,(first arglist) (,(second arglist) ordinal-map) ,@(cddr arglist))
35
(,ordinal-name ,@arglist))
36
(:method (,(first arglist) (,(second arglist) vector) ,@(cddr arglist))
37
(,ordinal-name ,@arglist))
38
(:method (,(first arglist) (,(second arglist) timestamp-map) ,@(cddr arglist))
39
(,timestamp-name ,@arglist)))
40
(define-compiler-macro ,generic-name (&whole form ,@arglist &environment env)
41
(case (variable-type-information ',(second arglist) env)
42
((ordinal-map foreign-ordinal-map vector-ordinal-map) (list ',ordinal-name ,@arglist))
43
(vector (list ',ordinal-name ,@arglist))
44
(timestamp-map (list ',timestamp-name ,@arglist))
46
(def-version-operator bounds-head (continue map))
47
(def-version-operator bounds-tail (continue map))
48
(def-version-operator bounds-extent (continue map))
49
(def-version-operator after (continue map start end))
50
(def-version-operator before(continue map start end))
51
(def-version-operator contains (continue map start end))
52
(def-version-operator disjoint (continue map start end))
53
(def-version-operator during (continue map start end))
54
(def-version-operator equals (continue map start end))
55
(def-version-operator finished-by (continue map start end))
56
(def-version-operator finishes (continue map start end))
57
(def-version-operator included-by (continue map start end))
58
(def-version-operator includes (continue map start end))
59
(def-version-operator in (continue map start end))
60
(def-version-operator meets (continue map start end))
61
(def-version-operator met-by (continue map start end))
62
(def-version-operator overlapped-by (continue map start end))
63
(def-version-operator overlaps (continue map start end))
64
(def-version-operator started-by (continue map start end))
65
(def-version-operator starts (continue map start end)))
70
(defmacro with-shadowed-continue (continue-operation expression)
71
`(let ((.continuation *temporal-continue*))
72
(flet ((.continuation (s e)
73
(funcall .continuation s e)
75
(declare (dynamic-extent #'.continuation))
76
(let ((*temporal-continue* #'.continuation))
77
(declare (special *temporal-continue*))
80
(defun compute-interval-lambda (expression)
81
(unless (member (first expression)
82
'(spocq.a:|&&| spocq.a:|and| spocq.a:|\|\|| spocq.a:|or| spocq.a:|!| spocq.a:|not|))
83
(setf expression `(spocq.a:|or| , expression)))
84
`(lambda (_version-continue_ _version-map_)
85
;;(print (list :c *temporal-continue* :m *temporal-map*))
86
(macrolet ((spocq.a:|&&| (&rest args) (list* 'spocq.a:|and| args))
87
(spocq.a:|and| (first &rest rest)
89
(list 'with-shadowed-continue (list* 'spocq.a:|and| rest) first)
91
(spocq.a:|\|\|| (&rest args) (list* 'spocq.a:|or| args))
92
(spocq.a:|or| (&rest rest)
93
(list 'with-shadowed-continue '(return-from :visible-or (values s e)) (list* 'progn rest)))
94
(spocq.a:|!| (arg) (list 'spocq.a:|not| arg))
95
(spocq.a:|not| (expression)
96
"if anything matches, then fail. if nothing matches, then continue."
97
(list 'block :visible-not
98
(list 'let '((*temporal-continue* #'(lambda (s e) (declare (ignore s e)) (return-from :visible-not nil))))
99
'(declare (special *temporal-continue*))
101
'(cw-ordinal-map-bounds-tail *temporal-continue* *temporal-map*))))
104
( (eval `(,(compute-interval-lambda '(spocq.a:|and| (apply *temporal-continue* (print (list 1 *temporal-continue*)))
105
(spocq.a:|not| (print (list 2 *temporal-continue*)))))
106
(lambda (s e) (print (list :outer s e))) #()))
107
(eval `(,(compute-interval-lambda '(spocq.a:|and| (apply *temporal-continue* (print (list 1 *temporal-continue*)))
108
(apply *temporal-continue* (print (list 2 *temporal-continue*)))))
109
(lambda (s e) (print (list :outer s e))) #()))
112
(defmacro with-shadowed-continue (continue-body expression)
113
`(let ((_version-continue_ (lambda (s e)
115
(declare (dynamic-extent _version-continue_))
118
(defmacro with-version-combinations (expression)
119
`(macrolet ((spocq.a:|&&| (&rest args) (list* 'spocq.a:|and| args))
120
(spocq.a:|and| (first &rest rest)
121
"require that all match and continue with the final"
123
(list 'with-shadowed-continue
124
(list '(declare (ignore s e))
126
(list* 'spocq.a:|and| rest))
127
(list 'progn ;; '(print :first-and)
130
(spocq.a:|\|\|| (&rest args) (list* 'spocq.a:|or| args))
131
(spocq.a:|or| (&rest rest)
132
"if any match, continue with it."
133
(list 'block :visible-or
135
(list 'with-shadowed-continue
136
'((funcall _version-continue_ s e)
137
(return-from :visible-or (values s e)))
140
(spocq.a:|!| (arg) (list 'spocq.a:|not| arg))
141
(spocq.a:|not| (expression)
142
"if anything matches, then fail. if nothing matches, then continue."
143
(list 'block :visible-not
144
(list 'let '((_version-continue_ #'(lambda (s e)
145
(declare (ignore s e))
146
;;(print (list :not-fail s e))
147
(return-from :visible-not nil))))
149
;;'(print :not-succeed)
150
'(cw-ordinal-map-bounds-tail _version-continue_ _version-map_))))
151
;;(print (list :version-combination ',expression))
154
(defun compute-interval-lambda (expression)
155
(unless (version-constraint-p expression)
156
(setf expression (if (consp (first expression))
157
`(spocq.a:|or| ,@expression)
158
`(spocq.a:|or| , expression))))
159
`(lambda (_version-continue_ _version-map_)
160
;;(print (list :c *temporal-continue* :m *temporal-map*))
161
(with-version-combinations ,expression)))
163
(macrolet ((def-version-predicate (time spocq)
164
`(defmacro ,time (start &optional (end start) &environment env)
165
(assert (and (eq (variable-information '_version-continue_ env) :lexical)
166
(eq (variable-information '_version-map_ env) :lexical))
168
"no lexical context for ~s." ',time)
169
(list ',spocq '_version-continue_ '_version-map_ start end))))
170
(def-version-predicate |time|:|versionAfter| continue-with-version-after)
171
(def-version-predicate |time|:|versionBefore| continue-with-version-before)
172
(def-version-predicate |time|:|versionContains| continue-with-version-contains)
173
(def-version-predicate |time|:|versionDisjoint| continue-with-version-disjoint)
174
(def-version-predicate |time|:|versionDuring| continue-with-version-during)
175
(def-version-predicate |time|:|versionEquals| continue-with-version-equals)
176
(def-version-predicate |time|:|versionFinishedby| continue-with-version-finished-by)
177
(def-version-predicate |time|:|versionFinishes| continue-with-version-finishes)
178
(def-version-predicate |time|:|versionIncludedby| continue-with-version-included-by)
179
(def-version-predicate |time|:|versionIncludes| continue-with-version-includes)
180
(def-version-predicate |time|:|versionIn| continue-with-version-in)
181
(def-version-predicate |time|:|versionMeets| continue-with-version-meets)
182
(def-version-predicate |time|:|versionMetby| continue-with-version-met-by)
183
(def-version-predicate |time|:|versionOverlappedby| continue-with-version-overlapped-by)
184
(def-version-predicate |time|:|versionOverlaps| continue-with-version-overlaps)
185
(def-version-predicate |time|:|versionStartedby| continue-with-version-started-by)
186
(def-version-predicate |time|:|versionStarts| continue-with-version-starts)
190
(defun compute-interval-lambda (expression)
191
"Given an expression which is a logical combination of allen intervals, rewrite
192
it into a lambda expression which accepts a continuation and a map.
193
if the relation is satisfied, the continuation is invoked with the bounds."
194
(case (first expression)
195
((spocq.a:|some| spocq.a:|every|) )
196
(t (setf expression `(spocq.a:|some| , expression))))
197
`(lambda (continue-op vector)
198
(macrolet ((|time|:|intervalAfter| (start &optional (end start)) (list* 'continue-with-interval-after 'continue-op 'vector start (when end (list end))))
199
(|time|:|intervalBefore| (start &optional (end start)) (list* 'continue-with-interval-before 'continue-op 'vector start (when end (list end))))
200
(|time|:|intervalContains| (start &optional (end start)) (list* 'continue-with-interval-contains 'continue-op 'vector start (when end (list end))))
201
(|time|:|intervalDisjoint| (start &optional (end start)) (list* 'continue-with-interval-disjoint 'continue-op 'vector start (when end (list end))))
202
(|time|:|intervalDuring| (start &optional (end start)) (list* 'continue-with-interval-during 'continue-op 'vector start (when end (list end))))
203
(|time|:|intervalEquals| (start &optional (end start)) (list* 'continue-with-interval-equals 'continue-op 'vector start (when end (list end))))
204
(|time|:|intervalFinishedBy| (start &optional (end start)) (list* 'continue-with-interval-finished-by 'continue-op 'vector start (when end (list end))))
205
(|time|:|intervalFinishes| (start &optional (end start)) (list* 'continue-with-interval-finishes 'continue-op 'vector start (when end (list end))))
206
(|time|:|intervalIncludedBy| (start &optional (end start)) (list* 'continue-with-interval-included-by 'continue-op 'vector start (when end (list end))))
207
(|time|:|intervalIncludes| (start &optional (end start)) (list* 'continue-with-interval-includes 'continue-op 'vector start (when end (list end))))
208
(|time|:|intervalIn| (start &optional (end start)) (list* 'continue-with-interval-in 'continue-op 'vector start (when end (list end))))
209
(|time|:|intervalMeets| (start &optional (end start)) (list* 'continue-with-interval-meets 'continue-op 'vector start (when end (list end))))
210
(|time|:|intervalMetBy| (start &optional (end start)) (list* 'continue-with-interval-met-by 'continue-op 'vector start (when end (list end))))
211
(|time|:|intervalOverlappedBy| (start &optional (end start))(list* 'continue-with-interval-overlapped-by 'continue-op 'vector start (when end (list end))))
212
(|time|:|intervalOverlaps| (start &optional (end start)) (list* 'continue-with-interval-overlaps 'continue-op 'vector start (when end (list end))))
213
(|time|:|intervalStartedBy| (start &optional (end start)) (list* 'continue-with-interval-started-by 'continue-op 'vector start (when end (list end))))
214
(|time|:|intervalStarts| (start &optional (end start)) (list* 'continue-with-interval-starts 'continue-op 'vector start (when end (list end))))
215
(spocq.a:|&&| (&rest args) (list* 'spocq.a:|and| args))
216
(spocq.a:|and| (first &rest rest)
218
(list 'let (list (list 'continue-op (list 'function (list* 'lambda '(s e) '(declare (ignore s e)) (list* 'spocq.a:|and| rest)))))
219
'(declare (dynamic-extent continue-op))
222
(spocq.a:|\|\|| (&rest args) (list* 'spocq.a:|or| args))
223
(spocq.a:|or| (&rest rest)
224
(list 'block :visible-or
225
(list* 'let '((continue-op #'(lambda (s e) (funcall continue-op s e))))
226
'(declare (dynamic-extent continue-op))
228
(spocq.a:|!| (arg) (list 'spocq.a:|not| arg))
229
(spocq.a:|not| (expression)
230
(list 'block :visible-not
231
(list 'let #((continue-op #'(lambda (s e) (declare (ignore s e)) (return-from :visible-not nil))))
232
'(declare (dynamic-extent #'continue-op))
234
'(continue-with-interval-tail continue-op vector)))
236
(spocq.a:|some| (expression)
237
;; return the first satisfying bounds
239
(list 'block :visible-some
240
(list 'let '((continue-op #'(lambda (s e)
241
(funcall continue-op s e)
242
(return-from :visible-some (values s e)))))
243
'(declare (dynamic-extent continue-op))
246
;; require that all satisfy
247
(list 'let '((continue-op #'(lambda (s e)
248
(funcall continue-op s e))))
249
'(declare (dynamic-extent continue-op))
252
;; map over all possibilities
253
(list 'let '((continue-op #'(lambda (s e)
254
(funcall continue-op s e))))
255
'(declare (dynamic-extent continue-op))
261
;;; see https://www.w3.org/TR/owl-time/
264
;;; based on ordinal maps
266
(defgeneric ordinal-map-bounds (map location)
267
(:method ((map vector) location)
268
(multiple-value-bind (true position) (rlmdb.i::test-ordinal-visibility location map (length map))
270
(values (aref map position) (when (< position (1- (length map))) (aref map (1+ position)))))))
271
(:method ((map foreign-ordinal-map) location)
272
(let ((%vector (foreign-ordinal-map-vector map))
273
(length (foreign-ordinal-map-length map)))
274
(multiple-value-bind (true position) (rlmdb.i::%test-visibility location %vector length)
276
(values (cffi:mem-aref %vector :uint32 position)
277
(when (< position (1- length)) (cffi:mem-aref %vector :uint32 (1+ position))))))))
278
(:method ((map vector-ordinal-map) location)
279
(ordinal-map-bounds (vector-ordinal-map-vector map) location)))
282
(defgeneric ordinal-map-bounds-next (map location)
283
(:documentation "Return the bounds for the next visible interval.
284
if the location is visible, this is (+2, +3) from that found.
285
if the location is not visible, this is (+1, +2).
286
return nil for last on an unterminate interval.")
287
(:method ((map vector) location)
288
(multiple-value-bind (true position) (rlmdb.i::test-ordinal-visibility location map (length map))
291
(let* ((next-first (+ position 2))
292
(next-last (1+ next-first)))
293
(when (> (length map) next-first)
294
(values (aref map next-first) (when (> (length map) next-last) (aref map next-last))))))
296
(let* ((next-first (1+ position))
297
(next-last (1+ next-first)))
298
(when (> (length map) next-first)
299
(values (aref map next-first) (when (> (length map) next-last) (aref map next-last))))))
300
(t ; check for prior to first entry
301
(when (> (length map) 0)
302
(values (aref map 0) (when (> (length map) 1) (aref map 1))))))))
303
(:method ((map foreign-ordinal-map) location)
304
(let ((%vector (foreign-ordinal-map-vector map))
305
(length (foreign-ordinal-map-length map)))
306
(multiple-value-bind (true position) (rlmdb.i::%test-visibility location %vector length)
309
(let* ((next-first (+ position 2))
310
(next-last (1+ next-first)))
311
(when (> length next-first)
312
(values (cffi:mem-aref %vector :uint32 next-first)
313
(when (> length next-last) (cffi:mem-aref %vector :uint32 next-last))))))
315
(let* ((next-first (1+ position))
316
(next-last (1+ next-first)))
317
(when (> length next-first)
318
(values (cffi:mem-aref %vector :uint32 next-first)
319
(when (> length next-last) (cffi:mem-aref %vector :uint32 next-last))))))
320
(t ; check for prior to first entry
322
(values (cffi:mem-aref %vector :uint32 0)
323
(when (> length 1) (cffi:mem-aref %vector :uint32 1)))))))))
324
(:method ((map vector-ordinal-map) location)
325
(ordinal-map-bounds-next (vector-ordinal-map-vector map) location)))
329
(defgeneric ordinal-map-bounds-previous (map location)
330
(:documentation "Return the bounds for the previous visible interval.
331
if the location is visible, this is (-2, -1) from that found.
332
if the location is not visible, this is (-1, 0).")
333
(:method ((map vector) location)
334
(multiple-value-bind (true position) (rlmdb.i::test-ordinal-visibility location map (length map))
336
(when (>= position 2)
337
(values (aref map (- position 2)) (aref map (- position 1)))))
339
(when (>= position 1)
340
(values (aref map (- position 1)) (aref map position))))
343
(:method ((map foreign-ordinal-map) location)
344
(let ((%vector (foreign-ordinal-map-vector map))
345
(length (foreign-ordinal-map-length map)))
346
(multiple-value-bind (true position) (rlmdb.i::%test-visibility location %vector length)
348
(when (>= position 2)
349
(values (cffi:mem-aref %vector :uint32 (- position 2)) (cffi:mem-aref %vector :uint32 (- position 1)))))
351
(when (>= position 1)
352
(values (cffi:mem-aref %vector :uint32 (- position 1)) (cffi:mem-aref %vector :uint32 position))))
355
(:method ((map vector-ordinal-map) location)
356
(ordinal-map-bounds-previous (vector-ordinal-map-vector map) location)))
358
(defgeneric ordinal-map-bounds-previous-exclusive (map location)
359
(:documentation "Return the bounds for the previous visible interval
360
- excluding one for which the location is the end
361
if the location is visible, this is (-2, -1) from that found.
362
if the location is not visible, this is (-1, 0) or (-3, -2) for an exact end.
363
return nil for last on an unterminate interval.")
364
(:method ((map vector) location)
365
(multiple-value-bind (true position) (rlmdb.i::test-ordinal-visibility location map (length map))
367
(when (>= position 2)
368
(values (aref map (- position 2)) (aref map (- position 1)))))
370
(if (= location (aref map position))
371
(when (>= position 3)
372
(values (aref map (- position 3)) (aref map (- position 2))))
373
(when (>= position 1)
374
(values (aref map (- position 1)) (aref map position)))))
377
(:method ((map foreign-ordinal-map) location)
378
(let ((%vector (foreign-ordinal-map-vector map))
379
(length (foreign-ordinal-map-length map)))
380
(multiple-value-bind (true position) (rlmdb.i::%test-visibility location %vector length)
382
(when (>= position 2)
383
(values (cffi:mem-aref %vector :uint32 (- position 2)) (cffi:mem-aref %vector :uint32 (- position 1)))))
385
(if (= location (cffi:mem-aref %vector :uint32 position))
386
(when (>= position 3)
387
(values (cffi:mem-aref %vector :uint32 (- position 3)) (cffi:mem-aref %vector :uint32 (- position 2))))
388
(when (>= position 1)
389
(values (cffi:mem-aref %vector :uint32 (- position 1)) (cffi:mem-aref %vector :uint32 position)))))
392
(:method ((map vector-ordinal-map) location)
393
(ordinal-map-bounds-previous-exclusive (vector-ordinal-map-vector map) location)))
396
(defgeneric cw-ordinal-map-bounds-head (continue map)
397
(:documentation "if visible at head, continue with that location and nil as the interval bounds.")
398
(:method (continue (map vector))
399
(when (oddp (length map))
400
(funcall continue (aref map (1- (length map))) nil)))
401
(:method (continue (map foreign-ordinal-map))
402
(let ((%vector (foreign-ordinal-map-vector map))
403
(length (foreign-ordinal-map-length map)))
405
(funcall continue (cffi:mem-aref %vector :uint32 (1- length)) nil))))
406
(:method (continue (map vector-ordinal-map))
407
(cw-ordinal-map-bounds-head continue (vector-ordinal-map-vector map))))
410
(defgeneric cw-ordinal-map-bounds-tail (continue map)
411
(:documentation "if visible at all, continue with first location and possible interval bounds.")
412
(:method (continue (map vector))
413
(when (plusp (length map))
414
(funcall continue (aref map 0) (when (> (length map) 1) (aref map 1)))))
415
(:method (continue (map foreign-ordinal-map))
416
(let ((%vector (foreign-ordinal-map-vector map))
417
(length (foreign-ordinal-map-length map)))
418
(funcall continue (cffi:mem-aref %vector :uint32 0)
419
(when (> length 1) (cffi:mem-aref %vector :uint32 1)))))
420
(:method (continue (map vector-ordinal-map))
421
(cw-ordinal-map-bounds-tail continue (vector-ordinal-map-vector map))))
423
(defgeneric cw-ordinal-map-bounds-extent (continue map)
424
(:documentation "if visible at all, continue with two values:
426
- if removed at end then the last visible bounds, otherwise nil")
427
(:method (continue (map vector))
428
(let ((length (length map)))
433
(aref map (1- length)))))))
434
(:method (continue (map foreign-ordinal-map))
435
(let ((%vector (foreign-ordinal-map-vector map))
436
(length (foreign-ordinal-map-length map)))
439
(cffi:mem-aref %vector :uint32 0)
441
(cffi:mem-aref %vector :uint32 (1- length)))))))
442
(:method (continue (map vector-ordinal-map))
443
(cw-ordinal-map-bounds-extent continue (vector-ordinal-map-vector map))))
447
;;; interval match operators
449
(defun cw-ordinal-map-after (continue map start &optional (end start))
450
"visible after, but not at, end
451
return the visible bounds"
452
(declare (ignore start))
453
(multiple-value-bind (v-start v-end) (ordinal-map-bounds-next map end)
455
(funcall continue v-start v-end))))
457
(defun cw-ordinal-map-before (continue map start &optional (end start))
458
"visible before, but not at, start
459
return the visible bounds"
460
(declare (ignore end))
461
(multiple-value-bind (v-start v-end) (ordinal-map-bounds-previous-exclusive map start)
463
(funcall continue v-start v-end))))
466
(defun cw-ordinal-map-contains (continue map start &optional (end start))
467
"map contains an interval which is visible at start and visible before start and after end, but not at either
468
return the visible bounds"
469
(multiple-value-bind (v-start v-end) (ordinal-map-bounds map start)
473
(funcall continue v-start v-end))))
475
(defun cw-ordinal-map-disjoint (continue vector start &optional (end start))
476
"not visible at start but visible after, but not at, end
477
= (and (not at) (or meets met-by)) - not beforeafter
478
return the previous and following"
479
(when (not (ordinal-map-bounds vector start))
480
(multiple-value-bind (v-start v-end) (ordinal-map-bounds-previous vector start)
481
(if (and v-end (<= v-end start))
482
(funcall continue v-start v-end)
483
(multiple-value-bind (v-start v-end) (ordinal-map-bounds-next vector end)
484
(when (and v-start (>= v-start end))
485
(funcall continue v-start v-end)))))))
487
;;; (trace ordinal-map-disjoint statement-visibility-next-bounds statement-visibility-previous-bounds)
489
(defun cw-ordinal-map-during (continue map start &optional (end start))
490
"neither visible at start nor at end but visible after start and before end
491
return the first visible bounds"
492
(when (not (ordinal-map-bounds map start))
493
(multiple-value-bind (v-start v-end) (ordinal-map-bounds-next map start)
494
(when (and v-start (> v-start start) (< v-end end))
495
(funcall continue v-start v-end)))))
497
(defun cw-ordinal-map-equals (continue map start &optional (end start))
498
"visible with equal bounds
500
(multiple-value-bind (v-start v-end) (ordinal-map-bounds map start)
501
(when (and v-start (= v-start start) (= v-end end))
502
(funcall continue v-start v-end))))
505
(defun cw-ordinal-map-finished-by (continue map start &optional (end start))
506
"visible before start and up to end
507
yield the visible bounds"
508
(multiple-value-bind (v-start v-end) (ordinal-map-bounds map start)
509
(when (and v-start (< v-start start) (= v-end end))
510
(funcall continue v-start v-end))))
512
(defun cw-ordinal-map-finishes (continue map start &optional (end start))
513
"visible after start and up to end
514
yield the visible bounds"
515
(multiple-value-bind (v-start v-end) (ordinal-map-bounds-next map start)
516
(when (and v-start (> v-start start) (= v-end end))
517
(funcall continue v-start v-end))))
520
(defun cw-ordinal-map-in (continue map start &optional (end start))
521
"visible at start or later and at end or earlier, but not both at
522
return the first visible bounds
523
https://www.w3.org/TR/owl-time/#time:intervalIn"
524
(multiple-value-bind (v-start v-end) (ordinal-map-bounds map start)
526
(if (= v-start start)
527
(when (< v-end end) (funcall continue v-start v-end)
528
(when (<= v-end end) (funcall continue v-start v-end))))
529
(multiple-value-bind (v-start v-end) (ordinal-map-bounds-next map start)
531
(when (<= v-end end) (funcall continue v-start v-end)))))))
533
(defun cw-ordinal-map-included-by (continue map start &optional (end start))
534
"visible on or after start and up to at or before end
535
yield the visible bounds
536
nb. extenion to allen's intervals to simplify the compound relation"
537
(multiple-value-bind (v-start v-end) (ordinal-map-bounds-next map start)
538
(when (and v-start (>= v-start start) (<= v-end end))
539
(funcall continue v-start v-end))))
541
(defun cw-ordinal-map-includes (continue map start &optional (end start))
542
"visible at or before start and up to or after end
543
yield the visible bounds
544
nb. extenion to allen's intervals to simplify the compound relation"
545
(multiple-value-bind (v-start v-end) (ordinal-map-bounds map start)
546
(when (and v-start (<= v-start start)
547
(or (null v-end) (and end (>= v-end end))))
548
(funcall continue v-start v-end))))
550
(defun cw-ordinal-map-meets (continue map start &optional end)
552
return the first visible bounds"
553
(declare (ignore end))
554
(multiple-value-bind (v-start v-end) (ordinal-map-bounds-previous map start)
555
(when (and v-end (= v-end start))
556
(funcall continue v-start v-end))))
558
(defun cw-ordinal-map-met-by (continue map start &optional (end start))
560
yield the first visible bounds"
561
(multiple-value-bind (v-start v-end) (ordinal-map-bounds map end)
562
(when (and v-start (= v-start end))
563
(funcall continue v-start v-end))))
566
(defun cw-ordinal-map-overlapped-by (continue map start &optional (end start))
567
"visible within bounds and after
568
yield the visible bounds
569
https://www.w3.org/TR/owl-time/#time:intervalOverlappedBy"
570
(multiple-value-bind (v-start v-end) (ordinal-map-bounds map end)
571
(when (and v-start (> v-start start) (< v-start end) (> v-end end))
572
(funcall continue v-start v-end))))
574
(defun cw-ordinal-map-overlaps (continue map start &optional (end start))
575
"visible within bounds and before
576
yield the visible bounds
577
https://www.w3.org/TR/owl-time/#time:intervalOverlappedBy"
578
(multiple-value-bind (v-start v-end) (ordinal-map-bounds map start)
579
(when (and v-start (< v-start start) (> v-end start) (< v-end end))
580
(funcall continue v-start v-end))))
583
(defun cw-ordinal-map-started-by (continue map start &optional (end start))
584
"visible from start until after end
585
yield the visible bounds"
586
(multiple-value-bind (v-start v-end) (ordinal-map-bounds map start)
587
(when (and v-start (= v-start start) (> v-end end))
588
(funcall continue v-start v-end))))
590
(defun cw-ordinal-map-starts (continue map start &optional (end start))
591
"visible from start until before end
592
yield the visible bounds"
593
(multiple-value-bind (v-start v-end) (ordinal-map-bounds map start)
594
(when (and v-start (= v-start start) (< v-end end))
595
(funcall continue v-start v-end))))
598
;;; base on temporal-id map of only
600
(defgeneric timestamp-map-bounds (map location)
601
(:method ((map vector) location)
602
(multiple-value-bind (true position) (test-uuid-visibility location map)
604
(values (aref map position) (when (< position (1- (length map))) (aref map (1+ position)))))))
605
(:method ((map timestamp-map) location)
606
(timestamp-map-bounds (timestamp-map-vector map) location)))
609
(defgeneric timestamp-map-bounds-next (map location)
610
(:documentation "Return the bounds for the next visible interval.
611
if the location is visible, this is (+2, +3) from that found.
612
if the location is not visible, this is (+1, +2).
613
return nil for last on an unterminate interval.")
614
(:method ((map vector) location)
615
(multiple-value-bind (true position) (rlmdb.i::test-ordinal-visibility location map (length map))
618
(let* ((next-first (+ position 2))
619
(next-last (1+ next-first)))
620
(when (> (length map) next-first)
621
(values (aref map next-first) (when (> (length map) next-last) (aref map next-last))))))
623
(let* ((next-first (1+ position))
624
(next-last (1+ next-first)))
625
(when (> (length map) next-first)
626
(values (aref map next-first) (when (> (length map) next-last) (aref map next-last))))))
627
(t ; check for prior to first entry
628
(when (> (length map) 0)
629
(values (aref map 0) (when (> (length map) 1) (aref map 1))))))))
630
(:method ((map timestamp-map) location)
631
(timestamp-map-bounds-next (timestamp-map-vector map) location)))
634
(defgeneric timestamp-map-bounds-previous (map location)
635
(:documentation "Return the bounds for the previous visible interval.
636
if the location is visible, this is (-2, -1) from that found.
637
if the location is not visible, this is (-1, 0).")
638
(:method ((map vector) location)
639
(multiple-value-bind (true position) (rlmdb.i::test-ordinal-visibility location map (length map))
641
(when (>= position 2)
642
(values (aref map (- position 2)) (aref map (- position 1)))))
644
(when (>= position 1)
645
(values (aref map (- position 1)) (aref map position))))
648
(:method ((map timestamp-map) location)
649
(timestamp-map-bounds-previous (timestamp-map-vector map) location)))
651
(defgeneric timestamp-map-bounds-previous-exclusive (map location)
652
(:documentation "Return the bounds for the previous visible interval
653
- excluding one for which the location is the end
654
if the location is visible, this is (-2, -1) from that found.
655
if the location is not visible, this is (-1, 0) or (-3, -2) for an exact end.
656
return nil for last on an unterminate interval.")
657
(:method ((map vector) location)
658
(multiple-value-bind (true position) (rlmdb.i::test-ordinal-visibility location map (length map))
660
(when (>= position 2)
661
(values (aref map (- position 2)) (aref map (- position 1)))))
663
(if (= location (aref map position))
664
(when (>= position 3)
665
(values (aref map (- position 3)) (aref map (- position 2))))
666
(when (>= position 1)
667
(values (aref map (- position 1)) (aref map position)))))
670
(:method ((map timestamp-map) location)
671
(timestamp-map-bounds-previous-exclusive (timestamp-map-vector map) location)))
674
(defgeneric cw-timestamp-map-bounds-head (continue map)
675
(:documentation"if visible at head, return that location and nil as the interval bounds.
676
returns just the single interval.")
677
(:method (continue (map vector))
678
(let ((insert-position (position-if #'insert-uuid-p map :from-end t)))
679
(when insert-position
681
(aref map insert-position)
682
(find-if #'delete-uuid-p map :start (1+ insert-position))))))
683
(:method (continue (map timestamp-map))
684
(cw-timestamp-map-bounds-head continue (timestamp-map-vector map))))
687
(defgeneric cw-timestamp-map-bounds-tail (continue map)
688
(:documentation "if visible at all, return the first location and possible interval bounds.
689
returns just the single interval.")
690
(:method (continue (map vector))
691
(let ((insert-position (position-if #'insert-uuid-p map)))
692
(when insert-position
694
(aref map insert-position)
695
(find-if #'delete-uuid-p map :start (1+ insert-position))))))
696
(:method (continue (map timestamp-map))
697
(cw-timestamp-map-bounds-tail continue (timestamp-map-vector map))))
699
(defgeneric cw-timestamp-map-bounds-extent (continue map)
700
(:documentation "if visible at all, continue with two values:
702
- if removed at end then the last visible bounds, otherwise nil")
703
(:method (continue (map vector))
704
(let ((insert-entry (find-if #'insert-uuid-p map)))
708
(when (> (length map) 1)
709
(let ((last-entry (aref map (1- (length map)))))
710
(when (delete-uuid-p last-entry)
712
(:method (continue (map timestamp-map))
713
(cw-timestamp-map-bounds-extent continue (timestamp-map-vector map))))
716
;;; interval match operators
718
(defun cw-timestamp-map-after (continue map start &optional (end start))
719
"visible after, but not at, end
720
return the visible bounds"
721
(declare (ignore start))
722
(multiple-value-bind (v-start v-end) (timestamp-map-bounds-next map end)
724
(funcall continue v-start v-end))))
726
(defun cw-timestamp-map-before (continue map start &optional (end start))
727
"visible before, but not at, start
728
return the visible bounds"
729
(declare (ignore end))
730
(multiple-value-bind (v-start v-end) (timestamp-map-bounds-previous-exclusive map start)
732
(funcall continue v-start v-end))))
735
(defun cw-timestamp-map-contains (continue map start &optional (end start))
736
"map contains an interval which is visible at start and visible before start and after end, but not at either
737
return the visible bounds"
738
(multiple-value-bind (v-start v-end) (ordinal-map-bounds map start)
742
(funcall continue v-start v-end))))
744
(defun cw-timestamp-map-disjoint (continue vector start &optional (end start))
745
"not visible at start but visible after, but not at, end
746
= (and (not at) (or meets met-by)) - not beforeafter
747
return the previous and following"
748
(when (not (timestamp-map-bounds vector start))
749
(multiple-value-bind (v-start v-end) (timestamp-map-bounds-previous vector start)
750
(if (and v-end (<= v-end start))
751
(funcall continue v-start v-end)
752
(multiple-value-bind (v-start v-end) (timestamp-map-bounds-next vector end)
753
(when (and v-start (>= v-start end))
754
(funcall continue v-start v-end)))))))
756
;;; (trace timestamp-map-disjoint statement-visibility-next-bounds statement-visibility-previous-bounds)
758
(defun cw-timestamp-map-during (continue map start &optional (end start))
759
"neither visible at start nor at end but visible after start and before end
760
return the first visible bounds"
761
(when (not (timestamp-map-bounds map start))
762
(multiple-value-bind (v-start v-end) (timestamp-map-bounds-next map start)
763
(when (and v-start (> v-start start) (< v-end end))
764
(funcall continue v-start v-end)))))
766
(defun cw-timestamp-map-equals (continue map start &optional (end start))
767
"visible with equal bounds
769
(multiple-value-bind (v-start v-end) (timestamp-map-bounds map start)
770
(when (and v-start (= v-start start) (= v-end end))
771
(funcall continue v-start v-end))))
774
(defun cw-timestamp-map-finished-by (continue map start &optional (end start))
775
"visible before start and up to end
776
yield the visible bounds"
777
(multiple-value-bind (v-start v-end) (timestamp-map-bounds map start)
778
(when (and v-start (< v-start start) (= v-end end))
779
(funcall continue v-start v-end))))
781
(defun cw-timestamp-map-finishes (continue map start &optional (end start))
782
"visible after start and up to end
783
yield the visible bounds"
784
(multiple-value-bind (v-start v-end) (timestamp-map-bounds-next map start)
785
(when (and v-start (> v-start start) (= v-end end))
786
(funcall continue v-start v-end))))
789
(defun cw-timestamp-map-in (continue map start &optional (end start))
790
"visible at start or later and at end or earlier, but not both at
791
return the first visible bounds
792
https://www.w3.org/TR/owl-time/#time:intervalIn"
793
(multiple-value-bind (v-start v-end) (timestamp-map-bounds map start)
795
(if (= v-start start)
796
(when (< v-end end) (funcall continue v-start v-end)
797
(when (<= v-end end) (funcall continue v-start v-end))))
798
(multiple-value-bind (v-start v-end) (timestamp-map-bounds-next map start)
800
(when (<= v-end end) (funcall continue v-start v-end)))))))
802
(defun cw-timestamp-map-included-by (continue map start &optional (end start))
803
"visible on or after start and up to at or before end
804
yield the visible bounds"
805
(multiple-value-bind (v-start v-end) (timestamp-map-bounds-next map start)
806
(when (and v-start (>= v-start start) (<= v-end end))
807
(funcall continue v-start v-end))))
809
(defun cw-timestamp-map-includes (continue map start &optional (end start))
810
"visible at or before start and up to or after end
811
yield the visible bounds"
812
(multiple-value-bind (v-start v-end) (timestamp-map-bounds map start)
813
(when (and v-start (<= v-start start) (>= v-end end))
814
(funcall continue v-start v-end))))
816
(defun cw-timestamp-map-meets (continue map start &optional end)
818
return the first visible bounds"
819
(declare (ignore end))
820
(multiple-value-bind (v-start v-end) (timestamp-map-bounds-previous map start)
821
(when (and v-end (= v-end start))
822
(funcall continue v-start v-end))))
824
(defun cw-timestamp-map-met-by (continue map start &optional (end start))
826
yield the first visible bounds"
827
(multiple-value-bind (v-start v-end) (timestamp-map-bounds map end)
828
(when (and v-start (= v-start end))
829
(funcall continue v-start v-end))))
832
(defun cw-timestamp-map-overlapped-by (continue map start &optional (end start))
833
"visible within bounds and after
834
yield the visible bounds
835
https://www.w3.org/TR/owl-time/#time:intervalOverlappedBy"
836
(multiple-value-bind (v-start v-end) (timestamp-map-bounds map end)
837
(when (and v-start (> v-start start) (< v-start end) (> v-end end))
838
(funcall continue v-start v-end))))
840
(defun cw-timestamp-map-overlaps (continue map start &optional (end start))
841
"visible within bounds and before
842
yield the visible bounds
843
https://www.w3.org/TR/owl-time/#time:intervalOverlappedBy"
844
(multiple-value-bind (v-start v-end) (timestamp-map-bounds map start)
845
(when (and v-start (< v-start start) (> v-end start) (< v-end end))
846
(funcall continue v-start v-end))))
849
(defun cw-timestamp-map-started-by (continue map start &optional (end start))
850
"visible from start until after end
851
yield the visible bounds"
852
(multiple-value-bind (v-start v-end) (timestamp-map-bounds map start)
853
(when (and v-start (= v-start start) (> v-end end))
854
(funcall continue v-start v-end))))
856
(defun cw-timestamp-map-starts (continue map start &optional (end start))
857
"visible from start until before end
858
yield the visible bounds"
859
(multiple-value-bind (v-start v-end) (timestamp-map-bounds map start)
860
(when (and v-start (= v-start start) (< v-end end))
861
(funcall continue v-start v-end))))
866
(defun test-visibility-map (continue-op map relation)
867
(declare (dynamic-extent continue-op))
868
(destructuring-bind (op . args) relation
870
(|time|:|intervalAfter| (apply #'match-statement-visibility-after continue-op map args))
871
(|time|:|intervalBefore| (apply #'match-statement-visibility-before continue-op map args))
872
(|time|:|intervalContains| (apply #'match-statement-visibility-contains continue-op map args))
873
(|time|:|intervalDisjoint| (apply #'match-statement-visibility-disjoint continue-op map args))
874
(|time|:|intervalDuring| (apply #'match-statement-visibility-during continue-op map args))
875
(|time|:|intervalEquals| (apply #'match-statement-visibility-equals continue-op map args))
876
(|time|:|intervalFinishedBy| (apply #'match-statement-visibility-finished-by continue-op map args))
877
(|time|:|intervalFinishes| (apply #'match-statement-visibility-finishes continue-op map args))
878
(|time|:|intervalIncludedBy| (apply #'match-statement-visibility-included-by continue-op map args))
879
(|time|:|intervalIncludes| (apply #'match-statement-visibility-includes continue-op map args))
880
(|time|:|intervalIn| (apply #'match-statement-visibility-in continue-op map args))
881
(|time|:|intervalMeets| (apply #'match-statement-visibility-meets continue-op map args))
882
(|time|:|intervalMetBy| (apply #'match-statement-visibility-met-by continue-op map args))
883
(|time|:|intervalOverlappedBy| (apply #'match-statement-visibility-overlapped-by continue-op map args))
884
(|time|:|intervalOverlaps| (apply #'match-statement-visibility-overlaps continue-op map args))
885
(|time|:|intervalStartedBy| (apply #'match-statement-visibility-started-by continue-op map args))
886
(|time|:|intervalStarts| (apply #'match-statement-visibility-starts continue-op map args))
887
((spocq.a:|and| spocq.a:|&&|)
888
(destructuring-bind (first &rest rest) args
890
(flet ((continue-op (start end)
891
(declare (ignore start end))
892
(test-visibility-map continue-op map `(spocq.a:|and| ,@rest))))
893
(declare (dynamic-extent #'continue-op))
894
(test-visibility-map #'continue-op map first))
895
(test-visibility-map continue-op map first))))
896
((spocq.a:|or| spocq.a:|\|\||)
897
(flet ((continue-op (start end)
898
(funcall continue-op start end)))
899
(declare (dynamic-extent #'continue-op))
900
(loop for expression in args
901
do (test-visibility-map #'continue-op map expression))))
902
((spocq.a:|not| spocq.a:|!|)
903
(flet ((continue-op (start end)
904
(declare (ignore start end))
905
(return-from test-visibility-map nil)))
906
(declare (dynamic-extent #'continue-op))
907
(test-visibility-map #'continue-op map (first args)))
908
;; if it does not match, invoke the continuation with the tail revision
909
(match-statement-visibility-tail continue-op map))
911
((spocq.a:|some| (flet ((some-continue (start end)
912
;; return the first satisfying bounds
913
(return-from test-visibility-map (funcall continue-op start end))))
914
(declare (dynamic-extent #'some-continue))
915
(test-visibility-map #'continue-op map (first args))
917
((spocq.a:|every| (flet ((some-continue (start end)
918
;; return all satisfying bounds
919
(funcall continue-op start end)))
920
(declare (dynamic-extent #'some-continue))
921
(test-visibility-map #'continue-op map (first args))
924
;;; not actually used in this form, but required in order that
925
;;; the filter expressions do permit the operators when parsed
926
(macrolet ((defTemporal (name implementation)
927
`(defmacro ,name (start &optional end)
928
(list* ',implementation '(function values)
929
'*statement-visibility-map* start (when end (list end))))))
930
(defTemporal |time|:|intervalAfter| match-statement-visibility-after)
931
(defTemporal |time|:|intervalBefore| match-statement-visibility-before)
932
(defTemporal |time|:|intervalContains| match-statement-visibility-contains)
933
(defTemporal |time|:|intervalDisjoint| match-statement-visibility-disjoint)
934
(defTemporal |time|:|intervalDuring| match-statement-visibility-during)
935
(defTemporal |time|:|intervalEquals| match-statement-visibility-equals)
936
(defTemporal |time|:|intervalFinishedBy| match-statement-visibility-finished-by)
937
(defTemporal |time|:|intervalFinishes| match-statement-visibility-finishes)
938
(defTemporal |time|:|intervalIncludedBy| match-statement-visibility-include-by)
939
(defTemporal |time|:|intervalIncludes| match-statement-visibility-includes)
940
(defTemporal |time|:|intervalIn| match-statement-visibility-in)
941
(defTemporal |time|:|intervalMeets| match-statement-visibility-meets)
942
(defTemporal |time|:|intervalMetBy| match-statement-visibility-met-by)
943
(defTemporal |time|:|intervalOverlappedBy| match-statement-visibility-overlapped-by)
944
(defTemporal |time|:|intervalOverlaps| match-statement-visibility-overlaps)
945
(defTemporal |time|:|intervalStartedBy| match-statement-visibility-started-by)
946
(defTemporal |time|:|intervalStarts| match-statement-visibility-starts)
950
(defgeneric compute-visibility-filter-lambda (context filters bindings)
952
"Translate the visibility filters and explicit bindings into a closure of two arguments,
953
the visibility map and a continuation.
954
- Leave free variables to close over the bgp function's lexical bindings for any dynamic variables.
955
- Arrange for the attribute accessors to return the appropriate temporal entity as an argument to predicates.
956
- Interpret the predicate expression based on the visibility map.
957
- Iff the map satisfies the constraint, then marshall any attributes for which an explicit bind is present,
958
intern them to yield term numbers, and call the continuation with them.
960
The bgp context arranges to accept them and bind them to the respective variable.
962
Should work for cross-statement comparisons as the respective maps have dynamic extent, but how?")
964
(:method ((context repository) (filters cons) (bindings list))
965
"should specialize (versioned) repository from replicable repository
966
in order to supply the same entities from different maps."
967
(let ((test (spocq.i::compute-interval-lambda filters))
968
(bound-attributes (compute-temporal-entities bindings 'visibility-map 'start 'end)))
969
`(lambda (visibility-map continuation)
970
(flet ((call-with-temporal-entities (start end)
971
(funcall continuation ,@temporal-entities)))
972
(,test visibility-map #'call-with-temporal-entities))))))
974
(defun compute-temporal-entities (bindings map start end)
975
(let ((forms (mapcar #'third (sort #'string-lessp bindings :key #'second))))
976
(loop for (op . args) in forms
977
;do (assert (and (revision-accessor-p op) (= (length args) 1)) () "invalid revision accessor")
978
collect `(,op ,map ,start ,end))))
980
(defgeneric |time|:|intervalAfter| (entity1 entity2)
981
(:documentation "True iff entity1 begins after the end of entity2")
982
(:method ((i1 spocq:interval) (i2 spocq:interval))
983
(time> (spocq:interval-start i1) (spocq:interval-end i2)))
984
(:method ((e1 spocq:interval) (position t))
985
(time> (spocq:interval-start i1) position))
986
(:method ((position t) (e2 spocq:interval))
987
(time> position (spocq:interval-end i2)))
988
(:method ((e1 t) (e2 t))
991
(defgeneric time< (t1 t2)
992
(:method ((t1 integer) (t2 integer))
994
(:method ((t1 spocq:temporal) (t2 spocq:temporal))
995
(< (timeline-location t1) (timeline-location t2)))
996
(:method ((t1 vector) (t2 vector))
997
(when (and (uuid-p t1) (uuid-p t2))
998
(< (uuid-timestamp t1) (uuid-timestamp t2))))
999
(:method ((t1 t) (t2 null))
1001
(:method ((t1 t) (t2 t))
1004
(defgeneric |time|:|intervalBefore| (entity1 entity2)
1005
(:documentation "True iff entity1 ends before entity1")
1006
(:method ((i1 spocq:interval) (i2 spocq:interval))
1007
(time< (spocq:interval-end i1) (spocq:interval-start i2)))
1008
(:method ((e1 spocq:interval) (position t))
1009
(time< (spocq:interval-end i1) position))
1010
(:method ((position t) (e2 spocq:interval))
1011
(time< position (spocq:interval-start i1)))
1012
(:method ((e1 t) (e2 t))
1015
(defgeneric |time|:|intervalContains| (entity1 entity2)
1016
(:documentation "True iff entity2 bounds are properly within those of entity1")
1017
(:method ((i1 spocq:interval) (i2 spocq:interval))
1018
(and (time< (spocq:interval-start i1) (spocq:interval-start i2))
1019
(time> (spocq:interval-start i1) (spocq:interval-start i2))))
1020
(:method ((e1 spocq:interval) (position t))
1021
(and (time< (spocq:interval-start i1) position)
1022
(time> (spocq:interval-end i1) position)))
1023
(:method ((position t) (e1 spocq:interval))
1025
(:method ((e1 t) (e2 t))
1027
;; should accept a visibility vector as the first argument, in which case it iterates over all satisfying intervals.
1031
(macrolet ((tm (a &environment env)
1032
`(list '(,a ,(multiple-value-list (variable-information a env))) ,a)))
1033
(declare (type string x))
1036
(define-compiler-macro |time|:|intervalContains| (&whole form entity1 entity2 &environment env)
1037
"Iff being compiled within a bgp visibility predicate, then expect a lexical environment
1038
in which there is a visibility map and a continuation when satisfied"
1039
(expand-interval-* '|time|:|intervalContains| form entity1 entity2 env))
1041
(defun compute-concrete-temporal-predicate (operator type1 type2 arg1 arg2)
1042
(let ((expanded-operator (find-symbol (format nil "~(~a-~ax~a~)" operator type1 type2) :spocq.e)))
1043
(assert (and expanded-operator (fboundp expanded-operator)) ()
1044
"Invalid temporal attribute: ~s" operator)
1045
`(,expanded-operator continuation ,arg1 ,arg2)))
1047
(defun spocq.e::intervalcontains.cardinality-mapXordinal (continuation map ordinal)
1048
"when visible at start then if visible before start and after end, but not at either
1050
(multiple-value-bind (v-start v-end) (cardinality-map-visibility-bounds vector start)
1052
(< v-start cardinal)
1054
(funcall continue v-start v-end))))
1056
(defun spocq.e::intervalcontains.cardinality-mapXdate-time (continuation map date-time)
1057
"when visible at start then if visible before start and after end, but not at either
1059
(let ((timestamp (date-time-timeline-location date-time)))
1060
(multiple-value-bind (v-start v-end) (cardinality-map-visibility-bounds-timestamp vector timestamp)
1062
(when (and (< (repository-ordinal-timestamp *metadata-repository* v-start) timestamp)
1063
(> (repository-ordinal-timestamp *metadata-repository* v-end) timestamp))
1064
(funcall continue v-start v-end))))))
1066
(defun spocq.e::intervalcontains.cardinality-mapXdate-time-interval (continuation map interval)
1067
"when visible at start then if visible before start and after end, but not at either
1069
(let ((start-timestamp (spocq:interval-start interval))
1070
(end-timestamp (spocq:interval-end interval)))
1071
(multiple-value-bind (v-start v-end) (cardinality-map-visibility-bounds-timestamp vector start-timestamp)
1073
(when (and (< (repository-ordinal-timestamp *metadata-repository* v-start) start-timestamp)
1074
(> (repository-ordinal-timestamp *metadata-repository* v-end) end-timestamp)))
1075
(funcall continue v-start v-end)))))
1077
;;; version is equivalent to a visibility interval in the map
1078
(defun spocq.e::intervalcontains.versionXordinal (continuation map ordinal)
1079
(spocq.e::intervalcontains.cardinality-mapXordinal continuation map ordinal))
1080
(defun spocq.e::intervalcontains.versionXinterval (continuation map interval)
1081
(spocq.e::intervalcontains.cardinality-mapXinterval continuation map interval))
1083
(defun spocq.e::intervalcontains.date-time-intervalXversion-end-date-time (continuation interval map)
1084
(let ((start-timestamp (spocq:interval-start interval))
1085
(end-timestamp (spocq:interval-end interval)))
1086
(multiple-value-bind (true end-position) (presence-position-timestamp-lessp map end-timestamp)
1087
(when (and end-position
1088
(not true) ;; position is absent
1089
(< start-timestamp (repository-ordinal-timestamp *metadata-repository* end-position)))
1090
(funcall continuation end-position end-position)))))
1092
(defun spocq.e::intervalcontains.date-time-intervalXversion-start-date-time (continuation interval map)
1093
(let ((start-timestamp (spocq:interval-start interval))
1094
(end-timestamp (spocq:interval-end interval)))
1095
(multiple-value-bind (true start-position) (presence-position-timestamp-lessp map end-timestamp)
1096
(when (and start-position
1097
true ;; position is present
1098
(< start-timestamp (repository-ordinal-timestamp *metadata-repository* end-position)))
1099
(funcall continuation start-position start-position)))))
1101
(defun |dydra|:|version-end-date-time| (&optional (version (|dydra|:|version|)))
1102
"This function returns the IRI of the end revision of a visibility constraint"
1103
(|dydra|:|revision-date-time| (version-end version)))
1105
(defun |dydra|:|version-end-ordinal| (&optional (version (|dydra|:|version|)))
1106
"This function returns the IRI of the end revision of a visibility constraint"
1107
(|dydra|:|revision-ordinal| (version-end version)))
1109
(defun |dydra|:|version-end-uuid| (&optional (version (|dydra|:|version|)))
1110
"This function returns the IRI of the end revision of a visibility constraint"
1111
(|dydra|:|revision-uuid| (version-end version)))
1113
(defun spocq.e::intervalcontains.versionXordinal (continuation map ordinal)
1114
"when visible at start then if visible before start and after end, but not at either
1116
(multiple-value-bind (v-start v-end) (cardinality-map-visibility-bounds vector start)
1118
(< v-start cardinal)
1120
(funcall continue v-start v-end))))
1122
(:documentation "True iff entity1 begins after entity2 ends or or entitry2 begins after entity1 ends")
1123
(:method ((i1 spocq:interval) (i2 spocq:interval))
1124
(or (time< (spocq:interval-end i1) (spocq:interval-start i2))
1125
(time> (spocq:interval-start i1) (spocq:interval-end i2))))
1126
(:method ((e1 spocq:interval) (position t))
1127
(or (time< (spocq:interval-end i1) position)
1128
(time> (spocq:interval-start i1) position)))
1129
(:method ((position t) (e2 spocq:interval))
1130
(or (time< (spocq:interval-end i2) position)
1131
(time> (spocq:interval-start i2) position)))
1132
(:method ((e1 t) (e2 t))
1133
(not (time= e1 e2))))
1134
(defun expand-interval-* (operator form e1 e2 env)
1135
(let ((pattern-variables (declaration-information 'spocq.e::pattern-variables env))
1136
(dynamic-variables (declaration-information 'spocq.e::dynamic-variables env)))
1138
(symbol (etypecase e2
1140
(compute-concrete-temporal-predicate operator
1141
(variable-type-information e1)
1142
(variable-type-information e2)
1145
(assert (= (length e2) 2) ()
1146
"Invalid temporal attribute: ~s" e2)
1147
(destructuring-bind (op arg) e2
1148
(assert (temporal-constuctor-p op) ()
1149
"Invalid temporal attribute: ~s" e2)
1150
(assert (or (member arg pattern-variables) (member arg dynamic-variables)) ()
1151
"Invalid temporal attribute: ~s" e2)
1152
(compute-concrete-temporal-predicate operator
1153
(variable-type-information e1)
1156
(t (error "invalid temporal constraint: ~s" form))))
1159
(assert (= (length e1) 2) ()
1160
"Invalid temporal attribute: ~s" e1)
1161
(destructuring-bind (op arg) e1
1162
(assert (temporal-constuctor-p op) ()
1163
"Invalid temporal attribute: ~s" e1)
1164
(assert (or (member arg pattern-variables) (member arg dynamic-variables)) ()
1165
"Invalid temporal attribute: ~s" e1)
1166
(compute-concrete-temporal-predicate operator
1168
(variable-type-information e1)
1171
(assert (= (length e1) 2) ()
1172
"Invalid temporal attribute: ~s" e1)
1173
(assert (= (length e2) 2) ()
1174
"Invalid temporal attribute: ~s" e2)
1175
(destructuring-bind (op1 arg1) e1
1176
(destructuring-bind (op2 arg2) e2
1177
(assert (temporal-constuctor-p op1) ()
1178
"Invalid temporal attribute: ~s" e1)
1179
(assert (temporal-constuctor-p op2) ()
1180
"Invalid temporal attribute: ~s" e2)
1181
(assert (or (member arg1 pattern-variables) (member arg1 dynamic-variables)) ()
1182
"Invalid temporal attribute: ~s" e1)
1183
(assert (or (member arg2 pattern-variables) (member arg2 dynamic-variables)) ()
1184
"Invalid temporal attribute: ~s" e2)
1185
(compute-concrete-temporal-predicate operator
1189
(t (error "invalid temporal constraint: ~s" form))))
1190
(t (error "invalid temporal constraint: ~s" form)))))
1194
(defgeneric |time|:|intervalDisjoint| (entity1 entity2)
1195
(:documentation "True iff entity1 begins after entity2 ends or or entitry2 begins after entity1 ends")
1196
(:method ((i1 spocq:interval) (i2 spocq:interval))
1197
(or (time< (spocq:interval-end i1) (spocq:interval-start i2))
1198
(time> (spocq:interval-start i1) (spocq:interval-end i2))))
1199
(:method ((e1 spocq:interval) (position t))
1200
(or (time< (spocq:interval-end i1) position)
1201
(time> (spocq:interval-start i1) position)))
1202
(:method ((position t) (e2 spocq:interval))
1203
(or (time< (spocq:interval-end i2) position)
1204
(time> (spocq:interval-start i2) position)))
1205
(:method ((e1 t) (e2 t))
1206
(not (time= e1 e2))))
1208
(defgeneric |time|:|intervalDuring| (entity1 entity2)
1210
(:method ((i1 spocq:interval) (i2 spocq:interval))
1212
(:method ((e1 spocq:interval) (position t))
1214
(:method ((position t) (e2 spocq:interval))
1216
(:method ((e1 t) (e2 t))
1219
(defgeneric |time|:|intervalEquals| (entity1 entity2)
1221
(:method ((i1 spocq:interval) (i2 spocq:interval))
1223
(:method ((e1 spocq:interval) (position t))
1225
(:method ((position t) (e2 spocq:interval))
1227
(:method ((e1 t) (e2 t))
1230
(defgeneric |time|:|intervalFinishedBy| (entity1 entity2)
1232
(:method ((i1 spocq:interval) (i2 spocq:interval))
1234
(:method ((e1 spocq:interval) (position t))
1236
(:method ((position t) (e2 spocq:interval))
1238
(:method ((e1 t) (e2 t))
1241
(defgeneric |time|:|intervalFinishes| (entity1 entity2)
1243
(:method ((i1 spocq:interval) (i2 spocq:interval))
1245
(:method ((e1 spocq:interval) (position t))
1247
(:method ((position t) (e2 spocq:interval))
1249
(:method ((e1 t) (e2 t))
1252
(defgeneric |time|:|intervalIncludedBy| (entity1 entity2)
1254
(:method ((i1 spocq:interval) (i2 spocq:interval))
1256
(:method ((e1 spocq:interval) (position t))
1258
(:method ((position t) (e2 spocq:interval))
1260
(:method ((e1 t) (e2 t))
1263
(defgeneric |time|:|intervalIncludes| (entity1 entity2)
1265
(:method ((i1 spocq:interval) (i2 spocq:interval))
1267
(:method ((e1 spocq:interval) (position t))
1269
(:method ((position t) (e2 spocq:interval))
1271
(:method ((e1 t) (e2 t))
1274
(defgeneric |time|:|intervalIn| (entity1 entity2)
1276
(:method ((i1 spocq:interval) (i2 spocq:interval))
1278
(:method ((e1 spocq:interval) (position t))
1280
(:method ((position t) (e2 spocq:interval))
1282
(:method ((e1 t) (e2 t))
1285
(defgeneric |time|:|intervalMeets| (entity1 entity2)
1287
(:method ((i1 spocq:interval) (i2 spocq:interval))
1289
(:method ((e1 spocq:interval) (position t))
1291
(:method ((position t) (e2 spocq:interval))
1293
(:method ((e1 t) (e2 t))
1296
(defgeneric |time|:|intervalMetBy| (entity1 entity2)
1298
(:method ((i1 spocq:interval) (i2 spocq:interval))
1300
(:method ((e1 spocq:interval) (position t))
1302
(:method ((position t) (e2 spocq:interval))
1304
(:method ((e1 t) (e2 t))
1307
(defgeneric |time|:|intervalOverlappedBy| (entity1 entity2)
1309
(:method ((i1 spocq:interval) (i2 spocq:interval))
1311
(:method ((e1 spocq:interval) (position t))
1313
(:method ((position t) (e2 spocq:interval))
1315
(:method ((e1 t) (e2 t))
1318
(defgeneric |time|:|intervalOverlaps| (entity1 entity2)
1320
(:method ((i1 spocq:interval) (i2 spocq:interval))
1322
(:method ((e1 spocq:interval) (position t))
1324
(:method ((position t) (e2 spocq:interval))
1326
(:method ((e1 t) (e2 t))
1329
(defgeneric |time|:|intervalStartedBy| (entity1 entity2)
1331
(:method ((i1 spocq:interval) (i2 spocq:interval))
1333
(:method ((e1 spocq:interval) (position t))
1335
(:method ((position t) (e2 spocq:interval))
1337
(:method ((e1 t) (e2 t))
1340
(defgeneric |time|:|intervalStarts| (entity1 entity2)
1342
(:method ((i1 spocq:interval) (i2 spocq:interval))
1344
(:method ((e1 spocq:interval) (position t))
1346
(:method ((position t) (e2 spocq:interval))
1348
(:method ((e1 t) (e2 t))
1353
temporal constraints involve a combination of three forms:
1354
- bind : specifies variables to be bound to revision entities to be used as filter arguments
1355
the entities are captured from the dynamic statement matching context and promoted into
1356
the current solution : operation scope and indefinite extent
1357
- filter : combines revision entities with themselves and/or atomic temporal values to constrain
1358
the solutions to those for which the contributing statements satisfy a temporal constraint.
1359
the are pushed into bgp's as for any filter
1360
- bgp : must provide a context for the combination
1362
the sse form will be (filter (join (bgp) (extend)))
1363
as that is the logical scope structure.
1364
the expression order of bind and filter cannot change that.
1367
PREFIX dydra: <http://dydra.com#>
1368
PREFIX time: <http://www.w3.org/2006/time#>
1369
select ?s ?o ?version
1371
?s <http://www.w3.org/2000/01/rdf-schema#label> ?o .
1372
bind(dydra:revision-interval(?s) as ?version) # [start..end)
1373
filter( time:intervalContains(?version, ?someOrdinal) )
1376
parses to the symbolic
1382
(spocq.a:|triple| ?::|s| |rdfs|:|label| ?::|o|))
1384
(|dydra|:|revision-interval| ?::|s|))
1385
(|time|:|intervalContains| ?::|version| ?::|someOrdinal|))
1386
(?::|s| ?::|o| ?::|version|))
1392
(declare (reference-dimensions ?::|s| ?::|o| ?::|version|))
1394
(spocq.a:|bind| ?::|version| (|dydra|:|version| ?::|s|))
1395
(spocq.a:|filter| (|time|:|intervalContains| ?::|version| ?::|someOrdinal|))
1396
(spocq.a:|triple| ?::|s| |rdfs|:|label| ?::|o|))))
1398
for which the compiled form must
1399
- construct the version instance with dynamic extent
1400
- apply the filter constraint to the version instance
1401
- capture it with indefinite extent, a intern it and yield it in the solutions bound to ?version
1403
the predicate can be applied to
1404
- version : the inserted intervals in the visibility map
1405
- revision ; the revison/transaction which inserted the statement
1406
- start-{uuid,ordinal,timestamp,date-time}, end-{uuid,ordinal,timestamp,date-time} as attributes of the respective version
1408
the statement scanner arranges to bind the statement variable to the version in order to make it possible to extract the other entities.
1410
how is the predicate applied.
1412
the implicit allen predicates provide just one argument and that is compared to the visibility map revisions implicity, that is,
1413
without instantiating them.
1414
by analogy, the respective accesor should compile into a primitive comparison with the map for testing
1415
and into an constructor for binding
1417
one part of this is the interval predicates
1418
- within the scanner, theyexpand themselves and their arguments in to direct map searches and comparisons.
1419
- outside of the scanner, tey compile into constructirs and generic operators.
1422
which is needs to yield rewritten into
1424
(flet ((do-match (s p o c revision) (when (time:|intervalContains| ?::|version| ?::|someOrdinal|) ...) ))
1425
(map-statements (function do-match) *repository* (quad ps pp po pq))
1427
the revision (start/end) binding has just the bgp as extent.
1428
this means it (or an attribute) must be captured to be bound to a projectable variable as a side-effect of a match.
1429
to the extent that more that the respective versions from multiple statement involve different revisions/transactions,
1430
it is necessary to produce as a result some merged version designator which both satisfies the constraint and reflect
1431
a condition which applies to all matched statements.
1433
this would mean [max(start *), min(end *)) -- for a given binding.
1435
filters are supplied once the minimal version definition has been computed.
1437
the compilation process involves recognizing the
1440
(extend (bgp ( ... <patternVar>) ) <temporalVar> (<temporal-constructor> <patternVar>) )
1441
(<interval-predicate> <temporalVar> ...) ... )
1443
when the filter recognizes that the predicate form is to be applied in the bgp, it augments the
1444
environment with an entry per variable
1445
when the extend sees a temporal constructor which is applied to a pattern variable, it does the same.
1447
at the point where the bgp compiler transforms a pattern,
1448
- it collects any predicate operators which apply temporal constraints compines them into a temporal algebra expression
1449
and passes them through to the pattern iterator to filter the results.
1450
- it collects any bindings which involve temporal constructors and merges them into the filter as well as
1451
calling the respective iterator which yields also the temporal entity to be bound.
1453
the constrained map operations would need to look like
1457
(macrolet ((tz (z &environment env)
1464
PREFIX dydra: <http://dydra.com#>
1465
PREFIX time: <http://www.w3.org/2006/time#>
1466
select ?s ?o ?version
1468
?s <http://www.w3.org/2000/01/rdf-schema#label> ?o .
1469
bind(dydra:version(?s) as ?version)
1470
filter( time:intervalContains(?version, ?someOrdinal) )
1473
(let ((*bgp.suppress-null-patterns* nil))
1475
PREFIX dydra: <http://dydra.com#>
1476
PREFIX time: <http://www.w3.org/2006/time#>
1477
select ?s ?o ?version
1479
?s <http://www.w3.org/2000/01/rdf-schema#label> ?o .
1480
bind(dydra:version(?s) as ?version)
1481
filter( time:intervalContains(?version, ?someOrdinal) )
1483
:repository-id "james/test"
1484
:agent (system-agent)
1485
:dynamic-bindings '((?::|someOrdinal|) nil)))
1490
(ORG.DATAGRAPH.SPOCQ.EVALUATION:PROJECTION-DIMENSIONS ?::|s| ?::|o|
1492
(ORG.DATAGRAPH.SPOCQ.EVALUATION:PROJECT
1495
(ORG.DATAGRAPH.SPOCQ.EVALUATION:REFERENCE-DIMENSIONS ?::|version| ?::|o|
1499
(ORG.DATAGRAPH.SPOCQ.EVALUATION:REFERENCE-DIMENSIONS ?::|version|))
1500
(ORG.DATAGRAPH.SPOCQ.ALGEBRA:|agp|
1501
(ORG.DATAGRAPH.SPOCQ.ALGEBRA:|id| #:AGP-1530)
1503
(ORG.DATAGRAPH.SPOCQ.ALGEBRA:|opaque| ?::|someOrdinal|))
1504
(ORG.DATAGRAPH.SPOCQ.ALGEBRA:|triple| ?::|s|
1507
(?::|s| #:|constant1529| ?::|o|))
1508
(ORG.DATAGRAPH.SPOCQ.ALGEBRA:|filter|
1509
(|time|:|intervalContains| ?::|version|
1511
(ORG.DATAGRAPH.SPOCQ.ALGEBRA:|bind| ?::|version|
1512
(|fn|:|version| ?::|s|)))))
1513
'(?::|s| ?::|o| ?::|version|)))
1515
;;; substitute all binds into filters until closure
1516
;;; if the bind variable is a reference dimension or is used by some other bind which is a reference dimension
1517
;;; then arrange to include it in the continuation result
1519
(let ((*bgp.suppress-null-patterns* nil))
1521
PREFIX dydra: <http://dydra.com#>
1522
PREFIX time: <http://www.w3.org/2006/time#>
1523
select ?s ?o ?version
1525
?s <http://www.w3.org/2000/01/rdf-schema#label> ?o .
1526
filter( time:intervalContains(dydra:version(?s), ?someOrdinal) )
1528
:repository-id "james/test"
1529
:agent (system-agent)
1530
:dynamic-bindings '((?::|someOrdinal|) nil)))
1534
(ORG.DATAGRAPH.SPOCQ.EVALUATION:PROJECTION-DIMENSIONS ?::|s| ?::|o|
1536
(ORG.DATAGRAPH.SPOCQ.EVALUATION:PROJECT
1539
(ORG.DATAGRAPH.SPOCQ.EVALUATION:REFERENCE-DIMENSIONS ?::|version| ?::|o|
1541
(ORG.DATAGRAPH.SPOCQ.ALGEBRA:|agp|
1542
(ORG.DATAGRAPH.SPOCQ.ALGEBRA:|id| #:AGP-1532)
1544
(ORG.DATAGRAPH.SPOCQ.ALGEBRA:|opaque| ?::|someOrdinal|))
1545
(ORG.DATAGRAPH.SPOCQ.ALGEBRA:|triple| ?::|s|
1548
(?::|s| #:|constant1531| ?::|o|))
1549
(ORG.DATAGRAPH.SPOCQ.ALGEBRA:|filter|
1550
(|time|:|intervalContains|
1551
(|fn|:|version| ?::|s|)
1552
?::|someOrdinal|))))
1553
'(?::|s| ?::|o| ?::|version|)))
1555
;;; see compute-visibility-filter
1562
continuation should take the map as well as the bounds
1567
PREFIX dydra: <http://dydra.com#>
1568
PREFIX time: <http://www.w3.org/2006/time#>
1569
select ?s ?o ?version
1571
{ ?s <http://www.w3.org/2000/01/rdf-schema#label> ?o .
1572
bind(dydra:st_distance(?s) as ?s1revision) # [start..end)
1573
filter( time:intervalContains(?revision, ?someFirstOrdinal))}
1574
{ ?s <http://www.w3.org/2000/01/rdf-schema#label> ?o .
1575
bind(dydra:st_distance(?s) as ?s2revision) # [start..end)
1576
filter( time:intervalContains(?revision, ?someOtherOrdinal)) }
1577
filter (time:intervalAfter(?s1revision, ?s2revision))
1586
{?s |http://www.w3.org/2000/01/rdf-schema# |:label ?o})
1587
?s2revision (|http://dydra.com/sparql-functions# |:st_distance ?s))
1588
(|http://www.w3.org/2006/time# |:intervalContains ?revision ?someOtherOrdinal))
1592
{?s |http://www.w3.org/2000/01/rdf-schema# |:label ?o})
1593
?s1revision (|http://dydra.com/sparql-functions# |:st_distance ?s))
1594
(|http://www.w3.org/2006/time# |:intervalContains ?revision ?someFirstOrdinal)))
1595
(|http://www.w3.org/2006/time# |:intervalAfter ?s1revision ?s2revision))
1598
within the bgp the ?s1Reviion and ?s2Revision need to be available for the immediate
1599
temporal predicate _and_ extend the field for the references in the filter.
1604
PREFIX dydra: <http://dydra.com#>
1605
PREFIX time: <http://www.w3.org/2006/time#>
1606
select ?s ?o ?version
1608
{ ?s <http://www.w3.org/2000/01/rdf-schema#label> ?o .
1609
bind(dydra:st_distance(?s) as ?s1revision)}
1610
{ bind(dydra:st_distance(?s) as ?s2revision)
1611
?s <http://www.w3.org/2000/01/rdf-schema#label> ?o . }
1612
filter (time:intervalAfter(?s1revision, ?s2revision))
1617
select ?s ?o ?version
1620
bind(str(?s) as ?sStr)}