eyeling 1.24.7 → 1.24.9

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 (184) hide show
  1. package/HANDBOOK.md +35 -35
  2. package/dist/browser/eyeling.browser.js +14 -1
  3. package/examples/act-alarm-bit-interoperability.n3 +5 -3
  4. package/examples/act-barley-seed-lineage.n3 +5 -3
  5. package/examples/act-docking-abort.n3 +5 -3
  6. package/examples/act-gravity-mediator-witness.n3 +5 -3
  7. package/examples/act-isolation-breach.n3 +5 -3
  8. package/examples/act-photosynthetic-exciton-transfer.n3 +5 -3
  9. package/examples/act-sensor-memory-reset.n3 +5 -3
  10. package/examples/act-tunnel-junction-wake-switch.n3 +5 -3
  11. package/examples/act-yeast-self-reproduction.n3 +5 -3
  12. package/examples/annotation.n3 +5 -0
  13. package/examples/auroracare.n3 +29 -29
  14. package/examples/backward-recursion.n3 +5 -0
  15. package/examples/barley-seed-becoming.n3 +5 -3
  16. package/examples/bmi.n3 +5 -3
  17. package/examples/builtin-coverage.n3 +5 -0
  18. package/examples/calidor.n3 +3 -3
  19. package/examples/collection.n3 +5 -0
  20. package/examples/complex-matrix-stability.n3 +5 -3
  21. package/examples/context-association.n3 +1 -9
  22. package/examples/control-system.n3 +5 -3
  23. package/examples/deep-taxonomy-10.n3 +5 -3
  24. package/examples/deep-taxonomy-100.n3 +5 -3
  25. package/examples/deep-taxonomy-1000.n3 +5 -3
  26. package/examples/deep-taxonomy-10000.n3 +5 -3
  27. package/examples/deep-taxonomy-100000.n3 +3 -1
  28. package/examples/delfour.n3 +3 -3
  29. package/examples/digital-product-passport.n3 +2 -0
  30. package/examples/dijkstra-risk-path.n3 +1 -2
  31. package/examples/easter.n3 +6 -4
  32. package/examples/eco-route-insight.n3 +1 -2
  33. package/examples/flandor.n3 +3 -3
  34. package/examples/french-cities.n3 +5 -3
  35. package/examples/fundamental-theorem-arithmetic.n3 +5 -3
  36. package/examples/genetic-algorithm-knapsack.n3 +1 -1
  37. package/examples/genetic-algorithm.n3 +1 -1
  38. package/examples/genetic-knapsack-selection.n3 +1 -2
  39. package/examples/gps.n3 +5 -3
  40. package/examples/harborsmr.n3 +5 -3
  41. package/examples/input/ontology-question-generation.trig +79 -0
  42. package/examples/input/rdf-message-flow.trig +10 -10
  43. package/examples/input/rdf-messages.trig +6 -6
  44. package/examples/interop-demo.n3 +3 -1
  45. package/examples/matrix-mechanics.n3 +3 -3
  46. package/examples/medior.n3 +3 -3
  47. package/examples/n3-speaks-for-itself.n3 +5 -0
  48. package/examples/odrl-dpv-ehds-risk-ranked.n3 +1 -1
  49. package/examples/odrl-dpv-healthcare-risk-ranked.n3 +1 -1
  50. package/examples/odrl-dpv-risk-ranked.n3 +1 -1
  51. package/examples/odrl-risk-mitigation.n3 +1 -1
  52. package/examples/odrl-risk.n3 +1 -1
  53. package/examples/ontology-question-generation.n3 +409 -0
  54. package/examples/output/{act-alarm-bit-interoperability.txt → act-alarm-bit-interoperability.md} +23 -17
  55. package/examples/output/act-barley-seed-lineage.md +31 -0
  56. package/examples/output/{act-docking-abort.txt → act-docking-abort.md} +25 -19
  57. package/examples/output/{act-gravity-mediator-witness.txt → act-gravity-mediator-witness.md} +27 -21
  58. package/examples/output/{act-isolation-breach.txt → act-isolation-breach.md} +30 -24
  59. package/examples/output/{act-photosynthetic-exciton-transfer.txt → act-photosynthetic-exciton-transfer.md} +23 -17
  60. package/examples/output/{act-sensor-memory-reset.txt → act-sensor-memory-reset.md} +23 -17
  61. package/examples/output/{act-tunnel-junction-wake-switch.txt → act-tunnel-junction-wake-switch.md} +24 -18
  62. package/examples/output/{act-yeast-self-reproduction.txt → act-yeast-self-reproduction.md} +26 -20
  63. package/examples/output/annotation.md +7 -0
  64. package/examples/output/auroracare.md +154 -0
  65. package/examples/output/backward-recursion.md +11 -0
  66. package/examples/output/barley-seed-becoming.md +31 -0
  67. package/examples/output/bmi.md +26 -0
  68. package/examples/output/builtin-coverage.md +7 -0
  69. package/examples/output/calidor.md +35 -0
  70. package/examples/output/collection.md +7 -0
  71. package/examples/output/{complex-matrix-stability.txt → complex-matrix-stability.md} +17 -11
  72. package/examples/output/context-association.md +12 -0
  73. package/examples/output/{control-system.txt → control-system.md} +23 -17
  74. package/examples/output/deep-taxonomy-10.md +21 -0
  75. package/examples/output/deep-taxonomy-100.md +21 -0
  76. package/examples/output/{deep-taxonomy-1000.txt → deep-taxonomy-1000.md} +18 -12
  77. package/examples/output/{deep-taxonomy-10000.txt → deep-taxonomy-10000.md} +18 -12
  78. package/examples/output/{deep-taxonomy-100000.txt → deep-taxonomy-100000.md} +18 -12
  79. package/examples/output/delfour.md +36 -0
  80. package/examples/output/digital-product-passport.md +7 -0
  81. package/examples/output/dijkstra-risk-path.md +16 -0
  82. package/examples/output/{easter.txt → easter.md} +156 -150
  83. package/examples/output/eco-route-insight.md +25 -0
  84. package/examples/output/flandor.md +37 -0
  85. package/examples/output/{french-cities.txt → french-cities.md} +17 -11
  86. package/examples/output/{fundamental-theorem-arithmetic.txt → fundamental-theorem-arithmetic.md} +18 -12
  87. package/examples/output/genetic-algorithm-knapsack.md +7 -0
  88. package/examples/output/genetic-algorithm.md +7 -0
  89. package/examples/output/genetic-knapsack-selection.md +18 -0
  90. package/examples/output/{gps.txt → gps.md} +18 -12
  91. package/examples/output/harborsmr.md +26 -0
  92. package/examples/output/interop-demo.md +7 -0
  93. package/examples/output/matrix-mechanics.md +20 -0
  94. package/examples/output/medior.md +38 -0
  95. package/examples/output/n3-speaks-for-itself.md +58 -0
  96. package/examples/output/{odrl-dpv-ehds-risk-ranked.txt → odrl-dpv-ehds-risk-ranked.md} +20 -15
  97. package/examples/output/{odrl-dpv-healthcare-risk-ranked.txt → odrl-dpv-healthcare-risk-ranked.md} +17 -12
  98. package/examples/output/{odrl-dpv-risk-ranked.txt → odrl-dpv-risk-ranked.md} +21 -16
  99. package/examples/output/{odrl-risk-mitigation.txt → odrl-risk-mitigation.md} +21 -16
  100. package/examples/output/{odrl-risk.txt → odrl-risk.md} +10 -5
  101. package/examples/output/ontology-question-generation.md +31 -0
  102. package/examples/output/parcellocker.md +26 -0
  103. package/examples/output/pn-junction-tunneling.md +29 -0
  104. package/examples/output/queens.md +27 -0
  105. package/examples/output/rc-discharge-envelope.md +16 -0
  106. package/examples/output/rdf-dataset.md +12 -0
  107. package/examples/output/rdf-message-flow.md +12 -0
  108. package/examples/output/rdf-messages.md +12 -0
  109. package/examples/output/{resto.txt → resto.md} +23 -17
  110. package/examples/output/school-placement-audit.md +16 -0
  111. package/examples/output/smoke-arithmetic.md +12 -0
  112. package/examples/output/sqrt2-cauchy.md +19 -0
  113. package/examples/output/sqrt2-dedekind.md +37 -0
  114. package/examples/output/sudoku.md +49 -0
  115. package/examples/output/transcendental-numbers-stretched.md +266 -0
  116. package/examples/output/transistor-switch.md +30 -0
  117. package/examples/output/triple-terms.md +12 -0
  118. package/examples/output/{tunnel-junction-wake-switch-becoming.txt → tunnel-junction-wake-switch-becoming.md} +24 -18
  119. package/examples/output/{wind-turbine.txt → wind-turbine.md} +21 -15
  120. package/examples/parcellocker.n3 +3 -1
  121. package/examples/pn-junction-tunneling.n3 +3 -3
  122. package/examples/queens.n3 +1 -0
  123. package/examples/rc-discharge-envelope.n3 +1 -1
  124. package/examples/rdf-dataset.n3 +5 -0
  125. package/examples/rdf-message-flow.n3 +1 -2
  126. package/examples/rdf-messages.n3 +1 -2
  127. package/examples/resto.n3 +5 -3
  128. package/examples/school-placement-audit.n3 +1 -2
  129. package/examples/smoke-arithmetic.n3 +1 -1
  130. package/examples/sqrt2-cauchy.n3 +2 -0
  131. package/examples/sqrt2-dedekind.n3 +2 -0
  132. package/examples/sudoku.n3 +14 -14
  133. package/examples/transcendental-numbers-stretched.n3 +5 -0
  134. package/examples/transistor-switch.n3 +3 -3
  135. package/examples/triple-terms.n3 +5 -0
  136. package/examples/tunnel-junction-wake-switch-becoming.n3 +5 -3
  137. package/examples/wind-turbine.n3 +5 -3
  138. package/eyeling.js +14 -1
  139. package/lib/explain.js +14 -1
  140. package/package.json +1 -1
  141. package/test/examples.test.js +44 -13
  142. package/test/package.test.js +43 -7
  143. package/examples/output/act-barley-seed-lineage.txt +0 -25
  144. package/examples/output/annotation.n3 +0 -0
  145. package/examples/output/auroracare.txt +0 -149
  146. package/examples/output/backward-recursion.n3 +0 -4
  147. package/examples/output/barley-seed-becoming.txt +0 -25
  148. package/examples/output/bmi.txt +0 -20
  149. package/examples/output/builtin-coverage.n3 +0 -0
  150. package/examples/output/calidor.txt +0 -29
  151. package/examples/output/collection.n3 +0 -0
  152. package/examples/output/context-association.n3 +0 -9
  153. package/examples/output/deep-taxonomy-10.txt +0 -15
  154. package/examples/output/deep-taxonomy-100.txt +0 -15
  155. package/examples/output/delfour.txt +0 -30
  156. package/examples/output/digital-product-passport.txt +0 -1
  157. package/examples/output/dijkstra-risk-path.n3 +0 -3
  158. package/examples/output/eco-route-insight.n3 +0 -3
  159. package/examples/output/flandor.txt +0 -31
  160. package/examples/output/genetic-algorithm-knapsack.txt +0 -1
  161. package/examples/output/genetic-algorithm.txt +0 -1
  162. package/examples/output/genetic-knapsack-selection.n3 +0 -3
  163. package/examples/output/harborsmr.txt +0 -20
  164. package/examples/output/interop-demo.txt +0 -1
  165. package/examples/output/matrix-mechanics.txt +0 -14
  166. package/examples/output/medior.txt +0 -32
  167. package/examples/output/n3-speaks-for-itself.txt +0 -52
  168. package/examples/output/parcellocker.txt +0 -20
  169. package/examples/output/pn-junction-tunneling.txt +0 -23
  170. package/examples/output/queens.txt +0 -21
  171. package/examples/output/rc-discharge-envelope.n3 +0 -9
  172. package/examples/output/rc-discharge-envelope.txt +0 -9
  173. package/examples/output/rdf-dataset.n3 +0 -5
  174. package/examples/output/rdf-message-flow.n3 +0 -7
  175. package/examples/output/rdf-messages.n3 +0 -7
  176. package/examples/output/school-placement-audit.n3 +0 -3
  177. package/examples/output/smoke-arithmetic.n3 +0 -5
  178. package/examples/output/smoke-arithmetic.txt +0 -5
  179. package/examples/output/sqrt2-cauchy.txt +0 -13
  180. package/examples/output/sqrt2-dedekind.txt +0 -31
  181. package/examples/output/sudoku.txt +0 -43
  182. package/examples/output/transcendental-numbers-stretched.txt +0 -260
  183. package/examples/output/transistor-switch.txt +0 -24
  184. package/examples/output/triple-terms.n3 +0 -5
