Coverage report: /development/source/library/org/datagraph/spocq-shard/src/core/encoding/json-ld/low-level-api.lisp

KindCoveredAll%
expression3984 0.3
branch0126 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 "low-level api"
6
   "These operators implement the primitive JSON-LD context and term algorithms:
7
  - merge-contexts : the core of context instantiation
8
  - create-term-definition : instantiate a term definition for a given key based on the
9
    declaration in a local context and the existing definition in an active context
10
  - expand-iri : interpret an iri designator in context
11
  - expand-element : provides object-walking control for expand-iri and error checking
12
 ")
13
 
14
 
15
 ;;; json-ld context processing
16
 
17
 (defparameter *json-ld-cache* (make-hash-table :test 'equal))
18
 (defparameter json-ld::*verbose* nil)
19
 
20
 (defgeneric json-ld:get-json-ld (location)
21
   ;; need to handle redirection
22
   (:method ((location spocq:iri))
23
     (let ((key (spocq:iri-lexical-form location)))
24
     (or (gethash key *json-ld-cache*)
25
         (setf (gethash key *json-ld-cache*)
26
               (handler-case (parse-json location :accept "application/ld+json, application/json")
27
                 (error (condition)
28
                        (json-ld:loading-remote-context-failed-error :location location
29
                                                                     :condition condition)))))))
30
   (:method ((location string))
31
     (when (eql (char location 0) #\<)
32
         (setf location (subseq location 1 (1- (length location)))))
33
     (json-ld:get-json-ld (merge-and-intern-iri location :base-iri (json-ld:base-iri))))
34
   (:method ((location pathname))
35
     (or (gethash location *json-ld-cache*)
36
         (setf (gethash location *json-ld-cache*)
37
               (parse-json location)))))
38
 
39
 
40
 (defgeneric json-ld:merge-contexts (base addition)
41
   (:documentation "The core of context operator is to merge two contexts, the two principle use cases
42
     being instantiation, in which the context declaration is merged with a null context, and extension,
43
     in which a declaration is merged with an existing context.")
44
 
45
   ;; 3
46
   (:method ((active-context json-ld:context) (addition vector))
47
     (loop for addition across addition
48
       do (setf active-context (json-ld:merge-contexts active-context addition)))
49
     active-context)
50
   (:method ((active json-ld:context) (addition null))
51
     ;; given a null addition clear the result
52
     (clone-instance active))
53
 
54
   ;; 3.1
55
   ;; the recommendation describes, the effect of a base option in the JSON-LD API invocation is to
56
   ;; "over-ride the base IRI". thus, in this context, that invocation-specific value is the new base
57
   ;; value, rather than clearin git to null. 
58
   (:method ((active json-ld:context) (addition (eql :|null|)))
59
     ;; given a null addition clear the result
60
     (make-instance 'json-ld:context :base (json-ld:base-iri)))
61
 
62
   ;; 3.2
63
   (:method ((active json-ld:context) (addition t))
64
     (json-ld:invalid-local-context-error :datum addition))
65
 
66
   ;; 3.3
67
   (:method ((active json-ld:context) (addition string))
68
     (json-ld:merge-contexts active (merge-and-intern-iri addition :base-iri (json-ld:base-iri))))
69
 
70
   (:method ((active json-ld:context) (addition spocq:iri))
71
     (when (find (iri-lexical-form addition) *json-ld-context-references*)
72
       (json-ld:recursive-content-inclusion-error :location addition))
73
     (let* ((json-ld (json-ld:get-json-ld addition))
74
            (addition (json-ld:object-member-value json-ld @:|@context|)))
75
       (if addition
76
         (json-ld:merge-contexts active addition)
77
         (json-ld:invalid-remote-context-error :location addition))))
78
 
79
   (:method ((active-context json-ld:context) (addition json-ld:context))
80
     (json-ld:merge-contexts active-context (json-ld:object-members addition)))
81
 
82
   ;; the interesting part: a context instance with an alist of definitions
83
   (:method ((active-context json-ld:context) (addition cons))
84
     ;; if the addition is itself a context definition, continue with its parts
85
     (cond ((json-ld:object-member addition @:|@context|)
86
            (json-ld:merge-contexts active-context (json-ld:object-member-value addition @:|@context|)))
87
           (t
88
            (setf (json-ld:object-members active-context)
89
                  (append addition (json-ld:object-members active-context)))
90
            (let ((addition-base (json-ld:object-member-value addition @:|@base|)))
91
              ;; 3.4
92
              (cond ((or (null addition-base) *json-ld-context-references*) )
93
                    ((eq addition-base  :|null|)
94
                     (setf (json-ld:object-base active-context) nil))
95
                    ((json-ld:absolute-iri-p addition-base)
96
                     (setf (json-ld:object-base active-context) (intern-iri addition-base)))
97
                    ((json-ld:object-base active-context)
98
                     (setf (json-ld:object-base active-context)
99
                           (merge-and-intern-iri addition-base :base-iri (json-ld:object-base active-context))))
100
                    (t (json-ld:invalid-base-iri-error :datum addition-base))))
101
            ;; 3.5
102
            (let ((addition-vocabulary (json-ld:object-member-value addition @:|@vocab|)))
103
              (when addition-vocabulary
104
                (setf (json-ld:context-vocabulary active-context) addition-vocabulary)))
105
            ;; 3.6
106
            (let ((addition-language (json-ld:object-member-value addition @:|@language|)))
107
              (when addition-language
108
                (setf (json-ld:context-language active-context) addition-language)))
109
            ;; 3.7,8: the individual definitions
110
            (loop for (name . value) in addition
111
              for name-key = (json-ld:keywordp name)
112
              for value-key = (json-ld:keywordp value)
113
              do (cond ((member name-key '(@:|@base| @:|@language| @:|@vocab|))
114
                        )
115
                       ((or (zerop (length name)) (eql (char name 0) #\@))
116
                        (when json-ld::*verbose* (log-warn "json-ld:merge-contexts : key ignored: ~s: ~s"
117
                                                           name value)))
118
                       (value-key
119
                        (print (list :mc.alias-map name value value-key))
120
                        (setf (key-alias active-context value-key) name))
121
                       (t
122
                        (json-ld:create-term-definition active-context addition name ()))))
123
            active-context))))
124
 
125
 
126
 (defun json-ld:create-term-definition (active-context local-context key defined)
127
   "instantiate a term definition for a given key based on the
128
    declaration in a local context and the existing definition in an active context"
129
 
130
   (ecase (rest (assoc key defined :test #'string=))
131
     (:true )
132
     ;; 1
133
     (:false (json-ld:cyclic-iri-mapping-error :context local-context :term key))
134
     ((nil)
135
      ;; 2 : new definition
136
      (setf defined (acons key :false defined))
137
      ;; 3
138
      (when (json-ld:keywordp key)
139
        (json-ld:keyword-redefinition-error :context local-context :term key))
140
      ;; 4
141
      (setf (json-ld:find-term-definition active-context key) nil)
142
      ;; 5
143
      (let ((value (json-ld:object-member-value local-context key)))
144
        (typecase value
145
          ((eql :|null|)
146
           ;; 6
147
           (return-from json-ld:create-term-definition nil))
148
          (cons (when (eq :|null| (json-ld:object-member-value value @:|@id|))
149
                  ;; 6
150
                  (return-from json-ld:create-term-definition nil)))
151
          ;; 7
152
          (string (setf value (acons @:|@id| value nil)))
153
          ;; 8
154
          (t (json-ld:invalid-term-definition-error :key key :datum value)))
155
        (let ((definition (json-ld:make-term-definition :key key))
156
              (type (json-ld:object-member-value value @:|@type|))
157
              (reverse (json-ld:object-member-value value @:|@reverse|))
158
              (id (json-ld:object-member-value value @:|@id|))
159
              (container (json-ld:object-member-value value @:|@container|))
160
              (language (json-ld:object-member-value value @:|@language|)))
161
          (flet ((define-term-and-return ()
162
                   (setf (json-ld:find-term-definition active-context key) definition)
163
                   (return-from json-ld:create-term-definition definition)))
164
            ;; 10
165
            (when type
166
              (typecase type
167
                (string
168
                 ;; when a string, expand wrt the active/local context
169
                 (setf (json-ld:term-definition-type definition) (json-ld:expand-iri active-context type
170
                                                                                     :vocabulary-p t
171
                                                                                     :relative-p nil
172
                                                                                     :local-context local-context
173
                                                                                     :defined defined)))
174
                (t
175
                 ;; otherwise, attempt to set as-is
176
                 (setf (json-ld:term-definition-type definition) type))))
177
            ;; 11
178
            (when reverse
179
              (when id (json-ld:invalid-reverse-property-error :datum value))
180
              (typecase reverse
181
                (string (let ((expanded-reverse (json-ld:expand-iri active-context reverse
182
                                                                    :vocabulary-p t
183
                                                                    :relative-p nil
184
                                                                    :local-context local-context
185
                                                                    :defined defined)))
186
                          (typecase expanded-reverse
187
                            ((or absolute-iri spocq:blank-node)
188
                             (setf (json-ld:term-definition-term definition) expanded-reverse))
189
                            (t
190
                             (json-ld:invalid-iri-mapping-error :datum value))))
191
                        (when container
192
                          (unless (member container '(@:|@set| @:|@index|) :test #'json-ld:key=)
193
                            (json-ld:invalid-reverse-property-error :datum value))
194
                           (setf (json-ld:term-definition-container definition) container))
195
                        (setf (json-ld:term-definition-reverse-property definition) t)
196
                        (define-term-and-return))
197
                (t (json-ld:invalid-iri-mapping-error :datum value :clause "11.3"))))
198
            ;; 12
199
            (setf (json-ld:term-definition-reverse-property definition) nil)
200
            ;; 13
201
            (cond ((and id (not (equalp id key)))
202
                   (typecase id
203
                     ;; 13.2
204
                     (string (let ((expanded-id (json-ld:expand-iri active-context id
205
                                                                    :vocabulary-p t
206
                                                                    :relative-p nil
207
                                                                    :local-context local-context
208
                                                                    :defined defined)))
209
                               (typecase expanded-id
210
                                 ((or json-ld:keyword absolute-iri spocq:blank-node)
211
                                  (setf (json-ld:term-definition-term definition) expanded-id))
212
                                 (t
213
                                  (json-ld:invalid-iri-mapping-error :datum (list :value value :expanded-id expanded-id)
214
                                                                     :clause "13.2")))))
215
                     ;; 13.1
216
                     (t (json-ld:invalid-iri-mapping-error :datum value
217
                                                           :clause "13.1"))))
218
                  ((find #\: (string key))
219
                   (multiple-value-bind (prefix local-part) (parse-qname key)
220
                     ;; 14.1
221
                     (when (json-ld:object-member-value local-context prefix)
222
                       (json-ld:create-term-definition active-context local-context prefix defined))
223
                     (let ((prefix-definition (json-ld:find-term-definition active-context prefix)))
224
                       (setf (json-ld:term-definition-term definition)
225
                             (cond (prefix-definition
226
                                    ;; 14.2
227
                                    (concatenate 'string
228
                                                 (iri-lexical-form (json-ld:term-definition-term prefix-definition))
229
                                                 local-part))
230
                                   ;; 14.3
231
                                   ((and (equal prefix "_"(is-blank_node_label local-part))
232
                                    (setf (json-ld:term-definition-term definition)
233
                                          (json-ld:make-blank-node local-part)))
234
                                   (t
235
                                    (json-ld:make-iri key)))))))
236
                  ;; 15
237
                  ((json-ld:context-vocabulary active-context)
238
                   (setf (json-ld:term-definition-term definition)
239
                         (concatenate 'string
240
                                      (iri-lexical-form (json-ld:context-vocabulary active-context))
241
                                      (string key))))
242
                  (t
243
                   (json-ld:invalid-iri-mapping-error :datum value :clause "create-term-definition:15")))
244
            (when container
245
              (setf (json-ld:term-definition-container definition) container))
246
            (when language
247
              (setf (json-ld:term-definition-language definition) language))
248
            (define-term-and-return)))))))
249
 
250
      
251
 (defgeneric json-ld:expand-iri (active-context key &key relative-p vocabulary-p local-context defined base-iri)
252
   (:documentation "re-interpret the given iri with respect to the active (and optionally the local) context.
253
    This allows qname expansion and term mapping.
254
    Return an absolute iri or a blank node")
255
 
256
   (:method ((active-context json-ld:context) (key null) &key &allow-other-keys)
257
     nil)
258
 
259
   (:method ((active-context json-ld:context) (key symbol) &rest args)
260
     (declare (dynamic-extent args))
261
     (if (json-ld:keywordp key)
262
       key
263
       (apply #'json-ld:expand-iri active-context (iri-lexical-form key) args)))
264
 
265
   (:method ((active-context json-ld:context) (key spocq:iri) &rest args)
266
     (declare (dynamic-extent args))
267
     (apply #'json-ld:expand-iri active-context (iri-lexical-form key) args))
268
 
269
   (:method ((active-context json-ld:context) (key string) &key relative-p vocabulary-p local-context defined
270
                            (base-iri (json-ld:base-iri)))
271
     (cond ((json-ld:keywordp key)) ;; 1, returns the interned keyword
272
           (t
273
            ;; 2
274
            (when (and local-context (json-ld:object-member-value local-context key)
275
                       (not (eql :true (rest (assoc key defined :test #'equal)))))
276
              (json-ld:create-term-definition active-context local-context key defined))
277
            (cond ((and vocabulary-p
278
                        (json-ld:find-term-definition active-context key))
279
                   ;; 3
280
                   (json-ld:term-definition-term (json-ld:find-term-definition active-context key)))
281
                  ((find #\: key :test #'eql)
282
                   ;; 4
283
                   (multiple-value-bind (prefix local-part) (parse-qname key)
284
                     (cond ((and (equal prefix "_"(is-blank_node_label local-part))
285
                            ;; 4.2
286
                            (json-ld:make-blank-node key))
287
                           ((string-equal "//" local-part :end2 (min 2 (length local-part)))
288
                            ;; 4.2
289
                            (json-ld:make-iri key))
290
                           (t
291
                            (when (and (json-ld:object-member-value local-context prefix)
292
                                       (not (eql :true (rest (assoc prefix defined)))))
293
                              ;; 4.3
294
                              (json-ld:create-term-definition active-context local-context prefix defined))
295
                            (let ((definition (json-ld:find-term-definition active-context prefix)))
296
                              (if definition
297
                                  ;; 4.4 : n.b. _not_ an iri merge, but rather, a catenation
298
                                  (json-ld:make-iri (concatenate 'string
299
                                                                 (iri-lexical-form (json-ld:term-definition-term definition))
300
                                                                 local-part))
301
                                  ;; 4.5
302
                                  (json-ld:make-iri key)))))))
303
                  ;; 5
304
                  ((and vocabulary-p (json-ld:context-vocabulary active-context))
305
                   (json-ld:make-iri (concatenate 'string
306
                                                  (iri-lexical-form (json-ld:context-vocabulary active-context))
307
                                                  key)))
308
                  ;; 6
309
                  (relative-p
310
                   ;; n.b. _not_ catenated, but rather, an iri merge
311
                   (merge-and-intern-iri key :base-iri base-iri))
312
                  (t
313
                   (json-ld:make-iri key)))))))
314
                
315
     
316
 ;;; expansion
317
 
318
 (defgeneric json-ld:expand (context property element)
319
   (:method ((context t) (property t) (element t))
320
     (json-ld:expand-element nil context property element)))
321
 
322
 (defgeneric json-ld:expand-element (parent context property element)
323
   (:argument-precedence-order element property parent context)
324
   (:method ((parent t) (context t) (property t) (element t)) ; 2
325
     (json-ld:expand-value context property element)) ; 2.2
326
 
327
   (:method ((parent t) (context t) (property t) (element (eql :|null|))) ; 1
328
     :|null|)
329
   (:method ((parent t) (context t) (property (eql :|null|)) (element string))
330
     :|null|)
331
   (:method ((parent t) (context t) (property (eql @:|@graph|)) (element string))
332
     :|null|)
333
 
334
   (:method ((parent t) (context t) (property t) (element vector)) ; 3
335
     (let ((into (make-array (length element) :adjustable t :fill-pointer 0))
336
           (list-property-p (or (eq property @:|@list|) (eq (json-ld:find-term-definition-container context property) @:|@list|))))
337
       (loop for item across element
338
         for expanded-item = (json-ld:expand-element parent context property item) ; 3.2.1
339
         when (and list-property-p (or (json-ld:arrayp expanded-item) (json-ld:list-object-p expanded-item))) ; 3.2.2
340
         do (json-ld:list-of-lists-error :datum expanded-item) ; 3.2.3
341
         if (json-ld:arrayp expanded-item)
342
         do (loop for expanded-item-item across expanded-item
343
              do (vector-push-extend expanded-item-item into))
344
         else do (vector-push-extend expanded-item into))
345
       into))
346
 
347
   (:method ((parent t) (context t) (property t) (element list)) ; 4
348
     (json-ld:expand-object (json-ld:make-object ) context property element))
349
   (:method ((parent t) (context t) (property t) (element json-ld:object)) ; 4
350
     (json-ld:expand-object (json-ld:make-object ) context property element))
351
   (:method ((parent json-ld:frame) (context t) (property t) (element list)) ; 4
352
     (json-ld:expand-object (json-ld:make-frame :context context) context property element))
353
   (:method ((parent json-ld:frame) (context t) (property t) (element json-ld:object)) ; 4
354
     (json-ld:expand-object (json-ld:make-frame :context context) context property element))
355
   )
356
 
357
 
358
 (defgeneric json-ld:expand-value (context property scalar-value)
359
   (:documentation "Normalize a scalar-value to incorporate declarations from the context for
360
    id, vocab, type, and/or language. The json-ld 'Processing Algorithms and API' recommendation
361
    describes a process whcich computes an annotated JSON object. As these algorithms are implemented
362
    in terms of RDF terms, it avoids the circumlocution and computes the respective term directly.
363
    - @id or @vocab type mappings yield an IRI
364
    - @type yields an interned term
365
    - @language yields a xsd:langString
366
    ---
367
    [1]: http://www.w3.org/TR/json-ld-api/#value-expansion")
368
 
369
   (:method ((context json-ld:context) (property t) (scalar-value t))
370
     (let ((type (json-ld:find-term-definition-type context property)))
371
       (case type
372
         (@:|@id| (json-ld:expand-iri context property :relative-p t))
373
         (@:|@vocab| (json-ld:expand-iri context property :relative-p t :vocabulary-p t))
374
         ((nil) (cond ((stringp scalar-value)
375
                       (let ((language (or (json-ld:find-term-definition-language context property)
376
                                           (json-ld:context-language context))))
377
                         (typecase language
378
                           (string (intern-plain-literal scalar-value language))
379
                           (t scalar-value))))
380
                      (t
381
                       scalar-value)))
382
         (t
383
          (case scalar-value
384
            (:|true|
385
              (unless (equal type |xsd|:|boolean|)
386
                (invalid-argument-type json-ld:expand-value scalar-value |xsd|:|boolean|))
387
              spocq.a:|true|)
388
            (:|false|
389
              (unless (equal type |xsd|:|boolean|)
390
                (invalid-argument-type json-ld:expand-value scalar-value |xsd|:|boolean|))
391
              spocq.a:|false|)
392
            (:|null|
393
              |rdf|:|nil|)
394
            (t
395
             (typecase scalar-value
396
               (number scalar-value)
397
               (string (intern-literal scalar-value type))
398
               (t
399
                (when json-ld::*verbose*
400
                  (log-warn "unexpected json type to intern ~s : ~s" type scalar-value)))))))))))
401
 
402
 
403
 (defgeneric json-ld:expand-object (result context property object)
404
   (:method ((result json-ld:object) (context json-ld:context) (property t) (from t))
405
     (flet ((ensure-array (value)
406
              (typecase value
407
                (json-ld:array value)
408
                (t (make-array 1 :fill-pointer 1 :adjustable t :initial-contents (list value))))))
409
       (let ((local-context (json-ld:object-member-value from @:|@context|)))
410
         (when local-context ; 5
411
           (setf context (json-ld:merge-contexts context local-context))))
412
       (when (json-ld:frame-p result)
413
         (setf (json-ld:frame-context result) context))
414
       (json-ld:map-members (key value) from ; 7
415
         ;; (print (list :map-members "7" key value))
416
         (unless (json-ld:key= key @:|@context|) ; 7.1
417
           (let ((expanded-key (json-ld:expand-iri context key :vocabulary-p t)) ; 7.2
418
                 (expanded-value nil))
419
             ;; (print (list "7.4.start" expanded-key value expanded-value))
420
             (cond ((or (eq expanded-key :|null|)
421
                        (and (not (json-ld:keywordp expanded-key))
422
                             (not (iri-p expanded-key))))) ; 7.3
423
                   ((json-ld:keywordp expanded-key) ; 7.4
424
                     ;; 7.4.1
425
                     (when (eq property @:|@reverse|)
426
                       (json-ld:invalid-reverse-property-map-error :datum expanded-key))
427
                     ;; 7.4.2
428
                     (when (json-ld:object-member context expanded-key)
429
                       (json-ld:colliding-keywords-error :datum expanded-key))
430
                     (case expanded-key
431
                       (@:|@id| ; 7.4.3
432
                          (unless (stringp value)
433
                             (json-ld:invalid-type-value-error :datum value))
434
                          (setf expanded-value (json-ld:expand-iri context value
435
                                                                   :relative-p t)))
436
                       (@:|@type| ; 7.4.4 . says string or array of such, but framr 2.2 allows an empty object
437
                          (typecase value
438
                            (string (setf expanded-value (json-ld:expand-iri context value
439
                                                                             :vocabulary-p t
440
                                                                             :relative-p t)))
441
                            (json-ld:array
442
                             (setf expanded-value (make-array (length value)))
443
                             (loop for value across value
444
                               for i from 0
445
                               if (stringp value)
446
                               do (setf (aref expanded-value i) (json-ld:expand-iri context value
447
                                                                                    :vocabulary-p t
448
                                                                                    :relative-p t))
449
                               else do (json-ld:invalid-type-value-error :datum value)))
450
                            (null
451
                             (setf expanded-value (json-ld:make-object )))
452
                            (t
453
                             (json-ld:invalid-type-value-error :datum value))))
454
                       (@:|@graph| ; 7.4.5
455
                          (setf expanded-value (json-ld:expand-element result context property value)))
456
                       (@:|@value| ; 7.4.6
457
                          (unless (or (json-ld:atomp value) (json-ld:null value))
458
                            (json-ld:invalid-value-object-value-error :datum value))
459
                          (setf expanded-value value)
460
                          (when (eq value :|null|)
461
                            (setf (json-ld:object-member-value result @:|@value|) value)))
462
                       (@:|@language| ; 7.4.7
463
                          (unless (stringp value)
464
                            (json-ld:invalid-language-tagged-string-error :datum expanded-value))
465
                          (setf expanded-value (string-downcase value)))
466
                       (@:|@index| ; 7.4.8
467
                          (unless (stringp value)
468
                            (json-ld:invalid-index-value-error :datum expanded-value))
469
                          (setf expanded-value value))
470
                       (@:|@list| ; (print  "7.4.9")
471
                          (unless (or (json-ld:null property) (eq property @:|@graph|))
472
                            (setf expanded-value (json-ld:expand-element result context property value))
473
                            (when (json-ld:list-object-p expanded-value)
474
                              (json-ld:list-of-lists-error :datum expanded-value))))
475
                       (@:|@set| ; 7.4.10
476
                           (setf expanded-value (json-ld:expand-element result context property value)))
477
                       (@:|@reverse| ; 7.4.11
478
                          (unless (json-ld:object-p value)
479
                            (json-ld:invalid-reverse-value-error :datum value))
480
                          (setf expanded-value (json-ld:expand-element result context @:|@reverse| value)) ; 7.4.11.1
481
                          (let ((reverse-map nil)) ; 7.4.11.3.1, 2
482
                            (flet ((reverse-map ()
483
                                     (or reverse-map
484
                                         (json-ld:object-member-value result @:|@reverse|) ; 7.4.11.3.1, 2
485
                                         (setf (json-ld:object-member-value result  @:|@reverse|)
486
                                               (json-ld:make-object )))))
487
                              (json-ld:map-members (property item) expanded-value
488
                                (case property
489
                                  (@:|@reverse| ; (print "7.4.11.2")
490
                                     (json-ld:map-members (property item) item
491
                                       (json-ld:append-object-member-value result property item)))
492
                                  ((or (json-ld:value-object-p item) (json-ld:list-object-p item))
493
                                   (json-ld:invalid-reverse-property-value-error :datum item :property property))
494
                                  (t
495
                                   (json-ld:append-object-member-value (reverse-map) property item)))))))) ; 7.4.11.3.3.1.3))))))
496
                     ;; (print (list "7.4.end" expanded-key expanded-value))
497
                     (setf (json-ld:object-member-value result expanded-key) expanded-value))
498
                    (t
499
                     ;; (print (list "7.5.start" expanded-key value expanded-value))
500
                     (if (json-ld:object-p value)
501
                         (cond ((eql @:|@language| (json-ld:find-term-definition-container context key))  ; 7.5
502
                                (let ((expanded-value (make-array 0 :fill-pointer 0 :adjustable t))) ; 7.5.1
503
                                  (json-ld:map-members (language language-value) value
504
                                                       ;; (print (list :map-members "7.5.1" language language-value))
505
                                                       (flet ((append-simple-string (string) ; (print (list :append string))
506
                                                                (typecase string
507
                                                                  (string (vector-push-extend (intern-plain-literal string language) expanded-value))
508
                                                                  (t (json-ld:invalid-language-map-value-error :datum string :property key)))))
509
                                                         (typecase language-value
510
                                                           (string (append-simple-string language-value))
511
                                                           (json-ld:array (loop for language-value across language-value
512
                                                                            do (append-simple-string language-value)))
513
                                                           (t (json-ld:invalid-language-map-value-error :datum language-value)))))))
514
                               ((eql @:|@index| (json-ld:find-term-definition-container context key)) ; (print "7.6")
515
                                (setf expanded-value (make-array 0 :fill-pointer 0 :adjustable t))
516
                                (json-ld:map-members (index-index index-value) value ; 7.6.2
517
                                                     ;; (print (list :map-members "7.6" index-index index-value))
518
                                                     (setf index-value (json-ld:expand-element result context key (ensure-array index-value))) ; 7.6.2.1
519
                                                     ;; (print (list :map-members "7.6" index-index :expanded index-value))
520
                                                     (loop for item across index-value
521
                                                       when (and (json-ld:object-p item(not (json-ld:object-member item @:|@index|)))
522
                                                       do (setf (json-ld:object-member-value item @:|@index|) index-index)
523
                                                       do (vector-push-extend item expanded-value))))
524
                               (t ; (print "7.7")
525
                                (setf expanded-value (json-ld:expand-element result context key value))))
526
                         (setf expanded-value (json-ld:expand context key value)))
527
             
528
                     (unless (json-ld:null expanded-value) ; 7.8
529
                       (cond ((eql @:|@list| (json-ld:find-term-definition-container context key)) ; (print "7.9")
530
                              (unless (json-ld:list-object-p expanded-value)
531
                                (setf expanded-value (json-ld:make-object `((@:|@list| . ,(ensure-array expanded-value)))))))
532
                             ((json-ld:find-term-definition-reverse-property context key) ; 7.10
533
                              (let ((reverse-map (or (json-ld:object-member-value result @:|@reverse|)
534
                                                     (setf (json-ld:object-member-value result @:|@reverse|)
535
                                                           (json-ld:make-object)))))
536
                                (setf expanded-value (ensure-array expanded-value)) ; 7.10.3
537
                                (loop for item across expanded-value
538
                                  ;; do (print (list "7.10.4.1" item))
539
                                  if (or (json-ld:value-object-p item) (json-ld:list-object-p item))
540
                                  do (json-ld:invalid-reverse-property-value-error :datum item) ; 
541
                                  do (json-ld:append-object-member-value reverse-map expanded-key item))))
542
                             (t ; 7.11
543
                              (json-ld:append-object-member-value result expanded-key expanded-value))))))))))
544
 
545
         ;; 8 : skipped as values are normalized
546
         ;; 9 ; skipped
547
         (let ((set-result (json-ld:object-member-value result @:|@set|))) ; 10.2
548
           (when set-result
549
             (setf result set-result)))
550
         ;; 11 skipped
551
         ;; 12 skipped
552
         result ; ; 13
553
         ))