Coverage report: /development/source/library/org/datagraph/spocq-shard/src/store/rlmdb/bgp-filters.lisp

KindCoveredAll%
expression01418 0.0
branch0240 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; -*-
2
 
3
 (in-package :org.datagraph.spocq.implementation)
4
 
5
 (:documentation "Implements comparison logic and compilation
6
   for temporal constraints within a bgp.
7
   Supports both ordinal and temporal-id visibility maps.")
8
 
9
 
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))
14
     (case type
15
       (:lexical (rest (assoc 'type declarations))))))
16
 
17
 
18
 
19
 (defvar *temporal-continue* )
20
 (defvar *temporal-map* )
21
 
22
 ;;; does not all compiler macro
23
 
24
 
25
 
26
 
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)))
31
                `(progn
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))
45
                       (t form)))))))
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)))
66
 
67
 
68
 
69
 #+(or)
70
 (defmacro with-shadowed-continue (continue-operation expression)
71
   `(let ((.continuation *temporal-continue*))
72
      (flet ((.continuation (s e) 
73
               (funcall .continuation s e)
74
               ,continue-operation))
75
        (declare (dynamic-extent #'.continuation))
76
        (let ((*temporal-continue* #'.continuation))
77
          (declare (special *temporal-continue*))
78
          ,expression))))
79
 #+(or)
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)
88
                   (if rest
89
                       (list 'with-shadowed-continue (list* 'spocq.a:|and| rest) first)
90
                       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*))
100
                               expression)
101
                         '(cw-ordinal-map-bounds-tail *temporal-continue* *temporal-map*))))
102
        ,expression)))
103
 #+(or)
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))) #()))
110
  )
111
 