@@ -13,7 +13,7 @@
13
13
  # Formal Eyeling input evidence in RDF 1.2 TriG.
14
14
  # The generated runner reads this TriG evidence directly.
15
15
 
16
- :temperatureFlow rdf:type msg:MessageStream .
16
+ :temperatureFlow a msg:MessageStream .
17
17
  :temperatureFlow msg:orderedMessages (:m001 :m002 :m003 :m004 :m005) .
18
18
  :temperatureFlow msg:message :m001 .
19
19
  :temperatureFlow msg:message :m002 .
@@ -23,33 +23,33 @@
23
23
  :temperatureFlow :pipeline (:ingest :validate :interpret :route :sink) .
24
24
  :temperatureFlow :highThreshold 26 .
25
25
  :m001 :atStage :ingest .
26
- :m001 rdf:type msg:RDFMessage .
26
+ :m001 a msg:RDFMessage .
27
27
  :m001 msg:offset 1 .
28
28
  :m001 msg:nextMessage :m002 .
29
29
  :m001 prov:generatedAtTime "2026-05-12T18:20:00Z" .
30
30
  :m001 msg:payloadKind :observation .
31
31
  :m001 msg:expectedResult 21 .
32
32
  :m001 msg:payload in:formula1 .
33
- :m002 rdf:type msg:RDFMessage .
33
+ :m002 a msg:RDFMessage .
34
34
  :m002 msg:offset 2 .
