guile-jsonld/jsonld/inverse-context-creation.scm

inverse-context-creation.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 inverse-context-creation)
19
  #:use-module (jsonld context)
20
  #:use-module (jsonld json)
21
  #:use-module (ice-9 match)
22
  #:export (inverse-context-creation))
23
24
(define (sort-size-lexico e1 e2)
25
  "A <=? implementation between two elements of an alist that sort according
26
to key size first, breaking ties by selecting the lexicographically least one."
27
  (match `(,e1 . ,e2)
28
    (((k1 . v1) . (k2 . v2))
29
     (let ((l1 (string-length k1))
30
           (l2 (string-length k2)))
31
       (if (= l1 l2)
32
         (string<=? k1 k2)
33
         (< l1 l2))))))
34
35
(define* (inverse-context-creation active-context)
36
  (let ((result '())
37
        (default-language "@none"))
38
    ;; 2
39
    (when (active-context-language active-context)
40
      (set! default-language (string-downcase (active-context-language
41
                                                active-context))))
42
    ;; 3
43
    (for-each-pair
44
      (lambda (term term-definition)
45
        ;; 3.1
46
        (unless (equal? term-definition #nil)
47
          ;; 3.2
48
          (let ((container "@none")
49
                ;; 3.3
50
                (var (term-definition-iri term-definition))
51
                ;; 3.5
52
                (container-map #f)
53
                ;; 3.7
54
                (type/language-map #f)
55
                ;; 3.8
56
                (type-map #f)
57
                ;; 3.10
58
                (language-map '()))
59
            (when (term-definition-container term-definition)
60
              (let ((mapping (term-definition-container term-definition)))
61
                (set! container
62
                  (apply string-append
63
                         (sort
64
                           (if (json-array? mapping)
65
                               (array->list mapping)
66
                               (list mapping))
67
                           string<=?)))))
68
            ;; 3.4
69
            (unless (json-has-key? result var)
70
              (set! result (alist-set result var '())))
71
            ;; 3.5
72
            (set! container-map (assoc-ref result var))
73
            ;; 3.6
74
            (unless (json-has-key? container-map container)
75
              (set! container-map
76
                (alist-set
77
                  container-map
78
                  container
79
                  `(("@language" . ())
80
                    ("@type" . ())
81
                    ("@any" . (("@none" . ,term)))))))
82
            ;; 3.7
83
            (set! type/language-map (assoc-ref container-map container))
84
            ;; 3.12
85
            (set! language-map (assoc-ref type/language-map "@language"))
86
            ;; 3.8
87
            (set! type-map (assoc-ref type/language-map "@type"))
88
            ;; 3.9
89
            (cond
90
              ((term-definition-reverse? term-definition)
91
               (unless (json-has-key? type-map "@reverse")
92
                 (set! type-map (alist-set type-map "@reverse" term))))
93
              ;; 3.10
94
              ((equal? (term-definition-type term-definition) "@none")
95
               (set! language-map (assoc-ref type/language-map "@language"))
96
               (unless (json-has-key? language-map "@any")
97
                 (set! language-map (alist-set language-map "@any" term)))
98
               (unless (json-has-key? type-map "@any")
99
                 (set! type-map (alist-set type-map "@any" term))))
100
              ;; 3.11
101
              ((term-definition-type term-definition)
102
               (unless (json-has-key? type-map
103
                                      (term-definition-type term-definition))
104
                 (set! type-map
105
                   (alist-set type-map (term-definition-type term-definition)
106
                              term))))
107
              ;; 3.13
108
              ((and (not (equal? (term-definition-language term-definition) #f))
109
                    (not (equal? (term-definition-direction term-definition) #f)))
110
               (let ((lang-dir #f))
111
                 (cond
112
                   ((and (term-definition-language term-definition)
113
                         (term-definition-direction term-definition))
114
                    (set! lang-dir
115
                      (string-downcase
116
                        (string-append
117
                          (term-definition-language term-definition)
118
                          "_"
119
                          (term-definition-direction term-definition)))))
120
                   ((term-definition-language term-definition)
121
                    (set! lang-dir (string-downcase (term-definition-language
122
                                                      term-definition))))
123
                   ((term-definition-direction term-definition)
124
                    (set! lang-dir
125
                      (string-append
126
                        "_"
127
                        (string-downcase (term-definition-language
128
                                           term-definition)))))
129
                   (else
130
                     (set! lang-dir "@null")))
131
                 (unless (json-has-key? language-map lang-dir)
132
                   (set! language-map
133
                     (alist-set language-map lang-dir term)))))
134
              ;; 3.14
135
              ((not (equal? (term-definition-language term-definition) #f))
136
               (let ((language
137
                       (if (term-definition-language term-definition)
138
                           (string-downcase
139
                             (term-definition-language term-definition))
140
                           "@null")))
141
                 (unless (json-has-key? language-map language)
142
                   (set! language-map
143
                     (alist-set language-map language term)))))
144
              ;; 3.15
145
              ((not (equal? (term-definition-direction term-definition) #f))
146
               (let ((direction
147
                       (if (term-definition-direction term-definition)
148
                           (string-append
149
                             "_"
150
                             (string-downcase
151
                               (term-definition-direction term-definition)))
152
                           "@none")))
153
                 (unless (json-has-key? language-map direction)
154
                   (set! language-map
155
                     (alist-set language-map direction term)))))
156
              ;; 3.16
157
              ((not (equal? (active-context-direction active-context) #f))
158
               (let ((lang-dir
159
                       (string-downcase
160
                         (string-append
161
                           default-language "_"
162
                           (or (active-context-direction active-context)
163
                               "")))))
164
                 (unless (json-has-key? language-map lang-dir)
165
                   (set! language-map
166
                     (alist-set language-map lang-dir term)))
167
                 (unless (json-has-key? language-map "@none")
168
                   (set! language-map
169
                     (alist-set language-map "@none" term)))
170
                 (unless (json-has-key? type-map "@none")
171
                   (set! type-map
172
                     (alist-set type-map "@none" term)))))
173
              ;; 3.17
174
              (else
175
                (unless (json-has-key? language-map default-language)
176
                  (set! language-map
177
                    (alist-set language-map default-language term)))
178
                (unless (json-has-key? language-map "@none")
179
                  (set! language-map
180
                    (alist-set language-map "@none" term)))
181
                (unless (json-has-key? type-map "@none")
182
                  (set! type-map
183
                    (alist-set type-map "@none" term)))))
184
            (set! type/language-map (alist-set type/language-map "@language" language-map))
185
            (set! type/language-map (alist-set type/language-map "@type" type-map))
186
            (set! container-map (alist-set container-map container type/language-map))
187
            (set! result (alist-set result var container-map)))))
188
      (alist-sort-by-key (active-context-definitions active-context)
189
                         #:less sort-size-lexico))
190
    ;; 4
191
    result))
192