eyeling 1.24.4 → 1.24.6

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 (301) hide show
  1. package/HANDBOOK.md +2 -101
  2. package/README.md +2 -2
  3. package/dist/browser/eyeling.browser.js +256 -4
  4. package/examples/annotation.n3 +3 -4
  5. package/{see/examples/n3/backward_recursion.n3 → examples/backward-recursion.n3} +0 -2
  6. package/examples/collection.n3 +1 -2
  7. package/examples/context-association.n3 +56 -30
  8. package/{see/examples/n3/dijkstra_risk_path.n3 → examples/dijkstra-risk-path.n3} +3 -18
  9. package/{see/examples/n3/eco_route_insight.n3 → examples/eco-route-insight.n3} +2 -47
  10. package/{see/examples/n3/genetic_knapsack_selection.n3 → examples/genetic-knapsack-selection.n3} +2 -24
  11. package/{see/examples → examples}/input/annotation.trig +3 -3
  12. package/{see/examples/input/backward_recursion.trig → examples/input/backward-recursion.trig} +2 -2
  13. package/{see/examples/input/builtin_coverage.trig → examples/input/builtin-coverage.trig} +2 -2
  14. package/{see/examples → examples}/input/collection.trig +3 -3
  15. package/{see/examples/input/dijkstra_risk_path.trig → examples/input/dijkstra-risk-path.trig} +4 -4
  16. package/{see/examples/input/eco_route_insight.trig → examples/input/eco-route-insight.trig} +4 -4
  17. package/{see/examples/input/genetic_knapsack_selection.trig → examples/input/genetic-knapsack-selection.trig} +4 -4
  18. package/{see/examples/input/rc_discharge_envelope.trig → examples/input/rc-discharge-envelope.trig} +4 -4
  19. package/{see/examples/input/rdf_dataset.trig → examples/input/rdf-dataset.trig} +4 -4
  20. package/{see/examples/input/rdf_message_flow.trig → examples/input/rdf-message-flow.trig} +3 -3
  21. package/{see/examples/input/rdf_messages.trig → examples/input/rdf-messages.trig} +4 -4
  22. package/{see/examples/input/school_placement_audit.trig → examples/input/school-placement-audit.trig} +4 -4
  23. package/{see/examples/input/smoke_arithmetic.trig → examples/input/smoke-arithmetic.trig} +3 -3
  24. package/{see/examples/input/triple_terms.trig → examples/input/triple-terms.trig} +3 -3
  25. package/examples/output/backward-recursion.n3 +4 -0
  26. package/examples/output/context-association.n3 +9 -0
  27. package/examples/output/dijkstra-risk-path.n3 +3 -0
  28. package/examples/output/eco-route-insight.n3 +3 -0
  29. package/examples/output/genetic-knapsack-selection.n3 +3 -0
  30. package/examples/output/rc-discharge-envelope.n3 +9 -0
  31. package/examples/output/rc-discharge-envelope.txt +9 -0
  32. package/examples/output/rdf-dataset.n3 +5 -0
  33. package/examples/output/rdf-message-flow.n3 +7 -0
  34. package/examples/output/rdf-messages.n3 +7 -0
  35. package/examples/output/school-placement-audit.n3 +3 -0
  36. package/examples/output/smoke-arithmetic.n3 +5 -0
  37. package/examples/output/smoke-arithmetic.txt +5 -0
  38. package/examples/output/triple-terms.n3 +5 -0
  39. package/{see/examples/n3/rc_discharge_envelope.n3 → examples/rc-discharge-envelope.n3} +2 -15
  40. package/{see/examples/n3/rdf_dataset.n3 → examples/rdf-dataset.n3} +2 -11
  41. package/{see/examples/n3/rdf_message_flow.n3 → examples/rdf-message-flow.n3} +9 -75
  42. package/{see/examples/n3/rdf_messages.n3 → examples/rdf-messages.n3} +6 -43
  43. package/{see/examples/n3/school_placement_audit.n3 → examples/school-placement-audit.n3} +2 -14
  44. package/{see/examples/n3/smoke_arithmetic.n3 → examples/smoke-arithmetic.n3} +3 -5
  45. package/{see/examples/n3/triple_terms.n3 → examples/triple-terms.n3} +1 -4
  46. package/eyeling.js +256 -4
  47. package/lib/builtins.js +6 -0
  48. package/lib/lexer.js +250 -4
  49. package/package.json +4 -7
  50. package/test/api.test.js +65 -8
  51. package/test/examples.test.js +22 -2
  52. package/test/package.test.js +16 -2
  53. package/examples/arcling/README.md +0 -11
  54. package/examples/input/annotation.ttl +0 -6
  55. package/examples/input/collection.ttl +0 -13
  56. package/examples/input/reifies.ttl +0 -10
  57. package/examples/input/triple-term.ttl +0 -8
  58. package/examples/output/triple-term.n3 +0 -0
  59. package/examples/reifies.n3 +0 -8
  60. package/examples/triple-term.n3 +0 -7
  61. package/see/README.md +0 -149
  62. package/see/examples/_see.js +0 -249
  63. package/see/examples/age.js +0 -1459
  64. package/see/examples/annotation.js +0 -1320
  65. package/see/examples/backward.js +0 -1405
  66. package/see/examples/backward_recursion.js +0 -1504
  67. package/see/examples/bayes_diagnosis.js +0 -2883
  68. package/see/examples/bayes_therapy.js +0 -4152
  69. package/see/examples/bmi.js +0 -3038
  70. package/see/examples/builtin_coverage.js +0 -2524
  71. package/see/examples/collection.js +0 -1320
  72. package/see/examples/complex.js +0 -3762
  73. package/see/examples/complex_matrix_stability.js +0 -2973
  74. package/see/examples/composition_of_injective_functions_is_injective.js +0 -2170
  75. package/see/examples/control_system.js +0 -1918
  76. package/see/examples/crypto_builtins_tests.js +0 -1489
  77. package/see/examples/delfour.js +0 -3174
  78. package/see/examples/digital_product_passport.js +0 -2856
  79. package/see/examples/dijkstra.js +0 -2070
  80. package/see/examples/dijkstra_risk_path.js +0 -1874
  81. package/see/examples/doc/age.md +0 -27
  82. package/see/examples/doc/annotation.md +0 -24
  83. package/see/examples/doc/backward.md +0 -26
  84. package/see/examples/doc/backward_recursion.md +0 -26
  85. package/see/examples/doc/bayes_diagnosis.md +0 -41
  86. package/see/examples/doc/bayes_therapy.md +0 -40
  87. package/see/examples/doc/bmi.md +0 -38
  88. package/see/examples/doc/builtin_coverage.md +0 -53
  89. package/see/examples/doc/collection.md +0 -24
  90. package/see/examples/doc/complex.md +0 -38
  91. package/see/examples/doc/complex_matrix_stability.md +0 -35
  92. package/see/examples/doc/composition_of_injective_functions_is_injective.md +0 -24
  93. package/see/examples/doc/control_system.md +0 -32
  94. package/see/examples/doc/crypto_builtins_tests.md +0 -27
  95. package/see/examples/doc/delfour.md +0 -37
  96. package/see/examples/doc/digital_product_passport.md +0 -36
  97. package/see/examples/doc/dijkstra.md +0 -28
  98. package/see/examples/doc/dijkstra_risk_path.md +0 -30
  99. package/see/examples/doc/dog.md +0 -28
  100. package/see/examples/doc/eco_route_insight.md +0 -33
  101. package/see/examples/doc/equals.md +0 -26
  102. package/see/examples/doc/equivalence_classes_overlap_implies_same_class.md +0 -24
  103. package/see/examples/doc/euler_identity.md +0 -39
  104. package/see/examples/doc/ev_roundtrip_planner.md +0 -32
  105. package/see/examples/doc/existential_rule.md +0 -24
  106. package/see/examples/doc/expression_eval.md +0 -26
  107. package/see/examples/doc/family_cousins.md +0 -24
  108. package/see/examples/doc/fastpow.md +0 -29
  109. package/see/examples/doc/fibonacci.md +0 -28
  110. package/see/examples/doc/french_cities.md +0 -28
  111. package/see/examples/doc/fundamental_theorem_arithmetic.md +0 -36
  112. package/see/examples/doc/genetic_knapsack_selection.md +0 -29
  113. package/see/examples/doc/goldbach_1000.md +0 -31
  114. package/see/examples/doc/good_cobbler.md +0 -27
  115. package/see/examples/doc/gps.md +0 -35
  116. package/see/examples/doc/gray_code_counter.md +0 -31
  117. package/see/examples/doc/greatest_lower_bound_uniqueness.md +0 -24
  118. package/see/examples/doc/group_inverse_uniqueness.md +0 -24
  119. package/see/examples/doc/hadamard_approx.md +0 -32
  120. package/see/examples/doc/hanoi.md +0 -26
  121. package/see/examples/doc/odrl_dpv_risk_ranked.md +0 -57
  122. package/see/examples/doc/path_discovery.md +0 -33
  123. package/see/examples/doc/rc_discharge_envelope.md +0 -33
  124. package/see/examples/doc/rdf_dataset.md +0 -26
  125. package/see/examples/doc/rdf_message_flow.md +0 -35
  126. package/see/examples/doc/rdf_messages.md +0 -37
  127. package/see/examples/doc/school_placement_audit.md +0 -31
  128. package/see/examples/doc/smoke_arithmetic.md +0 -31
  129. package/see/examples/doc/socrates.md +0 -24
  130. package/see/examples/doc/triple_terms.md +0 -26
  131. package/see/examples/doc/wind_turbine.md +0 -37
  132. package/see/examples/doc/witch.md +0 -28
  133. package/see/examples/dog.js +0 -1436
  134. package/see/examples/eco_route_insight.js +0 -2110
  135. package/see/examples/equals.js +0 -1363
  136. package/see/examples/equivalence_classes_overlap_implies_same_class.js +0 -1792
  137. package/see/examples/euler_identity.js +0 -2038
  138. package/see/examples/ev_roundtrip_planner.js +0 -2562
  139. package/see/examples/existential_rule.js +0 -1363
  140. package/see/examples/expression_eval.js +0 -1798
  141. package/see/examples/family_cousins.js +0 -1586
  142. package/see/examples/fastpow.js +0 -2207
  143. package/see/examples/fibonacci.js +0 -1594
  144. package/see/examples/french_cities.js +0 -1492
  145. package/see/examples/fundamental_theorem_arithmetic.js +0 -2106
  146. package/see/examples/genetic_knapsack_selection.js +0 -1743
  147. package/see/examples/goldbach_1000.js +0 -1798
  148. package/see/examples/good_cobbler.js +0 -1396
  149. package/see/examples/gps.js +0 -2813
  150. package/see/examples/gray_code_counter.js +0 -1641
  151. package/see/examples/greatest_lower_bound_uniqueness.js +0 -1918
  152. package/see/examples/group_inverse_uniqueness.js +0 -1897
  153. package/see/examples/hadamard_approx.js +0 -4417
  154. package/see/examples/hanoi.js +0 -1625
  155. package/see/examples/input/age.trig +0 -27
  156. package/see/examples/input/backward.trig +0 -25
  157. package/see/examples/input/bayes_diagnosis.trig +0 -111
  158. package/see/examples/input/bayes_therapy.trig +0 -130
  159. package/see/examples/input/bmi.trig +0 -28
  160. package/see/examples/input/complex.trig +0 -26
  161. package/see/examples/input/complex_matrix_stability.trig +0 -65
  162. package/see/examples/input/composition_of_injective_functions_is_injective.trig +0 -35
  163. package/see/examples/input/control_system.trig +0 -31
  164. package/see/examples/input/crypto_builtins_tests.trig +0 -25
  165. package/see/examples/input/delfour.trig +0 -90
  166. package/see/examples/input/digital_product_passport.trig +0 -116
  167. package/see/examples/input/dijkstra.trig +0 -34
  168. package/see/examples/input/dog.trig +0 -31
  169. package/see/examples/input/equals.trig +0 -25
  170. package/see/examples/input/equivalence_classes_overlap_implies_same_class.trig +0 -28
  171. package/see/examples/input/euler_identity.trig +0 -34
  172. package/see/examples/input/ev_roundtrip_planner.trig +0 -90
  173. package/see/examples/input/existential_rule.trig +0 -26
  174. package/see/examples/input/expression_eval.trig +0 -41
  175. package/see/examples/input/family_cousins.trig +0 -39
  176. package/see/examples/input/fastpow.trig +0 -25
  177. package/see/examples/input/fibonacci.trig +0 -51
  178. package/see/examples/input/french_cities.trig +0 -38
  179. package/see/examples/input/fundamental_theorem_arithmetic.trig +0 -42
  180. package/see/examples/input/goldbach_1000.trig +0 -53
  181. package/see/examples/input/good_cobbler.trig +0 -24
  182. package/see/examples/input/gps.trig +0 -35
  183. package/see/examples/input/gray_code_counter.trig +0 -33
  184. package/see/examples/input/greatest_lower_bound_uniqueness.trig +0 -29
  185. package/see/examples/input/group_inverse_uniqueness.trig +0 -29
  186. package/see/examples/input/hadamard_approx.trig +0 -32
  187. package/see/examples/input/hanoi.trig +0 -26
  188. package/see/examples/input/odrl_dpv_risk_ranked.trig +0 -107
  189. package/see/examples/input/path-discovery.trig +0 -96448
  190. package/see/examples/input/path_discovery.trig +0 -29
  191. package/see/examples/input/socrates.trig +0 -26
  192. package/see/examples/input/wind_turbine.trig +0 -48
  193. package/see/examples/input/witch.trig +0 -26
  194. package/see/examples/n3/age.n3 +0 -28
  195. package/see/examples/n3/annotation.n3 +0 -7
  196. package/see/examples/n3/backward.n3 +0 -22
  197. package/see/examples/n3/bayes_diagnosis.n3 +0 -122
  198. package/see/examples/n3/bayes_therapy.n3 +0 -149
  199. package/see/examples/n3/bmi.n3 +0 -145
  200. package/see/examples/n3/collection.n3 +0 -3
  201. package/see/examples/n3/complex.n3 +0 -140
  202. package/see/examples/n3/complex_matrix_stability.n3 +0 -113
  203. package/see/examples/n3/composition_of_injective_functions_is_injective.n3 +0 -27
  204. package/see/examples/n3/control_system.n3 +0 -59
  205. package/see/examples/n3/crypto_builtins_tests.n3 +0 -18
  206. package/see/examples/n3/delfour.n3 +0 -167
  207. package/see/examples/n3/digital_product_passport.n3 +0 -156
  208. package/see/examples/n3/dijkstra.n3 +0 -46
  209. package/see/examples/n3/dog.n3 +0 -20
  210. package/see/examples/n3/equals.n3 +0 -11
  211. package/see/examples/n3/equivalence_classes_overlap_implies_same_class.n3 +0 -19
  212. package/see/examples/n3/euler_identity.n3 +0 -41
  213. package/see/examples/n3/ev_roundtrip_planner.n3 +0 -82
  214. package/see/examples/n3/existential_rule.n3 +0 -10
  215. package/see/examples/n3/expression_eval.n3 +0 -21
  216. package/see/examples/n3/family_cousins.n3 +0 -62
  217. package/see/examples/n3/fastpow.n3 +0 -56
  218. package/see/examples/n3/fibonacci.n3 +0 -44
  219. package/see/examples/n3/french_cities.n3 +0 -28
  220. package/see/examples/n3/fundamental_theorem_arithmetic.n3 +0 -84
  221. package/see/examples/n3/goldbach_1000.n3 +0 -66
  222. package/see/examples/n3/good_cobbler.n3 +0 -10
  223. package/see/examples/n3/gps.n3 +0 -70
  224. package/see/examples/n3/gray_code_counter.n3 +0 -53
  225. package/see/examples/n3/greatest_lower_bound_uniqueness.n3 +0 -20
  226. package/see/examples/n3/group_inverse_uniqueness.n3 +0 -19
  227. package/see/examples/n3/hadamard_approx.n3 +0 -43
  228. package/see/examples/n3/hanoi.n3 +0 -16
  229. package/see/examples/n3/odrl_dpv_risk_ranked.n3 +0 -460
  230. package/see/examples/n3/path_discovery.n3 +0 -43
  231. package/see/examples/n3/socrates.n3 +0 -21
  232. package/see/examples/n3/wind_turbine.n3 +0 -85
  233. package/see/examples/n3/witch.n3 +0 -30
  234. package/see/examples/odrl_dpv_risk_ranked.js +0 -5128
  235. package/see/examples/output/age.md +0 -48
  236. package/see/examples/output/annotation.md +0 -43
  237. package/see/examples/output/backward.md +0 -50
  238. package/see/examples/output/backward_recursion.md +0 -54
  239. package/see/examples/output/bayes_diagnosis.md +0 -103
  240. package/see/examples/output/bayes_therapy.md +0 -84
  241. package/see/examples/output/bmi.md +0 -164
  242. package/see/examples/output/builtin_coverage.md +0 -99
  243. package/see/examples/output/collection.md +0 -44
  244. package/see/examples/output/complex.md +0 -61
  245. package/see/examples/output/complex_matrix_stability.md +0 -55
  246. package/see/examples/output/composition_of_injective_functions_is_injective.md +0 -62
  247. package/see/examples/output/control_system.md +0 -61
  248. package/see/examples/output/crypto_builtins_tests.md +0 -68
  249. package/see/examples/output/delfour.md +0 -100
  250. package/see/examples/output/digital_product_passport.md +0 -100
  251. package/see/examples/output/dijkstra.md +0 -74
  252. package/see/examples/output/dijkstra_risk_path.md +0 -76
  253. package/see/examples/output/dog.md +0 -50
  254. package/see/examples/output/eco_route_insight.md +0 -88
  255. package/see/examples/output/equals.md +0 -50
  256. package/see/examples/output/equivalence_classes_overlap_implies_same_class.md +0 -86
  257. package/see/examples/output/euler_identity.md +0 -73
  258. package/see/examples/output/ev_roundtrip_planner.md +0 -79
  259. package/see/examples/output/existential_rule.md +0 -54
  260. package/see/examples/output/expression_eval.md +0 -50
  261. package/see/examples/output/family_cousins.md +0 -187
  262. package/see/examples/output/fastpow.md +0 -36
  263. package/see/examples/output/fibonacci.md +0 -53
  264. package/see/examples/output/french_cities.md +0 -70
  265. package/see/examples/output/fundamental_theorem_arithmetic.md +0 -101
  266. package/see/examples/output/genetic_knapsack_selection.md +0 -66
  267. package/see/examples/output/goldbach_1000.md +0 -58
  268. package/see/examples/output/good_cobbler.md +0 -54
  269. package/see/examples/output/gps.md +0 -102
  270. package/see/examples/output/gray_code_counter.md +0 -68
  271. package/see/examples/output/greatest_lower_bound_uniqueness.md +0 -60
  272. package/see/examples/output/group_inverse_uniqueness.md +0 -60
  273. package/see/examples/output/hadamard_approx.md +0 -510
  274. package/see/examples/output/hanoi.md +0 -51
  275. package/see/examples/output/odrl_dpv_risk_ranked.md +0 -139
  276. package/see/examples/output/path_discovery.md +0 -65
  277. package/see/examples/output/rc_discharge_envelope.md +0 -102
  278. package/see/examples/output/rdf_dataset.md +0 -54
  279. package/see/examples/output/rdf_message_flow.md +0 -198
  280. package/see/examples/output/rdf_messages.md +0 -134
  281. package/see/examples/output/school_placement_audit.md +0 -99
  282. package/see/examples/output/smoke_arithmetic.md +0 -54
  283. package/see/examples/output/socrates.md +0 -55
  284. package/see/examples/output/triple_terms.md +0 -53
  285. package/see/examples/output/wind_turbine.md +0 -108
  286. package/see/examples/output/witch.md +0 -87
  287. package/see/examples/path_discovery.js +0 -1774
  288. package/see/examples/rc_discharge_envelope.js +0 -1993
  289. package/see/examples/rdf_dataset.js +0 -1512
  290. package/see/examples/rdf_message_flow.js +0 -2580
  291. package/see/examples/rdf_messages.js +0 -2176
  292. package/see/examples/school_placement_audit.js +0 -1867
  293. package/see/examples/smoke_arithmetic.js +0 -1483
  294. package/see/examples/socrates.js +0 -1420
  295. package/see/examples/triple_terms.js +0 -1442
  296. package/see/examples/wind_turbine.js +0 -2853
  297. package/see/examples/witch.js +0 -1519
  298. package/see/see.js +0 -2179
  299. package/test/see.test.js +0 -159
  300. /package/{see/examples/n3/builtin_coverage.n3 → examples/builtin-coverage.n3} +0 -0
  301. /package/examples/output/{reifies.n3 → builtin-coverage.n3} +0 -0
