eyeling 1.6.1 → 1.6.3

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.
@@ -0,0 +1,84 @@
1
+ # alignment-demo.n3
2
+ # Minimal alignment example (SKOS mappings + inferred roll-up to a reference concept)
3
+
4
+ @prefix ex: <http://example.org/> .
5
+ @prefix ref: <http://example.org/taxonomy/ref/> .
6
+ @prefix tel: <http://example.org/taxonomy/telraam/> .
7
+ @prefix anpr: <http://example.org/taxonomy/anpr/> .
8
+
9
+ @prefix skos: <http://www.w3.org/2004/02/skos/core#> .
10
+ @prefix log: <http://www.w3.org/2000/10/swap/log#> .
11
+ @prefix list: <http://www.w3.org/2000/10/swap/list#> .
12
+
13
+ ######################################################################
14
+ # 1) Minimal concepts (3 schemes)
15
+ ######################################################################
16
+
17
+ ref:Car a skos:Concept ; skos:prefLabel "Car (reference reporting class)"@en .
18
+
19
+ tel:Car a skos:Concept ; skos:prefLabel "Telraam car"@en .
20
+ tel:HeavyVehicle a skos:Concept ; skos:prefLabel "Telraam heavy vehicle"@en .
21
+
22
+ anpr:VehicleWithPlate a skos:Concept ; skos:prefLabel "ANPR: vehicle with plate"@en .
23
+ anpr:PassengerCar a skos:Concept ; skos:prefLabel "ANPR: passenger car"@en ;
24
+ skos:broader anpr:VehicleWithPlate .
25
+
26
+ ######################################################################
27
+ # 2) Alignments (cross-scheme mappings)
28
+ ######################################################################
29
+
30
+ # Telraam categories mapped to the reference reporting class
31
+ tel:Car skos:broadMatch ref:Car .
32
+ tel:HeavyVehicle skos:broadMatch ref:Car .
33
+
34
+ # ANPR top concept mapped to reference reporting class
35
+ anpr:VehicleWithPlate skos:broadMatch ref:Car .
36
+
37
+ ######################################################################
38
+ # 3) Generic SKOS-ish rules needed for alignment reasoning
39
+ ######################################################################
40
+
41
+ # Treat skos:broadMatch as a "broader-than" link for roll-up
42
+ { ?a skos:broadMatch ?b. } => { ?a skos:broader ?b. } .
43
+
44
+ # Inverse broader/narrower
45
+ { ?n skos:broader ?b. } => { ?b skos:narrower ?n. } .
46
+
47
+ # Transitive closure seeds
48
+ { ?n skos:broader ?b. } => { ?n skos:broaderTransitive ?b. } .
49
+ { ?n skos:narrower ?c. } => { ?n skos:narrowerTransitive ?c. } .
50
+
51
+ # Transitivity
52
+ { ?a skos:broaderTransitive ?b. ?b skos:broaderTransitive ?c. } => { ?a skos:broaderTransitive ?c. } .
53
+ { ?a skos:narrowerTransitive ?b. ?b skos:narrowerTransitive ?c. } => { ?a skos:narrowerTransitive ?c. } .
54
+
55
+ # Keep transitive props inverse too (handy for downstream rules)
56
+ { ?a skos:broaderTransitive ?b. } => { ?b skos:narrowerTransitive ?a. } .
57
+ { ?a skos:narrowerTransitive ?b. } => { ?b skos:broaderTransitive ?a. } .
58
+
59
+ ######################################################################
60
+ # 4) One derived relation used by aggregation/queries:
61
+ # "datasetConcept is narrower-or-equal to referenceConcept"
62
+ ######################################################################
63
+
64
+ # Reflexive
65
+ { ?c a skos:Concept. } => { ?c ex:narrowerOrEqualOf ?c. } .
66
+
67
+ # Anything whose broaderTransitive reaches a concept contributes to that concept
68
+ { ?c skos:broaderTransitive ?b. } => { ?c ex:narrowerOrEqualOf ?b. } .
69
+
70
+ ######################################################################
71
+ # 5) Tiny “demo output” rule: flag concepts that roll up to ref:Car
72
+ ######################################################################
73
+
74
+ { ?x ex:narrowerOrEqualOf ref:Car. } => { ?x ex:rollsUpTo ref:Car. } .
75
+
76
+ ######################################################################
77
+ # Expected inferences (you should see these appear as derived facts):
78
+ #
79
+ # tel:Car ex:rollsUpTo ref:Car .
80
+ # tel:HeavyVehicle ex:rollsUpTo ref:Car .
81
+ # anpr:VehicleWithPlate ex:rollsUpTo ref:Car .
82
+ # anpr:PassengerCar ex:rollsUpTo ref:Car . # via broader anpr:VehicleWithPlate + mapping
83
+ ######################################################################
84
+
@@ -0,0 +1,38 @@
1
+ # ------------------------------------------------------------
2
+ # Minimal SKOS alignment + propagation example
3
+ #
4
+ # Goal:
5
+ # Show how a SKOS mapping (broadMatch) lets you treat dataset-
6
+ # specific categories as a reference category, and how that
7
+ # alignment propagates to more specific (narrower) categories.
8
+ #
9
+ # What should be inferred:
10
+ # anpr:VehicleWithPlate ex:treatedAs ref:Car .
11
+ # anpr:PassengerCar ex:treatedAs ref:Car .
12
+ #
13
+ # Run (example):
14
+ # eyeling minimal-skos-alignment.n3
15
+ # ------------------------------------------------------------
16
+
17
+ @prefix ex: <http://example.org/> .
18
+ @prefix ref: <http://example.org/ref/> .
19
+ @prefix anpr: <http://example.org/anpr/> .
20
+ @prefix skos: <http://www.w3.org/2004/02/skos/core#> .
21
+
22
+ # --- Concepts (two schemes) ---
23
+ ref:Car a skos:Concept .
24
+
25
+ anpr:VehicleWithPlate a skos:Concept ;
26
+ skos:broadMatch ref:Car .
27
+
28
+ anpr:PassengerCar a skos:Concept ;
29
+ skos:broader anpr:VehicleWithPlate .
30
+
31
+ # --- Rules ---
32
+ # Rule 1: interpret skos:broadMatch as "treat A as B" for reporting
33
+ { ?a skos:broadMatch ?b. } => { ?a ex:treatedAs ?b. } .
34
+
35
+ # Rule 2: propagate that treatment down the SKOS hierarchy:
36
+ # if X has broader concept Y, and Y is treatedAs Z, then X is treatedAs Z
37
+ { ?x skos:broader ?y. ?y ex:treatedAs ?z. } => { ?x ex:treatedAs ?z. } .
38
+
@@ -0,0 +1,610 @@
1
+ @prefix anpr: <http://example.org/taxonomy/anpr/> .
2
+ @prefix ex: <http://example.org/> .
3
+ @prefix ref: <http://example.org/taxonomy/ref/> .
4
+ @prefix skos: <http://www.w3.org/2004/02/skos/core#> .
5
+ @prefix tel: <http://example.org/taxonomy/telraam/> .
6
+
7
+ # ----------------------------------------------------------------------
8
+ # Proof for derived triple:
9
+ # tel:Car skos:broader ref:Car .
10
+ # It holds because the following instance of the rule body is provable:
11
+ # tel:Car skos:broadMatch ref:Car .
12
+ # via the schematic forward rule:
13
+ # {
14
+ # ?a skos:broadMatch ?b .
15
+ # } => {
16
+ # ?a skos:broader ?b .
17
+ # } .
18
+ # with substitution (on rule variables):
19
+ # ?a = tel:Car
20
+ # ?b = ref:Car
21
+ # Therefore the derived triple above is entailed by the rules and facts.
22
+ # ----------------------------------------------------------------------
23
+
24
+ tel:Car skos:broader ref:Car .
25
+
26
+ # ----------------------------------------------------------------------
27
+ # Proof for derived triple:
28
+ # tel:HeavyVehicle skos:broader ref:Car .
29
+ # It holds because the following instance of the rule body is provable:
30
+ # tel:HeavyVehicle skos:broadMatch ref:Car .
31
+ # via the schematic forward rule:
32
+ # {
33
+ # ?a skos:broadMatch ?b .
34
+ # } => {
35
+ # ?a skos:broader ?b .
36
+ # } .
37
+ # with substitution (on rule variables):
38
+ # ?a = tel:HeavyVehicle
39
+ # ?b = ref:Car
40
+ # Therefore the derived triple above is entailed by the rules and facts.
41
+ # ----------------------------------------------------------------------
42
+
43
+ tel:HeavyVehicle skos:broader ref:Car .
44
+
45
+ # ----------------------------------------------------------------------
46
+ # Proof for derived triple:
47
+ # anpr:VehicleWithPlate skos:broader ref:Car .
48
+ # It holds because the following instance of the rule body is provable:
49
+ # anpr:VehicleWithPlate skos:broadMatch ref:Car .
50
+ # via the schematic forward rule:
51
+ # {
52
+ # ?a skos:broadMatch ?b .
53
+ # } => {
54
+ # ?a skos:broader ?b .
55
+ # } .
56
+ # with substitution (on rule variables):
57
+ # ?a = anpr:VehicleWithPlate
58
+ # ?b = ref:Car
59
+ # Therefore the derived triple above is entailed by the rules and facts.
60
+ # ----------------------------------------------------------------------
61
+
62
+ anpr:VehicleWithPlate skos:broader ref:Car .
63
+
64
+ # ----------------------------------------------------------------------
65
+ # Proof for derived triple:
66
+ # anpr:VehicleWithPlate skos:narrower anpr:PassengerCar .
67
+ # It holds because the following instance of the rule body is provable:
68
+ # anpr:PassengerCar skos:broader anpr:VehicleWithPlate .
69
+ # via the schematic forward rule:
70
+ # {
71
+ # ?n skos:broader ?b .
72
+ # } => {
73
+ # ?b skos:narrower ?n .
74
+ # } .
75
+ # with substitution (on rule variables):
76
+ # ?b = anpr:VehicleWithPlate
77
+ # ?n = anpr:PassengerCar
78
+ # Therefore the derived triple above is entailed by the rules and facts.
79
+ # ----------------------------------------------------------------------
80
+
81
+ anpr:VehicleWithPlate skos:narrower anpr:PassengerCar .
82
+
83
+ # ----------------------------------------------------------------------
84
+ # Proof for derived triple:
85
+ # ref:Car skos:narrower tel:Car .
86
+ # It holds because the following instance of the rule body is provable:
87
+ # tel:Car skos:broader ref:Car .
88
+ # via the schematic forward rule:
89
+ # {
90
+ # ?n skos:broader ?b .
91
+ # } => {
92
+ # ?b skos:narrower ?n .
93
+ # } .
94
+ # with substitution (on rule variables):
95
+ # ?b = ref:Car
96
+ # ?n = tel:Car
97
+ # Therefore the derived triple above is entailed by the rules and facts.
98
+ # ----------------------------------------------------------------------
99
+
100
+ ref:Car skos:narrower tel:Car .
101
+
102
+ # ----------------------------------------------------------------------
103
+ # Proof for derived triple:
104
+ # ref:Car skos:narrower tel:HeavyVehicle .
105
+ # It holds because the following instance of the rule body is provable:
106
+ # tel:HeavyVehicle skos:broader ref:Car .
107
+ # via the schematic forward rule:
108
+ # {
109
+ # ?n skos:broader ?b .
110
+ # } => {
111
+ # ?b skos:narrower ?n .
112
+ # } .
113
+ # with substitution (on rule variables):
114
+ # ?b = ref:Car
115
+ # ?n = tel:HeavyVehicle
116
+ # Therefore the derived triple above is entailed by the rules and facts.
117
+ # ----------------------------------------------------------------------
118
+
119
+ ref:Car skos:narrower tel:HeavyVehicle .
120
+
121
+ # ----------------------------------------------------------------------
122
+ # Proof for derived triple:
123
+ # ref:Car skos:narrower anpr:VehicleWithPlate .
124
+ # It holds because the following instance of the rule body is provable:
125
+ # anpr:VehicleWithPlate skos:broader ref:Car .
126
+ # via the schematic forward rule:
127
+ # {
128
+ # ?n skos:broader ?b .
129
+ # } => {
130
+ # ?b skos:narrower ?n .
131
+ # } .
132
+ # with substitution (on rule variables):
133
+ # ?b = ref:Car
134
+ # ?n = anpr:VehicleWithPlate
135
+ # Therefore the derived triple above is entailed by the rules and facts.
136
+ # ----------------------------------------------------------------------
137
+
138
+ ref:Car skos:narrower anpr:VehicleWithPlate .
139
+
140
+ # ----------------------------------------------------------------------
141
+ # Proof for derived triple:
142
+ # anpr:PassengerCar skos:broaderTransitive anpr:VehicleWithPlate .
143
+ # It holds because the following instance of the rule body is provable:
144
+ # anpr:PassengerCar skos:broader anpr:VehicleWithPlate .
145
+ # via the schematic forward rule:
146
+ # {
147
+ # ?n skos:broader ?b .
148
+ # } => {
149
+ # ?n skos:broaderTransitive ?b .
150
+ # } .
151
+ # with substitution (on rule variables):
152
+ # ?b = anpr:VehicleWithPlate
153
+ # ?n = anpr:PassengerCar
154
+ # Therefore the derived triple above is entailed by the rules and facts.
155
+ # ----------------------------------------------------------------------
156
+
157
+ anpr:PassengerCar skos:broaderTransitive anpr:VehicleWithPlate .
158
+
159
+ # ----------------------------------------------------------------------
160
+ # Proof for derived triple:
161
+ # tel:Car skos:broaderTransitive ref:Car .
162
+ # It holds because the following instance of the rule body is provable:
163
+ # tel:Car skos:broader ref:Car .
164
+ # via the schematic forward rule:
165
+ # {
166
+ # ?n skos:broader ?b .
167
+ # } => {
168
+ # ?n skos:broaderTransitive ?b .
169
+ # } .
170
+ # with substitution (on rule variables):
171
+ # ?b = ref:Car
172
+ # ?n = tel:Car
173
+ # Therefore the derived triple above is entailed by the rules and facts.
174
+ # ----------------------------------------------------------------------
175
+
176
+ tel:Car skos:broaderTransitive ref:Car .
177
+
178
+ # ----------------------------------------------------------------------
179
+ # Proof for derived triple:
180
+ # tel:HeavyVehicle skos:broaderTransitive ref:Car .
181
+ # It holds because the following instance of the rule body is provable:
182
+ # tel:HeavyVehicle skos:broader ref:Car .
183
+ # via the schematic forward rule:
184
+ # {
185
+ # ?n skos:broader ?b .
186
+ # } => {
187
+ # ?n skos:broaderTransitive ?b .
188
+ # } .
189
+ # with substitution (on rule variables):
190
+ # ?b = ref:Car
191
+ # ?n = tel:HeavyVehicle
192
+ # Therefore the derived triple above is entailed by the rules and facts.
193
+ # ----------------------------------------------------------------------
194
+
195
+ tel:HeavyVehicle skos:broaderTransitive ref:Car .
196
+
197
+ # ----------------------------------------------------------------------
198
+ # Proof for derived triple:
199
+ # anpr:VehicleWithPlate skos:broaderTransitive ref:Car .
200
+ # It holds because the following instance of the rule body is provable:
201
+ # anpr:VehicleWithPlate skos:broader ref:Car .
202
+ # via the schematic forward rule:
203
+ # {
204
+ # ?n skos:broader ?b .
205
+ # } => {
206
+ # ?n skos:broaderTransitive ?b .
207
+ # } .
208
+ # with substitution (on rule variables):
209
+ # ?b = ref:Car
210
+ # ?n = anpr:VehicleWithPlate
211
+ # Therefore the derived triple above is entailed by the rules and facts.
212
+ # ----------------------------------------------------------------------
213
+
214
+ anpr:VehicleWithPlate skos:broaderTransitive ref:Car .
215
+
216
+ # ----------------------------------------------------------------------
217
+ # Proof for derived triple:
218
+ # anpr:VehicleWithPlate skos:narrowerTransitive anpr:PassengerCar .
219
+ # It holds because the following instance of the rule body is provable:
220
+ # anpr:VehicleWithPlate skos:narrower anpr:PassengerCar .
221
+ # via the schematic forward rule:
222
+ # {
223
+ # ?n skos:narrower ?c .
224
+ # } => {
225
+ # ?n skos:narrowerTransitive ?c .
226
+ # } .
227
+ # with substitution (on rule variables):
228
+ # ?c = anpr:PassengerCar
229
+ # ?n = anpr:VehicleWithPlate
230
+ # Therefore the derived triple above is entailed by the rules and facts.
231
+ # ----------------------------------------------------------------------
232
+
233
+ anpr:VehicleWithPlate skos:narrowerTransitive anpr:PassengerCar .
234
+
235
+ # ----------------------------------------------------------------------
236
+ # Proof for derived triple:
237
+ # ref:Car skos:narrowerTransitive tel:Car .
238
+ # It holds because the following instance of the rule body is provable:
239
+ # ref:Car skos:narrower tel:Car .
240
+ # via the schematic forward rule:
241
+ # {
242
+ # ?n skos:narrower ?c .
243
+ # } => {
244
+ # ?n skos:narrowerTransitive ?c .
245
+ # } .
246
+ # with substitution (on rule variables):
247
+ # ?c = tel:Car
248
+ # ?n = ref:Car
249
+ # Therefore the derived triple above is entailed by the rules and facts.
250
+ # ----------------------------------------------------------------------
251
+
252
+ ref:Car skos:narrowerTransitive tel:Car .
253
+
254
+ # ----------------------------------------------------------------------
255
+ # Proof for derived triple:
256
+ # ref:Car skos:narrowerTransitive tel:HeavyVehicle .
257
+ # It holds because the following instance of the rule body is provable:
258
+ # ref:Car skos:narrower tel:HeavyVehicle .
259
+ # via the schematic forward rule:
260
+ # {
261
+ # ?n skos:narrower ?c .
262
+ # } => {
263
+ # ?n skos:narrowerTransitive ?c .
264
+ # } .
265
+ # with substitution (on rule variables):
266
+ # ?c = tel:HeavyVehicle
267
+ # ?n = ref:Car
268
+ # Therefore the derived triple above is entailed by the rules and facts.
269
+ # ----------------------------------------------------------------------
270
+
271
+ ref:Car skos:narrowerTransitive tel:HeavyVehicle .
272
+
273
+ # ----------------------------------------------------------------------
274
+ # Proof for derived triple:
275
+ # ref:Car skos:narrowerTransitive anpr:VehicleWithPlate .
276
+ # It holds because the following instance of the rule body is provable:
277
+ # ref:Car skos:narrower anpr:VehicleWithPlate .
278
+ # via the schematic forward rule:
279
+ # {
280
+ # ?n skos:narrower ?c .
281
+ # } => {
282
+ # ?n skos:narrowerTransitive ?c .
283
+ # } .
284
+ # with substitution (on rule variables):
285
+ # ?c = anpr:VehicleWithPlate
286
+ # ?n = ref:Car
287
+ # Therefore the derived triple above is entailed by the rules and facts.
288
+ # ----------------------------------------------------------------------
289
+
290
+ ref:Car skos:narrowerTransitive anpr:VehicleWithPlate .
291
+
292
+ # ----------------------------------------------------------------------
293
+ # Proof for derived triple:
294
+ # anpr:PassengerCar skos:broaderTransitive ref:Car .
295
+ # It holds because the following instance of the rule body is provable:
296
+ # anpr:PassengerCar skos:broaderTransitive anpr:VehicleWithPlate .
297
+ # anpr:VehicleWithPlate skos:broaderTransitive ref:Car .
298
+ # via the schematic forward rule:
299
+ # {
300
+ # ?a skos:broaderTransitive ?b .
301
+ # ?b skos:broaderTransitive ?c .
302
+ # } => {
303
+ # ?a skos:broaderTransitive ?c .
304
+ # } .
305
+ # with substitution (on rule variables):
306
+ # ?a = anpr:PassengerCar
307
+ # ?b = anpr:VehicleWithPlate
308
+ # ?c = ref:Car
309
+ # Therefore the derived triple above is entailed by the rules and facts.
310
+ # ----------------------------------------------------------------------
311
+
312
+ anpr:PassengerCar skos:broaderTransitive ref:Car .
313
+
314
+ # ----------------------------------------------------------------------
315
+ # Proof for derived triple:
316
+ # ref:Car skos:narrowerTransitive anpr:PassengerCar .
317
+ # It holds because the following instance of the rule body is provable:
318
+ # ref:Car skos:narrowerTransitive anpr:VehicleWithPlate .
319
+ # anpr:VehicleWithPlate skos:narrowerTransitive anpr:PassengerCar .
320
+ # via the schematic forward rule:
321
+ # {
322
+ # ?a skos:narrowerTransitive ?b .
323
+ # ?b skos:narrowerTransitive ?c .
324
+ # } => {
325
+ # ?a skos:narrowerTransitive ?c .
326
+ # } .
327
+ # with substitution (on rule variables):
328
+ # ?a = ref:Car
329
+ # ?b = anpr:VehicleWithPlate
330
+ # ?c = anpr:PassengerCar
331
+ # Therefore the derived triple above is entailed by the rules and facts.
332
+ # ----------------------------------------------------------------------
333
+
334
+ ref:Car skos:narrowerTransitive anpr:PassengerCar .
335
+
336
+ # ----------------------------------------------------------------------
337
+ # Proof for derived triple:
338
+ # ref:Car ex:narrowerOrEqualOf ref:Car .
339
+ # It holds because the following instance of the rule body is provable:
340
+ # ref:Car a skos:Concept .
341
+ # via the schematic forward rule:
342
+ # {
343
+ # ?c a skos:Concept .
344
+ # } => {
345
+ # ?c ex:narrowerOrEqualOf ?c .
346
+ # } .
347
+ # with substitution (on rule variables):
348
+ # ?c = ref:Car
349
+ # Therefore the derived triple above is entailed by the rules and facts.
350
+ # ----------------------------------------------------------------------
351
+
352
+ ref:Car ex:narrowerOrEqualOf ref:Car .
353
+
354
+ # ----------------------------------------------------------------------
355
+ # Proof for derived triple:
356
+ # tel:Car ex:narrowerOrEqualOf tel:Car .
357
+ # It holds because the following instance of the rule body is provable:
358
+ # tel:Car a skos:Concept .
359
+ # via the schematic forward rule:
360
+ # {
361
+ # ?c a skos:Concept .
362
+ # } => {
363
+ # ?c ex:narrowerOrEqualOf ?c .
364
+ # } .
365
+ # with substitution (on rule variables):
366
+ # ?c = tel:Car
367
+ # Therefore the derived triple above is entailed by the rules and facts.
368
+ # ----------------------------------------------------------------------
369
+
370
+ tel:Car ex:narrowerOrEqualOf tel:Car .
371
+
372
+ # ----------------------------------------------------------------------
373
+ # Proof for derived triple:
374
+ # tel:HeavyVehicle ex:narrowerOrEqualOf tel:HeavyVehicle .
375
+ # It holds because the following instance of the rule body is provable:
376
+ # tel:HeavyVehicle a skos:Concept .
377
+ # via the schematic forward rule:
378
+ # {
379
+ # ?c a skos:Concept .
380
+ # } => {
381
+ # ?c ex:narrowerOrEqualOf ?c .
382
+ # } .
383
+ # with substitution (on rule variables):
384
+ # ?c = tel:HeavyVehicle
385
+ # Therefore the derived triple above is entailed by the rules and facts.
386
+ # ----------------------------------------------------------------------
387
+
388
+ tel:HeavyVehicle ex:narrowerOrEqualOf tel:HeavyVehicle .
389
+
390
+ # ----------------------------------------------------------------------
391
+ # Proof for derived triple:
392
+ # anpr:VehicleWithPlate ex:narrowerOrEqualOf anpr:VehicleWithPlate .
393
+ # It holds because the following instance of the rule body is provable:
394
+ # anpr:VehicleWithPlate a skos:Concept .
395
+ # via the schematic forward rule:
396
+ # {
397
+ # ?c a skos:Concept .
398
+ # } => {
399
+ # ?c ex:narrowerOrEqualOf ?c .
400
+ # } .
401
+ # with substitution (on rule variables):
402
+ # ?c = anpr:VehicleWithPlate
403
+ # Therefore the derived triple above is entailed by the rules and facts.
404
+ # ----------------------------------------------------------------------
405
+
406
+ anpr:VehicleWithPlate ex:narrowerOrEqualOf anpr:VehicleWithPlate .
407
+
408
+ # ----------------------------------------------------------------------
409
+ # Proof for derived triple:
410
+ # anpr:PassengerCar ex:narrowerOrEqualOf anpr:PassengerCar .
411
+ # It holds because the following instance of the rule body is provable:
412
+ # anpr:PassengerCar a skos:Concept .
413
+ # via the schematic forward rule:
414
+ # {
415
+ # ?c a skos:Concept .
416
+ # } => {
417
+ # ?c ex:narrowerOrEqualOf ?c .
418
+ # } .
419
+ # with substitution (on rule variables):
420
+ # ?c = anpr:PassengerCar
421
+ # Therefore the derived triple above is entailed by the rules and facts.
422
+ # ----------------------------------------------------------------------
423
+
424
+ anpr:PassengerCar ex:narrowerOrEqualOf anpr:PassengerCar .
425
+
426
+ # ----------------------------------------------------------------------
427
+ # Proof for derived triple:
428
+ # anpr:PassengerCar ex:narrowerOrEqualOf anpr:VehicleWithPlate .
429
+ # It holds because the following instance of the rule body is provable:
430
+ # anpr:PassengerCar skos:broaderTransitive anpr:VehicleWithPlate .
431
+ # via the schematic forward rule:
432
+ # {
433
+ # ?c skos:broaderTransitive ?b .
434
+ # } => {
435
+ # ?c ex:narrowerOrEqualOf ?b .
436
+ # } .
437
+ # with substitution (on rule variables):
438
+ # ?b = anpr:VehicleWithPlate
439
+ # ?c = anpr:PassengerCar
440
+ # Therefore the derived triple above is entailed by the rules and facts.
441
+ # ----------------------------------------------------------------------
442
+
443
+ anpr:PassengerCar ex:narrowerOrEqualOf anpr:VehicleWithPlate .
444
+
445
+ # ----------------------------------------------------------------------
446
+ # Proof for derived triple:
447
+ # tel:Car ex:narrowerOrEqualOf ref:Car .
448
+ # It holds because the following instance of the rule body is provable:
449
+ # tel:Car skos:broaderTransitive ref:Car .
450
+ # via the schematic forward rule:
451
+ # {
452
+ # ?c skos:broaderTransitive ?b .
453
+ # } => {
454
+ # ?c ex:narrowerOrEqualOf ?b .
455
+ # } .
456
+ # with substitution (on rule variables):
457
+ # ?b = ref:Car
458
+ # ?c = tel:Car
459
+ # Therefore the derived triple above is entailed by the rules and facts.
460
+ # ----------------------------------------------------------------------
461
+
462
+ tel:Car ex:narrowerOrEqualOf ref:Car .
463
+
464
+ # ----------------------------------------------------------------------
465
+ # Proof for derived triple:
466
+ # tel:HeavyVehicle ex:narrowerOrEqualOf ref:Car .
467
+ # It holds because the following instance of the rule body is provable:
468
+ # tel:HeavyVehicle skos:broaderTransitive ref:Car .
469
+ # via the schematic forward rule:
470
+ # {
471
+ # ?c skos:broaderTransitive ?b .
472
+ # } => {
473
+ # ?c ex:narrowerOrEqualOf ?b .
474
+ # } .
475
+ # with substitution (on rule variables):
476
+ # ?b = ref:Car
477
+ # ?c = tel:HeavyVehicle
478
+ # Therefore the derived triple above is entailed by the rules and facts.
479
+ # ----------------------------------------------------------------------
480
+
481
+ tel:HeavyVehicle ex:narrowerOrEqualOf ref:Car .
482
+
483
+ # ----------------------------------------------------------------------
484
+ # Proof for derived triple:
485
+ # anpr:VehicleWithPlate ex:narrowerOrEqualOf ref:Car .
486
+ # It holds because the following instance of the rule body is provable:
487
+ # anpr:VehicleWithPlate skos:broaderTransitive ref:Car .
488
+ # via the schematic forward rule:
489
+ # {
490
+ # ?c skos:broaderTransitive ?b .
491
+ # } => {
492
+ # ?c ex:narrowerOrEqualOf ?b .
493
+ # } .
494
+ # with substitution (on rule variables):
495
+ # ?b = ref:Car
496
+ # ?c = anpr:VehicleWithPlate
497
+ # Therefore the derived triple above is entailed by the rules and facts.
498
+ # ----------------------------------------------------------------------
499
+
500
+ anpr:VehicleWithPlate ex:narrowerOrEqualOf ref:Car .
501
+
502
+ # ----------------------------------------------------------------------
503
+ # Proof for derived triple:
504
+ # anpr:PassengerCar ex:narrowerOrEqualOf ref:Car .
505
+ # It holds because the following instance of the rule body is provable:
506
+ # anpr:PassengerCar skos:broaderTransitive ref:Car .
507
+ # via the schematic forward rule:
508
+ # {
509
+ # ?c skos:broaderTransitive ?b .
510
+ # } => {
511
+ # ?c ex:narrowerOrEqualOf ?b .
512
+ # } .
513
+ # with substitution (on rule variables):
514
+ # ?b = ref:Car
515
+ # ?c = anpr:PassengerCar
516
+ # Therefore the derived triple above is entailed by the rules and facts.
517
+ # ----------------------------------------------------------------------
518
+
519
+ anpr:PassengerCar ex:narrowerOrEqualOf ref:Car .
520
+
521
+ # ----------------------------------------------------------------------
522
+ # Proof for derived triple:
523
+ # ref:Car ex:rollsUpTo ref:Car .
524
+ # It holds because the following instance of the rule body is provable:
525
+ # ref:Car ex:narrowerOrEqualOf ref:Car .
526
+ # via the schematic forward rule:
527
+ # {
528
+ # ?x ex:narrowerOrEqualOf ref:Car .
529
+ # } => {
530
+ # ?x ex:rollsUpTo ref:Car .
531
+ # } .
532
+ # with substitution (on rule variables):
533
+ # ?x = ref:Car
534
+ # Therefore the derived triple above is entailed by the rules and facts.
535
+ # ----------------------------------------------------------------------
536
+
537
+ ref:Car ex:rollsUpTo ref:Car .
538
+
539
+ # ----------------------------------------------------------------------
540
+ # Proof for derived triple:
541
+ # tel:Car ex:rollsUpTo ref:Car .
542
+ # It holds because the following instance of the rule body is provable:
543
+ # tel:Car ex:narrowerOrEqualOf ref:Car .
544
+ # via the schematic forward rule:
545
+ # {
546
+ # ?x ex:narrowerOrEqualOf ref:Car .
547
+ # } => {
548
+ # ?x ex:rollsUpTo ref:Car .
549
+ # } .
550
+ # with substitution (on rule variables):
551
+ # ?x = tel:Car
552
+ # Therefore the derived triple above is entailed by the rules and facts.
553
+ # ----------------------------------------------------------------------
554
+
555
+ tel:Car ex:rollsUpTo ref:Car .
556
+
557
+ # ----------------------------------------------------------------------
558
+ # Proof for derived triple:
559
+ # tel:HeavyVehicle ex:rollsUpTo ref:Car .
560
+ # It holds because the following instance of the rule body is provable:
561
+ # tel:HeavyVehicle ex:narrowerOrEqualOf ref:Car .
562
+ # via the schematic forward rule:
563
+ # {
564
+ # ?x ex:narrowerOrEqualOf ref:Car .
565
+ # } => {
566
+ # ?x ex:rollsUpTo ref:Car .
567
+ # } .
568
+ # with substitution (on rule variables):
569
+ # ?x = tel:HeavyVehicle
570
+ # Therefore the derived triple above is entailed by the rules and facts.
571
+ # ----------------------------------------------------------------------
572
+
573
+ tel:HeavyVehicle ex:rollsUpTo ref:Car .
574
+
575
+ # ----------------------------------------------------------------------
576
+ # Proof for derived triple:
577
+ # anpr:VehicleWithPlate ex:rollsUpTo ref:Car .
578
+ # It holds because the following instance of the rule body is provable:
579
+ # anpr:VehicleWithPlate ex:narrowerOrEqualOf ref:Car .
580
+ # via the schematic forward rule:
581
+ # {
582
+ # ?x ex:narrowerOrEqualOf ref:Car .
583
+ # } => {
584
+ # ?x ex:rollsUpTo ref:Car .
585
+ # } .
586
+ # with substitution (on rule variables):
587
+ # ?x = anpr:VehicleWithPlate
588
+ # Therefore the derived triple above is entailed by the rules and facts.
589
+ # ----------------------------------------------------------------------
590
+
591
+ anpr:VehicleWithPlate ex:rollsUpTo ref:Car .
592
+
593
+ # ----------------------------------------------------------------------
594
+ # Proof for derived triple:
595
+ # anpr:PassengerCar ex:rollsUpTo ref:Car .
596
+ # It holds because the following instance of the rule body is provable:
597
+ # anpr:PassengerCar ex:narrowerOrEqualOf ref:Car .
598
+ # via the schematic forward rule:
599
+ # {
600
+ # ?x ex:narrowerOrEqualOf ref:Car .
601
+ # } => {
602
+ # ?x ex:rollsUpTo ref:Car .
603
+ # } .
604
+ # with substitution (on rule variables):
605
+ # ?x = anpr:PassengerCar
606
+ # Therefore the derived triple above is entailed by the rules and facts.
607
+ # ----------------------------------------------------------------------
608
+
609
+ anpr:PassengerCar ex:rollsUpTo ref:Car .
610
+
@@ -0,0 +1,45 @@
1
+ @prefix anpr: <http://example.org/anpr/> .
2
+ @prefix ex: <http://example.org/> .
3
+ @prefix ref: <http://example.org/ref/> .
4
+
5
+ # ----------------------------------------------------------------------
6
+ # Proof for derived triple:
7
+ # anpr:VehicleWithPlate ex:treatedAs ref:Car .
8
+ # It holds because the following instance of the rule body is provable:
9
+ # anpr:VehicleWithPlate skos:broadMatch ref:Car .
10
+ # via the schematic forward rule:
11
+ # {
12
+ # ?a skos:broadMatch ?b .
13
+ # } => {
14
+ # ?a ex:treatedAs ?b .
15
+ # } .
16
+ # with substitution (on rule variables):
17
+ # ?a = anpr:VehicleWithPlate
18
+ # ?b = ref:Car
19
+ # Therefore the derived triple above is entailed by the rules and facts.
20
+ # ----------------------------------------------------------------------
21
+
22
+ anpr:VehicleWithPlate ex:treatedAs ref:Car .
23
+
24
+ # ----------------------------------------------------------------------
25
+ # Proof for derived triple:
26
+ # anpr:PassengerCar ex:treatedAs ref:Car .
27
+ # It holds because the following instance of the rule body is provable:
28
+ # anpr:PassengerCar skos:broader anpr:VehicleWithPlate .
29
+ # anpr:VehicleWithPlate ex:treatedAs ref:Car .
30
+ # via the schematic forward rule:
31
+ # {
32
+ # ?x skos:broader ?y .
33
+ # ?y ex:treatedAs ?z .
34
+ # } => {
35
+ # ?x ex:treatedAs ?z .
36
+ # } .
37
+ # with substitution (on rule variables):
38
+ # ?x = anpr:PassengerCar
39
+ # ?y = anpr:VehicleWithPlate
40
+ # ?z = ref:Car
41
+ # Therefore the derived triple above is entailed by the rules and facts.
42
+ # ----------------------------------------------------------------------
43
+
44
+ anpr:PassengerCar ex:treatedAs ref:Car .
45
+
package/eyeling.js CHANGED
@@ -499,6 +499,25 @@ function lex(inputText) {
499
499
  }