112
 (defmacro with-shadowed-continue (continue-body expression)
113
   `(let ((_version-continue_ (lambda (s e)
114
                                 ,@continue-body)))
115
        (declare (dynamic-extent _version-continue_))
116
      ,expression))
117
 
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"
122
                 (if rest
123
                     (list 'with-shadowed-continue
124
                           (list '(declare (ignore s e))
125
                                 ;;'(print :rest-and)
126
                                 (list* 'spocq.a:|and| rest))
127
                           (list 'progn ;; '(print :first-and)
128
                                 first))
129
                     first))
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
134
                       (if (rest rest)
135
                           (list 'with-shadowed-continue
136
                                 '((funcall _version-continue_ s e)
137
                                   (return-from :visible-or (values s e)))
138
                                 (list* 'progn rest))
139
                           (first rest))))
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))))
148
                             expression)
149
                       ;;'(print :not-succeed)
150
                       '(cw-ordinal-map-bounds-tail _version-continue_ _version-map_))))
151
      ;;(print (list :version-combination ',expression))
152
      ,expression))
153
 
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)))
162
 
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))
167
                         ()
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)
187
   )
188
 
189
 #+(or) 
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)
217
                   (if 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))
220
                             first)
221
                       first))
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))
227
                                rest)))
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))
233
                               expression)
234
                         '(continue-with-interval-tail continue-op vector)))
235
 
236
                 (spocq.a:|some| (expression)
237
                   ;; return the first satisfying bounds
238
                   (print
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))
244
                               expression))))
245
                 (spocq.a:|every|
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))
250
                         expression))
251
                 (spocq.a:|each|
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))
256
                         expression)))
257
                 
258
            ,expression)))
259
 
260
 
261
 ;;; see https://www.w3.org/TR/owl-time/
262
 
263
 
264
 ;;; based on ordinal maps
265
 
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))
269
       (when true
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)
275
       (when true
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)))
280
 
281
 
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))
289
       (cond
290
        (true
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))))))
295
        (position
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)
307
         (cond
308
          (true
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))))))
314
          (position
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
321
           (when (> length 0)
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)))
326
 
327
 
328
 
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))
335
       (cond (true
336
              (when (>= position 2)
337
                (values (aref map (- position 2)) (aref map (- position 1)))))
338
             (position
339
              (when (>= position 1)
340
                (values (aref map (- position 1)) (aref map position))))
341
             (t
342
              nil))))
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)
347
         (cond (true
348
                (when (>= position 2)
349
                  (values (cffi:mem-aref %vector :uint32 (- position 2)) (cffi:mem-aref %vector :uint32 (- position 1)))))
350
               (position
351
                (when (>= position 1)
352
                  (values (cffi:mem-aref %vector :uint32 (- position 1)) (cffi:mem-aref %vector :uint32 position))))
353
               (t
354
                nil)))))
355
   (:method ((map vector-ordinal-map) location)
356
     (ordinal-map-bounds-previous (vector-ordinal-map-vector map) location)))
357
 
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))
366
       (cond (true
367
              (when (>= position 2)
368
                (values (aref map (- position 2)) (aref map (- position 1)))))
369
             (position
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)))))
375
             (t
376
              nil))))
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)
381
          (cond (true
382
                 (when (>= position 2)
383
                   (values (cffi:mem-aref %vector :uint32 (- position 2)) (cffi:mem-aref %vector :uint32 (- position 1)))))
384
                (position
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)))))
390
                (t
391
                 nil)))))
392
   (:method ((map vector-ordinal-map) location)
393
     (ordinal-map-bounds-previous-exclusive (vector-ordinal-map-vector map) location)))
394
   
395
 
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)))
404
       (when (oddp length)
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))))
408
 
409
 
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))))
422
 
423
 (defgeneric cw-ordinal-map-bounds-extent (continue map)
424
   (:documentation "if visible at all, continue with two values:
425
    - the first location
426
    - if removed at end then the last visible bounds, otherwise nil")
427
   (:method (continue (map vector))
428
     (let ((length (length map)))
429
       (when (plusp length)
430
         (funcall continue
431
                  (aref map 0)
432
                  (when (evenp length)
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)))
437
       (when (plusp length)
438
         (funcall continue
439
                  (cffi:mem-aref %vector :uint32 0)
440
                  (when (evenp length)
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))))
444
 
445
 
446
 
447
 ;;; interval match operators
448
 
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)
454
     (when v-start
455
       (funcall continue v-start v-end))))
456
 
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)
462
     (when v-start
463
       (funcall continue v-start v-end))))
464
 
465
 
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)
470
     (when (and v-start
471
                (< v-start start)
472
                (> v-end end))
473
       (funcall continue v-start v-end))))
474
 
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)))))))
486
 
487
 ;;; (trace ordinal-map-disjoint statement-visibility-next-bounds statement-visibility-previous-bounds)
488
 
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)))))
496
 
497
 (defun cw-ordinal-map-equals (continue map start &optional (end start))
498
   "visible with equal bounds
499
    yield the 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))))
503
 
504
 
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))))
511
 
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))))
518
 
519
 
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)
525
     (if v-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)
530
           (when v-start
531
             (when (<= v-end end) (funcall continue v-start v-end)))))))
532
 
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))))
540
 
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))))
549
 
550
 (defun cw-ordinal-map-meets (continue map start &optional end)
551
   "visible up to start
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))))
557
 
558
 (defun cw-ordinal-map-met-by (continue map start &optional (end start))
559
   "visible up to 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))))
564
 
565
 
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))))
573
 
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))))
581
 
582
 
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))))
589
 
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))))
596
 
597
 
598
 ;;; base on temporal-id map of only
599
 
600
 (defgeneric timestamp-map-bounds  (map location)
601
   (:method ((map vector) location)
602
     (multiple-value-bind (true position) (test-uuid-visibility location map)
603
       (when true
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)))
607
 
608
 
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))
616
       (cond
617
        (true
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))))))
622
        (position
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)))
632
 
633
 
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))
640
       (cond (true
641
              (when (>= position 2)
642
                (values (aref map (- position 2)) (aref map (- position 1)))))
643
             (position
644
              (when (>= position 1)
645
                (values (aref map (- position 1)) (aref map position))))
646
             (t
647
              nil))))
648
   (:method ((map timestamp-map) location)
649
     (timestamp-map-bounds-previous (timestamp-map-vector map) location)))
650
 
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))
659
       (cond (true
660
              (when (>= position 2)
661
                (values (aref map (- position 2)) (aref map (- position 1)))))
662
             (position
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)))))
668
             (t
669
              nil))))
670
   (:method ((map timestamp-map) location)
671
     (timestamp-map-bounds-previous-exclusive (timestamp-map-vector map) location)))
672
   
673
 
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
680
         (funcall continue
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))))
685
 
686
 
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
693
         (funcall continue
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))))
698
 
699
 (defgeneric cw-timestamp-map-bounds-extent (continue map)
700
   (:documentation "if visible at all, continue with two values:
701
    - the first location
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)))
705
       (when insert-entry
706
         (funcall continue
707
                  insert-entry
708
                  (when (> (length map) 1)
709
                    (let ((last-entry (aref map (1- (length map)))))
710
                      (when (delete-uuid-p last-entry)
711
                        last-entry)))))))
712
   (:method (continue (map timestamp-map))
713
     (cw-timestamp-map-bounds-extent continue (timestamp-map-vector map))))
714
 
715
 
716
 ;;; interval match operators
717
 
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)
723
     (when v-start
724
       (funcall continue v-start v-end))))
725
 
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)
731
     (when v-start
732
       (funcall continue v-start v-end))))
733
 
734
 
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)
739
     (when (and v-start
740
                (< v-start start)
741
                (> v-end end))
742
       (funcall continue v-start v-end))))
743
 
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)))))))
755
 
756
 ;;; (trace timestamp-map-disjoint statement-visibility-next-bounds statement-visibility-previous-bounds)
757
 
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)))))
765
 
766
 (defun cw-timestamp-map-equals (continue map start &optional (end start))
767
   "visible with equal bounds
768
    yield the 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))))
772
 
773
 
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))))
780
 
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))))
787
 
788
 
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)
794
     (if v-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)
799
           (when v-start
800
             (when (<= v-end end) (funcall continue v-start v-end)))))))
801
 
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))))
808
 
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))))
815
 
816
 (defun cw-timestamp-map-meets (continue map start &optional end)
817
   "visible up to start
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))))
823
 
824
 (defun cw-timestamp-map-met-by (continue map start &optional (end start))
825
   "visible up to 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))))
830
 
831
 
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))))
839
 
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))))
847
 
848
 
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))))
855
 
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))))
862
 
863
 
864
 #|
865
 
866
 (defun test-visibility-map (continue-op map relation)
867
   (declare (dynamic-extent continue-op))
868
   (destructuring-bind (op . args) relation
869
     (ecase op
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
889
           (if rest
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))
910
 
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))
916
                          nil)))
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))
922
                          nil))))))
923
 
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)
947
   )
948
 
949
 
950
 (defgeneric compute-visibility-filter-lambda (context filters bindings)
951
   (:documentation
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.
959
 
960
    The bgp context arranges to accept them and bind them to the respective variable.
961
 
962
    Should work for cross-statement comparisons as the respective maps have dynamic extent, but how?")
963
 
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))))))
973
 
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))))
979
 
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))
989
     (time> e1 e2)))
990
 
991
 (defgeneric time< (t1 t2)
992
   (:method ((t1 integer) (t2 integer))
993
     (< t1 t2))
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))
1000
     t)
1001
   (:method ((t1 t) (t2 t))
1002
     nil))
1003
     
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))
1013
     (time< e1 e2)))
1014
 
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))
1024
     nil)
1025
   (:method ((e1 t) (e2 t))
1026
     nil))
1027
 ;; should accept a visibility vector as the first argument, in which case it iterates over all satisfying intervals.
1028
 ;; !?
1029
 
1030
 (defun test-di (x)
1031
   (macrolet ((tm (a &environment env)
1032
                `(list '(,a ,(multiple-value-list (variable-information a env))) ,a)))
1033
     (declare (type string x))
1034
     (tm x)))
