eyeling 1.10.21 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/HANDBOOK.md +2 -88
  2. package/eyeling-builtins.ttl +0 -48
  3. package/eyeling.js +67 -314
  4. package/lib/engine.js +67 -309
  5. package/lib/rules.js +0 -5
  6. package/package.json +1 -1
  7. package/test/n3gen.test.js +4 -4
  8. package/test/package.test.js +1 -1
  9. package/tools/n3gen.js +6 -1883
  10. package/examples/bind-builtins.n3 +0 -11
  11. package/examples/bind.n3 +0 -7
  12. package/examples/brussels-brew-club.n3 +0 -119
  13. package/examples/builtins-string-math.n3 +0 -11
  14. package/examples/builtins-triple-termtests.n3 +0 -7
  15. package/examples/family.n3 +0 -10
  16. package/examples/filter-demorgan.n3 +0 -9
  17. package/examples/filter-in-notin.n3 +0 -10
  18. package/examples/filter-nested-or.n3 +0 -10
  19. package/examples/filter.n3 +0 -8
  20. package/examples/input/bind-builtins.srl +0 -30
  21. package/examples/input/bind.srl +0 -12
  22. package/examples/input/builtins-string-math.srl +0 -38
  23. package/examples/input/builtins-triple-termtests.srl +0 -27
  24. package/examples/input/family.srl +0 -12
  25. package/examples/input/filter-demorgan.srl +0 -15
  26. package/examples/input/filter-in-notin.srl +0 -15
  27. package/examples/input/filter-nested-or.srl +0 -15
  28. package/examples/input/filter.srl +0 -9
  29. package/examples/input/snaf.srl +0 -6
  30. package/examples/it-is-about-time.n3 +0 -580
  31. package/examples/json-pointer.n3 +0 -75
  32. package/examples/json-reconcile-vat.n3 +0 -361
  33. package/examples/output/bind-builtins.n3 +0 -9
  34. package/examples/output/bind.n3 +0 -3
  35. package/examples/output/brussels-brew-club.n3 +0 -22
  36. package/examples/output/builtins-string-math.n3 +0 -0
  37. package/examples/output/builtins-triple-termtests.n3 +0 -0
  38. package/examples/output/family.n3 +0 -13
  39. package/examples/output/filter-demorgan.n3 +0 -3
  40. package/examples/output/filter-in-notin.n3 +0 -4
  41. package/examples/output/filter-nested-or.n3 +0 -4
  42. package/examples/output/filter.n3 +0 -3
  43. package/examples/output/it-is-about-time.n3 +0 -0
  44. package/examples/output/json-pointer.n3 +0 -13
  45. package/examples/output/json-reconcile-vat.n3 +0 -226
  46. package/examples/output/snaf.n3 +0 -3
  47. package/examples/snaf.n3 +0 -6
