compaction.scm
| 1 | ;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu> |
| 2 | ;;;; |
| 3 | ;;;; This library is free software; you can redistribute it and/or |
| 4 | ;;;; modify it under the terms of the GNU Lesser General Public |
| 5 | ;;;; License as published by the Free Software Foundation; either |
| 6 | ;;;; version 3 of the License, or (at your option) any later version. |
| 7 | ;;;; |
| 8 | ;;;; This library is distributed in the hope that it will be useful, |
| 9 | ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 11 | ;;;; Lesser General Public License for more details. |
| 12 | ;;;; |
| 13 | ;;;; You should have received a copy of the GNU Lesser General Public |
| 14 | ;;;; License along with this library; if not, write to the Free Software |
| 15 | ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 16 | ;;;; |
| 17 | |
| 18 | (define-module (jsonld compaction) |
| 19 | #:use-module (jsonld context) |
| 20 | #:use-module (jsonld context-processing) |
| 21 | #:use-module (jsonld inverse-context-creation) |
| 22 | #:use-module (jsonld iri-compaction) |
| 23 | #:use-module (jsonld iri-expansion) |
| 24 | #:use-module (jsonld json) |
| 25 | #:use-module (jsonld value-compaction) |
| 26 | #:export (compaction)) |
| 27 | |
| 28 | (define-syntax update-result |
| 29 | (syntax-rules () |
| 30 | ((_ result nest-term nest-result) |
| 31 | (set! result |
| 32 | (if nest-term |
| 33 | (alist-set result nest-term nest-result) |
| 34 | nest-result))))) |
| 35 | |
| 36 | (define (add-value object key value as-array?) |
| 37 | (let* ((value (if (json-array? value) |
| 38 | (array->list value) |
| 39 | (list value))) |
| 40 | (original (if (json-has-key? object key) |
| 41 | (assoc-ref object key) |
| 42 | #())) |
| 43 | (original (if (json-array? original) |
| 44 | (array->list original) |
| 45 | (list original))) |
| 46 | (new-value (append original value)) |
| 47 | (new-value |
| 48 | (if (and (= (length new-value) 1) (not as-array?)) |
| 49 | (car new-value) |
| 50 | (list->array 1 new-value)))) |
| 51 | (alist-set object key new-value))) |
| 52 | |
| 53 | (define* (compaction active-context inverse-context active-property element |
| 54 | #:key (compact-arrays? #f) (ordered? #f) processing-mode) |
| 55 | (pk 'compaction element) |
| 56 | ;; 1 |
| 57 | (let ((type-scoped-context active-context) |
| 58 | (def (term-definition-ref active-context active-property))) |
| 59 | (cond |
| 60 | ;; 2 |
| 61 | ((scalar? element) |
| 62 | element) |
| 63 | ;; 3 |
| 64 | ((json-array? element) |
| 65 | ;; 3.1 |
| 66 | (let ((result '())) |
| 67 | ;; 3.2 |
| 68 | (for-each |
| 69 | (lambda (item) |
| 70 | ;; 3.2.1 |
| 71 | (let ((compacted-item (compaction active-context inverse-context |
| 72 | active-property item |
| 73 | #:compact-arrays? compact-arrays? |
| 74 | #:ordered? ordered? |
| 75 | #:processing-mode processing-mode))) |
| 76 | ;; 3.2.2 |
| 77 | (unless (json-null? compacted-item) |
| 78 | (set! result (cons compacted-item result))))) |
| 79 | (array->list element)) |
| 80 | (set! result (reverse result)) |
| 81 | (if (let ((container-mapping |
| 82 | (container-mapping active-context active-property))) |
| 83 | (or (not (= (length result) 1)) |
| 84 | (equal? compact-arrays? #f) |
| 85 | (equal? active-property "@graph") |
| 86 | (equal? active-property "@set") |
| 87 | (member "@set" container-mapping) |
| 88 | (member "@list" container-mapping))) |
| 89 | ;; 3.3 |
| 90 | (list->array 1 result) |
| 91 | ;; 3.4 |
| 92 | (car result)))) |
| 93 | ;; 4 |
| 94 | (else |
| 95 | ;; 5 |
| 96 | (when (not-null-or-false (active-context-previous active-context)) |
| 97 | (unless (or (json-has-key? element "@value") |
| 98 | (and (json-has-key? element "@id") |
| 99 | (null? (filter (lambda (kp) (not (equal? (car kp) "@id"))) |
| 100 | element)))) |
| 101 | (set! active-context (active-context-previous active-context)) |
| 102 | (set! inverse-context (inverse-context-creation active-context)))) |
| 103 | ;; 6 |
| 104 | (when (and (term-definition? def) |
| 105 | (not-null-or-false (term-definition-context def))) |
| 106 | ;; 6.1 |
| 107 | (set! active-context |
| 108 | (context-processing active-context (term-definition-context def) |
| 109 | (term-definition-base-url def) |
| 110 | #:override-protected? #t)) |
| 111 | ;; 6.2 |
| 112 | (set! inverse-context (inverse-context-creation active-context))) |
| 113 | ;; 7 |
| 114 | (cond |
| 115 | ((and (or (json-has-key? element "@value") |
| 116 | (json-has-key? element "@id")) |
| 117 | (let ((compact |
| 118 | (value-compaction active-context inverse-context |
| 119 | active-property element processing-mode))) |
| 120 | (or (scalar? compact) |
| 121 | (and (term-definition? def) |
| 122 | (equal? (term-definition-type def) "@json"))))) |
| 123 | (value-compaction active-context inverse-context active-property |
| 124 | element processing-mode)) |
| 125 | ;; 8 |
| 126 | ((and (json-has-key? element "@list") |
| 127 | (member "@list" (container-mapping active-context active-property))) |
| 128 | (compaction active-context inverse-context active-property |
| 129 | (assoc-ref element "@list") |
| 130 | #:compact-arrays? compact-arrays? |
| 131 | #:ordered? ordered?)) |
| 132 | ;; 9 and 10 |
| 133 | (else |
| 134 | (let ((inside-reverse? (equal? active-property "@reverse")) |
| 135 | (result '())) |
| 136 | ;; 11 |
| 137 | (when (json-has-key? element "@type") |
| 138 | (let* ((types (assoc-ref element "@type")) |
| 139 | (types (if (json-array? types) |
| 140 | (array->list types) |
| 141 | (list types))) |
| 142 | (compacted-types |
| 143 | (map |
| 144 | (lambda (type) |
| 145 | (iri-compaction active-context inverse-context type |
| 146 | #:vocab? #t #:processing-mode processing-mode)) |
| 147 | types))) |
| 148 | (pk 'compacted-types compacted-types) |
| 149 | (for-each |
| 150 | (lambda (term) |
| 151 | ;; 11.1 |
| 152 | (when (and |
| 153 | (term-definition? (term-definition-ref type-scoped-context term)) |
| 154 | (term-definition-context |
| 155 | (term-definition-ref type-scoped-context term))) |
| 156 | ;; 11.1.1 |
| 157 | (set! active-context |
| 158 | (context-processing |
| 159 | active-context |
| 160 | (term-definition-context |
| 161 | (term-definition-ref type-scoped-context term)) |
| 162 | (term-definition-base-url |
| 163 | (term-definition-ref type-scoped-context term)) |
| 164 | #:propagate? #f)) |
| 165 | ;; 11.1.2 |
| 166 | (set! inverse-context |
| 167 | (inverse-context-creation active-context)))) |
| 168 | (sort compacted-types string<=?)))) |
| 169 | ;; 12 |
| 170 | (for-each-pair |
| 171 | (lambda (expanded-property expanded-value) |
| 172 | (set! result |
| 173 | (step-12 active-context inverse-context expanded-property |
| 174 | expanded-value result compact-arrays? ordered? |
| 175 | inside-reverse? type-scoped-context active-property |
| 176 | processing-mode))) |
| 177 | (if ordered? |
| 178 | (alist-sort-by-key element) |
| 179 | element)) |
| 180 | ;; 13 |
| 181 | result))))))) |
| 182 | |
| 183 | (define (step-12 active-context inverse-context expanded-property expanded-value |
| 184 | result compact-arrays? ordered? inside-reverse? type-scoped-context |
| 185 | active-property processing-mode) |
| 186 | (cond |
| 187 | ;; 12.1 |
| 188 | ((equal? expanded-property "@id") |
| 189 | (pk 'expanded-value expanded-value) |
| 190 | ;; XXX: not clear what to do if expanded-value is not a |
| 191 | ;; string, make sure there is a test |
| 192 | (let ((compacted-value |
| 193 | (if (string? expanded-value) |
| 194 | (iri-compaction active-context inverse-context expanded-value |
| 195 | #:vocab? #f #:processing-mode processing-mode) |
| 196 | expanded-value)) |
| 197 | (alias (iri-compaction active-context inverse-context expanded-property |
| 198 | #:vocab? #t #:processing-mode processing-mode))) |
| 199 | (pk 'compacted-value compacted-value) |
| 200 | (pk 'alias alias) |
| 201 | (set! result |
| 202 | (alist-set result alias compacted-value)))) |
| 203 | ;; 12.2 |
| 204 | ((equal? expanded-property "@type") |
| 205 | (let* ((compacted-value #f) |
| 206 | (alias (iri-compaction active-context inverse-context expanded-property |
| 207 | #:vocab? #t #:processing-mode processing-mode)) |
| 208 | (as-array? |
| 209 | (or |
| 210 | (and |
| 211 | (not (processing-mode-1.0? processing-mode)) |
| 212 | (member "@set" (container-mapping active-context alias))) |
| 213 | (not compact-arrays?))) |
| 214 | (type-scoped-inverse-context |
| 215 | (inverse-context-creation type-scoped-context))) |
| 216 | (pk 'alias alias) |
| 217 | (if (string? expanded-value) |
| 218 | (set! compacted-value |
| 219 | (iri-compaction type-scoped-context type-scoped-inverse-context |
| 220 | expanded-value |
| 221 | #:vocab? #t #:processing-mode processing-mode)) |
| 222 | (begin |
| 223 | (set! expanded-value (array->list expanded-value)) |
| 224 | (set! compacted-value |
| 225 | (list->array 1 |
| 226 | (map |
| 227 | (lambda (v) |
| 228 | (pk 'v (iri-compaction type-scoped-context type-scoped-inverse-context |
| 229 | v |
| 230 | #:vocab? #t #:processing-mode processing-mode))) |
| 231 | expanded-value))))) |
| 232 | (pk 'compacted-value compacted-value) |
| 233 | (when (and (json-array? compacted-value) (= (array-length compacted-value) 1)) |
| 234 | (set! compacted-value (car (array->list compacted-value)))) |
| 235 | (set! result |
| 236 | (add-value result alias compacted-value as-array?)))) |
| 237 | ;; 12.3 |
| 238 | ((equal? expanded-property "@reverse") |
| 239 | (let ((compacted-value |
| 240 | (compaction active-context inverse-context "@reverse" expanded-value |
| 241 | #:compact-arrays? compact-arrays? #:ordered? ordered?))) |
| 242 | ;; 12.3.2 |
| 243 | (for-each-pair |
| 244 | (lambda (property value) |
| 245 | (let ((def (term-definition-ref active-context property))) |
| 246 | (when (and (term-definition? def) (term-definition-reverse? def)) |
| 247 | (let ((as-array? (or |
| 248 | (member "@set" |
| 249 | (container-mapping active-context property)) |
| 250 | (not compact-arrays?)))) |
| 251 | (set! result |
| 252 | (add-value result property value as-array?))) |
| 253 | (set! compacted-value |
| 254 | (alist-remove compacted-value property))))) |
| 255 | compacted-value) |
| 256 | ;; 12.3.3 |
| 257 | (unless (null? compacted-value) |
| 258 | (let ((alias (iri-compaction active-context inverse-context "@reverse" |
| 259 | #:vocab? #t #:processing-mode processing-mode))) |
| 260 | (pk 'alias alias) |
| 261 | (set! result (alist-set result alias compacted-value)))))) |
| 262 | ;; 12.4 |
| 263 | ((equal? expanded-property "@preserve") |
| 264 | (let ((compacted-value |
| 265 | (compaction active-context inverse-context active-property |
| 266 | expanded-value #:compact-arrays? compact-arrays? |
| 267 | #:ordered? ordered?))) |
| 268 | (unless (equal? expanded-value #()) |
| 269 | (set! result (alist-set result "@preserve" compacted-value))))) |
| 270 | ;; 12.5 |
| 271 | ((and (equal? expanded-property "@index") |
| 272 | (member "@index" |
| 273 | (container-mapping active-context active-property))) |
| 274 | #t) |
| 275 | ;; 12.6 |
| 276 | ((or (equal? expanded-property "@direction") |
| 277 | (equal? expanded-property "@index") |
| 278 | (equal? expanded-property "@language") |
| 279 | (equal? expanded-property "@value")) |
| 280 | (let ((alias (iri-compaction active-context inverse-context expanded-property |
| 281 | #:vocab? #t #:processing-mode processing-mode))) |
| 282 | (pk 'alias alias) |
| 283 | (set! result |
| 284 | (alist-set result alias expanded-value)))) |
| 285 | (else |
| 286 | ;; 12.7 |
| 287 | (when (equal? expanded-value #()) |
| 288 | (let* ((item-active-property |
| 289 | (iri-compaction active-context inverse-context expanded-property |
| 290 | #:value expanded-value |
| 291 | #:vocab? #t |
| 292 | #:reverse? inside-reverse? |
| 293 | #:processing-mode processing-mode)) |
| 294 | (def (term-definition-ref active-context |
| 295 | item-active-property)) |
| 296 | (nest-term (if (term-definition? def) (term-definition-nest def) #f)) |
| 297 | ;; 12.7.4 |
| 298 | (nest-result result)) |
| 299 | (pk 'item-active-property item-active-property) |
| 300 | ;; 12.7.2 |
| 301 | (when nest-term |
| 302 | (unless (or (equal? nest-term "@nest") |
| 303 | (equal? (expand-key active-context nest-term) |
| 304 | "@nest")) |
| 305 | (throw 'invalid-@nest-value)) |
| 306 | (set! nest-result |
| 307 | (if (json-has-key? result nest-term) |
| 308 | (assoc-ref result nest-term) |
| 309 | '()))) |
| 310 | ;; 12.7.4 |
| 311 | (set! nest-result |
| 312 | (add-value nest-result item-active-property #() #t)) |
| 313 | (update-result result nest-term nest-result))) |
| 314 | ;; 12.8 |
| 315 | (for-each |
| 316 | (lambda (expanded-item) |
| 317 | (let* ((item-active-property |
| 318 | (iri-compaction |
| 319 | active-context inverse-context expanded-property |
| 320 | #:value expanded-item |
| 321 | #:vocab? #t |
| 322 | #:reverse? inside-reverse? |
| 323 | #:processing-mode processing-mode)) |
| 324 | (def (term-definition-ref active-context item-active-property)) |
| 325 | (nest-term (if (term-definition? def) (term-definition-nest def) #f)) |
| 326 | ;; 12.8.3 |
| 327 | (nest-result result) |
| 328 | ;; 12.8.4 |
| 329 | (container (container-mapping active-context item-active-property)) |
| 330 | ;; 12.8.5 |
| 331 | (as-array? (or (member "@set" container) |
| 332 | (equal? item-active-property "@list") |
| 333 | (equal? item-active-property "@graph") |
| 334 | (not compact-arrays?))) |
| 335 | ;; 12.8.6 |
| 336 | (compacted-item |
| 337 | (compaction active-context inverse-context item-active-property |
| 338 | (if (json-has-key? expanded-item "@list") |
| 339 | (assoc-ref expanded-item "@list") |
| 340 | (if (graph-object? expanded-item) |
| 341 | (assoc-ref expanded-item "@graph") |
| 342 | expanded-item)) |
| 343 | #:compact-arrays? compact-arrays? |
| 344 | #:ordered? ordered?))) |
| 345 | (pk 'item-active-property item-active-property) |
| 346 | ;; 12.8.2 |
| 347 | (when (not-null-or-false nest-term) |
| 348 | (unless (or (equal? nest-term "@nest") |
| 349 | (equal? (expand-key active-context nest-term) "@nest")) |
| 350 | (throw 'invalid-@nest-value)) |
| 351 | (set! nest-result |
| 352 | (if (json-has-key? result nest-term) |
| 353 | (assoc-ref result nest-term) |
| 354 | '()))) |
| 355 | (cond |
| 356 | ;; 12.8.7 |
| 357 | ((json-has-key? expanded-item "@list") |
| 358 | ;; 12.8.7.1 |
| 359 | (unless (json-array? compacted-item) |
| 360 | (set! compacted-item `#(,compacted-item))) |
| 361 | (if (member "@list" container) |
| 362 | ;; 12.8.7.3 |
| 363 | (set! nest-result |
| 364 | (alist-set nest-result item-active-property compacted-item)) |
| 365 | ;; 12.8.7.2 |
| 366 | (begin |
| 367 | (set! compacted-item |
| 368 | `((,(iri-compaction active-context inverse-context |
| 369 | "@list" #:vocab? #t |
| 370 | #:processing-mode processing-mode) . |
| 371 | ,compacted-item))) |
| 372 | (when (json-has-key? expanded-item "@index") |
| 373 | (set! compacted-item |
| 374 | (alist-set |
| 375 | compacted-item |
| 376 | (iri-compaction active-context inverse-context |
| 377 | "@index" #:vocab? #t |
| 378 | #:processing-mode processing-mode) |
| 379 | (assoc-ref expanded-item "@index")))) |
| 380 | (set! nest-result |
| 381 | (add-value nest-result item-active-property compacted-item |
| 382 | as-array?)))) |
| 383 | (update-result result nest-term nest-result)) |
| 384 | ;; 12.8.8 |
| 385 | ((graph-object? expanded-item) |
| 386 | (cond |
| 387 | ;; 12.8.8.1 |
| 388 | ((and (member "@id" container) |
| 389 | (member "@graph" container)) |
| 390 | (let* ((map-object |
| 391 | (or (not-null-or-false (assoc-ref nest-result item-active-property)) '())) |
| 392 | (map-key |
| 393 | (if (json-has-key? expanded-item "@id") |
| 394 | (assoc-ref expanded-item "@id") |
| 395 | "@none")) |
| 396 | (map-key |
| 397 | (iri-compaction |
| 398 | active-context inverse-context map-key |
| 399 | #:vocab? (not (json-has-key? expanded-item "@id")) |
| 400 | #:processing-mode processing-mode))) |
| 401 | ;; 12.8.8.1.3 |
| 402 | (set! map-object |
| 403 | (add-value map-object map-key compacted-item as-array?)) |
| 404 | (set! nest-result |
| 405 | (alist-set nest-result item-active-property map-object)) |
| 406 | (update-result result nest-term nest-result))) |
| 407 | ;; 12.8.8.2 |
| 408 | ((and (member "@graph" container) |
| 409 | (member "@index" container) |
| 410 | (simple-graph-object? expanded-item)) |
| 411 | (let ((map-object |
| 412 | (or (not-null-or-false (assoc-ref nest-result item-active-property)) '())) |
| 413 | (map-key |
| 414 | (if (json-has-key? expanded-item "@index") |
| 415 | (assoc-ref expanded-item "@index") |
| 416 | "@none"))) |
| 417 | ;; 12.8.8.2.3 |
| 418 | (set! map-object |
| 419 | (add-value map-object map-key compacted-item as-array?)) |
| 420 | (set! nest-result |
| 421 | (alist-set nest-result item-active-property map-object)) |
| 422 | (update-result result nest-term nest-result))) |
| 423 | ;; 12.8.8.3 |
| 424 | ((and (member "@graph" container) |
| 425 | (simple-graph-object? expanded-item)) |
| 426 | (when (and (json-array? compacted-item) |
| 427 | (> (array-length compacted-item) 1)) |
| 428 | (set! compacted-item |
| 429 | `((,(iri-compaction active-context inverse-context "@included" |
| 430 | #:vocab? #t #:processing-mode processing-mode) . |
| 431 | ,compacted-item)))) |
| 432 | (set! nest-result |
| 433 | (add-value nest-result item-active-property compacted-item |
| 434 | as-array?)) |
| 435 | (update-result result nest-term nest-result)) |
| 436 | ;; 12.8.8.4 |
| 437 | (else |
| 438 | ;; 12.8.8.4.1 |
| 439 | (set! compacted-item |
| 440 | `((,(iri-compaction active-context inverse-context "@graph" |
| 441 | #:vocab? #t #:processing-mode processing-mode) . |
| 442 | ,compacted-item))) |
| 443 | ;; 12.8.8.4.2 |
| 444 | (when (json-has-key? expanded-item "@id") |
| 445 | (set! compacted-item |
| 446 | (alist-set |
| 447 | compacted-item |
| 448 | (iri-compaction active-context inverse-context "@id" |
| 449 | #:vocab? #t |
| 450 | #:processing-mode processing-mode) |
| 451 | (iri-compaction active-context inverse-context |
| 452 | (assoc-ref expanded-item "@id") |
| 453 | #:vocab? #f |
| 454 | #:processing-mode processing-mode)))) |
| 455 | ;; 12.8.8.4.3 |
| 456 | (when (json-has-key? expanded-item "@index") |
| 457 | (set! compacted-item |
| 458 | (alist-set |
| 459 | compacted-item |
| 460 | (iri-compaction active-context inverse-context "@index" |
| 461 | #:vocab? #t |
| 462 | #:processing-mode processing-mode) |
| 463 | (assoc-ref expanded-item "@index")))) |
| 464 | ;; 12.8.8.4.4 |
| 465 | (set! nest-result |
| 466 | (add-value nest-result item-active-property compacted-item |
| 467 | as-array?)) |
| 468 | (update-result result nest-term nest-result)))) |
| 469 | ;; 12.8.9 |
| 470 | ((and (not (member "@graph" container)) |
| 471 | (or (member "@language" container) |
| 472 | (member "@index" container) |
| 473 | (member "@id" container) |
| 474 | (member "@type" container))) |
| 475 | ;; 12.8.9.1 |
| 476 | (let* ((map-object (or (assoc-ref nest-result item-active-property) |
| 477 | '())) |
| 478 | ;; 12.8.9.2 |
| 479 | (container-key (iri-compaction active-context inverse-context |
| 480 | (cond |
| 481 | ((member "@language" container) "@language") |
| 482 | ((member "@index" container) "@index") |
| 483 | ((member "@id" container) "@id") |
| 484 | (else "@type")) |
| 485 | #:vocab? #t)) |
| 486 | (map-key json-null) |
| 487 | ;; 12.8.9.3 |
| 488 | (def (term-definition-ref active-context item-active-property)) |
| 489 | (index-key (or (and (term-definition? def) |
| 490 | (term-definition-index def)) |
| 491 | "@index"))) |
| 492 | (cond |
| 493 | ;; 12.8.9.4 |
| 494 | ((and (member "@language" container) |
| 495 | (json-has-key? expanded-item "@value")) |
| 496 | (set! compacted-item (assoc-ref expanded-item "@value")) |
| 497 | (when (json-has-key? expanded-item "@language") |
| 498 | (set! map-key (assoc-ref expanded-item "@language")))) |
| 499 | ;; 12.8.9.5 |
| 500 | ((and (member "@index" container) |
| 501 | (equal? index-key "@index")) |
| 502 | (when (json-has-key? expanded-item "@index") |
| 503 | (set! map-key (assoc-ref expanded-item "@index")))) |
| 504 | ;; 12.8.9.6 |
| 505 | ((member "@index" container) |
| 506 | ;; 12.8.9.6.1 |
| 507 | (set! container-key |
| 508 | (iri-compaction active-context inverse-context index-key |
| 509 | #:vocab? #t)) |
| 510 | ;; 12.8.9.6.2 |
| 511 | (let* ((keys (assoc-ref compacted-item container-key)) |
| 512 | (keys (if (json-array? keys) |
| 513 | (array->list keys) |
| 514 | (list keys))) |
| 515 | (key (and (not (null? keys)) (not-null-or-false (car keys)))) |
| 516 | (remaining (if key (cdr keys) '()))) |
| 517 | (when key |
| 518 | (unless (string? key) |
| 519 | (set! remaining keys) |
| 520 | (set! key #f)) |
| 521 | (when key |
| 522 | (set! map-key key))) |
| 523 | ;; 12.8.9.6.3 |
| 524 | (if (null? remaining) |
| 525 | (when (json-has-key? compacted-item container-key) |
| 526 | (set! compacted-item |
| 527 | (alist-remove compacted-item container-key))) |
| 528 | (set! compacted-item |
| 529 | (alist-set compacted-item container-key |
| 530 | (if (= (length remaining) 1) |
| 531 | (car remaining) |
| 532 | (list->array 1 remaining))))))) |
| 533 | ;; 12.8.9.7 |
| 534 | ((member "@id" container) |
| 535 | (when (json-has-key? compacted-item container-key) |
| 536 | (set! map-key (assoc-ref compacted-item container-key)) |
| 537 | (set! compacted-item (alist-remove compacted-item container-key)))) |
| 538 | ;; 12.8.9.8 |
| 539 | ((member "@type" container) |
| 540 | (let* ((keys (assoc-ref compacted-item container-key)) |
| 541 | (keys (if (json-array? keys) |
| 542 | (array->list keys) |
| 543 | (list keys))) |
| 544 | (key (and (not (null? keys)) (not-null-or-false (car keys)))) |
| 545 | (remaining (if key (cdr keys) '()))) |
| 546 | ;; 12.8.9.8.1 |
| 547 | (when (not-null-or-false key) |
| 548 | (set! map-key key)) |
| 549 | ;; 12.8.9.8.2 |
| 550 | (if (null? remaining) |
| 551 | (set! compacted-item |
| 552 | (alist-remove compacted-item container-key)) |
| 553 | (set! compacted-item |
| 554 | (alist-set compacted-item container-key |
| 555 | (if (= (length remaining) 1) |
| 556 | (car remaining) |
| 557 | (list->array 1 remaining))))) |
| 558 | (when (and (= (length compacted-item) 1) |
| 559 | (equal? |
| 560 | (expand-key active-context (car (car compacted-item))) |
| 561 | "@id")) |
| 562 | (set! compacted-item |
| 563 | (compaction |
| 564 | active-context inverse-context item-active-property |
| 565 | `(("@id" . ,(assoc-ref expanded-item "@id"))))))))) |
| 566 | ;; 12.8.9.9 |
| 567 | (when (json-null? map-key) |
| 568 | (set! map-key (iri-compaction active-context inverse-context |
| 569 | "@none" #:vocab? #t))) |
| 570 | ;; 12.8.9.10 |
| 571 | (set! map-object |
| 572 | (add-value map-object map-key compacted-item as-array?)) |
| 573 | (set! nest-result |
| 574 | (alist-set nest-result item-active-property map-object)) |
| 575 | (update-result result nest-term nest-result))) |
| 576 | ;; 12.8.10 |
| 577 | (else |
| 578 | (set! nest-result |
| 579 | (add-value nest-result item-active-property |
| 580 | compacted-item as-array?)) |
| 581 | (update-result result nest-term nest-result))))) |
| 582 | (array->list expanded-value)))) |
| 583 | result) |
| 584 |