35
35
  :m002 msg:nextMessage :m003 .
36
36
  :m002 prov:generatedAtTime "2026-05-12T18:21:00Z" .
37
37
  :m002 msg:payloadKind :observation .
38
38
  :m002 msg:expectedResult 22 .
39
39
  :m002 msg:payload in:formula2 .
40
- :m003 rdf:type msg:RDFMessage .
40
+ :m003 a msg:RDFMessage .
41
41
  :m003 msg:offset 3 .
42
42
  :m003 msg:nextMessage :m004 .
43
43
  :m003 prov:generatedAtTime "2026-05-12T18:22:00Z" .
44
44
  :m003 msg:payloadKind :heartbeat .
45
- :m004 rdf:type msg:RDFMessage .
45
+ :m004 a msg:RDFMessage .
46
46
  :m004 msg:offset 4 .
47
47
  :m004 msg:nextMessage :m005 .
48
48
  :m004 prov:generatedAtTime "2026-05-12T18:23:00Z" .
49
49
  :m004 msg:payloadKind :observation .
50
50
  :m004 msg:expectedResult 28 .
51
51
  :m004 msg:payload in:formula3 .
52
- :m005 rdf:type msg:RDFMessage .
52
+ :m005 a msg:RDFMessage .
53
53
  :m005 msg:offset 5 .
54
54
  :m005 prov:generatedAtTime "2026-05-12T18:24:00Z" .
55
55
  :m005 msg:payloadKind :observation .
@@ -57,28 +57,28 @@
57
57
  :m005 msg:payload in:formula4 .
58
58
 
59
59
  in:formula1 {
60
- _:m001b0 rdf:type sosa:Observation .
60
+ _:m001b0 a sosa:Observation .
61
61
  _:m001b0 sosa:madeBySensor :thermometerA .
62
62
  _:m001b0 sosa:resultTime "2026-05-12T18:20:00Z" .
63
63
  _:m001b0 sosa:hasSimpleResult 21 .
64
64
  }
65
65
 
66
66
  in:formula2 {
67
- _:m002b0 rdf:type sosa:Observation .
67
+ _:m002b0 a sosa:Observation .
68
68
  _:m002b0 sosa:madeBySensor :thermometerA .
69
69
  _:m002b0 sosa:resultTime "2026-05-12T18:21:00Z" .
70
70
  _:m002b0 sosa:hasSimpleResult 22 .
71
71
  }
72
72
 
73
73
  in:formula3 {
74
- _:m004b0 rdf:type sosa:Observation .
74
+ _:m004b0 a sosa:Observation .
75
75
  _:m004b0 sosa:madeBySensor :thermometerA .
76
76
  _:m004b0 sosa:resultTime "2026-05-12T18:23:00Z" .
77
77
  _:m004b0 sosa:hasSimpleResult 28 .
78
78
  }
79
79
 