@@ -7,7 +7,7 @@
7
7
  # stream behaves as an ordered, replayable flow rather than a single merged RDF
8
8
  # graph.
9
9
 
10
- @prefix : <https://eyereasoner.github.io/see/examples/rdf-message-flow#>.
10
+ @prefix : <https://eyereasoner.github.io/eyeling/examples/rdf-message-flow#>.
11
11
  @prefix msg: <https://example.org/msg#>.
12
12
  @prefix prov: <http://www.w3.org/ns/prov#>.
13
13
  @prefix sosa: <http://www.w3.org/ns/sosa/>.
@@ -17,85 +17,18 @@
17
17
  @prefix log: <http://www.w3.org/2000/10/swap/log#>.
18
18
  @prefix string: <http://www.w3.org/2000/10/swap/string#>.
19
19
 
20
- :temperatureFlow
21
- a msg:MessageStream;
22
- msg:orderedMessages (:m001 :m002 :m003 :m004 :m005);
23
- msg:message :m001, :m002, :m003, :m004, :m005;
24
- :pipeline (:ingest :validate :interpret :route :sink);
25
- :highThreshold 26.
26
20
 
27
21
  # The stream starts with just the first message at ingress. Later messages are
28
22
  # not pre-loaded; each one is released by the previous message after sink.