1035
 
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))
1040
 
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)))
1046
 
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
1049
    accept the bounds"
1050
   (multiple-value-bind (v-start v-end) (cardinality-map-visibility-bounds vector start)
1051
     (when (and v-start
1052
                (< v-start cardinal)
1053
                (> v-end cardinal))
1054
       (funcall continue v-start v-end))))
1055
 
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
1058
    accept the bounds"
1059
   (let ((timestamp (date-time-timeline-location date-time)))
1060
     (multiple-value-bind (v-start v-end) (cardinality-map-visibility-bounds-timestamp vector timestamp)
1061
       (when v-start
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))))))
1065
 
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
1068
    accept the bounds"
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)
1072
       (when v-start
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)))))
1076
 
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))
1082
 
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)))))
1091
 
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)))))
1100
 
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)))
1104
 
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)))
1108
 
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)))
1112
 
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
1115
    accept the bounds"
1116
   (multiple-value-bind (v-start v-end) (cardinality-map-visibility-bounds vector start)
1117
     (when (and v-start
1118
                (< v-start cardinal)
1119
                (> v-end cardinal))
1120
       (funcall continue v-start v-end))))
1121
 
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)))
1137
     (etypecase e1
1138
       (symbol (etypecase e2
1139
                 (symbol
1140
                  (compute-concrete-temporal-predicate operator
1141
                                                       (variable-type-information e1)
1142
                                                       (variable-type-information e2)
1143
                                                       e1 e2))
1144
                 (cons
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)
1154
                                                         op
1155
                                                         e1 arg)))
