Coverage report: /development/source/library/org/datagraph/spocq-shard/src/core/terms.lisp

KindCoveredAll%
expression71261 27.2
branch04 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; -*-
2
 
3
 (in-package :org.datagraph.spocq)
4
 
5
 (:documentation "algebra engine term clases"
6
   "Most of the classes and their hierachy follow the specifications in the RDF - and following from that, the
7
  XSD and XPAth recommentations. In some aspects, however, the model adds fields or relations in order to
8
  facilitate the implmentation. For example temporals constitute a hierarchy and intermeidate pre-computed
9
  values provide the basis for comparison predicates. Based on the classes described in the XML schema documents
10
  'XML Schema Part 2: Datatypes Second Edition'[1] and
11
  'W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes'[2], in particular the 'built in datatypes'
12
  diagrams[3,4], the following classes are supported in the following relations:
13
 
14
  - term
15
    - literal
16
      - typed-literal
17
        - atomic-typed-literal
18
          - boolean
19
          - number
20
            - decimal
21
            - double
22
            - float
23
            - integer 
24
          - string
25
        - compound-typed-literal
26
          - temporal (all share universal-time and value fields)
27
            - date
28
            - date-time
29
            - duration (all share month-value and xecond-value fields)
30
              - day-time-duration
31
              - year-month-duration
32
            - gregorian
33
              - g-day
34
              - g-month
35
              - g-month-day
36
              - g-year
37
              - g-year-month
38
           - time
39
 
40
 To be considered:
41
  - a date, a date-time or a duration value may be negative.
42
  In thoses cases, for a duration, all composnests are negative while for a 
43
  date or date-time the year only is negative.
44
 
45
 
46
 [1] : http://www.w3.org/TR/xmlschema-2/
47
 [2] : http://www.w3.org/TR/xmlschema11-2/
48
 [3] : http://www.w3.org/TR/xmlschema-2/#built-in-datatypes
49
 [4] : http://www.w3.org/TR/xmlschema11-2/#built-in-datatypes
50
 ")
51
 
52
 (defconstant +reference-year+ 1972)
53
 (defconstant +reference-month+ 1)
54
 (defconstant +reference-day+ 1)
55
 (defconstant +reference-minute+ 0)
56
 (defconstant +reference-hour+ 0)
57
 (defconstant +reference-second+ 0)
58
 (defconstant +reference-fraction+ 0)
59
 (defconstant +reference-zone+ 0)
60
 
61
 (defstruct term
62
   id)
63
 
64
 (defstruct (non-literal (:include term))
65
   )
66
 
67
 (defstruct (blank-node (:include non-literal) (:constructor make-blank-node (label)))
68
   (label (error "label is required.") :type cl:string)
69
   (constant-p nil))
70
 
71
 (defstruct (iri (:include non-literal) (:constructor make-iri (lexical-form)))
72
   (lexical-form (error "lexical-form is required") :type cl:string))
73
 (defstruct (uuid (:include iri) (:constructor make-uuid (lexical-form)))
74
   )
75
 (defstruct (url (:include iri) (:constructor make-url (lexical-form)))
76
   )
77
 (defstruct (http-url (:include url) (:constructor make-http-url (lexical-form)))
78
   )
79
 (defstruct (mailto-url (:include url) (:constructor make-mailto-url (lexical-form)))
80
   )
81
 (defstruct (file-url (:include url) (:constructor make-file-url (lexical-form)))
82
   )
83
 (defstruct (urn (:include iri) (:constructor make-urn (lexical-form)))
84
   )
85
 (defstruct (sha256-urn (:include iri) (:constructor make-sha256-urn (lexical-form)))
86
   )
87
 
88
 (defstruct (literal (:include term))
89
   (lexical-form nil :type (or null cl:string)))
90
 
91
 (defstruct (plain-literal (:include literal) (:constructor make-plain-literal (lexical-form language-tag)))
92
   (language-tag (error "language-tag is required") :type (or cl:string null)))
93
 
94
 (defstruct (typed-literal (:include literal))
95
   )
96
 
97
 (defstruct (unsupported-typed-literal (:include typed-literal) (:constructor make-unsupported-typed-literal
98
                                                                                 (lexical-form datatype-uri
99
                                                                                               &optional condition)))
100
   (datatype-uri (error "datatype-uri is required") :type (or spocq:iri symbol))
101
   (condition nil))
102
 
103
 (defstruct (atomic-typed-literal (:include typed-literal))
104
   (value nil))
105
 
106
 (defstruct (compound-typed-literal (:include typed-literal))
107
   )
108
 
109
 (defstruct (boolean (:include atomic-typed-literal) (:constructor make-boolean-aux (lexical-form value))))
110
 (defstruct (number (:include atomic-typed-literal)))
111
 (defstruct (decimal(:include number) ))
112
 (defstruct (double (:include number)))
113
 (defstruct (float (:include number)))
114
 (defstruct (integer (:include decimal)))
115
 (defstruct (string (:include atomic-typed-literal)))
116
 
117
 (deftype temporal-fragment () 'fixnum)
118
 (deftype timeline-location () '(signed-byte 64))
119
 (deftype zone-fragment () '(real -14 14))
120
 
121
 
122
 (defstruct (temporal (:include compound-typed-literal))
123
   "Provide the shared structure for all temporal values. This includes
124
  - a numeric location field, which serves as the timeline location, as basis for
125
    comparisons and combinations
126
  - a zone field (which defaults to ZULU
127
  All values fragments are canonicalized to zulu time.
128
  A non-sero zone is reatined for reference and conversion."
129
   (timeline-location nil :type (or timeline-location null))
130
   (zone nil))
131
 
132
 (defstruct (interval (:include compound-typed-literal))
133
   (start nil )
134
   (end nil ))
135
 
136
 (defstruct (date-interval (:include interval))
137
   )
138
 
139
 (defstruct (date-time-interval (:include interval))
140
   )
141
 
142
 (defstruct (time-interval (:include interval))
143
   )
144
 
145
 (deftype revision-designator ()
146
   `(or fixnum spocq.i::repository-revision
147
        (satisfies spocq.i::is-uuid-string)
148
        (satisfies spocq.i::uuid-vector-p)
149
        rlmdb:revision-record
150
        uuid))
151
 
152
 (defstruct (spocq:revision-interval (:include spocq:time-interval
153
                                               (start nil :type revision-designator)
154
                                               (end nil :type (or revision-designator null))))
155
   "A revision-interval provides, as its start and end, the respective revisions
156
   which ensure the validity of the statements which it 'contains'.
157
   As revision designators it permits
158
   - rlmdb revision records
159
   - fixnum ordinals
160
   - revision instances
161
   - string uuids
162
   - vector uuid timestamps
163
   - uuid instances
164
   Any accessor functions resolves the state respective their result types.
165
   The lexical form is the iso8601 time interval for the respective revisions.")
166
 
167
 (defstruct (temporal-location (:include temporal))
168
   )
169
 
170
 (defstruct (gregorian (:include temporal (zone nil)))
171
   (year nil :type (or temporal-fragment null))
172
   (month nil :type (or temporal-fragment null))
173
   (day nil :type (or temporal-fragment null))
174
   (hour nil :type (or temporal-fragment null))
175
   (minute nil :type (or temporal-fragment null))
176
   (second nil :type (or temporal-fragment null)))
177
 
178
 (defstruct (date (:include temporal-location (zone 0)))
179
   "A data adds the facets for a from yeard to minutes, sufficient for a zoned daz
180
  and implements in integer timeline location value."
181
   (year nil :type (or temporal-fragment null))
182
   (month nil :type (or temporal-fragment null))
183
   (day nil :type (or temporal-fragment null))
184
   (hour nil :type (or temporal-fragment null))
185
   (minute nil :type (or temporal-fragment null)))
186
 
187
 (defstruct (date-time (:include temporal-location))
188
   "A date-time adds field to record distinct facets from years to seconds and
189
  implements a real timeline location value which allows for fractional seconds."
190
   (year nil :type (or temporal-fragment null))
191
   (month nil :type (or temporal-fragment null))
192
   (day nil :type (or temporal-fragment null))
193
   (hour nil :type (or temporal-fragment null))
194
   (minute nil :type (or temporal-fragment null))
195
   (second nil :type (or temporal-fragment null))
196
   (fraction nil :type (or temporal-fragment null))
197
   )
198
 
199
 
200
 ;;; the abstract class specifies the structure, but leaves all slots null
201
 ;;; each concrete class provides default values for implicit slots to facilitate combinations,
202
 ;;; but leaves the topical slots null to permit lazy decoding.
203
 
204
 (defstruct (duration (:include temporal (zone 0)))
205
   "The abstract duration class introduces a months-value and a second-value,
206
  integer and real, respectively, to supply to operators."
207
   (year nil :type (or fixnum null))
208
   (month  nil :type (or temporal-fragment null))
209
   (day  nil :type (or temporal-fragment null))
210
   (hour  nil :type (or temporal-fragment null))
211
   (minute  nil :type (or temporal-fragment null))
212
   (second  nil :type (or temporal-fragment null))
213
   (fraction  nil :type (or temporal-fragment null))
214
   (month-location nil :type (or timeline-location null))
215
   (second-location nil :type (or timeline-location null))
216
   )
217
 
218
 (defstruct (day-time-duration (:include duration
219
                                         (fraction 0)
220
                                         (second nil)
221
                                         (minute nil)
222
                                         (hour nil)
223
                                         (day nil)
224
                                         (month 0) (year 0))))
225
 
226
 (defstruct (g-day (:include gregorian
227
                             (second +reference-second+) (minute +reference-minute+) (hour +reference-hour+)
228
                             (day nil)
229
                             (month +reference-month+) (year +reference-year+))))
230
 
231
 (defstruct (g-month (:include gregorian
232
                               (second 0) (minute 0) (hour 0) (day +reference-day+)
233
                               (month nil)
234
                               (year +reference-year+))))
235
 
236
 (defstruct (g-month-day (:include gregorian
237
                                   (second +reference-second+) (minute +reference-minute+) (hour +reference-hour+)
238
                                   (day nil) (month nil)
239
                                   (year +reference-year+))) )
240
 
241
 (defstruct (g-year (:include gregorian
242
                              (second +reference-second+) (minute +reference-minute+) (hour +reference-hour+)
243
                              (day +reference-day+) (month +reference-month+)
244
                              (year nil))) )
245
 
246
 (defstruct (g-year-month (:include gregorian
247
                              (second +reference-second+) (minute +reference-minute+) (hour +reference-hour+)
248
                              (day +reference-day+)
249
                              (month nil)
250
                              (year nil))) )
251
 
252
 (defstruct (time (:include temporal-location))
253
   (year nil :type (or temporal-fragment null))          ; must reatin hh:mm:ss for offset
254
   (month nil :type (or temporal-fragment null))         ; zones in order to compute the timeline position
255
   (day nil :type (or temporal-fragment null))
256
   (hour nil :type (or temporal-fragment null))
257
   (minute nil :type (or temporal-fragment null))
258
   (second nil :type (or temporal-fragment null))
259
   (fraction nil :type (or temporal-fragment null))
260
   )
261
 
262
 (defstruct (year-month-duration (:include duration
263
                                           (fraction 0) (second 0) (minute 0) (hour 0) (day 0)
264
                                           (month nil)
265
                                           (year nil))) )
266
 
267
 (defstruct (unbound-variable (:constructor make-unbound-variable (name)))
268
   name)
269
 
270
 
271
 ;;; integer variations
272
 (defstruct (|xsd|:|integer| (:include integer)))
273
 (defstruct (|xsd|:|nonPositiveInteger| (:include |xsd|:|integer|)))
274
 (defstruct (|xsd|:|nonNegativeInteger| (:include |xsd|:|integer|)))
275
 (defstruct (|xsd|:|long| (:include |xsd|:|integer|)))
276
 (defstruct (|xsd|:|negativeInteger| (:include |xsd|:|nonPositiveInteger|)))
277
 (defstruct (|xsd|:|int| (:include |xsd|:|long|)))
278
 (defstruct (|xsd|:|short| (:include |xsd|:|int|)))
279
 (defstruct (|xsd|:|byte| (:include |xsd|:|short|)))
280
 (defstruct (|xsd|:|unsignedLong| (:include |xsd|:|nonNegativeInteger|)))
281
 (defstruct (|xsd|:|unsignedInt| (:include |xsd|:|unsignedLong|)))
282
 (defstruct (|xsd|:|unsignedShort| (:include |xsd|:|unsignedInt|)))
283
 (defstruct (|xsd|:|unsignedByte| (:include |xsd|:|unsignedShort|)))
284
 (defstruct (|xsd|:|positiveInteger| (:include |xsd|:|nonNegativeInteger|)))
285
 
286
 (defmethod de.setf.resource:identifier-p ((object iri)) t)
287
 
288
 (defmethod print-object ((object iri) stream)
289
   (format stream "<~a>" (iri-lexical-form object)))
290
 (defmethod print-object ((object blank-node) stream)
291
   (format stream "<_:~a>" (blank-node-label object)))
292
 
293
 (defgeneric literal-datatype-uri (literal)
294
   (:method ((literal plain-literal))
295
     #+(or) ; as of WD-sparql11-query-20120105 a plain literal has a type
296
     (error 'simple-type-error :datum literal :expected-type |xsd|:|string|
297
               :format-control "A plain literal has no datatype uri: ~s." literal)
298
     '|rdf|:|langString|)
299
   (:method ((object boolean))   '|xsd|:|boolean|)
300
   (:method ((object date))      '|xsd|:|date|)
301
   (:method ((object date-time)) '|xsd|:|dateTime|)
302
   (:method ((object day-time-duration))  '|xsd|:|dayTimeDuration|)
303
   (:method ((object decimal))   '|xsd|:|decimal|)
304
   (:method ((object double))    '|xsd|:|double|)
305
   (:method ((object duration))  '|xsd|:|duration|)
306
   (:method ((object float))     '|xsd|:|float|)
307
   (:method ((object g-day))  '|xsd|:|gDay|)
308
   (:method ((object g-month))  '|xsd|:|gMonth|)
309
   (:method ((object g-month-day))  '|xsd|:|gMonthDay|)
310
   (:method ((object g-year))  '|xsd|:|gYear|)
311
   (:method ((object g-year-month))  '|xsd|:|gYearMonth|)
312
   (:method ((object integer))   '|xsd|:|integer|)
313
   (:method ((object string))    '|xsd|:|string|)
314
   (:method ((object time))  '|xsd|:|time|)
315
   (:method ((object year-month-duration))  '|xsd|:|yearMonthDuration|)
316
   (:method ((object |xsd|:|integer|)) (type-of object))
317
   (:method ((object unsupported-typed-literal)) (unsupported-typed-literal-datatype-uri object)))
318
   
319
 
320
 ;;;
321
 ;;; load forms
322
 
323
 (defvar spocq.a:|true| (make-boolean-aux "true" t))
324
 (defvar spocq.a:|false| (make-boolean-aux "false" nil))
325
 (defvar spocq.a:|unbound| (make-unbound-variable nil))
326
 
327
 
328
 
329
 (defun make-boolean (lexical-form)
330
   (cond ((string-equal lexical-form "true") spocq.a:|true|)
331
         ((string-equal lexical-form "false") spocq.a:|false|)
332
         (t (error 'simple-type-error
333
                   :datum lexical-form :expected-type |xsd|:|boolean|
334
                   :format-control "A boolean literal must be true or false: ~s."
335
                   :format-arguments (list lexical-form)))))
336
 
337
 ;;; define make-load-form methods for the concrete classes only.
338
 ;;; thus neither temporal nor duration has a definition
339
 
340
 (macrolet ((mlf (class form)
341
                 `(defmethod make-load-form ((object ,class) &optional env)
342
                    (declare (ignore env))
343
                    (values ,form nil))))
344
   (mlf blank-node `(make-blank-node ,(blank-node-label object)))
345
   (mlf iri `(make-iri ,(iri-lexical-form object)))
346
   (mlf uuid `(make-uuid ,(iri-lexical-form object)))
347
   (mlf urn `(make-urn ,(iri-lexical-form object)))
348
   (mlf sha256-urn `(make-sha256-urn ,(iri-lexical-form object)))
349
   (mlf plain-literal `(make-plain-literal ,(literal-lexical-form object)
350
                                           ,(plain-literal-language-tag object)))
351
   (mlf typed-literal (list 'make-unsupported-typed-literal
352
                               (literal-lexical-form object)
353
                               (literal-datatype-uri object)))
354
   (mlf date `(make-date :lexical-form ,(literal-lexical-form object)
355
                         :year ,(date-year object)
356
                         :month ,(date-month object)
357
                         :day ,(date-day object)
358
                         :hour ,(date-hour object)
359
                         :minute ,(date-minute object)
360
                         :zone ,(temporal-zone object)))
361
   (mlf date-time `(make-date-time :lexical-form ,(literal-lexical-form object)
362
                                   :year ,(date-time-year object)
363
                                   :month ,(date-time-month object)
364
                                   :day ,(date-time-day object)
365
                                   :hour ,(date-time-hour object)
366
                                   :minute ,(date-time-minute object)
367
                                   :second ,(date-time-second object)
368
                                   :zone ,(temporal-zone object)))
369
   (mlf day-time-duration `(make-day-time-duration :lexical-form ,(literal-lexical-form object)
370
                                                   :day ,(day-time-duration-day object)
371
                                                   :hour ,(day-time-duration-hour object)
372
                                                   :minute ,(day-time-duration-minute object)
373
                                                   :second ,(day-time-duration-second object)
374
                                                   :zone ,(temporal-zone object)))
375
   (mlf g-day `(make-g-day :lexical-form ,(literal-lexical-form object)
376
                           :day ,(g-day-day object)
377
                           :zone ,(temporal-zone object)))
378
   (mlf g-month `(make-g-month :lexical-form ,(literal-lexical-form object)
379
                               :month ,(g-month-month object)
380
                               :zone ,(temporal-zone object)))
381
   (mlf g-month-day `(make-g-month-day :lexical-form ,(literal-lexical-form object)
382
                                       :month ,(g-month-day-month object)
383
                                       :day ,(g-month-day-day object)
384
                                       :zone ,(temporal-zone object)))
385
   (mlf g-year `(make-g-year :lexical-form ,(literal-lexical-form object)
386
                             :year ,(g-year-year object)
387
                             :zone ,(temporal-zone object)))
388
   (mlf g-year-month `(make-g-year-month :lexical-form ,(literal-lexical-form object)
389
                                         :year ,(g-year-month-year object)
390
                                         :month ,(g-year-month-month object)
391
                                         :zone ,(temporal-zone object)))
392
   (mlf time `(make-time :lexical-form ,(literal-lexical-form object)
393
                         :hour ,(time-hour object)
394
                         :minute ,(time-minute object)
395
                         :second ,(time-second object)
396
                         :zone ,(temporal-zone object)))
397
   (mlf year-month-duration `(make-year-month-duration :lexical-form ,(literal-lexical-form object)
398
                                                       :year ,(year-month-duration-year object)
399
                                                       :month ,(year-month-duration-month object)
400
                                                       :zone ,(temporal-zone object))))
401
 
402
 (defmethod  n3:print-property ((term spocq:iri) stream)
403
   (format stream "<~a>" (spocq:iri-lexical-form term)))
404
 (defmethod  n3:print-property ((term spocq:date) stream)
405
   (format stream "\"~/spocq:format-date/\"^^<http://www.w3.org/2001/XMLSchema#date>"
406
            term))
407
 (defmethod  n3:print-property ((term spocq:date-time) stream)
408
   ;;;!!! this needs to use spocq.i::term-lexical-form in order to handle negative dates
409
   (format stream "\"~/spocq:format-date-time/\"^^<http://www.w3.org/2001/XMLSchema#dateTime>"
410
           term))
411
 (defmethod  n3:print-property ((term spocq:time) stream)
412
   (format stream "\"~/spocq:format-time/\"^^<http://www.w3.org/2001/XMLSchema#date>"
413
           term))
414
 (defmethod  n3:print-property ((term spocq:blank-node) stream)
415
   (format stream "_:~a" (spocq:blank-node-label term)))