29
- :m001 :atStage :ingest.
30
-
31
- :m001
32
- a msg:RDFMessage;
33
- msg:offset 1;
34
- msg:nextMessage :m002;
35
- prov:generatedAtTime "2026-05-12T18:20:00Z"^^xsd:dateTime;
36
- msg:payloadKind :observation;
37
- msg:expectedResult 21;
38
- msg:payload {
39
- _:m001b0
40
- a sosa:Observation;
41
- sosa:madeBySensor :thermometerA;
42
- sosa:resultTime "2026-05-12T18:20:00Z"^^xsd:dateTime;
43
- sosa:hasSimpleResult 21.
44
- }.
45
-
46
- :m002
47
- a msg:RDFMessage;
48
- msg:offset 2;
49
- msg:nextMessage :m003;
50
- prov:generatedAtTime "2026-05-12T18:21:00Z"^^xsd:dateTime;
51
- msg:payloadKind :observation;
52
- msg:expectedResult 22;
53
- msg:payload {
54
- _:m002b0
55
- a sosa:Observation;
56
- sosa:madeBySensor :thermometerA;
57
- sosa:resultTime "2026-05-12T18:21:00Z"^^xsd:dateTime;
58
- sosa:hasSimpleResult 22.
59
- }.
23
+
24
+
60
25
 