1156
                 (t (error "invalid temporal constraint: ~s" form))))
1157
       (cons (etypecase e2
1158
               (symbol
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
1167
                                                       op
1168
                                                       (variable-type-information e1)
1169
                                                       e1 e2)))
1170
               (cons
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
1186
                                                         op1
1187
                                                         op2
1188
                                                         e1 e2))))
1189
               (t  (error "invalid temporal constraint: ~s" form))))
1190
       (t   (error "invalid temporal constraint: ~s" form)))))
1191
         
1192
 
1193
 
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))))
1207
 
1208
 (defgeneric |time|:|intervalDuring| (entity1 entity2)
1209
   (:documentation "")
1210
   (:method ((i1 spocq:interval) (i2 spocq:interval))
1211
     )
1212
   (:method ((e1 spocq:interval) (position t))
1213
     )
1214
   (:method ((position t) (e2 spocq:interval))
1215
     )
1216
   (:method ((e1 t) (e2 t))
1217
     nil))
1218
 
1219
 (defgeneric |time|:|intervalEquals| (entity1 entity2)
1220
   (:documentation "")
1221
   (:method ((i1 spocq:interval) (i2 spocq:interval))
1222
     )
1223
   (:method ((e1 spocq:interval) (position t))
1224
     )
1225
   (:method ((position t) (e2 spocq:interval))
1226
     )
1227
   (:method ((e1 t) (e2 t))
1228
     nil))
1229
 
1230
 (defgeneric |time|:|intervalFinishedBy| (entity1 entity2)
1231
   (:documentation "")
1232
   (:method ((i1 spocq:interval) (i2 spocq:interval))
1233
     )
1234
   (:method ((e1 spocq:interval) (position t))
1235
     )
1236
   (:method ((position t) (e2 spocq:interval))
1237
     )
1238
   (:method ((e1 t) (e2 t))
1239
     nil))
1240
 
1241
 (defgeneric |time|:|intervalFinishes| (entity1 entity2)
1242
   (:documentation "")
1243
   (:method ((i1 spocq:interval) (i2 spocq:interval))
1244
     )
1245
   (:method ((e1 spocq:interval) (position t))
1246
     )
1247
   (:method ((position t) (e2 spocq:interval))
1248
     )
1249
   (:method ((e1 t) (e2 t))
1250
     nil))
1251
 
1252
 (defgeneric |time|:|intervalIncludedBy| (entity1 entity2)
1253
   (:documentation "")
1254
   (:method ((i1 spocq:interval) (i2 spocq:interval))
1255
     )
1256
   (:method ((e1 spocq:interval) (position t))
1257
     )
1258
   (:method ((position t) (e2 spocq:interval))
1259
     )
1260
   (:method ((e1 t) (e2 t))
1261
     nil))
1262
 