80
80
  in:formula4 {
81
- _:m005b0 rdf:type sosa:Observation .
81
+ _:m005b0 a sosa:Observation .
82
82
  _:m005b0 sosa:madeBySensor :thermometerA .
83
83
  _:m005b0 sosa:resultTime "2026-05-12T18:24:00Z" .
84
84
  _:m005b0 sosa:hasSimpleResult 29 .
@@ -13,25 +13,25 @@
13
13
  # Formal Eyeling input evidence in RDF 1.2 TriG.
14
14
  # The generated runner reads this TriG evidence directly.
15
15
 
16
- :temperatureLog rdf:type msg:MessageLog .
16
+ :temperatureLog a msg:MessageLog .
17
17
  :temperatureLog msg:orderedMessages (:m001 :m002 :m003) .
18
18
  :temperatureLog msg:message :m001 .
19
19
  :temperatureLog msg:message :m002 .
20
20
  :temperatureLog msg:message :m003 .
21
21
  :temperatureLog msg:profile :generatedAtTimeProfile .
22
22
  :temperatureLog msg:retentionPolicy "replayable archive" .
23
- :m001 rdf:type msg:RDFMessage .
23
+ :m001 a msg:RDFMessage .
24
24
  :m001 msg:offset 1 .
25
25
  :m001 prov:generatedAtTime "2026-05-12T18:20:00Z" .
26
26
  :m001 msg:payloadKind :observation .
27
27
  :m001 msg:localBlankLabel "_:b0" .
28
28
  :m001 msg:expectedResult 22 .
29
29
  :m001 msg:payload in:formula1 .
30
- :m002 rdf:type msg:RDFMessage .
30
+ :m002 a msg:RDFMessage .
31
31
  :m002 msg:offset 2 .
32
32
  :m002 prov:generatedAtTime "2026-05-12T18:22:00Z" .
33
33
  :m002 msg:payloadKind :heartbeat .
34
- :m003 rdf:type msg:RDFMessage .
34
+ :m003 a msg:RDFMessage .
35
35
  :m003 msg:offset 3 .
36
36
  :m003 prov:generatedAtTime "2026-05-12T18:25:00Z" .
37
37
  :m003 msg:payloadKind :observation .
@@ -40,14 +40,14 @@
40
40
  :m003 msg:payload in:formula2 .
41
41
 
42
42
  in:formula1 {
43
- _:m001b0 rdf:type sosa:Observation .
43
+ _:m001b0 a sosa:Observation .
44
44
  _:m001b0 sosa:madeBySensor :thermometerA .
45
45
  _:m001b0 sosa:resultTime "2026-05-12T18:20:00Z" .
46
46
  _:m001b0 sosa:hasSimpleResult 22 .
47
47
  }
48
48
 
49
49
  in:formula2 {
50
- _:m003b0 rdf:type sosa:Observation .
50
+ _:m003b0 a sosa:Observation .
51
51
  _:m003b0 sosa:madeBySensor :thermometerA .
52
52
  _:m003b0 sosa:resultTime "2026-05-12T18:25:00Z" .
53
53
  _:m003b0 sosa:hasSimpleResult 23 .
@@ -14,6 +14,8 @@
14
14
  @prefix math: <http://www.w3.org/2000/10/swap/math#>.
15
15
  @prefix log: <http://www.w3.org/2000/10/swap/log#>.
16
16
 
17
+ "000" log:outputString "# interop-demo\n\n## Source files\n\n- [N3 rules](../interop-demo.n3)\n\n" .
18
+
17
19
  # ---------------------------------------------
18
20
  # 1) Three independent apps (different schemas)
19
21
  # ---------------------------------------------
@@ -101,6 +103,6 @@
101
103
  ?c ex:recommendedAction ex:ApplyGoldDiscountAndSendInvoiceReminder.
102
104
 
103
105
  # Optional ordered console output for eyeling
104
- "001" log:outputString "ACTION: apply GoldDiscount and send invoice reminder (opt-in confirmed).".
106
+ "001" log:outputString "ACTION: apply GoldDiscount and send invoice reminder (opt-in confirmed).\n".
105
107
  }.
106
108
 
@@ -241,9 +241,9 @@
241
241
  }
242
242
  =>
243
243
  {
244
- :s01 log:outputString "=== Answer ===\n" .
244
+ :s01 log:outputString "# matrix-mechanics\n\n## Source files\n\n- [N3 rules](../matrix-mechanics.n3)\n\n## Answer\n" .
245
245
  :s02 log:outputString ?txt .
246
- :s03 log:outputString "\n\n=== Reason Why ===\n" .
246
+ :s03 log:outputString "\n\n## Reason Why\n" .
247
247
  } .
248
248
 
249
249
  {
@@ -301,7 +301,7 @@
301
301
  }
302
302
  =>
303
303
  {
304
- :s09 log:outputString "\n=== Check ===\n" .
304
+ :s09 log:outputString "\n## Check\n" .
305
305
  } .
306
306
 
307
307
  {
@@ -366,7 +366,7 @@
366
366
  # ARC rendering through log:outputString
367
367
  # --------------------------------------
368
368
 
369
- :out01 log:outputString "=== Answer ===\n" .
369
+ :out01 log:outputString "# medior\n\n## Source files\n\n- [N3 rules](../medior.n3)\n\n## Answer\n" .
370
370
  :out02 log:outputString "Name: Medior\n" .
371
371
  :out03 log:outputString "Region: Flanders\n" .
372
372
  :out04 log:outputString "Metric: post_discharge_coordination_priority\n" .
@@ -387,7 +387,7 @@
387
387
  ("Envelope HMAC-SHA-256: %s\n" ?sig) string:format ?line .
388
388
  } => { :out10 log:outputString ?line . } .
389
389
 
390
- :out11 log:outputString "\n=== Reason Why ===\n" .
390
+ :out11 log:outputString "\n## Reason Why\n" .
391
391
  :out12 log:outputString "RenalSafetyConcern holds because eGFR = 52 and the threshold is < 60.\n" .
392
392
  :out13 log:outputString "PolypharmacyRisk holds because the active medication count is 9 and the threshold is ≥ 8.\n" .
393
393
  :out14 log:outputString "ReadmissionHistory holds because admissionsLast180Days = 2 and the threshold is ≥ 1.\n" .
@@ -396,7 +396,7 @@
396
396
  :out17 log:outputString "The selected package is \"Medior Continuity Pulse\" with cost €4, touches=3.\n" .
397
397
  :out18 log:outputString "Use is permitted only for purpose \"care_coordination\" and expires at 2026-04-11T08:00:00+00:00.\n" .
398
398
 
399
- :out19 log:outputString "\n=== Check ===\n" .
399
+ :out19 log:outputString "\n## Check\n" .
400
400
  { :check :payloadHashMatches true . }
401
401
  => { :out20 log:outputString "- PASS: payloadHashMatches\n" . } .
402
402
  { :check :signatureVerifies true . }
@@ -116,3 +116,8 @@ log:query
116
116
  {
117
117
  :report :aliceReaches ?Who.
118
118
  }.