61
26
  # Empty heartbeat: it flows through the same pipeline and keeps the stream live.
62
- :m003
63
- a msg:RDFMessage;
64
- msg:offset 3;
65
- msg:nextMessage :m004;
66
- prov:generatedAtTime "2026-05-12T18:22:00Z"^^xsd:dateTime;
67
- msg:payloadKind :heartbeat.
68
-
69
- :m004
70
- a msg:RDFMessage;
71
- msg:offset 4;
72
- msg:nextMessage :m005;
73
- prov:generatedAtTime "2026-05-12T18:23:00Z"^^xsd:dateTime;
74
- msg:payloadKind :observation;
75
- msg:expectedResult 28;
76
- msg:payload {
77
- _:m004b0
78
- a sosa:Observation;
79
- sosa:madeBySensor :thermometerA;
80
- sosa:resultTime "2026-05-12T18:23:00Z"^^xsd:dateTime;
81
- sosa:hasSimpleResult 28.
82
- }.
83
-
84
- :m005
85
- a msg:RDFMessage;
86
- msg:offset 5;
87
- prov:generatedAtTime "2026-05-12T18:24:00Z"^^xsd:dateTime;
88
- msg:payloadKind :observation;
89
- msg:expectedResult 29;
90
- msg:payload {
91
- _:m005b0
92
- a sosa:Observation;
93
- sosa:madeBySensor :thermometerA;
94
- sosa:resultTime "2026-05-12T18:24:00Z"^^xsd:dateTime;
95
- sosa:hasSimpleResult 29.
96
- }.
27
+
28
+
97
29
 