500
500
  break;
501
501
  }
502
+
503
+ // Optional exponent part: e.g., 1e0, 1.1e-3, 1.1E+0
504
+ if (i < n && (chars[i] === 'e' || chars[i] === 'E')) {
505
+ let j = i + 1;
506
+ if (j < n && (chars[j] === '+' || chars[j] === '-')) j++;
507
+ if (j < n && /[0-9]/.test(chars[j])) {
508
+ numChars.push(chars[i]); // e/E
509
+ i++;
510
+ if (i < n && (chars[i] === '+' || chars[i] === '-')) {
511
+ numChars.push(chars[i]);
512
+ i++;
513
+ }
514
+ while (i < n && /[0-9]/.test(chars[i])) {
515
+ numChars.push(chars[i]);
516
+ i++;
517
+ }
518
+ }
519
+ }
520
+
502
521
  tokens.push(new Token('Literal', numChars.join('')));
503
522
  continue;
504
523
  }
@@ -1245,7 +1264,21 @@ function termsEqual(a, b) {
1245
1264
  if (!a || !b) return false;
1246
1265
  if (a.constructor !== b.constructor) return false;
1247
1266
  if (a instanceof Iri) return a.value === b.value;
1248
- if (a instanceof Literal) return a.value === b.value;
1267
+ if (a instanceof Literal) {
1268
+ if (a.value === b.value) return true;
1269
+ if (literalsEquivalentAsXsdString(a.value, b.value)) return true;
1270
+
1271
+ // Keep in sync with unifyTerm(): numeric-value equality (EYE-style)
1272
+ const av = parseNumberLiteral(a);
1273
+ const bv = parseNumberLiteral(b);
1274
+ if (av !== null && bv !== null) {
1275
+ if (typeof av === 'bigint' && typeof bv === 'bigint') return av === bv;
1276
+ const an = typeof av === 'bigint' ? Number(av) : av;
1277
+ const bn = typeof bv === 'bigint' ? Number(bv) : bv;
1278
+ return !Number.isNaN(an) && !Number.isNaN(bn) && an === bn;
1279
+ }
1280
+ return false;
1281
+ }
1249
1282
  if (a instanceof Var) return a.name === b.name;
1250
1283
  if (a instanceof Blank) return a.label === b.label;
1251
1284
  if (a instanceof ListTerm) {
@@ -1428,7 +1461,7 @@ function hasAlphaEquiv(triples, tr) {
1428
1461
 
1429
1462
  function termFastKey(t) {
1430
1463
  if (t instanceof Iri) return 'I:' + t.value;
1431
- if (t instanceof Literal) return 'L:' + t.value;
1464
+ if (t instanceof Literal) return 'L:' + normalizeLiteralForFastKey(t.value);
1432
1465
  return null;
1433
1466
  }
1434
1467
 
@@ -1863,6 +1896,27 @@ function unifyTerm(a, b, subst) {
1863
1896
  if (a instanceof Literal && b instanceof Literal && a.value === b.value) return { ...subst };
1864
1897
  if (a instanceof Blank && b instanceof Blank && a.label === b.label) return { ...subst };
1865
1898
 
1899
+ // String-literal match (RDF 1.1): treat plain strings and xsd:string as equal (but not @lang)
1900
+ if (a instanceof Literal && b instanceof Literal) {
1901
+ if (literalsEquivalentAsXsdString(a.value, b.value)) return { ...subst };
1902
+ }
1903
+
1904
+ // Numeric-value match for literals, BUT ONLY when datatypes agree (or infer to agree)
1905
+ if (a instanceof Literal && b instanceof Literal) {
1906
+ const ai = parseNumericLiteralInfo(a);
1907
+ const bi = parseNumericLiteralInfo(b);
1908
+
1909
+ if (ai && bi && ai.dt === bi.dt) {
1910
+ if (ai.kind === 'bigint' && bi.kind === 'bigint') {
1911
+ if (ai.value === bi.value) return { ...subst };
1912
+ } else {
1913
+ const an = ai.kind === 'bigint' ? Number(ai.value) : ai.value;
1914
+ const bn = bi.kind === 'bigint' ? Number(bi.value) : bi.value;
1915
+ if (!Number.isNaN(an) && !Number.isNaN(bn) && an === bn) return { ...subst };
1916
+ }
1917
+ }
1918
+ }
1919
+
1866
1920
  // Open list vs concrete list
1867
1921
  if (a instanceof OpenListTerm && b instanceof ListTerm) {
1868
1922
  return unifyOpenWithList(a.prefix, a.tailVar, b.elems, subst);
@@ -1965,6 +2019,65 @@ function literalParts(lit) {
1965
2019
  return [lex, dt];
1966
2020
  }
1967
2021
 
2022
+ function literalHasLangTag(lit) {
2023
+ // True iff the literal is a quoted string literal with a language tag suffix,
2024
+ // e.g. "hello"@en or """hello"""@en.
2025
+ // (The parser rejects language tags combined with datatypes.)
2026
+ if (typeof lit !== 'string') return false;
2027
+ if (lit.indexOf('^^') >= 0) return false;
2028
+ if (!lit.startsWith('"')) return false;
2029
+
2030
+ if (lit.startsWith('"""')) {
2031
+ const end = lit.lastIndexOf('"""');
2032
+ if (end < 0) return false;
2033
+ const after = end + 3;
2034
+ return after < lit.length && lit[after] === '@';
2035
+ }
2036
+
2037
+ const lastQuote = lit.lastIndexOf('"');
2038
+ if (lastQuote < 0) return false;
2039
+ const after = lastQuote + 1;
2040
+ return after < lit.length && lit[after] === '@';
2041
+ }
2042
+
2043
+ function isPlainStringLiteralValue(lit) {
2044
+ // Plain string literal: quoted, no datatype, no lang.
2045
+ if (typeof lit !== 'string') return false;
2046
+ if (lit.indexOf('^^') >= 0) return false;
2047
+ if (!isQuotedLexical(lit)) return false;
2048
+ return !literalHasLangTag(lit);
2049
+ }
2050
+
2051
+ function literalsEquivalentAsXsdString(aLit, bLit) {
2052
+ // Treat "abc" and "abc"^^xsd:string as equal, but do NOT conflate language-tagged strings.
2053
+ if (typeof aLit !== 'string' || typeof bLit !== 'string') return false;
2054
+
2055
+ const [alex, adt] = literalParts(aLit);
2056
+ const [blex, bdt] = literalParts(bLit);
2057
+ if (alex !== blex) return false;
2058
+
2059
+ const aPlain = adt === null && isPlainStringLiteralValue(aLit);
2060
+ const bPlain = bdt === null && isPlainStringLiteralValue(bLit);
2061
+ const aXsdStr = adt === XSD_NS + 'string';
2062
+ const bXsdStr = bdt === XSD_NS + 'string';
2063
+
2064
+ return (aPlain && bXsdStr) || (bPlain && aXsdStr);
2065
+ }
2066
+
2067
+ function normalizeLiteralForFastKey(lit) {
2068
+ // Canonicalize so that "abc" and "abc"^^xsd:string share the same index/dedup key.
2069
+ if (typeof lit !== 'string') return lit;
2070
+ const [lex, dt] = literalParts(lit);
2071
+
2072
+ if (dt === XSD_NS + 'string') {
2073
+ return `${lex}^^<${XSD_NS}string>`;
2074
+ }
2075
+ if (dt === null && isPlainStringLiteralValue(lit)) {
2076
+ return `${lex}^^<${XSD_NS}string>`;
2077
+ }
2078
+ return lit;
2079
+ }
2080
+
1968
2081
  function stripQuotes(lex) {
1969
2082
  if (lex.length >= 6 && lex.startsWith('"""') && lex.endsWith('"""')) {
1970
2083
  return lex.slice(3, -3);
@@ -2443,6 +2556,54 @@ function numEqualTerm(t, n, eps = 1e-9) {
2443
2556
  return v !== null && Math.abs(v - n) < eps;
2444
2557
  }
2445
2558
 
2559
+ function numericDatatypeFromLex(lex) {
2560
+ if (/[eE]/.test(lex)) return XSD_NS + 'double';
2561
+ if (lex.includes('.')) return XSD_NS + 'decimal';
2562
+ return XSD_NS + 'integer';
2563
+ }
2564
+
2565
+ function parseNumericLiteralInfo(t) {
2566
+ if (!(t instanceof Literal)) return null;
2567
+
2568
+ const v = t.value;
2569
+ const [lex, dt] = literalParts(v);
2570
+
2571
+ let dt2 = dt;
2572
+ let lexStr;
2573
+
2574
+ if (dt2 !== null) {
2575
+ // Only handle the numeric datatypes we want to unify by value
2576
+ if (
2577
+ dt2 !== XSD_NS + 'integer' &&
2578
+ dt2 !== XSD_NS + 'decimal' &&
2579
+ dt2 !== XSD_NS + 'double'
2580
+ ) return null;
2581
+
2582
+ // typed numerics are like "1.1"^^<...>
2583
+ lexStr = stripQuotes(lex);
2584
+ } else {
2585
+ // Raw numeric token like 42, 1.1, 1.1e0 (NOT quoted strings, NOT lang-tagged)
2586
+ if (typeof v !== 'string') return null;
2587
+ if (v.startsWith('"')) return null;
2588
+ if (!/^[+-]?(?:\d+\.\d*|\.\d+|\d+)(?:[eE][+-]?\d+)?$/.test(v)) return null;
2589
+
2590
+ dt2 = numericDatatypeFromLex(v);
2591
+ lexStr = v;
2592
+ }
2593
+
2594
+ if (dt2 === XSD_NS + 'integer') {
2595
+ try {
2596
+ return { dt: dt2, kind: 'bigint', value: BigInt(lexStr) };
2597
+ } catch {
2598
+ return null;
2599
+ }
2600
+ }
2601
+
2602
+ const num = Number(lexStr);
2603
+ if (Number.isNaN(num)) return null;
2604
+ return { dt: dt2, kind: 'number', value: num };
2605
+ }
2606
+
2446
2607
  // ============================================================================
2447
2608
  // Backward proof & builtins mutual recursion — declarations first
2448
2609
  // ============================================================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.6.1",
3
+ "version": "1.6.3",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [