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 (not-null-or-false (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 (json-null? term-definition) |
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 (not-null-or-false (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 (not-null-or-false (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 (not-null-or-false (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 |