98
30
  # Stage 1: once a message has entered the stream, validate its envelope.
31
+
99
32
  { ?Message :atStage :ingest. } => {
100
33
  ?Message :atStage :validate.
101
34
  }.
@@ -116,7 +49,8 @@
116
49
  msg:payloadKind :observation;
117
50
  msg:expectedResult ?Result;
118
51
  msg:payload ?Payload.
119
- ?Payload log:includes { ?Observation sosa:hasSimpleResult ?Result. }.
52
+ ?Payload log:nameOf ?PayloadContext.
53
+ ?PayloadContext log:includes { ?Observation sosa:hasSimpleResult ?Result. }.
120
54
  } => {
121
55
  ?Message msg:payloadResult ?Result.
122
56
  ?Message :atStage :route.
@@ -175,7 +109,7 @@
175
109
  ?Next :atStage :ingest.
176
110
  }.
177
111
 
178
- # The SEE verdict is emitted only after all five messages have flowed through
112
+ # The Eyeling verdict is emitted only after all five messages have flowed through
179
113
  # ingest, validation, interpretation, routing, and sink.
180
114
  {
181
115
  :temperatureFlow msg:orderedMessages ?Messages;
@@ -1,7 +1,7 @@
1
1
  # ============
2
2
  # RDF Messages
3
3
  # ============
4
- # This SEE example models the main idea from
4
+ # This Eyeling example models the main idea from
5
5
  # https://pietercolpaert.be/papers/eswc2026-rdf-messages/:
6
6
  # a message stream/log is not just one freely mergeable RDF graph. It is an
7
7
  # ordered sequence of RDF Datasets that are interpreted atomically, one message
@@ -9,7 +9,7 @@
9
9
  # the local blank-node label "_:b0" is deliberately reused by two messages to
10
10
  # show message-scoped blank nodes.
11
11
 
12
- @prefix : <https://eyereasoner.github.io/see/examples/rdf-messages#>.
12
+ @prefix : <https://eyereasoner.github.io/eyeling/examples/rdf-messages#>.
13
13
  @prefix msg: <https://w3c-cg.github.io/rsp/spec/messages#>.
14
14
  @prefix prov: <http://www.w3.org/ns/prov#>.
15
15
  @prefix sosa: <http://www.w3.org/ns/sosa/>.
@@ -19,51 +19,13 @@
19
19
  @prefix log: <http://www.w3.org/2000/10/swap/log#>.
20
20
  @prefix string: <http://www.w3.org/2000/10/swap/string#>.
21
21
 
22
- :temperatureLog
23
- a msg:MessageLog;
24
- msg:orderedMessages (:m001 :m002 :m003);
25
- msg:message :m001, :m002, :m003;
26
- msg:profile :generatedAtTimeProfile;
27
- msg:retentionPolicy "replayable archive".
28
22
 
29
- :m001
30
- a msg:RDFMessage;
31
- msg:offset 1;
32
- prov:generatedAtTime "2026-05-12T18:20:00Z"^^xsd:dateTime;
33
- msg:payloadKind :observation;
34
- msg:localBlankLabel "_:b0";
35
- msg:expectedResult 22;
36
- msg:payload {
37
- _:m001b0
38
- a sosa:Observation;
39
- sosa:madeBySensor :thermometerA;
40
- sosa:resultTime "2026-05-12T18:20:00Z"^^xsd:dateTime;
41
- sosa:hasSimpleResult 22.
42
- }.
43
23
 
44
24
  # Empty RDF Message: a legal heartbeat/keep-alive event.
45
- :m002
46
- a msg:RDFMessage;
47
- msg:offset 2;
48
- prov:generatedAtTime "2026-05-12T18:22:00Z"^^xsd:dateTime;
49
- msg:payloadKind :heartbeat.
50
25
 
51
- :m003
52
- a msg:RDFMessage;
53
- msg:offset 3;
54
- prov:generatedAtTime "2026-05-12T18:25:00Z"^^xsd:dateTime;
55
- msg:payloadKind :observation;
56
- msg:localBlankLabel "_:b0";
57
- msg:expectedResult 23;
58
- msg:payload {
59
- _:m003b0
60
- a sosa:Observation;
61
- sosa:madeBySensor :thermometerA;
62
- sosa:resultTime "2026-05-12T18:25:00Z"^^xsd:dateTime;
63
- sosa:hasSimpleResult 23.
64
- }.
65
26
 
66
27
  # A message with an offset inside a log has an explicit replay boundary.
28
+
67
29
  {
68
30
  ?Log a msg:MessageLog;
69
31
  msg:message ?Message.
@@ -80,7 +42,8 @@
80
42
  ?Message a msg:RDFMessage;
81
43
  msg:expectedResult ?Result;
82
44
  msg:payload ?Payload.
83
- ?Payload log:includes { ?Observation sosa:hasSimpleResult ?Result. }.
45
+ ?Payload log:nameOf ?PayloadContext.
46
+ ?PayloadContext log:includes { ?Observation sosa:hasSimpleResult ?Result. }.
84
47
  } => {
85
48
  ?Message msg:payloadResult ?Result.
86
49
  }.
@@ -120,7 +83,7 @@
120
83
  :MessageContext :differentObservationsStayContextual true.
121
84
  }.
122
85
 
123
- # The SEE verdict is emitted only when all message-specific validations have been
86
+ # The Eyeling verdict is emitted only when all message-specific validations have been
124
87
  # derived from the log, message metadata, payload formulas, and built-ins.