119
+
120
+
121
+ # Markdown rendering via log:outputString.
122
+ :__md_output :text "# n3-speaks-for-itself\n\n## Source files\n\n- [N3 rules](../n3-speaks-for-itself.n3)\n\n@prefix : <https://example.org/n3-speaks#> .\n@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n@prefix id: <https://example.org/id/> .\n\n:report :aliceReaches id:bob .\n:report :aliceReaches id:carol .\n:report :aliceReaches id:dave .\n:report :believes {\n id:alice foaf:knows id:bob .\n} .\n:report :believes {\n id:alice foaf:name \"Alice\" .\n} .\n:report :believes {\n id:bob foaf:knows id:carol .\n} .\n:report :believes {\n id:bob foaf:name \"Bob\" .\n} .\n:report :believes {\n id:carol foaf:knows id:dave .\n} .\n:report :believes {\n id:carol foaf:name \"Carol\" .\n} .\n:report :believes {\n id:dave foaf:name \"Dave\" .\n} .\n:report :trusts <https://alice.example/profile.n3> .\n:report :trusts <https://bob.example/profile.n3> .\n:report :trusts <https://carol.example/profile.n3> .\n{\n id:alice foaf:knows id:bob .\n} :believedFromDoc <https://alice.example/profile.n3> .\n{\n id:alice foaf:name \"Alice\" .\n} :believedFromDoc <https://alice.example/profile.n3> .\n{\n id:bob foaf:knows id:carol .\n} :believedFromDoc <https://bob.example/profile.n3> .\n{\n id:bob foaf:name \"Bob\" .\n} :believedFromDoc <https://bob.example/profile.n3> .\n{\n id:carol foaf:knows id:dave .\n} :believedFromDoc <https://carol.example/profile.n3> .\n{\n id:carol foaf:name \"Carol\" .\n} :believedFromDoc <https://carol.example/profile.n3> .\n{\n id:dave foaf:name \"Dave\" .\n} :believedFromDoc <https://carol.example/profile.n3> .\n" .
123
+ { :__md_output :text ?text } log:query { :__md_output log:outputString ?text } .
@@ -410,7 +410,7 @@
410
410
  {
411
411
  :AgreementEHDS1 dct:title ?alabel .
412
412
  :PatientProfileExample dct:title ?plabel .
413
- ( "\n=== Ranked DPV Risk Report (EHDS-aligned) ===\nAgreement: %s\nProfile: %s\n\n"
413
+ ( "# odrl-dpv-ehds-risk-ranked\n\n## Source files\n\n- [N3 rules](../odrl-dpv-ehds-risk-ranked.n3)\n\n## Ranked DPV Risk Report (EHDS-aligned)\nAgreement: %s\nProfile: %s\n\n"
414
414
  ?alabel ?plabel ) string:format ?hdr .
415
415
  }
416
416
  log:query
@@ -527,7 +527,7 @@
527
527
  {
528
528
  :AgreementHC1 dct:title ?alabel .
529
529
  :PatientExample dct:title ?plabel .
530
- ( "\n=== Ranked DPV Risk Report (Healthcare & Life Sciences) ===\nAgreement: %s\nProfile: %s\n\n"
530
+ ( "# odrl-dpv-healthcare-risk-ranked\n\n## Source files\n\n- [N3 rules](../odrl-dpv-healthcare-risk-ranked.n3)\n\n## Ranked DPV Risk Report (Healthcare & Life Sciences)\nAgreement: %s\nProfile: %s\n\n"
531
531
  ?alabel ?plabel ) string:format ?hdr .
532
532
  }
533
533
  =>
@@ -412,7 +412,7 @@
412
412
  {
413
413
  :Agreement1 dct:title ?alabel .
414
414
  :ConsumerExample dct:title ?plabel .
415
- ( "\n=== Ranked DPV Risk Report ===\nAgreement: %s\nProfile: %s\n\n"
415
+ ( "# odrl-dpv-risk-ranked\n\n## Source files\n\n- [N3 rules](../odrl-dpv-risk-ranked.n3)\n\n## Ranked DPV Risk Report\nAgreement: %s\nProfile: %s\n\n"
416
416
  ?alabel ?plabel ) string:format ?hdr .
417
417
  }
418
418
  log:query
@@ -773,7 +773,7 @@
773
773
  {
774
774
  ?agreement a :Agreement; :label ?alabel.
775
775
  ?profile a :ConsumerProfile; :label ?plabel.
776
- ( "\n=== Risk report for %s (profile: %s) ===\n" ?alabel ?plabel ) string:format ?hdr.
776
+ ( "# odrl-risk-mitigation\n\n## Source files\n\n- [N3 rules](../odrl-risk-mitigation.n3)\n\n## Risk report for %s (profile: %s)\n" ?alabel ?plabel ) string:format ?hdr.
777
777
  }
778
778
  =>
779
779
  {
@@ -391,7 +391,7 @@
391
391
  ?agreement a :Agreement; :label ?alabel.
392
392
  ?profile a :ConsumerProfile; :label ?plabel.
393
393
 
394
- ( "\n=== Risk report for %s (profile: %s) ===\n" ?alabel ?plabel ) string:format ?hdr.
394
+ ( "# odrl-risk\n\n## Source files\n\n- [N3 rules](../odrl-risk.n3)\n\n## Risk report for %s (profile: %s)\n" ?alabel ?plabel ) string:format ?hdr.
395
395
  }
396
396
  =>
397
397
  {
@@ -0,0 +1,409 @@
1
+ # Question generation from ontological patterns
2
+ #
3
+ # Run:
4
+ # npx eyeling -r examples/ontology-question-generation.n3 examples/input/ontology-question-generation.trig
5
+ #
6
+ # The input TriG file contains the ontology. These N3 rules detect common
7
+ # OWL/RDFS modeling patterns, derive structured q:CompetencyQuestion nodes,
8
+ # and render a Markdown report with log:outputString.
9
+
10
+ @prefix : <https://eyereasoner.github.io/eyeling/examples/ontology-question-generation#>.
11
+ @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
12
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
13
+ @prefix owl: <http://www.w3.org/2002/07/owl#>.
14
+ @prefix log: <http://www.w3.org/2000/10/swap/log#>.
15
+ @prefix string:<http://www.w3.org/2000/10/swap/string#>.
16
+
17
+ @prefix q: <http://example.org/question#>.
18
+ @prefix pat: <http://example.org/question/pattern#>.
19
+
20
+ #################################################################
21
+ # Markdown frame
22
+ #################################################################
23
+
24
+ <urn:eyeling:oqg:000:title>
25
+ log:outputString "# ontology-question-generation\n\n".
26
+
27
+ <urn:eyeling:oqg:010:intro>
28
+ log:outputString "This example uses N3 rules to generate candidate competency questions from OWL/RDFS ontology patterns. The rules derive structured `q:CompetencyQuestion` resources and render this Markdown with `log:outputString`.\n\n".
29
+
30
+ <urn:eyeling:oqg:015:sources>
31
+ log:outputString "## Source files\n\n- [N3 rules](../ontology-question-generation.n3)\n- [Input ontology TriG](../input/ontology-question-generation.trig)\n\n".
32
+
33
+ <urn:eyeling:oqg:020:patterns>
34
+ log:outputString "## Detected competency questions\n\n".
35
+
36
+ <urn:eyeling:oqg:900:shape-title>
37
+ log:outputString "\n## RDF shape behind the Markdown\n\n".
38
+
39
+ <urn:eyeling:oqg:910:shape-body>
40
+ log:outputString "Each rendered line is backed by a structured generated resource with a pattern, slots, an answer shape, and priority. That means a later layer can verbalize the same generated questions as Markdown, SPARQL skeletons, SHACL prompts, UI forms, or documentation checks.\n".
41
+
42
+ #################################################################
43
+ # Helper classifications
44
+ #################################################################
45
+
46
+ { ?class a owl:Class. }
47
+ =>
48
+ { ?class q:isOntologicalClass true. }.
49
+
50
+ { ?class a rdfs:Class. }
51
+ =>
52
+ { ?class q:isOntologicalClass true. }.
53
+
54
+ { ?property a owl:ObjectProperty. }
55
+ =>
56
+ { ?property q:isObjectProperty true. }.
57
+
58
+ { ?property a owl:DatatypeProperty. }
59
+ =>
60
+ { ?property q:isDatatypeProperty true. }.
61
+
62
+ { ?property rdfs:domain ?domain. ?property rdfs:range ?range. ?range q:isOntologicalClass true. }
63
+ =>
64
+ { ?property q:isObjectProperty true. }.
65
+
66
+ { ?property rdfs:domain ?domain. ?property rdfs:range ?datatype. ?datatype a rdfs:Datatype. }
67
+ =>
68
+ { ?property q:isDatatypeProperty true. }.
69
+
70
+ #################################################################
71
+ # 1. Class population pattern
72
+ #################################################################
73
+
74
+ { ?class q:isOntologicalClass true. ?class rdfs:label ?classLabel. }
75
+ =>
76
+ {
77
+ [
78
+ a q:CompetencyQuestion;
79
+ q:pattern pat:ClassPopulationQuestion;
80
+ q:aboutClass ?class;
81
+ q:questionTemplate "Which things are instances of {class}?";
82
+ q:slot [ q:slotName "class"; q:slotValue ?class; q:slotLabel ?classLabel ];
83
+ q:expectedAnswerShape pat:SetOfIndividuals;
84
+ q:priority 3
85
+ ].
86
+ }.
87
+
88
+ {
89
+ ?class q:isOntologicalClass true.
90
+ ?class rdfs:label ?classLabel.
91
+ ?class log:uri ?classIri.
92
+ ("urn:eyeling:oqg:100:class:%s" ?classIri) string:format ?key.
93
+ ?out log:uri ?key.
94
+ ("- **Class population** — Which things are instances of `%s`?\n" ?classLabel) string:format ?line.
95
+ }
96
+ =>
97
+ { ?out log:outputString ?line. }.
98
+
99
+ #################################################################
100
+ # 2. Subclass distinction pattern
101
+ #################################################################
102
+
103
+ { ?subClass rdfs:subClassOf ?superClass. ?subClass q:isOntologicalClass true. ?superClass q:isOntologicalClass true. }
104
+ =>
105
+ {
106
+ [
107
+ a q:CompetencyQuestion;
108
+ q:pattern pat:SubclassDistinctionQuestion;
109
+ q:sourcePattern rdfs:subClassOf;
110
+ q:aboutClass ?subClass;
111
+ q:questionTemplate "What distinguishes a {subClass} from a general {superClass}?";
112
+ q:slot [ q:slotName "subClass"; q:slotValue ?subClass ];
113
+ q:slot [ q:slotName "superClass"; q:slotValue ?superClass ];
114
+ q:expectedAnswerShape pat:DefinitionOrConstraint;
115
+ q:priority 4
116
+ ].
117
+ }.
118
+
119
+ {
120
+ ?subClass rdfs:subClassOf ?superClass.
121
+ ?subClass q:isOntologicalClass true.
122
+ ?superClass q:isOntologicalClass true.
123
+ ?subClass rdfs:label ?subLabel.
124
+ ?superClass rdfs:label ?superLabel.
125
+ ?subClass log:uri ?subIri.
126
+ ?superClass log:uri ?superIri.
127
+ ("urn:eyeling:oqg:200:subclass:%s:%s" ?subIri ?superIri) string:format ?key.
128
+ ?out log:uri ?key.
129
+ ("- **Subclass distinction** — What distinguishes `%s` from a general `%s`?\n" ?subLabel ?superLabel) string:format ?line.
130
+ }
131
+ =>
132
+ { ?out log:outputString ?line. }.
133
+
134
+ #################################################################
135
+ # 3. Object property domain/range pattern
136
+ #################################################################
137
+
138
+ { ?property q:isObjectProperty true. ?property rdfs:domain ?domain. ?property rdfs:range ?range. }
139
+ =>
140
+ {
141
+ [
142
+ a q:CompetencyQuestion;
143
+ q:pattern pat:ObjectPropertyQuestion;
144
+ q:sourcePattern pat:DomainRangePattern;
145
+ q:aboutProperty ?property;
146
+ q:questionTemplate "For a given {domain}, which {range} is related by {property}?";
147
+ q:slot [ q:slotName "domain"; q:slotValue ?domain ];
148
+ q:slot [ q:slotName "property"; q:slotValue ?property ];
149
+ q:slot [ q:slotName "range"; q:slotValue ?range ];
150
+ q:expectedAnswerShape pat:SubjectPredicateObjectBindings;
151
+ q:priority 5
152
+ ].
153
+ }.
154
+
155
+ {
156
+ ?property q:isObjectProperty true.
157
+ ?property rdfs:domain ?domain.
158
+ ?property rdfs:range ?range.
159
+ ?property rdfs:label ?propertyLabel.
160
+ ?domain rdfs:label ?domainLabel.
161
+ ?range rdfs:label ?rangeLabel.
162
+ ?property log:uri ?propertyIri.
163
+ ("urn:eyeling:oqg:300:object-property:%s" ?propertyIri) string:format ?key.
164
+ ?out log:uri ?key.
165
+ ("- **Object property** — For a given `%s`, which `%s` is related by `%s`?\n" ?domainLabel ?rangeLabel ?propertyLabel) string:format ?line.
166
+ }
167
+ =>
168
+ { ?out log:outputString ?line. }.
169
+
170
+ #################################################################
171
+ # 4. Datatype property pattern
172
+ #################################################################
173
+
174
+ { ?property q:isDatatypeProperty true. ?property rdfs:domain ?domain. ?property rdfs:range ?datatype. }
175
+ =>
176
+ {
177
+ [
178
+ a q:CompetencyQuestion;
179
+ q:pattern pat:DatatypePropertyQuestion;
180
+ q:sourcePattern pat:DomainDatatypeRangePattern;
181
+ q:aboutProperty ?property;
182
+ q:questionTemplate "What is the {property} value of a given {domain}?";
183
+ q:slot [ q:slotName "domain"; q:slotValue ?domain ];
184
+ q:slot [ q:slotName "property"; q:slotValue ?property ];
185
+ q:slot [ q:slotName "datatype"; q:slotValue ?datatype ];
186
+ q:expectedAnswerShape pat:LiteralValue;
187
+ q:priority 5
188
+ ].
189
+ }.
190
+
191
+ {
192
+ ?property q:isDatatypeProperty true.
193
+ ?property rdfs:domain ?domain.
194
+ ?property rdfs:range ?datatype.
195
+ ?property rdfs:label ?propertyLabel.
196
+ ?domain rdfs:label ?domainLabel.
197
+ ?property log:uri ?propertyIri.
198
+ ("urn:eyeling:oqg:400:datatype-property:%s" ?propertyIri) string:format ?key.
199
+ ?out log:uri ?key.
200
+ ("- **Datatype property** — What is the `%s` value of a given `%s`?\n" ?propertyLabel ?domainLabel) string:format ?line.
201
+ }
202
+ =>
203
+ { ?out log:outputString ?line. }.
204
+
205
+ #################################################################
206
+ # 5. Existential restriction pattern
207
+ #################################################################
208
+
209
+ { ?class rdfs:subClassOf ?restriction. ?restriction a owl:Restriction. ?restriction owl:onProperty ?property. ?restriction owl:someValuesFrom ?filler. }
210
+ =>
211
+ {
212
+ [
213
+ a q:CompetencyQuestion;
214
+ q:pattern pat:ExistentialRestrictionQuestion;
215
+ q:sourcePattern owl:someValuesFrom;
216
+ q:aboutClass ?class;
217
+ q:aboutProperty ?property;
218
+ q:questionTemplate "For each {class}, which {filler} must exist via {property}?";
219
+ q:slot [ q:slotName "class"; q:slotValue ?class ];
220
+ q:slot [ q:slotName "property"; q:slotValue ?property ];
221
+ q:slot [ q:slotName "filler"; q:slotValue ?filler ];
222
+ q:expectedAnswerShape pat:RequiredExistentialWitness;
223
+ q:priority 8
224
+ ].
225
+ }.
226
+
227
+ {
228
+ ?class rdfs:subClassOf ?restriction.
229
+ ?restriction a owl:Restriction.
230
+ ?restriction owl:onProperty ?property.
231
+ ?restriction owl:someValuesFrom ?filler.
232
+ ?class rdfs:label ?classLabel.
233
+ ?property rdfs:label ?propertyLabel.
234
+ ?filler rdfs:label ?fillerLabel.
235
+ ?class log:uri ?classIri.
236
+ ?property log:uri ?propertyIri.
237
+ ?filler log:uri ?fillerIri.
238
+ ("urn:eyeling:oqg:500:some-values:%s:%s:%s" ?classIri ?propertyIri ?fillerIri) string:format ?key.
239
+ ?out log:uri ?key.
240
+ ("- **Existential restriction** — For each `%s`, which `%s` must exist via `%s`?\n" ?classLabel ?fillerLabel ?propertyLabel) string:format ?line.
241
+ }
242
+ =>
243
+ { ?out log:outputString ?line. }.
244
+
245
+ #################################################################
246
+ # 6. Minimum cardinality pattern
247
+ #################################################################
248
+
249
+ { ?class rdfs:subClassOf ?restriction. ?restriction a owl:Restriction. ?restriction owl:onProperty ?property. ?restriction owl:minCardinality ?n. }
250
+ =>
251
+ {
252
+ [
253
+ a q:CompetencyQuestion;
254
+ q:pattern pat:MinimumCardinalityQuestion;
255
+ q:sourcePattern owl:minCardinality;
256
+ q:aboutClass ?class;
257
+ q:aboutProperty ?property;
258
+ q:questionTemplate "Does every {class} need at least {n} value(s) for {property}?";
259
+ q:slot [ q:slotName "class"; q:slotValue ?class ];
260
+ q:slot [ q:slotName "property"; q:slotValue ?property ];
261
+ q:slot [ q:slotName "n"; q:slotValue ?n ];
262
+ q:expectedAnswerShape pat:MinimumCardinalityConstraint;
263
+ q:priority 8
264
+ ].
265
+ }.
266
+
267
+ {
268
+ ?class rdfs:subClassOf ?restriction.
269
+ ?restriction a owl:Restriction.
270
+ ?restriction owl:onProperty ?property.
271
+ ?restriction owl:minCardinality ?n.
272
+ ?class rdfs:label ?classLabel.
273
+ ?property rdfs:label ?propertyLabel.
274
+ ?class log:uri ?classIri.
275
+ ?property log:uri ?propertyIri.
276
+ ("urn:eyeling:oqg:600:min-cardinality:%s:%s:%s" ?classIri ?propertyIri ?n) string:format ?key.
277
+ ?out log:uri ?key.
278
+ ("- **Minimum cardinality** — Does every `%s` need at least `%s` value for `%s`?\n" ?classLabel ?n ?propertyLabel) string:format ?line.
279
+ }
280
+ =>
281
+ { ?out log:outputString ?line. }.
282
+
283
+ #################################################################
284
+ # 7. Disjointness pattern
285
+ #################################################################
286
+
287
+ { ?classA owl:disjointWith ?classB. }
288
+ =>
289
+ {
290
+ [
291
+ a q:CompetencyQuestion;
292
+ q:pattern pat:DisjointnessQuestion;
293
+ q:sourcePattern owl:disjointWith;
294
+ q:questionTemplate "Can something ever be both a {classA} and a {classB}?";
295
+ q:slot [ q:slotName "classA"; q:slotValue ?classA ];
296
+ q:slot [ q:slotName "classB"; q:slotValue ?classB ];
297
+ q:expectedAnswerShape pat:BooleanOrExceptionList;
298
+ q:priority 6
299
+ ].
300
+ }.
301
+
302
+ {
303
+ ?classA owl:disjointWith ?classB.
304
+ ?classA rdfs:label ?labelA.
305
+ ?classB rdfs:label ?labelB.
306
+ ?classA log:uri ?iriA.
307
+ ?classB log:uri ?iriB.
308
+ ("urn:eyeling:oqg:700:disjoint:%s:%s" ?iriA ?iriB) string:format ?key.
309
+ ?out log:uri ?key.
310
+ ("- **Disjointness** — Can something ever be both an `%s` and a `%s`?\n" ?labelA ?labelB) string:format ?line.
311
+ }
312
+ =>
313
+ { ?out log:outputString ?line. }.
314
+
315
+ #################################################################
316
+ # 8. Functional property pattern
317
+ #################################################################
318
+
319
+ { ?property a owl:FunctionalProperty. }
320
+ =>
321
+ {
322
+ [
323
+ a q:CompetencyQuestion;
324
+ q:pattern pat:FunctionalPropertyQuestion;
325
+ q:sourcePattern owl:FunctionalProperty;
326
+ q:aboutProperty ?property;
327
+ q:questionTemplate "Can one subject have multiple values for {property}?";
328
+ q:slot [ q:slotName "property"; q:slotValue ?property ];
329
+ q:expectedAnswerShape pat:BooleanOrConstraint;
330
+ q:priority 6
331
+ ].
332
+ }.
333
+
334
+ {
335
+ ?property a owl:FunctionalProperty.
336
+ ?property rdfs:label ?propertyLabel.
337
+ ?property log:uri ?propertyIri.
338
+ ("urn:eyeling:oqg:800:functional:%s" ?propertyIri) string:format ?key.
339
+ ?out log:uri ?key.
340
+ ("- **Functional property** — Can one subject have multiple values for `%s`?\n" ?propertyLabel) string:format ?line.
341
+ }
342
+ =>
343
+ { ?out log:outputString ?line. }.
344
+
345
+ #################################################################
346
+ # 9. Inverse property pattern
347
+ #################################################################
348
+
349
+ { ?property owl:inverseOf ?inverseProperty. }
350
+ =>
351
+ {
352
+ [
353
+ a q:CompetencyQuestion;
354
+ q:pattern pat:InversePropertyQuestion;
355
+ q:sourcePattern owl:inverseOf;
356
+ q:aboutProperty ?property;
357
+ q:questionTemplate "If {x} has {property} {y}, should {y} have {inverseProperty} {x}?";
358
+ q:slot [ q:slotName "property"; q:slotValue ?property ];
359
+ q:slot [ q:slotName "inverseProperty"; q:slotValue ?inverseProperty ];
360
+ q:expectedAnswerShape pat:InverseRelationCheck;
361
+ q:priority 5
362
+ ].
363
+ }.
364
+
365
+ {
366
+ ?property owl:inverseOf ?inverseProperty.
367
+ ?property rdfs:label ?propertyLabel.
368
+ ?inverseProperty rdfs:label ?inverseLabel.
369
+ ?property log:uri ?propertyIri.
370
+ ?inverseProperty log:uri ?inverseIri.
371
+ ("urn:eyeling:oqg:810:inverse:%s:%s" ?propertyIri ?inverseIri) string:format ?key.
372
+ ?out log:uri ?key.
373
+ ("- **Inverse property** — If `x` has `%s` `y`, should `y` have `%s` `x`?\n" ?propertyLabel ?inverseLabel) string:format ?line.
374
+ }
375
+ =>
376
+ { ?out log:outputString ?line. }.
377
+
378
+ #################################################################
379
+ # 10. Property hierarchy pattern
380
+ #################################################################
381
+
382
+ { ?subProperty rdfs:subPropertyOf ?superProperty. }
383
+ =>
384
+ {
385
+ [
386
+ a q:CompetencyQuestion;
387
+ q:pattern pat:SubpropertyQuestion;
388
+ q:sourcePattern rdfs:subPropertyOf;
389
+ q:aboutProperty ?subProperty;
390
+ q:questionTemplate "When {subProperty} holds, should {superProperty} also hold?";
391
+ q:slot [ q:slotName "subProperty"; q:slotValue ?subProperty ];
392
+ q:slot [ q:slotName "superProperty"; q:slotValue ?superProperty ];
393
+ q:expectedAnswerShape pat:BooleanOrRule;
394
+ q:priority 4
395
+ ].
396
+ }.
397
+
398
+ {
399
+ ?subProperty rdfs:subPropertyOf ?superProperty.
400
+ ?subProperty rdfs:label ?subLabel.
401
+ ?superProperty rdfs:label ?superLabel.
402
+ ?subProperty log:uri ?subIri.
403
+ ?superProperty log:uri ?superIri.
404
+ ("urn:eyeling:oqg:820:subproperty:%s:%s" ?subIri ?superIri) string:format ?key.
405
+ ?out log:uri ?key.
406
+ ("- **Subproperty** — When `%s` holds, should `%s` also hold?\n" ?subLabel ?superLabel) string:format ?line.
407
+ }
408
+ =>
409
+ { ?out log:outputString ?line. }.