@@ -1,580 +0,0 @@
1
- @prefix ex: <http://example.org/> .
2
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
3
- @prefix tfn: <https://w3id.org/time-fn#> .
4
- @prefix math: <http://www.w3.org/2000/10/swap/math#> .
5
- @prefix string: <http://www.w3.org/2000/10/swap/string#> .
6
- @prefix list: <http://www.w3.org/2000/10/swap/list#> .
7
- @prefix log: <http://www.w3.org/2000/10/swap/log#> .
8
- @prefix : <https://w3id.org/time-fn/rules#> .
9
-
10
- ex:e1 a ex:Event ;
11
- ex:when "2000-01-02T03:04:05"^^xsd:dateTime ; # floating (no TZ)
12
- ex:day "2000-01-02"^^xsd:date ;
13
- ex:tz "Z" .
14
- ex:e2 a ex:Event ;
15
- ex:when "2000-01-02T03:04:05-03:00"^^xsd:dateTime ;
16
- ex:day "2000-01-02"^^xsd:date ;
17
- ex:tz "-03:00" .
18
-
19
- { ?this ex:when ?whenRaw .
20
- ?this ex:day ?day .
21
- ?this ex:tz ?tz .
22
- (?whenRaw ?tz) tfn:bindDefaultTimezone ?whenBound .
23
- (?day) tfn:periodMinInclusive ?startInc .
24
- (?day) tfn:periodMaxInclusive ?endInc .
25
- (?day) tfn:periodMinExclusive ?startEx .
26
- (?day) tfn:periodMaxExclusive ?endEx .
27
- ?startInc math:notGreaterThan ?whenBound .
28
- ?whenBound math:notGreaterThan ?endInc .
29
- } => { ?this ex:occursOn ?day . ?this ex:whenBound ?whenBound . } .
30
-
31
- # Backward rules implementing the Time Functions (tfn:*) from:
32
- # https://spec.knows.idlab.ugent.be/time-fn/latest/
33
-
34
- ######################################################################
35
- # Helpers: timezone suffix & core lexical form
36
- ######################################################################
37
-
38
- # tz suffix extraction: Z
39
- { ?lex :tzSuffix "Z" } <= { ?lex string:endsWith "Z" . } .
40
-
41
- # tz suffix extraction: ±HH:MM
42
- { ?lex :tzSuffix ?tz } <= {
43
- ?lex string:matches ".*[+-][0-9][0-9]:[0-9][0-9]$" .
44
- ( ?lex "([+-][0-9][0-9]:[0-9][0-9])$" ) string:scrape ?tz .
45
- } .
46
-
47
- # tz suffix extraction: none
48
- { ?lex :tzSuffix "" } <= {
49
- ?lex string:notMatches ".*(Z|[+-][0-9][0-9]:[0-9][0-9])$" .
50
- } .
51
-
52
- # core lexical form (strip trailing Z)
53
- { ?lex :coreNoTz ?core } <= {
54
- ?lex string:endsWith "Z" .
55
- ( ?lex "Z$" "" ) string:replace ?core .
56
- } .
57
-
58
- # core lexical form (strip trailing ±HH:MM)
59
- { ?lex :coreNoTz ?core } <= {
60
- ?lex string:matches ".*[+-][0-9][0-9]:[0-9][0-9]$" .
61
- ( ?lex "([+-][0-9][0-9]:[0-9][0-9])$" "" ) string:replace ?core .
62
- } .
63
-
64
- # core lexical form (no tz)
65
- { ?lex :coreNoTz ?lex } <= {
66
- ?lex string:notMatches ".*(Z|[+-][0-9][0-9]:[0-9][0-9])$" .
67
- } .
68
-
69
- # timezone defaults for floating literals
70
- { ?lex :tzForMin "+14:00" } <= { ?lex :tzSuffix "" . } .
71
- { ?lex :tzForMin ?tz } <= { ?lex :tzSuffix ?tz . ?tz log:notEqualTo "" . } .
72
-
73
- { ?lex :tzForMax "-14:00" } <= { ?lex :tzSuffix "" . } .
74
- { ?lex :tzForMax ?tz } <= { ?lex :tzSuffix ?tz . ?tz log:notEqualTo "" . } .
75
-
76
- ######################################################################
77
- # Helpers: ensure xsd:dateTime core has milliseconds
78
- ######################################################################
79
-
80
- { ?core :ensureMs ?core } <= { ?core string:matches ".*\\.[0-9][0-9][0-9]$" . } .
81
-
82
- { ?core :ensureMs ?core2 } <= {
83
- ?core string:notMatches ".*\\.[0-9][0-9][0-9]$" .
84
- ( ?core ".000" ) string:concatenation ?core2 .
85
- } .
86
-
87
- ######################################################################
88
- # Helpers: parse parts from lexical strings
89
- ######################################################################
90
-
91
- # Parse YYYY-MM-DD
92
- { ?dateCore :dateParts (?y ?m ?d) } <= {
93
- ( ?dateCore "^(\\d{4,})" ) string:scrape ?yS .
94
- ( ?dateCore "^\\d{4,}-(\\d\\d)" ) string:scrape ?mS .
95
- ( ?dateCore "^\\d{4,}-\\d\\d-(\\d\\d)$" ) string:scrape ?dS .
96
- ( ?yS xsd:integer ) log:dtlit ?y .
97
- ( ?mS xsd:integer ) log:dtlit ?m .
98
- ( ?dS xsd:integer ) log:dtlit ?d .
99
- } .
100
-
101
- # Parse YYYY-MM
102
- { ?ymCore :yearMonthParts (?y ?m) } <= {
103
- ( ?ymCore "^(\\d{4,})" ) string:scrape ?yS .
104
- ( ?ymCore "^\\d{4,}-(\\d\\d)$" ) string:scrape ?mS .
105
- ( ?yS xsd:integer ) log:dtlit ?y .
106
- ( ?mS xsd:integer ) log:dtlit ?m .
107
- } .
108
-
109
- # Parse YYYY
110
- { ?yCore :yearPart ?y } <= {
111
- ( ?yCore "^(\\d{4,})$" ) string:scrape ?yS .
112
- ( ?yS xsd:integer ) log:dtlit ?y .
113
- } .
114
-
115
- # Parse YYYY-MM-DDTHH:MM:SS.mmm
116
- { ?dtCore :dateTimeParts (?y ?m ?d ?hh ?mm ?ss ?ms) } <= {
117
- ( ?dtCore "^(\\d{4,})" ) string:scrape ?yS .
118
- ( ?dtCore "^\\d{4,}-(\\d\\d)" ) string:scrape ?mS .
119
- ( ?dtCore "^\\d{4,}-\\d\\d-(\\d\\d)" ) string:scrape ?dS .
120
- ( ?dtCore "T(\\d\\d):" ) string:scrape ?hhS .
121
- ( ?dtCore "T\\d\\d:(\\d\\d):" ) string:scrape ?mmS .
122
- ( ?dtCore "T\\d\\d:\\d\\d:(\\d\\d)" ) string:scrape ?ssS .
123
- ( ?dtCore "\\.(\\d\\d\\d)$" ) string:scrape ?msS .
124
- ( ?yS xsd:integer ) log:dtlit ?y .
125
- ( ?mS xsd:integer ) log:dtlit ?m .
126
- ( ?dS xsd:integer ) log:dtlit ?d .
127
- ( ?hhS xsd:integer ) log:dtlit ?hh .
128
- ( ?mmS xsd:integer ) log:dtlit ?mm .
129
- ( ?ssS xsd:integer ) log:dtlit ?ss .
130
- ( ?msS xsd:integer ) log:dtlit ?ms .
131
- } .
132
-
133
- ######################################################################
134
- # Helpers: formatting (pad2 / pad3)
135
- ######################################################################
136
-
137
- { ?n :pad2 ?s } <= {
138
- ?n math:lessThan 10 .
139
- ( ?nS ?t ) log:dtlit ?n .
140
- ( "0" ?nS ) string:concatenation ?s .
141
- } .
142
-
143
- { ?n :pad2 ?s } <= {
144
- ?n math:notLessThan 10 .
145
- ( ?nS ?t ) log:dtlit ?n .
146
- ?s log:equalTo ?nS .
147
- } .
148
-
149
- { ?n :pad3 ?s } <= {
150
- ?n math:lessThan 10 .
151
- ( ?nS ?t ) log:dtlit ?n .
152
- ( "00" ?nS ) string:concatenation ?s .
153
- } .
154
-
155
- { ?n :pad3 ?s } <= {
156
- ?n math:notLessThan 10 .
157
- ?n math:lessThan 100 .
158
- ( ?nS ?t ) log:dtlit ?n .
159
- ( "0" ?nS ) string:concatenation ?s .
160
- } .
161
-
162
- { ?n :pad3 ?s } <= {
163
- ?n math:notLessThan 100 .
164
- ( ?nS ?t ) log:dtlit ?n .
165
- ?s log:equalTo ?nS .
166
- } .
167
-
168
- ######################################################################
169
- # Helpers: leap years & month lengths
170
- ######################################################################
171
-
172
- { ?y :isLeapYear true } <= { ( ?y 400 ) math:remainder 0 . } .
173
-
174
- { ?y :isLeapYear true } <= {
175
- ( ?y 400 ) math:remainder ?r400 . ?r400 math:notEqualTo 0 .
176
- ( ?y 100 ) math:remainder ?r100 . ?r100 math:notEqualTo 0 .
177
- ( ?y 4 ) math:remainder 0 .
178
- } .
179
-
180
- { ?y :isLeapYear false } <= {
181
- ( ?y 400 ) math:remainder ?r400 . ?r400 math:notEqualTo 0 .
182
- ( ?y 100 ) math:remainder 0 .
183
- } .
184
-
185
- { ?y :isLeapYear false } <= { ( ?y 4 ) math:remainder ?r4 . ?r4 math:notEqualTo 0 . } .
186
-
187
- { ( ?y ?m ) :daysInMonth 31 } <= { ?m list:in (1 3 5 7 8 10 12) . } .
188
- { ( ?y ?m ) :daysInMonth 30 } <= { ?m list:in (4 6 9 11) . } .
189
-
190
- { ( ?y 2 ) :daysInMonth 29 } <= { ?y :isLeapYear true . } .
191
- { ( ?y 2 ) :daysInMonth 28 } <= { ?y :isLeapYear false . } .
192
-
193
- ######################################################################
194
- # Helpers: next/prev month, next/prev day
195
- ######################################################################
196
-
197
- { ( ?y ?m ) :nextMonth ( ?y ?m2 ) } <= {
198
- ?m math:lessThan 12 .
199
- ( ?m 1 ) math:sum ?m2 .
200
- } .
201
-
202
- { ( ?y ?m ) :nextMonth ( ?y2 1 ) } <= {
203
- ?m math:equalTo 12 .
204
- ( ?y 1 ) math:sum ?y2 .
205
- } .
206
-
207
- { ( ?y ?m ) :prevMonth ( ?y ?m2 ) } <= {
208
- ?m math:greaterThan 1 .
209
- ( ?m 1 ) math:difference ?m2 .
210
- } .
211
-
212
- { ( ?y ?m ) :prevMonth ( ?y2 12 ) } <= {
213
- ?m math:equalTo 1 .
214
- ( ?y 1 ) math:difference ?y2 .
215
- } .
216
-
217
- { ( ?y ?m ?d ) :nextDay ( ?y ?m ?d2 ) } <= {
218
- ( ?y ?m ) :daysInMonth ?dim .
219
- ?d math:lessThan ?dim .
220
- ( ?d 1 ) math:sum ?d2 .
221
- } .
222
-
223
- { ( ?y ?m ?d ) :nextDay ( ?y ?m2 1 ) } <= {
224
- ( ?y ?m ) :daysInMonth ?dim .
225
- ?d math:equalTo ?dim .
226
- ?m math:lessThan 12 .
227
- ( ?m 1 ) math:sum ?m2 .
228
- } .
229
-
230
- { ( ?y ?m ?d ) :nextDay ( ?y2 1 1 ) } <= {
231
- ( ?y ?m ) :daysInMonth ?dim .
232
- ?d math:equalTo ?dim .
233
- ?m math:equalTo 12 .
234
- ( ?y 1 ) math:sum ?y2 .
235
- } .
236
-
237
- { ( ?y ?m ?d ) :prevDay ( ?y ?m ?d2 ) } <= {
238
- ?d math:greaterThan 1 .
239
- ( ?d 1 ) math:difference ?d2 .
240
- } .
241
-
242
- # NOTE: prevDay across month boundary (d=1). We compute previous month/year first.
243
- { ( ?y ?m 1 ) :prevDay ( ?yPrev ?mPrev ?dPrevLast ) } <= {
244
- ( ?y ?m ) :prevMonth ( ?yPrev ?mPrev ) .
245
- ( ?yPrev ?mPrev ) :daysInMonth ?dPrevLast .
246
- } .
247
-
248
- ######################################################################
249
- # Helpers: +1ms / -1ms on date-time parts
250
- ######################################################################
251
-
252
- # addCarry on 0..999 (milliseconds)
253
- { ?ms :inc1000 ( ?ms2 0 ) } <= {
254
- ?ms math:lessThan 999 .
255
- ( ?ms 1 ) math:sum ?ms2 .
256
- } .
257
- { ?ms :inc1000 ( 0 1 ) } <= { ?ms math:equalTo 999 . } .
258
-
259
- # decCarry on 0..999 (milliseconds)
260
- { ?ms :dec1000 ( ?ms2 0 ) } <= {
261
- ?ms math:greaterThan 0 .
262
- ( ?ms 1 ) math:difference ?ms2 .
263
- } .
264
- { ?ms :dec1000 ( 999 1 ) } <= { ?ms math:equalTo 0 . } .
265
-
266
- # Add carry to 0..59 (seconds/minutes): (value carryIn) -> (valueOut carryOut)
267
- { ( ?v 0 ) :addCarry60 ( ?v 0 ) } <= { } .
268
- { ( ?v 1 ) :addCarry60 ( ?v2 0 ) } <= {
269
- ?v math:lessThan 59 .
270
- ( ?v 1 ) math:sum ?v2 .
271
- } .
272
- { ( ?v 1 ) :addCarry60 ( 0 1 ) } <= { ?v math:equalTo 59 . } .
273
-
274
- # Sub borrow from 0..59 (seconds/minutes): (value borrowIn) -> (valueOut borrowOut)
275
- { ( ?v 0 ) :subBorrow60 ( ?v 0 ) } <= { } .
276
- { ( ?v 1 ) :subBorrow60 ( ?v2 0 ) } <= {
277
- ?v math:greaterThan 0 .
278
- ( ?v 1 ) math:difference ?v2 .
279
- } .
280
- { ( ?v 1 ) :subBorrow60 ( 59 1 ) } <= { ?v math:equalTo 0 . } .
281
-
282
- # Add carry to 0..23 (hours): (value carryIn) -> (valueOut carryOut)
283
- { ( ?v 0 ) :addCarry24 ( ?v 0 ) } <= { } .
284
- { ( ?v 1 ) :addCarry24 ( ?v2 0 ) } <= {
285
- ?v math:lessThan 23 .
286
- ( ?v 1 ) math:sum ?v2 .
287
- } .
288
- { ( ?v 1 ) :addCarry24 ( 0 1 ) } <= { ?v math:equalTo 23 . } .
289
-
290
- # Sub borrow from 0..23 (hours): (value borrowIn) -> (valueOut borrowOut)
291
- { ( ?v 0 ) :subBorrow24 ( ?v 0 ) } <= { } .
292
- { ( ?v 1 ) :subBorrow24 ( ?v2 0 ) } <= {
293
- ?v math:greaterThan 0 .
294
- ( ?v 1 ) math:difference ?v2 .
295
- } .
296
- { ( ?v 1 ) :subBorrow24 ( 23 1 ) } <= { ?v math:equalTo 0 . } .
297
-
298
- # Add carry to date: (y m d carryIn) -> (y2 m2 d2)
299
- { ( ?y ?m ?d 0 ) :addCarryDay ( ?y ?m ?d ) } <= { } .
300
- { ( ?y ?m ?d 1 ) :addCarryDay ( ?y2 ?m2 ?d2 ) } <= { ( ?y ?m ?d ) :nextDay ( ?y2 ?m2 ?d2 ) . } .
301
-
302
- # Sub borrow from date: (y m d borrowIn) -> (y2 m2 d2)
303
- { ( ?y ?m ?d 0 ) :subBorrowDay ( ?y ?m ?d ) } <= { } .
304
- { ( ?y ?m ?d 1 ) :subBorrowDay ( ?y2 ?m2 ?d2 ) } <= { ( ?y ?m ?d ) :prevDay ( ?y2 ?m2 ?d2 ) . } .
305
-
306
- # Full +1ms: (y m d hh mm ss ms) -> (...)
307
- { ( ?y ?m ?d ?hh ?mm ?ss ?ms ) :add1ms ( ?y2 ?m2 ?d2 ?hh2 ?mm2 ?ss2 ?ms2 ) } <= {
308
- ?ms :inc1000 ( ?ms2 ?c1 ) .
309
- ( ?ss ?c1 ) :addCarry60 ( ?ss2 ?c2 ) .
310
- ( ?mm ?c2 ) :addCarry60 ( ?mm2 ?c3 ) .
311
- ( ?hh ?c3 ) :addCarry24 ( ?hh2 ?c4 ) .
312
- ( ?y ?m ?d ?c4 ) :addCarryDay ( ?y2 ?m2 ?d2 ) .
313
- } .
314
-
315
- # Full -1ms: (y m d hh mm ss ms) -> (...)
316
- { ( ?y ?m ?d ?hh ?mm ?ss ?ms ) :sub1ms ( ?y2 ?m2 ?d2 ?hh2 ?mm2 ?ss2 ?ms2 ) } <= {
317
- ?ms :dec1000 ( ?ms2 ?b1 ) .
318
- ( ?ss ?b1 ) :subBorrow60 ( ?ss2 ?b2 ) .
319
- ( ?mm ?b2 ) :subBorrow60 ( ?mm2 ?b3 ) .
320
- ( ?hh ?b3 ) :subBorrow24 ( ?hh2 ?b4 ) .
321
- ( ?y ?m ?d ?b4 ) :subBorrowDay ( ?y2 ?m2 ?d2 ) .
322
- } .
323
-
324
- ######################################################################
325
- # Helpers: build xsd:dateTime literal from parts + timezone
326
- ######################################################################
327
-
328
- { ( ?y ?m ?d ?hh ?mm ?ss ?ms ?tz ) :buildDateTime ?dt } <= {
329
- ( ?yS ?tY ) log:dtlit ?y .
330
- ?m :pad2 ?mS .
331
- ?d :pad2 ?dS .
332
- ?hh :pad2 ?hhS .
333
- ?mm :pad2 ?mmS .
334
- ?ss :pad2 ?ssS .
335
- ?ms :pad3 ?msS .
336
- ( ?yS "-" ?mS "-" ?dS "T" ?hhS ":" ?mmS ":" ?ssS "." ?msS ?tz ) string:concatenation ?lex .
337
- ( ?lex xsd:dateTime ) log:dtlit ?dt .
338
- } .
339
-
340
- ######################################################################
341
- # Unary list wrappers (optional convenience)
342
- ######################################################################
343
-
344
- { ( ?p ) tfn:periodMinInclusive ?o } <= { ?p tfn:periodMinInclusive ?o . } .
345
- { ( ?p ) tfn:periodMaxInclusive ?o } <= { ?p tfn:periodMaxInclusive ?o . } .
346
- { ( ?p ) tfn:periodMinExclusive ?o } <= { ?p tfn:periodMinExclusive ?o . } .
347
- { ( ?p ) tfn:periodMaxExclusive ?o } <= { ?p tfn:periodMaxExclusive ?o . } .
348
-
349
- ######################################################################
350
- # tfn:bindDefaultTimezone
351
- ######################################################################
352
-
353
- # If timezone present: unchanged
354
- { ( ?time ?defaultTz ) tfn:bindDefaultTimezone ?out } <= {
355
- ( ?lex ?dt ) log:dtlit ?time .
356
- ?lex :tzSuffix ?tz .
357
- ?tz log:notEqualTo "" .
358
- ?out log:equalTo ?time .
359
- } .
360
-
361
- # If no timezone: append default and keep datatype
362
- { ( ?time ?defaultTz ) tfn:bindDefaultTimezone ?out } <= {
363
- ( ?lex ?dt ) log:dtlit ?time .
364
- ?lex :tzSuffix "" .
365
- ( ?lex ?defaultTz ) string:concatenation ?lex2 .
366
- ( ?lex2 ?dt ) log:dtlit ?out .
367
- } .
368
-
369
- ######################################################################
370
- # tfn:periodMinInclusive
371
- ######################################################################
372
-
373
- # xsd:dateTime with tz -> same
374
- { ?p tfn:periodMinInclusive ?out } <= {
375
- ( ?lex xsd:dateTime ) log:dtlit ?p .
376
- ?lex :tzSuffix ?tz .
377
- ?tz log:notEqualTo "" .
378
- ?out log:equalTo ?p .
379
- } .
380
-
381
- # xsd:dateTime without tz -> bind +14:00
382
- { ?p tfn:periodMinInclusive ?out } <= {
383
- ( ?lex xsd:dateTime ) log:dtlit ?p .
384
- ?lex :tzSuffix "" .
385
- ?lex :coreNoTz ?core .
386
- ( ?core "+14:00" ) string:concatenation ?lex2 .
387
- ( ?lex2 xsd:dateTime ) log:dtlit ?out .
388
- } .
389
-
390
- # xsd:date -> YYYY-MM-DDT00:00:00.000 with given tz or +14:00
391
- { ?p tfn:periodMinInclusive ?out } <= {
392
- ( ?lex xsd:date ) log:dtlit ?p .
393
- ?lex :coreNoTz ?core .
394
- ?lex :tzForMin ?tz .
395
- ?core :dateParts ( ?y ?m ?d ) .
396
- ( ?y ?m ?d 0 0 0 0 ?tz ) :buildDateTime ?out .
397
- } .
398
-
399
- # xsd:gYearMonth -> YYYY-MM-01T00:00:00.000 with given tz or +14:00
400
- { ?p tfn:periodMinInclusive ?out } <= {
401
- ( ?lex xsd:gYearMonth ) log:dtlit ?p .
402
- ?lex :coreNoTz ?core .
403
- ?lex :tzForMin ?tz .
404
- ?core :yearMonthParts ( ?y ?m ) .
405
- ( ?y ?m 1 0 0 0 0 ?tz ) :buildDateTime ?out .
406
- } .
407
-
408
- # xsd:gYear -> YYYY-01-01T00:00:00.000 with given tz or +14:00
409
- { ?p tfn:periodMinInclusive ?out } <= {
410
- ( ?lex xsd:gYear ) log:dtlit ?p .
411
- ?lex :coreNoTz ?core .
412
- ?lex :tzForMin ?tz .
413
- ?core :yearPart ?y .
414
- ( ?y 1 1 0 0 0 0 ?tz ) :buildDateTime ?out .
415
- } .
416
-
417
- ######################################################################
418
- # tfn:periodMaxInclusive
419
- ######################################################################
420
-
421
- # xsd:dateTime with tz -> same
422
- { ?p tfn:periodMaxInclusive ?out } <= {
423
- ( ?lex xsd:dateTime ) log:dtlit ?p .
424
- ?lex :tzSuffix ?tz .
425
- ?tz log:notEqualTo "" .
426
- ?out log:equalTo ?p .
427
- } .
428
-
429
- # xsd:dateTime without tz -> bind -14:00
430
- { ?p tfn:periodMaxInclusive ?out } <= {
431
- ( ?lex xsd:dateTime ) log:dtlit ?p .
432
- ?lex :tzSuffix "" .
433
- ?lex :coreNoTz ?core .
434
- ( ?core "-14:00" ) string:concatenation ?lex2 .
435
- ( ?lex2 xsd:dateTime ) log:dtlit ?out .
436
- } .
437
-
438
- # xsd:date -> YYYY-MM-DDT23:59:59.999 with given tz or -14:00
439
- { ?p tfn:periodMaxInclusive ?out } <= {
440
- ( ?lex xsd:date ) log:dtlit ?p .
441
- ?lex :coreNoTz ?core .
442
- ?lex :tzForMax ?tz .
443
- ?core :dateParts ( ?y ?m ?d ) .
444
- ( ?y ?m ?d 23 59 59 999 ?tz ) :buildDateTime ?out .
445
- } .
446
-
447
- # xsd:gYearMonth -> YYYY-MM-lastDayT23:59:59.999 with given tz or -14:00
448
- { ?p tfn:periodMaxInclusive ?out } <= {
449
- ( ?lex xsd:gYearMonth ) log:dtlit ?p .
450
- ?lex :coreNoTz ?core .
451
- ?lex :tzForMax ?tz .
452
- ?core :yearMonthParts ( ?y ?m ) .
453
- ( ?y ?m ) :daysInMonth ?dLast .
454
- ( ?y ?m ?dLast 23 59 59 999 ?tz ) :buildDateTime ?out .
455
- } .
456
-
457
- # xsd:gYear -> YYYY-12-31T23:59:59.999 with given tz or -14:00
458
- { ?p tfn:periodMaxInclusive ?out } <= {
459
- ( ?lex xsd:gYear ) log:dtlit ?p .
460
- ?lex :coreNoTz ?core .
461
- ?lex :tzForMax ?tz .
462
- ?core :yearPart ?y .
463
- ( ?y 12 31 23 59 59 999 ?tz ) :buildDateTime ?out .
464
- } .
465
-
466
- ######################################################################
467
- # tfn:periodMinExclusive
468
- ######################################################################
469
-
470
- # xsd:dateTime with tz -> subtract 1ms, keep tz
471
- { ?p tfn:periodMinExclusive ?out } <= {
472
- ( ?lex xsd:dateTime ) log:dtlit ?p .
473
- ?lex :tzSuffix ?tz .
474
- ?tz log:notEqualTo "" .
475
- ?lex :coreNoTz ?core0 .
476
- ?core0 :ensureMs ?core .
477
- ?core :dateTimeParts ( ?y ?m ?d ?hh ?mm ?ss ?ms ) .
478
- ( ?y ?m ?d ?hh ?mm ?ss ?ms ) :sub1ms ( ?y2 ?m2 ?d2 ?hh2 ?mm2 ?ss2 ?ms2 ) .
479
- ( ?y2 ?m2 ?d2 ?hh2 ?mm2 ?ss2 ?ms2 ?tz ) :buildDateTime ?out .
480
- } .
481
-
482
- # xsd:dateTime without tz -> subtract 1ms, bind +14:00
483
- { ?p tfn:periodMinExclusive ?out } <= {
484
- ( ?lex xsd:dateTime ) log:dtlit ?p .
485
- ?lex :tzSuffix "" .
486
- ?lex :coreNoTz ?core0 .
487
- ?core0 :ensureMs ?core .
488
- ?core :dateTimeParts ( ?y ?m ?d ?hh ?mm ?ss ?ms ) .
489
- ( ?y ?m ?d ?hh ?mm ?ss ?ms ) :sub1ms ( ?y2 ?m2 ?d2 ?hh2 ?mm2 ?ss2 ?ms2 ) .
490
- ( ?y2 ?m2 ?d2 ?hh2 ?mm2 ?ss2 ?ms2 "+14:00" ) :buildDateTime ?out .
491
- } .
492
-
493
- # xsd:date -> previous day at 23:59:59.999, tz or +14:00
494
- { ?p tfn:periodMinExclusive ?out } <= {
495
- ( ?lex xsd:date ) log:dtlit ?p .
496
- ?lex :coreNoTz ?core .
497
- ?lex :tzForMin ?tz .
498
- ?core :dateParts ( ?y ?m ?d ) .
499
- ( ?y ?m ?d ) :prevDay ( ?y2 ?m2 ?d2 ) .
500
- ( ?y2 ?m2 ?d2 23 59 59 999 ?tz ) :buildDateTime ?out .
501
- } .
502
-
503
- # xsd:gYearMonth -> previous month's last day at 23:59:59.999, tz or +14:00
504
- { ?p tfn:periodMinExclusive ?out } <= {
505
- ( ?lex xsd:gYearMonth ) log:dtlit ?p .
506
- ?lex :coreNoTz ?core .
507
- ?lex :tzForMin ?tz .
508
- ?core :yearMonthParts ( ?y ?m ) .
509
- ( ?y ?m ) :prevMonth ( ?yPrev ?mPrev ) .
510
- ( ?yPrev ?mPrev ) :daysInMonth ?dPrevLast .
511
- ( ?yPrev ?mPrev ?dPrevLast 23 59 59 999 ?tz ) :buildDateTime ?out .
512
- } .
513
-
514
- # xsd:gYear -> previous year Dec 31 at 23:59:59.999, tz or +14:00
515
- { ?p tfn:periodMinExclusive ?out } <= {
516
- ( ?lex xsd:gYear ) log:dtlit ?p .
517
- ?lex :coreNoTz ?core .
518
- ?lex :tzForMin ?tz .
519
- ?core :yearPart ?y .
520
- ( ?y 1 ) math:difference ?yPrev .
521
- ( ?yPrev 12 31 23 59 59 999 ?tz ) :buildDateTime ?out .
522
- } .
523
-
524
- ######################################################################
525
- # tfn:periodMaxExclusive
526
- ######################################################################
527
-
528
- # xsd:dateTime with tz -> add 1ms, keep tz
529
- { ?p tfn:periodMaxExclusive ?out } <= {
530
- ( ?lex xsd:dateTime ) log:dtlit ?p .
531
- ?lex :tzSuffix ?tz .
532
- ?tz log:notEqualTo "" .
533
- ?lex :coreNoTz ?core0 .
534
- ?core0 :ensureMs ?core .
535
- ?core :dateTimeParts ( ?y ?m ?d ?hh ?mm ?ss ?ms ) .
536
- ( ?y ?m ?d ?hh ?mm ?ss ?ms ) :add1ms ( ?y2 ?m2 ?d2 ?hh2 ?mm2 ?ss2 ?ms2 ) .
537
- ( ?y2 ?m2 ?d2 ?hh2 ?mm2 ?ss2 ?ms2 ?tz ) :buildDateTime ?out .
538
- } .
539
-
540
- # xsd:dateTime without tz -> add 1ms, bind -14:00
541
- { ?p tfn:periodMaxExclusive ?out } <= {
542
- ( ?lex xsd:dateTime ) log:dtlit ?p .
543
- ?lex :tzSuffix "" .
544
- ?lex :coreNoTz ?core0 .
545
- ?core0 :ensureMs ?core .
546
- ?core :dateTimeParts ( ?y ?m ?d ?hh ?mm ?ss ?ms ) .
547
- ( ?y ?m ?d ?hh ?mm ?ss ?ms ) :add1ms ( ?y2 ?m2 ?d2 ?hh2 ?mm2 ?ss2 ?ms2 ) .
548
- ( ?y2 ?m2 ?d2 ?hh2 ?mm2 ?ss2 ?ms2 "-14:00" ) :buildDateTime ?out .
549
- } .
550
-
551
- # xsd:date -> next day at 00:00:00.000, tz or -14:00
552
- { ?p tfn:periodMaxExclusive ?out } <= {
553
- ( ?lex xsd:date ) log:dtlit ?p .
554
- ?lex :coreNoTz ?core .
555
- ?lex :tzForMax ?tz .
556
- ?core :dateParts ( ?y ?m ?d ) .
557
- ( ?y ?m ?d ) :nextDay ( ?y2 ?m2 ?d2 ) .
558
- ( ?y2 ?m2 ?d2 0 0 0 0 ?tz ) :buildDateTime ?out .
559
- } .
560
-
561
- # xsd:gYearMonth -> next month, first day at 00:00:00.000, tz or -14:00
562
- { ?p tfn:periodMaxExclusive ?out } <= {
563
- ( ?lex xsd:gYearMonth ) log:dtlit ?p .
564
- ?lex :coreNoTz ?core .
565
- ?lex :tzForMax ?tz .
566
- ?core :yearMonthParts ( ?y ?m ) .
567
- ( ?y ?m ) :nextMonth ( ?y2 ?m2 ) .
568
- ( ?y2 ?m2 1 0 0 0 0 ?tz ) :buildDateTime ?out .
569
- } .
570
-
571
- # xsd:gYear -> next year Jan 1 at 00:00:00.000, tz or -14:00
572
- { ?p tfn:periodMaxExclusive ?out } <= {
573
- ( ?lex xsd:gYear ) log:dtlit ?p .
574
- ?lex :coreNoTz ?core .
575
- ?lex :tzForMax ?tz .
576
- ?core :yearPart ?y .
577
- ( ?y 1 ) math:sum ?yNext .
578
- ( ?yNext 1 1 0 0 0 0 ?tz ) :buildDateTime ?out .
579
- } .
580
-
@@ -1,75 +0,0 @@
1
- # =================================================
2
- # JSON Pointer example
3
- # See https://datatracker.ietf.org/doc/html/rfc6901
4
- # =================================================
5
-
6
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
7
- @prefix string: <http://www.w3.org/2000/10/swap/string#> .
8
- @prefix list: <http://www.w3.org/2000/10/swap/list#> .
9
- @prefix log: <http://www.w3.org/2000/10/swap/log#> .
10
- @prefix ex: <http://example.org/#> .
11
-
12
- ex:doc ex:json """{
13
- "users": [
14
- { "id": "u1", "email": "ada@example.org", "profile/name": "Ada Lovelace" },
15
- { "id": "u2", "email": "bob@evil.invalid", "profile/name": "Bob Mallory" }
16
- ],
17
- "policy": { "allowedDomains": ["example.org", "example.com"] }
18
- }"""^^rdf:JSON .
19
-
20
- # Sanity check: key contains "/" so JSON Pointer must use "~1"
21
- {
22
- ex:doc ex:json ?J .
23
- (?J "/users/0/profile~1name") string:jsonPointer "Ada Lovelace" .
24
- } => {
25
- ex:checks ex:firstUserNameOk true .
26
- } .
27
-
28
- # Allowed users: email domain is in policy.allowedDomains
29
- {
30
- ex:doc ex:json ?J .
31
- (?J "/policy/allowedDomains") string:jsonPointer ?Allowed .
32
- (?J "/users") string:jsonPointer ?Users .
33
-
34
- ?Users list:iterate (?Idx ?UserJson) .
35
- (?UserJson "/id") string:jsonPointer ?Id .
36
- (?UserJson "/email") string:jsonPointer ?Email .
37
- (?UserJson "/profile~1name") string:jsonPointer ?Name .
38
-
39
- (?Email "@([^@]+)$") string:scrape ?EmailDomain .
40
- ?Allowed list:member ?EmailDomain .
41
-
42
- ("urn:example:user:%s" ?Id) string:format ?UriStr .
43
- ?User log:uri ?UriStr .
44
- } => {
45
- ?User a ex:AllowedUser ;
46
- ex:name ?Name ;
47
- ex:email ?Email ;
48
- ex:emailDomain ?EmailDomain ;
49
- ex:userIndex ?Idx .
50
- } .
51
-
52
- # Blocked users: email domain is NOT in the allowlist
53
- {
54
- ex:doc ex:json ?J .
55
- (?J "/policy/allowedDomains") string:jsonPointer ?Allowed .
56
- (?J "/users") string:jsonPointer ?Users .
57
-
58
- ?Users list:iterate (?Idx ?UserJson) .
59
- (?UserJson "/id") string:jsonPointer ?Id .
60
- (?UserJson "/email") string:jsonPointer ?Email .
61
- (?UserJson "/profile~1name") string:jsonPointer ?Name .
62
-
63
- (?Email "@([^@]+)$") string:scrape ?EmailDomain .
64
- ?Allowed list:notMember ?EmailDomain .
65
-
66
- ("urn:example:user:%s" ?Id) string:format ?UriStr .
67
- ?User log:uri ?UriStr .
68
- } => {
69
- ?User a ex:BlockedUser ;
70
- ex:name ?Name ;
71
- ex:email ?Email ;
72
- ex:emailDomain ?EmailDomain ;
73
- ex:userIndex ?Idx .
74
- } .
75
-