125
88
  {
126
89
  :temperatureLog msg:orderedMessages ?Messages.
@@ -1,26 +1,14 @@
1
1
  # ============================
2
2
  # School Placement Route Audit
3
3
  # ============================
4
- # N3-compiled version of the school placement audit. The original student,
4
+ # N3 version of the school placement audit. The original student,
5
5
  # school, distance, and policy JSON is preserved as the data-input sidecar.
6
6
 
7
- @prefix : <https://eyereasoner.github.io/see/examples/school-placement-audit#>.
7
+ @prefix : <https://eyereasoner.github.io/eyeling/examples/school-placement-audit#>.
8
8
  @prefix math: <http://www.w3.org/2000/10/swap/math#>.
9
9
  @prefix log: <http://www.w3.org/2000/10/swap/log#>.
10
10
  @prefix string: <http://www.w3.org/2000/10/swap/string#>.
11
11
 
12
- :Policy :maxWalkingMeters 2500; :preferencePenaltyMeters 600.
13
-
14
- :Ada :name "Ada"; :provisional :Centrum; :auditedBest :Lindholmen; :hiddenDetour 3000; :walkingMeters 3600.
15
- :Bjorn :name "Björn"; :provisional :Centrum; :auditedBest :Backa; :hiddenDetour 2000; :walkingMeters 3100.
16
- :Clara :name "Clara"; :provisional :Haga; :auditedBest :Haga; :hiddenDetour 150; :walkingMeters 800.
17
- :Davi :name "Davi"; :provisional :Centrum; :auditedBest :Haga; :hiddenDetour 1800; :walkingMeters 2800.
18
-
19
- :Lindholmen :label "Lindholmen".
20
- :Haga :label "Haga".
21
- :Centrum :label "Centrum".
22
- :Backa :label "Backa".
23
-
24
12
  {
25
13
  ?Student :provisional ?Provisional; :auditedBest ?Audited; :walkingMeters ?Walk.
26
14
  :Policy :maxWalkingMeters ?MaxWalking.
@@ -1,15 +1,13 @@
1
1
  # Smoke Arithmetic
2
- # Small Notation3 source used to prove that see.js generates a specialized JS
3
- # example which derives its answer from facts, math built-ins, fuses, and string
4
- # formatting instead of reading a prewritten conclusion.
2
+ # Small Notation3 source used to prove that Eyeling derives its answer from
3
+ # facts, math built-ins, fuses, and string formatting instead of reading a
4
+ # prewritten conclusion.
5
5
 
6
6
  @prefix : <https://example.org/see/smoke#>.
7
7
  @prefix math: <http://www.w3.org/2000/10/swap/math#>.
8
8
  @prefix string: <http://www.w3.org/2000/10/swap/string#>.
9
9
  @prefix log: <http://www.w3.org/2000/10/swap/log#>.
10
10
 
11
- :Input :x 6; :y 7.
12
-
13
11
  { :Input :x ?X; :y ?Y.
14
12
  (?X ?Y) math:product ?Product.
15
13
  ?Product math:greaterThan 0.
@@ -4,13 +4,10 @@
4
4
 
5
5
  VERSION "1.2"
6
6
 
7
- @prefix : <https://eyereasoner.github.io/eyeling/see/examples/triple_terms#> .
7
+ @prefix : <https://eyereasoner.github.io/eyeling/examples/triple_terms#> .
8
8
  @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
9
9
  @prefix log: <http://www.w3.org/2000/10/swap/log#> .
10
10
 
11
- :observation rdf:reifies <<( :sensor :reports :overheating )>> .
12
- :overheating :requires :inspection .
13
-
14
11
  {
15
12
  ?observation rdf:reifies <<( ?device :reports ?condition )>> .
16
13
  ?condition :requires ?action .
package/eyeling.js CHANGED
@@ -4249,6 +4249,12 @@ function isBuiltinPred(p) {
4249
4249
  return v === LOG_NS + 'implies' || v === LOG_NS + 'impliedBy';
4250
4250
  }
4251
4251
 
4252
+ // log:nameOf is the ordinary fact predicate used by the RDF/TriG
4253
+ // compatibility layer for named graph blocks. It must remain matchable
4254
+ // against extensional facts instead of being swallowed as an unimplemented
4255
+ // log:* builtin.
4256
+ if (v === LOG_NS + 'nameOf') return false;
4257
+
4252
4258
  // Treat RDF Collections as list-term builtins too.
4253
4259
  if (v === RDF_NS + 'first' || v === RDF_NS + 'rest') {
4254
4260
  return true;
@@ -9590,6 +9596,7 @@ function stripQuotes(lex) {
9590
9596
  // - A top-level default graph block { ... } is unwrapped into ordinary triples.
9591
9597
  // This keeps all downstream parsing/reasoning N3-only.
9592
9598
  const LOG_NAME_OF_IRI = '<http://www.w3.org/2000/10/swap/log#nameOf>';
9599
+ const RDF_REIFIES_IRI = '<http://www.w3.org/1999/02/22-rdf-syntax-ns#reifies>';
9593
9600
 
9594
9601
  function normalizeRdfCompatibility(inputText) {
9595
9602
  let text = String(inputText ?? '');
@@ -9598,11 +9605,12 @@ function normalizeRdfCompatibility(inputText) {
9598
9605
  // surface-syntax normalization. Avoid scanning large files character-by-character
9599
9606
  // unless they actually contain RDF 1.2 triple terms, VERSION directives, or a
9600
9607
  // plausible top-level TriG named graph block.
9601
- const hasTripleTerms = text.includes('<<(');
9608
+ const hasTripleTerms = text.includes('<<');
9602
9609
  const hasVersionDirective = /^\s*(?:@version|VERSION)\s+(["'])1\.2\1\s*\.?\s*(?:#.*)?$/im.test(text);
9603
9610
  const hasNamedGraphCandidate = /(?:^|[.\r\n])\s*(?:GRAPH\s+)?(?:<[^>\r\n]*>|_:[A-Za-z][A-Za-z0-9_-]*|[A-Za-z][A-Za-z0-9_-]*:[^\s{};,.()[\]]*)\s*\{/m.test(text);
9611
+ const hasAnnotationSyntax = /(?:^|\s)~\s*(?:<|_:[A-Za-z]|[A-Za-z][A-Za-z0-9_-]*:|\{\|)|\{\|/.test(text);
9604
9612
 
9605
- if (!hasTripleTerms && !hasVersionDirective && !hasNamedGraphCandidate) return text;
9613
+ if (!hasTripleTerms && !hasVersionDirective && !hasNamedGraphCandidate && !hasAnnotationSyntax) return text;
9606
9614
 
9607
9615
  function isWordChar(ch) {
9608
9616
  return ch != null && /[A-Za-z0-9_:-]/.test(ch);
@@ -9664,11 +9672,67 @@ function normalizeRdfCompatibility(inputText) {
9664
9672
 
9665
9673
  function convertTripleTerms(s) {
9666
9674
  let i = 0;
9675
+ const reifierTriples = [];
9667
9676
 
9668
9677
  function startsAt(needle, at = i) {
9669
9678
  return s.startsWith(needle, at);
9670
9679
  }
9671
9680
 
9681
+ function splitTopLevelReifier(body) {
9682
+ let depthBrace = 0;
9683
+ let depthBracket = 0;
9684
+ let depthParen = 0;
9685
+ for (let j = 0; j < body.length; j++) {
9686
+ const ch = body[j];
9687
+ if (ch === '"' || ch === "'") {
9688
+ const str = readStringAt(body, j);
9689
+ j = str.end - 1;
9690
+ continue;
9691
+ }
9692
+ if (ch === '<') {
9693
+ const iri = readIriAt(body, j);
9694
+ j = iri.end - 1;
9695
+ continue;
9696
+ }
9697
+ if (ch === '#') {
9698
+ while (j < body.length && body[j] !== '\n' && body[j] !== '\r') j += 1;
9699
+ continue;
9700
+ }
9701
+ if (ch === '{') depthBrace += 1;
9702
+ else if (ch === '}' && depthBrace > 0) depthBrace -= 1;
9703
+ else if (ch === '[') depthBracket += 1;
9704
+ else if (ch === ']' && depthBracket > 0) depthBracket -= 1;
9705
+ else if (ch === '(') depthParen += 1;
9706
+ else if (ch === ')' && depthParen > 0) depthParen -= 1;
9707
+ else if (ch === '~' && depthBrace === 0 && depthBracket === 0 && depthParen === 0) {
9708
+ return { triple: body.slice(0, j).trim(), reifier: body.slice(j + 1).trim() };
9709
+ }
9710
+ }
9711
+ return { triple: body.trim(), reifier: '' };
9712
+ }
9713
+
9714
+ function firstTerm(text) {
9715
+ const at = skipWsAndComments(text, 0);
9716
+ if (at >= text.length) return '';
9717
+ if (text[at] === '<') return readIriAt(text, at).text;
9718
+ let j = at;
9719
+ while (j < text.length && !/\s/.test(text[j]) && !'{}[](),;.'.includes(text[j])) j += 1;
9720
+ return text.slice(at, j);
9721
+ }
9722
+
9723
+ function graphTermFromTripleBody(rawBody, parenthesized) {
9724
+ let body = rawBody.trim();
9725
+ if (parenthesized && body.startsWith('(') && body.endsWith(')')) body = body.slice(1, -1).trim();
9726
+ const split = splitTopLevelReifier(body);
9727
+ const triple = split.triple;
9728
+ const graph = '{ ' + triple + ' }';
9729
+ if (split.reifier) {
9730
+ const reifier = firstTerm(split.reifier);
9731
+ if (reifier) reifierTriples.push(`${reifier} ${RDF_REIFIES_IRI} ${graph} .`);
9732
+ }
9733
+ return graph;
9734
+ }
9735
+
9672
9736
  function convertUntil(stopToken) {
9673
9737
  let out = '';
9674
9738
  while (i < s.length) {
@@ -9678,7 +9742,12 @@ function normalizeRdfCompatibility(inputText) {
9678
9742
  }
9679
9743
  if (startsAt('<<(')) {
9680
9744
  i += 3;
9681
- out += '{ ' + convertUntil(')>>').trim() + ' }';
9745
+ out += graphTermFromTripleBody(convertUntil(')>>'), false);
9746
+ continue;
9747
+ }
9748
+ if (startsAt('<<')) {
9749
+ i += 2;
9750
+ out += graphTermFromTripleBody(convertUntil('>>'), false);
9682
9751
  continue;
9683
9752
  }
9684
9753
  const ch = s[i];
@@ -9709,7 +9778,189 @@ function normalizeRdfCompatibility(inputText) {
9709
9778
  return out;
9710
9779
  }
9711
9780
 
9712
- return convertUntil(null);
9781
+ const converted = convertUntil(null);
9782
+ if (reifierTriples.length === 0) return converted;
9783
+ return converted + (converted.endsWith('\n') ? '' : '\n') + reifierTriples.join('\n') + '\n';
9784
+ }
9785
+
9786
+
9787
+ function convertAnnotations(s) {
9788
+ let out = '';
9789
+ let i = 0;
9790
+ let statementStart = true;
9791
+ let generatedBlank = 0;
9792
+
9793
+ function readBalancedDelimited(s, at, open, close) {
9794
+ if (!s.startsWith(open, at)) return null;
9795
+ let j = at + open.length;
9796
+ let depth = 1;
9797
+ while (j < s.length) {
9798
+ const ch = s[j];
9799
+ if (ch === '"' || ch === "'") {
9800
+ j = readStringAt(s, j).end;
9801
+ continue;
9802
+ }
9803
+ if (ch === '<' && !s.startsWith('<<', j)) {
9804
+ j = readIriAt(s, j).end;
9805
+ continue;
9806
+ }
9807
+ if (ch === '#') {
9808
+ while (j < s.length && s[j] !== '\n' && s[j] !== '\r') j += 1;
9809
+ continue;
9810
+ }
9811
+ if (s.startsWith(open, j)) {
9812
+ depth += 1;
9813
+ j += open.length;
9814
+ continue;
9815
+ }
9816
+ if (s.startsWith(close, j)) {
9817
+ depth -= 1;
9818
+ j += close.length;
9819
+ if (depth === 0) return { text: s.slice(at, j), inner: s.slice(at + open.length, j - close.length), end: j };
9820
+ continue;
9821
+ }
9822
+ j += 1;
9823
+ }
9824
+ throw new N3SyntaxError(`Unterminated RDF annotation block, expected ${close}`);
9825
+ }
9826
+
9827
+ function readTermLikeAt(s, at) {
9828
+ const j = skipWsAndComments(s, at);
9829
+ if (j >= s.length) return null;
9830
+ if (s[j] === '<') return readIriAt(s, j);
9831
+ if (s[j] === '"' || s[j] === "'") {
9832
+ const str = readStringAt(s, j);
9833
+ let end = str.end;
9834
+ let text = str.text;
9835
+ if (s.startsWith('^^', end)) {
9836
+ const dt = readTermAt(s, end + 2);
9837
+ if (dt) {
9838
+ text += '^^' + dt.text;
9839
+ end = dt.end;
9840
+ }
9841
+ } else if (s[end] === '@') {
9842
+ let k = end + 1;
9843
+ if (/[A-Za-z]/.test(s[k] || '')) {
9844
+ while (k < s.length && /[A-Za-z0-9-]/.test(s[k])) k += 1;
9845
+ text += s.slice(end, k);
9846
+ end = k;
9847
+ }
9848
+ }
9849
+ return { text, end };
9850
+ }
9851
+ if (s[j] === '{') return readBalancedBlock(s, j);
9852
+ if (s[j] === '[') return readBalancedDelimited(s, j, '[', ']');
9853
+ if (s[j] === '(') return readBalancedDelimited(s, j, '(', ')');
9854
+ return readTermAt(s, j);
9855
+ }
9856
+
9857
+ function readAnnotationBlockAt(s, at) {
9858
+ if (!s.startsWith('{|', at)) return null;
9859
+ return readBalancedDelimited(s, at, '{|', '|}');
9860
+ }
9861
+
9862
+ function tryReadAnnotatedTriple(at) {
9863
+ const start = skipWsAndComments(s, at);
9864
+ if (start >= s.length) return null;
9865
+ if (s[start] === '@') return null;
9866
+ if (startsWordAt(s, 'PREFIX', start) || startsWordAt(s, 'BASE', start) || startsWordAt(s, 'VERSION', start)) return null;
9867
+ if (startsWordAt(s, 'GRAPH', start)) return null;
9868
+
9869
+ const subj = readTermLikeAt(s, start);
9870
+ if (!subj) return null;
9871
+ let j = skipWsAndComments(s, subj.end);
9872
+ const pred = readTermLikeAt(s, j);
9873
+ if (!pred) return null;
9874
+ j = skipWsAndComments(s, pred.end);
9875
+ const obj = readTermLikeAt(s, j);
9876
+ if (!obj) return null;
9877
+ j = skipWsAndComments(s, obj.end);
9878
+ if (s[j] !== '~' && !s.startsWith('{|', j)) return null;
9879
+
9880
+ let reifier = '';
9881
+ const annotationBlocks = [];
9882
+ while (j < s.length) {
9883
+ j = skipWsAndComments(s, j);
9884
+ if (s[j] === '~') {
9885
+ j += 1;
9886
+ j = skipWsAndComments(s, j);
9887
+ const term = readTermAt(s, j);
9888
+ if (term) {
9889
+ reifier = term.text;
9890
+ j = term.end;
9891
+ } else if (!reifier) {
9892
+ reifier = `_:rdfAnnotation${++generatedBlank}`;
9893
+ }
9894
+ continue;
9895
+ }
9896
+ if (s.startsWith('{|', j)) {
9897
+ const block = readAnnotationBlockAt(s, j);
9898
+ if (!reifier) reifier = `_:rdfAnnotation${++generatedBlank}`;
9899
+ annotationBlocks.push(block.inner.trim());
9900
+ j = block.end;
9901
+ continue;
9902
+ }
9903
+ break;
9904
+ }
9905
+
9906
+ const after = skipWsAndComments(s, j);
9907
+ if (s[after] !== '.') return null;
9908
+ if (!reifier && annotationBlocks.length === 0) return null;
9909
+
9910
+ const baseTriple = `${subj.text} ${pred.text} ${obj.text}`;
9911
+ const graph = `{ ${baseTriple} }`;
9912
+ const extra = [];
9913
+ if (reifier) extra.push(`${reifier} ${RDF_REIFIES_IRI} ${graph} .`);
9914
+ for (const inner of annotationBlocks) {
9915
+ if (inner) extra.push(`${reifier} ${inner} .`);
9916
+ }
9917
+ return {
9918
+ start,
9919
+ end: after + 1,
9920
+ text: `${baseTriple} .${extra.length ? '\n' + extra.join('\n') : ''}`,
9921
+ };
9922
+ }
9923
+
9924
+ while (i < s.length) {
9925
+ if (statementStart) {
9926
+ const converted = tryReadAnnotatedTriple(i);
9927
+ if (converted) {
9928
+ out += s.slice(i, converted.start) + converted.text;
9929
+ i = converted.end;
9930
+ statementStart = true;
9931
+ continue;
9932
+ }
9933
+ }
9934
+
9935
+ const ch = s[i];
9936
+ if (ch === '"' || ch === "'") {
9937
+ const str = readStringAt(s, i);
9938
+ out += str.text;
9939
+ i = str.end;
9940
+ continue;
9941
+ }
9942
+ if (ch === '<' && !s.startsWith('<<', i)) {
9943
+ const iri = readIriAt(s, i);
9944
+ out += iri.text;
9945
+ i = iri.end;
9946
+ continue;
9947
+ }
9948
+ if (ch === '#') {
9949
+ while (i < s.length) {
9950
+ const c = s[i++];
9951
+ out += c;
9952
+ if (c === '\n' || c === '\r') break;
9953
+ }
9954
+ statementStart = true;
9955
+ continue;
9956
+ }
9957
+ out += ch;
9958
+ if (ch === '.' || ch === '{' || ch === '}' || ch === '\n' || ch === '\r') statementStart = true;
9959
+ else if (!/\s/.test(ch)) statementStart = false;
9960
+ i += 1;
9961
+ }
9962
+
9963
+ return out;
9713
9964
  }
9714
9965
 
9715
9966
  function stripVersionDirectives(s) {
@@ -9868,6 +10119,7 @@ function normalizeRdfCompatibility(inputText) {
9868
10119
  }
9869
10120
 
9870
10121
  if (hasTripleTerms) text = convertTripleTerms(text);
10122
+ if (hasAnnotationSyntax) text = convertAnnotations(text);
9871
10123
  if (hasVersionDirective) text = stripVersionDirectives(text);
9872
10124
  if (hasVersionDirective || hasNamedGraphCandidate) text = normalizeNamedGraphs(text);
9873
10125
  return text;
package/lib/builtins.js CHANGED
@@ -4238,6 +4238,12 @@ function isBuiltinPred(p) {
4238
4238
  return v === LOG_NS + 'implies' || v === LOG_NS + 'impliedBy';
4239
4239
  }
4240
4240
 
4241
+ // log:nameOf is the ordinary fact predicate used by the RDF/TriG
4242
+ // compatibility layer for named graph blocks. It must remain matchable
4243
+ // against extensional facts instead of being swallowed as an unimplemented
4244
+ // log:* builtin.
4245
+ if (v === LOG_NS + 'nameOf') return false;
4246
+
4241
4247
  // Treat RDF Collections as list-term builtins too.
4242
4248
  if (v === RDF_NS + 'first' || v === RDF_NS + 'rest') {
4243
4249
  return true;