Coverage report: /development/source/library/org/datagraph/spocq-shard/src/core/terms.lisp
| Kind | Covered | All | % |
| expression | 71 | 261 | 27.2 |
| branch | 0 | 4 | 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; -*-
3
(in-package :org.datagraph.spocq)
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:
17
- atomic-typed-literal
25
- compound-typed-literal
26
- temporal (all share universal-time and value fields)
29
- duration (all share month-value and xecond-value fields)
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.
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
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)
64
(defstruct (non-literal (:include term))
67
(defstruct (blank-node (:include non-literal) (:constructor make-blank-node (label)))
68
(label (error "label is required.") :type cl:string)
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)))
75
(defstruct (url (:include iri) (:constructor make-url (lexical-form)))
77
(defstruct (http-url (:include url) (:constructor make-http-url (lexical-form)))
79
(defstruct (mailto-url (:include url) (:constructor make-mailto-url (lexical-form)))
81
(defstruct (file-url (:include url) (:constructor make-file-url (lexical-form)))
83
(defstruct (urn (:include iri) (:constructor make-urn (lexical-form)))
85
(defstruct (sha256-urn (:include iri) (:constructor make-sha256-urn (lexical-form)))
88
(defstruct (literal (:include term))
89
(lexical-form nil :type (or null cl:string)))
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)))
94
(defstruct (typed-literal (:include literal))
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))
103
(defstruct (atomic-typed-literal (:include typed-literal))
106
(defstruct (compound-typed-literal (:include typed-literal))
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)))
117
(deftype temporal-fragment () 'fixnum)
118
(deftype timeline-location () '(signed-byte 64))
119
(deftype zone-fragment () '(real -14 14))
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))
132
(defstruct (interval (:include compound-typed-literal))
136
(defstruct (date-interval (:include interval))
139
(defstruct (date-time-interval (:include interval))
142
(defstruct (time-interval (:include interval))
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
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
162
- vector uuid timestamps
164
Any accessor functions resolves the state respective their result types.
165
The lexical form is the iso8601 time interval for the respective revisions.")
167
(defstruct (temporal-location (:include temporal))
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)))
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)))
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))
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.
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))
218
(defstruct (day-time-duration (:include duration
224
(month 0) (year 0))))
226
(defstruct (g-day (:include gregorian
227
(second +reference-second+) (minute +reference-minute+) (hour +reference-hour+)
229
(month +reference-month+) (year +reference-year+))))
231
(defstruct (g-month (:include gregorian
232
(second 0) (minute 0) (hour 0) (day +reference-day+)
234
(year +reference-year+))))
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+))) )
241
(defstruct (g-year (:include gregorian
242
(second +reference-second+) (minute +reference-minute+) (hour +reference-hour+)
243
(day +reference-day+) (month +reference-month+)
246
(defstruct (g-year-month (:include gregorian
247
(second +reference-second+) (minute +reference-minute+) (hour +reference-hour+)
248
(day +reference-day+)
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))
262
(defstruct (year-month-duration (:include duration
263
(fraction 0) (second 0) (minute 0) (hour 0) (day 0)
267
(defstruct (unbound-variable (:constructor make-unbound-variable (name)))
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|)))
286
(defmethod de.setf.resource:identifier-p ((object iri)) t)
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)))
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)
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)))
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))
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)))))
337
;;; define make-load-form methods for the concrete classes only.
338
;;; thus neither temporal nor duration has a definition
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))))
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>"
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>"
411
(defmethod n3:print-property ((term spocq:time) stream)
412
(format stream "\"~/spocq:format-time/\"^^<http://www.w3.org/2001/XMLSchema#date>"
414
(defmethod n3:print-property ((term spocq:blank-node) stream)
415
(format stream "_:~a" (spocq:blank-node-label term)))