1263
 (defgeneric |time|:|intervalIncludes| (entity1 entity2)
1264
   (:documentation "")
1265
   (:method ((i1 spocq:interval) (i2 spocq:interval))
1266
     )
1267
   (:method ((e1 spocq:interval) (position t))
1268
     )
1269
   (:method ((position t) (e2 spocq:interval))
1270
     )
1271
   (:method ((e1 t) (e2 t))
1272
     nil))
1273
 
1274
 (defgeneric |time|:|intervalIn| (entity1 entity2)
1275
   (:documentation "")
1276
   (:method ((i1 spocq:interval) (i2 spocq:interval))
1277
     )
1278
   (:method ((e1 spocq:interval) (position t))
1279
     )
1280
   (:method ((position t) (e2 spocq:interval))
1281
     )
1282
   (:method ((e1 t) (e2 t))
1283
     nil))
1284
 
1285
 (defgeneric |time|:|intervalMeets| (entity1 entity2)
1286
   (:documentation "")
1287
   (:method ((i1 spocq:interval) (i2 spocq:interval))
1288
     )
1289
   (:method ((e1 spocq:interval) (position t))
1290
     )
1291
   (:method ((position t) (e2 spocq:interval))
1292
     )
1293
   (:method ((e1 t) (e2 t))
1294
     nil))
1295
 
1296
 (defgeneric |time|:|intervalMetBy| (entity1 entity2)
1297
   (:documentation "")
1298
   (:method ((i1 spocq:interval) (i2 spocq:interval))
1299
     )
1300
   (:method ((e1 spocq:interval) (position t))
1301
     )
1302
   (:method ((position t) (e2 spocq:interval))
1303
     )
1304
   (:method ((e1 t) (e2 t))
1305
     nil))
1306
 
1307
 (defgeneric |time|:|intervalOverlappedBy| (entity1 entity2)
1308
   (:documentation "")
1309
   (:method ((i1 spocq:interval) (i2 spocq:interval))
1310
     )
1311
   (:method ((e1 spocq:interval) (position t))
1312
     )
1313
   (:method ((position t) (e2 spocq:interval))
1314
     )
1315
   (:method ((e1 t) (e2 t))
1316
     nil))
1317
 
1318
 (defgeneric |time|:|intervalOverlaps| (entity1 entity2)
1319
   (:documentation "")
1320
   (:method ((i1 spocq:interval) (i2 spocq:interval))
1321
     )
1322
   (:method ((e1 spocq:interval) (position t))
1323
     )
1324
   (:method ((position t) (e2 spocq:interval))
1325
     )
1326
   (:method ((e1 t) (e2 t))
1327
     nil))
1328
 
1329
 (defgeneric |time|:|intervalStartedBy| (entity1 entity2)
1330
   (:documentation "")
1331
   (:method ((i1 spocq:interval) (i2 spocq:interval))
1332
     )
1333
   (:method ((e1 spocq:interval) (position t))
1334
     )
1335
   (:method ((position t) (e2 spocq:interval))
1336
     )
1337
   (:method ((e1 t) (e2 t))
1338
     nil))
1339
 
1340
 (defgeneric |time|:|intervalStarts| (entity1 entity2)
1341
   (:documentation "")
1342
   (:method ((i1 spocq:interval) (i2 spocq:interval))
1343
     )
1344
   (:method ((e1 spocq:interval) (position t))
1345
     )
1346
   (:method ((position t) (e2 spocq:interval))
1347
     )
1348
   (:method ((e1 t) (e2 t))
1349
     nil))
1350
 |#
1351
 
1352
 #|
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
1361
 
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.
1365
 
1366
 (parse-sparql "
1367
 PREFIX dydra: <http://dydra.com#>
1368
 PREFIX time: <http://www.w3.org/2006/time#>
1369
 select ?s ?o ?version
1370
 where {
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) )
1374
 }")
1375
 
1376
 parses to the symbolic
1377
 
1378
 (spocq.a:|select|
1379
  (spocq.a:|filter|
1380
   (spocq.a:|extend|
1381
    (spocq.a:|bgp|
1382
      (spocq.a:|triple| ?::|s| |rdfs|:|label| ?::|o|))
1383
    ?::|version|
1384
    (|dydra|:|revision-interval| ?::|s|))
1385
   (|time|:|intervalContains| ?::|version| ?::|someOrdinal|))
1386
  (?::|s| ?::|o| ?::|version|))
1387
 
1388
 which expands into
1389
 
1390
 (spocq.a:|select|
1391
   (locally
1392
     (declare (reference-dimensions ?::|s| ?::|o| ?::|version|))
1393
     (spocq.a:|bgp|
1394
       (spocq.a:|bind| ?::|version| (|dydra|:|version| ?::|s|))
1395
       (spocq.a:|filter| (|time|:|intervalContains| ?::|version| ?::|someOrdinal|))
1396
       (spocq.a:|triple| ?::|s| |rdfs|:|label| ?::|o|))))
1397
 
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
1402
 
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
1407
 
1408
 the statement scanner arranges to bind the statement variable to the version in order to make it possible to extract the other entities.
1409
 
1410
 how is the predicate applied.
1411
 
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
1416
 
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.
1420
 
1421
 
1422
 which is needs to yield rewritten into
1423
 
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))
1426
 
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.
1432
 
1433
 this would mean [max(start *), min(end *)) -- for a given binding.
1434
 
1435
 filters are supplied once the minimal version definition has been computed.
1436
 
1437
 the compilation process involves recognizing the
1438
 
1439
      (filter 
1440
         (extend  (bgp ( ... <patternVar>) ) <temporalVar> (<temporal-constructor> <patternVar>) )
1441
         (<interval-predicate> <temporalVar> ...) ... )
1442
 
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.
1446
 
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.
1452
 
1453
 the constrained map operations would need to look like
1454
 
1455
 (defun tx (x)
1456
   (flet ((ty (y)
1457
            (macrolet ((tz (z &environment env)
1458
                         (print env)
1459
                         `(quote ,z)))
1460
              (tz y)))
1461
     (ty x)))
1462
 
1463
 (parse-sparql "
1464
 PREFIX dydra: <http://dydra.com#>
1465
 PREFIX time: <http://www.w3.org/2006/time#>
1466
 select ?s ?o ?version
1467
 where {
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) )
1471
 }")
1472
 
1473
 (let ((*bgp.suppress-null-patterns* nil))
1474
 (expand-query "
1475
 PREFIX dydra: <http://dydra.com#>
1476
 PREFIX time: <http://www.w3.org/2006/time#>
1477
 select ?s ?o ?version
1478
 where {
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) )
1482
 }"
1483
   :repository-id "james/test"
1484
   :agent (system-agent)
1485
   :dynamic-bindings '((?::|someOrdinal|) nil)))
1486
 
1487
 =>
1488
 (LOCALLY
1489
  (DECLARE
1490
   (ORG.DATAGRAPH.SPOCQ.EVALUATION:PROJECTION-DIMENSIONS ?::|s| ?::|o|
1491
    ?::|version|))
1492
  (ORG.DATAGRAPH.SPOCQ.EVALUATION:PROJECT
1493
   (LOCALLY
1494
    (DECLARE
1495
     (ORG.DATAGRAPH.SPOCQ.EVALUATION:REFERENCE-DIMENSIONS ?::|version| ?::|o|
1496
      ?::|s|))
1497
    (LOCALLY
1498
     (DECLARE
1499
      (ORG.DATAGRAPH.SPOCQ.EVALUATION:REFERENCE-DIMENSIONS ?::|version|))
1500
     (ORG.DATAGRAPH.SPOCQ.ALGEBRA:|agp|
1501
      (ORG.DATAGRAPH.SPOCQ.ALGEBRA:|id| #:AGP-1530)
1502
      (declare
1503
       (ORG.DATAGRAPH.SPOCQ.ALGEBRA:|opaque| ?::|someOrdinal|))
1504
      (ORG.DATAGRAPH.SPOCQ.ALGEBRA:|triple| ?::|s|
1505
                                            |rdfs|:|label|
1506
                                            ?::|o| :DIMENSIONS
1507
                                            (?::|s| #:|constant1529| ?::|o|))
1508
      (ORG.DATAGRAPH.SPOCQ.ALGEBRA:|filter|
1509
       (|time|:|intervalContains| ?::|version|
1510
                                                          ?::|someOrdinal|))
1511
      (ORG.DATAGRAPH.SPOCQ.ALGEBRA:|bind| ?::|version|
1512
       (|fn|:|version| ?::|s|)))))
1513
   '(?::|s| ?::|o| ?::|version|)))
1514
 
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
1518
 
1519
 (let ((*bgp.suppress-null-patterns* nil))
1520
 (expand-query "
1521
 PREFIX dydra: <http://dydra.com#>
1522
 PREFIX time: <http://www.w3.org/2006/time#>
1523
 select ?s ?o ?version
1524
 where {
1525
   ?s <http://www.w3.org/2000/01/rdf-schema#label> ?o .
1526
   filter( time:intervalContains(dydra:version(?s), ?someOrdinal) )
1527
 }"
1528
   :repository-id "james/test"
1529
   :agent (system-agent)
1530
   :dynamic-bindings '((?::|someOrdinal|) nil)))
1531
 
1532
 (LOCALLY
1533
  (DECLARE
1534
   (ORG.DATAGRAPH.SPOCQ.EVALUATION:PROJECTION-DIMENSIONS ?::|s| ?::|o|
1535
    ?::|version|))
1536
  (ORG.DATAGRAPH.SPOCQ.EVALUATION:PROJECT
1537
   (LOCALLY
1538
    (DECLARE
1539
     (ORG.DATAGRAPH.SPOCQ.EVALUATION:REFERENCE-DIMENSIONS ?::|version| ?::|o|
1540
      ?::|s|))
1541
    (ORG.DATAGRAPH.SPOCQ.ALGEBRA:|agp|
1542
     (ORG.DATAGRAPH.SPOCQ.ALGEBRA:|id| #:AGP-1532)
1543
     (declare
1544
      (ORG.DATAGRAPH.SPOCQ.ALGEBRA:|opaque| ?::|someOrdinal|))
1545
     (ORG.DATAGRAPH.SPOCQ.ALGEBRA:|triple| ?::|s|
1546
                                           |rdfs|:|label|
1547
                                           ?::|o| :DIMENSIONS
1548
                                           (?::|s| #:|constant1531| ?::|o|))
1549
     (ORG.DATAGRAPH.SPOCQ.ALGEBRA:|filter|
1550
      (|time|:|intervalContains|
1551
       (|fn|:|version| ?::|s|)
1552
       ?::|someOrdinal|))))
1553
   '(?::|s| ?::|o| ?::|version|)))
1554
 
1555
 ;;; see compute-visibility-filter
1556
 
1557
 |#
1558
 
1559
 
1560
 #|
1561
 
1562
 continuation should take the map as well as the bounds 
1563
 ;;; more complex
1564
 
1565
 (pprint-sse
1566
   (parse-sparql "
1567
 PREFIX dydra: <http://dydra.com#>
1568
 PREFIX time: <http://www.w3.org/2006/time#>
1569
 select ?s ?o ?version
1570
 where {
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))
1578
 }"))
1579
 
1580
 (select
1581
    (filter
1582
     (join
1583
      (filter
1584
       (extend
1585
        (bgp
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))
1589
      (filter
1590
       (extend
1591
        (bgp
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))
1596
    (?s ?o ?version))
1597
 
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.
1600
 
1601
 
1602
 (pprint-sse
1603
   (parse-sparql "
1604
 PREFIX dydra: <http://dydra.com#>
1605
 PREFIX time: <http://www.w3.org/2006/time#>
1606
 select ?s ?o ?version
1607
 where {
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))
1613
 }"))
1614
 
1615
 (pprint-sse
1616
   (parse-sparql "
1617
 select ?s ?o ?version
1618
 where {
1619
  { ?s a ?o .
1620
     bind(str(?s) as ?sStr)}
1621
 } group by ?s"))
1622
 |#
1623
 
1624
 
1625