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
@@ -112,7 +112,7 @@
112
112
  ?givens ?blanks ?forced ?guessed ?nodes ?backtracks ?moveSummary ) string:format ?reasonText .
113
113
  }
114
114
  => {
115
- :01-answer log:outputString "=== Answer ===\n" ;
115
+ :01-answer log:outputString "# sudoku\n\n## Source files\n\n- [N3 rules](../sudoku.n3)\n\n## Answer\n" ;
116
116
  log:outputString ?answerText .
117
117
  :01a-answer log:outputString "case : sudoku\n" ;
118
118
  log:outputString "default puzzle : classic\n\n" ;
@@ -122,7 +122,7 @@
122
122
  log:outputString "Completed grid\n" ;
123
123
  log:outputString ?solutionText .
124
124
  :01b-answer log:outputString "\n" .
125
- :02-reason log:outputString "=== Reason Why ===\n" ;
125
+ :02-reason log:outputString "## Reason Why\n" ;
126
126
  log:outputString ?reasonText ;
127
127
  log:outputString "\n\n" .
128
128
  } .
@@ -144,7 +144,7 @@
144
144
  ?givens ?blanks ?forced ?guessed ?nodes ?backtracks ?moveSummary ) string:format ?reasonText .
145
145
  }
146
146
  => {
147
- :01-answer log:outputString "=== Answer ===\n" ;
147
+ :01-answer log:outputString "# sudoku\n\n## Source files\n\n- [N3 rules](../sudoku.n3)\n\n## Answer\n" ;
148
148
  log:outputString ?answerText .
149
149
  :01a-answer log:outputString "case : sudoku\n" ;
150
150
  log:outputString "default puzzle : classic\n\n" ;
@@ -154,7 +154,7 @@
154
154
  log:outputString "Completed grid\n" ;
155
155
  log:outputString ?solutionText ;
156
156
  log:outputString "\n" .
157
- :02-reason log:outputString "=== Reason Why ===\n" ;
157
+ :02-reason log:outputString "## Reason Why\n" ;
158
158
  log:outputString ?reasonText ;
159
159
  log:outputString "\n\n" .
160
160
  } .
@@ -164,10 +164,10 @@
164
164
  :case :error ?error .
165
165
  }
166
166
  => {
167
- :01-answer log:outputString "=== Answer ===\n" ;
167
+ :01-answer log:outputString "# sudoku\n\n## Source files\n\n- [N3 rules](../sudoku.n3)\n\n## Answer\n" ;
168
168
  log:outputString "The supplied puzzle is not well formed and cannot be parsed as a 9×9 Sudoku.\n" ;
169
169
  log:outputString "case : sudoku\n\n" .
170
- :02-reason log:outputString "=== Reason Why ===\n" ;
170
+ :02-reason log:outputString "## Reason Why\n" ;
171
171
  log:outputString ?error ;
172
172
  log:outputString "\n\n" .
173
173
  } .
@@ -178,13 +178,13 @@
178
178
  :error ?error .
179
179
  }
180
180
  => {
181
- :01-answer log:outputString "=== Answer ===\n" ;
181
+ :01-answer log:outputString "# sudoku\n\n## Source files\n\n- [N3 rules](../sudoku.n3)\n\n## Answer\n" ;
182
182
  log:outputString "The puzzle is invalid and cannot be solved as a standard Sudoku.\n" ;
183
183
  log:outputString "case : sudoku\n\n" ;
184
184
  log:outputString "Puzzle\n" ;
185
185
  log:outputString ?puzzleText ;
186
186
  log:outputString "\n" .
187
- :02-reason log:outputString "=== Reason Why ===\n" ;
187
+ :02-reason log:outputString "## Reason Why\n" ;
188
188
  log:outputString ?error ;
189
189
  log:outputString "\n\n" .
190
190
  } .
@@ -200,14 +200,14 @@
200
200
  ?nodes ?backtracks ) string:format ?reasonText .
201
201
  }
202
202
  => {
203
- :01-answer log:outputString "=== Answer ===\n" ;
203
+ :01-answer log:outputString "# sudoku\n\n## Source files\n\n- [N3 rules](../sudoku.n3)\n\n## Answer\n" ;
204
204
  log:outputString "No valid Sudoku solution exists for the supplied puzzle.\n" ;
205
205
  log:outputString "case : sudoku\n" ;
206
206
  log:outputString "default puzzle : classic\n" ;
207
207
  log:outputString "\nPuzzle\n" ;
208
208
  log:outputString ?puzzleText ;
209
209
  log:outputString "\n" .
210
- :02-reason log:outputString "=== Reason Why ===\n" ;
210
+ :02-reason log:outputString "## Reason Why\n" ;
211
211
  log:outputString ?reasonText ;
212
212
  log:outputString "\n\n" .
213
213
  } .
@@ -233,7 +233,7 @@
233
233
  ( "C7 %s - the search statistics and the successful proof path are internally consistent.\n" ?c7 ) string:format ?l7 .
234
234
  }
235
235
  => {
236
- :03-check log:outputString "=== Check ===\n" ;
236
+ :03-check log:outputString "## Check\n" ;
237
237
  log:outputString ?l1 ;
238
238
  log:outputString ?l2 ;
239
239
  log:outputString ?l3 ;
@@ -254,10 +254,10 @@
254
254
  => { :03a-check log:outputString "C8 INFO - a second search found another solution, so the puzzle is not unique.\n" . } .
255
255
 
256
256
  { :case :status "illegal-clues" . }
257
- => { :03-check log:outputString "=== Check ===\nC1 failed - the given clues already violate Sudoku rules.\n" . } .
257
+ => { :03-check log:outputString "## Check\nC1 failed - the given clues already violate Sudoku rules.\n" . } .
258
258
 
259
259
  { :case :status "invalid-input" . }
260
- => { :03-check log:outputString "=== Check ===\nC1 failed - the supplied text does not normalize to exactly 81 legal Sudoku cells.\n" . } .
260
+ => { :03-check log:outputString "## Check\nC1 failed - the supplied text does not normalize to exactly 81 legal Sudoku cells.\n" . } .
261
261
 
262
262
  { :case :status "unsatisfiable" . }
263
- => { :03-check log:outputString "=== Check ===\nC1 OK - the given clues are internally consistent.\nC2 OK - every explored assignment respected row, column, and box legality.\nC3 failed - exhaustive search found no complete legal grid.\n" . } .
263
+ => { :03-check log:outputString "## Check\nC1 OK - the given clues are internally consistent.\nC2 OK - every explored assignment respected row, column, and box legality.\nC3 failed - exhaustive search found no complete legal grid.\n" . } .
@@ -303,3 +303,8 @@ log:query
303
303
  :report :concerns ?A.
304
304
  :report :concerns ?B.
305
305
  }.
306
+
307
+
308
+ # Markdown rendering via log:outputString.
309
+ :__md_output :text "# transcendental-numbers-stretched\n\n## Source files\n\n- [N3 rules](../transcendental-numbers-stretched.n3)\n\n@prefix : <https://example.org/transcendental#> .\n\n:report :concerns :prod_e_pi .\n:report :concerns :sum_e_pi .\n:report :headline :quadraticTrick .\n:report :irrational :e .\n:report :irrational :e_div_2 .\n:report :irrational :e_plus_1 .\n:report :irrational :e_plus_2 .\n:report :irrational :exp_minus_pi_over_2 .\n:report :irrational :exp_sqrt2 .\n:report :irrational :half_times_e .\n:report :irrational :half_times_pi .\n:report :irrational :pi .\n:report :irrational :pi_div_2 .\n:report :irrational :pi_plus_1 .\n:report :irrational :pi_plus_sqrt2 .\n:report :irrational :pow_2_sqrt2 .\n:report :irrational :pow_e_pi .\n:report :irrational :pow_i_i .\n:report :irrational :pow_minus1_minusI .\n:report :irrational :pow2sqrt2_div_2 .\n:report :irrational :pow2sqrt2_plus_1 .\n:report :irrational :two_times_e .\n:report :irrational :two_times_pi .\n:report :irrational :two_times_pow2sqrt2 .\n:report :notConstructible :e .\n:report :notConstructible :e_div_2 .\n:report :notConstructible :e_plus_1 .\n:report :notConstructible :e_plus_2 .\n:report :notConstructible :exp_minus_pi_over_2 .\n:report :notConstructible :exp_sqrt2 .\n:report :notConstructible :half_times_e .\n:report :notConstructible :half_times_pi .\n:report :notConstructible :pi .\n:report :notConstructible :pi_div_2 .\n:report :notConstructible :pi_plus_1 .\n:report :notConstructible :pi_plus_sqrt2 .\n:report :notConstructible :pow_2_sqrt2 .\n:report :notConstructible :pow_e_pi .\n:report :notConstructible :pow_i_i .\n:report :notConstructible :pow_minus1_minusI .\n:report :notConstructible :pow2sqrt2_div_2 .\n:report :notConstructible :pow2sqrt2_plus_1 .\n:report :notConstructible :two_times_e .\n:report :notConstructible :two_times_pi .\n:report :notConstructible :two_times_pow2sqrt2 .\n:report :proof {\n :e :provedBy :Hermite1873 .\n} .\n:report :proof {\n :e :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :e :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :e_div_2 :provedBy :TransDivAlg .\n} .\n:report :proof {\n :e_div_2 :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :e_div_2 :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :e_plus_1 :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :e_plus_1 :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :e_plus_1 :provedBy :TransPlusAlg .\n} .\n:report :proof {\n :e_plus_2 :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :e_plus_2 :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :e_plus_2 :provedBy :TransPlusAlg .\n} .\n:report :proof {\n :exp_minus_pi_over_2 :provedBy :GelfondSchneider .\n} .\n:report :proof {\n :exp_minus_pi_over_2 :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :exp_minus_pi_over_2 :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :exp_sqrt2 :provedBy :LindemannWeierstrass .\n} .\n:report :proof {\n :exp_sqrt2 :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :exp_sqrt2 :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :half_times_e :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :half_times_e :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :half_times_e :provedBy :TransTimesAlg .\n} .\n:report :proof {\n :half_times_pi :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :half_times_pi :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :half_times_pi :provedBy :TransTimesAlg .\n} .\n:report :proof {\n :pi :provedBy :Lindemann1882 .\n} .\n:report :proof {\n :pi :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :pi :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :pi_div_2 :provedBy :TransDivAlg .\n} .\n:report :proof {\n :pi_div_2 :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :pi_div_2 :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :pi_plus_1 :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :pi_plus_1 :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :pi_plus_1 :provedBy :TransPlusAlg .\n} .\n:report :proof {\n :pi_plus_sqrt2 :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :pi_plus_sqrt2 :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :pi_plus_sqrt2 :provedBy :TransPlusAlg .\n} .\n:report :proof {\n :pow_2_sqrt2 :provedBy :GelfondSchneider .\n} .\n:report :proof {\n :pow_2_sqrt2 :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :pow_2_sqrt2 :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :pow_e_pi :provedBy :GelfondSchneider .\n} .\n:report :proof {\n :pow_e_pi :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :pow_e_pi :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :pow_i_i :provedBy :GelfondSchneider .\n} .\n:report :proof {\n :pow_i_i :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :pow_i_i :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :pow_minus1_minusI :provedBy :GelfondSchneider .\n} .\n:report :proof {\n :pow_minus1_minusI :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :pow_minus1_minusI :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :pow2sqrt2_div_2 :provedBy :TransDivAlg .\n} .\n:report :proof {\n :pow2sqrt2_div_2 :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :pow2sqrt2_div_2 :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :pow2sqrt2_plus_1 :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :pow2sqrt2_plus_1 :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :pow2sqrt2_plus_1 :provedBy :TransPlusAlg .\n} .\n:report :proof {\n :two_times_e :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :two_times_e :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :two_times_e :provedBy :TransTimesAlg .\n} .\n:report :proof {\n :two_times_pi :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :two_times_pi :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :two_times_pi :provedBy :TransTimesAlg .\n} .\n:report :proof {\n :two_times_pow2sqrt2 :provedBy :TransImpliesIrrational .\n} .\n:report :proof {\n :two_times_pow2sqrt2 :provedBy :TransImpliesNotConstructible .\n} .\n:report :proof {\n :two_times_pow2sqrt2 :provedBy :TransTimesAlg .\n} .\n:report :transcendental :e .\n:report :transcendental :e_div_2 .\n:report :transcendental :e_plus_1 .\n:report :transcendental :e_plus_2 .\n:report :transcendental :exp_minus_pi_over_2 .\n:report :transcendental :exp_sqrt2 .\n:report :transcendental :half_times_e .\n:report :transcendental :half_times_pi .\n:report :transcendental :pi .\n:report :transcendental :pi_div_2 .\n:report :transcendental :pi_plus_1 .\n:report :transcendental :pi_plus_sqrt2 .\n:report :transcendental :pow_2_sqrt2 .\n:report :transcendental :pow_e_pi .\n:report :transcendental :pow_i_i .\n:report :transcendental :pow_minus1_minusI .\n:report :transcendental :pow2sqrt2_div_2 .\n:report :transcendental :pow2sqrt2_plus_1 .\n:report :transcendental :two_times_e .\n:report :transcendental :two_times_pi .\n:report :transcendental :two_times_pow2sqrt2 .\n:report :unknown :pow_pi_e .\n:report :unknown :prod_e_pi .\n:report :unknown :sum_e_pi .\n" .
310
+ { :__md_output :text ?text } log:query { :__md_output log:outputString ?text } .
@@ -193,7 +193,7 @@
193
193
  ( "on-state load current : %s\n\n" ?onCurrentText ) string:format ?onCurrentLine .
194
194
  }
195
195
  => {
196
- :01-answer-1 log:outputString "=== Answer ===\n" .
196
+ :01-answer-1 log:outputString "# transistor-switch\n\n## Source files\n\n- [N3 rules](../transistor-switch.n3)\n\n## Answer\n" .
197
197
  :01-answer-2 log:outputString "In this toy transistor-switch model, a low input leaves the transistor in cutoff (OFF) and a high input drives it into saturation (ON), so the load behaves like an on/off branch rather than a linear amplifier.\n" .
198
198
  :01-answer-3 log:outputString "case : transistor-switch\n" .
199
199
  :01-answer-4 log:outputString ?lowStateLine .
@@ -223,7 +223,7 @@
223
223
  ( "high-input load limit : %s\n" ?loadLimitText ) string:format ?loadLine .
224
224
  }
225
225
  => {
226
- :02-why-01 log:outputString "=== Reason Why ===\n" .
226
+ :02-why-01 log:outputString "## Reason Why\n" .
227
227
  :02-why-02 log:outputString "We model an NPN low-side switch with exact millivolt and microamp arithmetic. The base current comes from (Vin - Vbe,on)/Rb when the base-emitter junction is forward biased, and the collector current is the smaller of beta * Ib and the load-limited current (Vcc - Vce,sat)/Rl.\n" .
228
228
  :02-why-03 log:outputString ?supplyLine .
229
229
  :02-why-04 log:outputString ?rbLine .
@@ -244,7 +244,7 @@
244
244
  :case :loadVoltageMatchesResistorDrop true .
245
245
  }
246
246
  => {
247
- :03-check-1 log:outputString "=== Check ===\n" .
247
+ :03-check-1 log:outputString "## Check\n" .
248
248
  :03-check-2 log:outputString "low input stays in cutoff : yes\n" .
249
249
  :03-check-3 log:outputString "high input reaches saturation : yes\n" .
250
250
  :03-check-4 log:outputString "switching states differ : yes\n" .
@@ -18,3 +18,8 @@ VERSION "1.2"
18
18
  { ?observation :entails ?entailment }
19
19
  log:query
20
20
  { ?observation :entails ?entailment } .
21
+
22
+
23
+ # Markdown rendering via log:outputString.
24
+ :__md_output :text "# triple-terms\n\n## Source files\n\n- [N3 rules](../triple-terms.n3)\n- [Input TriG](../input/triple-terms.trig)\n\nVERSION \"1.2\"\n\n@prefix : <https://eyereasoner.github.io/eyeling/examples/triple_terms#> .\n\n:observation :entails <<( :sensor :needs :inspection )>> .\n" .
25
+ { :__md_output :text ?text } log:query { :__md_output log:outputString ?text } .
@@ -18,6 +18,8 @@
18
18
  @prefix arc: <https://example.org/arc#> .
19
19
  @prefix log: <http://www.w3.org/2000/10/swap/log#> .
20
20
 
21
+ :000_md_title log:outputString "# tunnel-junction-wake-switch-becoming\n\n## Source files\n\n- [N3 rules](../tunnel-junction-wake-switch-becoming.n3)\n\n" .
22
+
21
23
  :case a arc:Case ;
22
24
  arc:question "Can a tunnel-junction wake switch become a low-bias wake-triggering state in a regime where a conventional PN junction cannot?" .
23
25
 
@@ -193,14 +195,14 @@
193
195
  {
194
196
  :out log:outputString """tunnel-junction wake switch — becoming
195
197
 
196
- Answer
198
+ ## Answer
197
199
  YES for the tunnel junction.
198
200
  NO for the conventional low-bias PN junction in the same wake-switch regime.
199
201
 
200
- Reason Why
202
+ ## Reason Why
201
203
  The tunnel junction can be read as a becoming under low forward bias. Because it is modeled as a heavily doped narrow PN junction with overlapping states, it can become a quantum-transfer state. In that regime it can become a sub-threshold current state, and under peak-to-valley scanning it can also become a negative differential response state. As a wake-switch device, that lets it become an ultra-low-bias switching state and finally a leak-alarm wake-serving state. By contrast, the conventional junction lacks the structural conditions needed for the same transition into quantum transfer, so the later wake-serving becoming is blocked as well.
202
204
 
203
- Check
205
+ ## Check
204
206
  B1 OK - the tunnel junction can become a quantum-transfer state
205
207
  B2 OK - the tunnel junction is classified as tunneling-dominant
206
208
  B3 OK - the tunnel junction can become a sub-threshold current state
@@ -15,6 +15,8 @@
15
15
  @prefix string: <http://www.w3.org/2000/10/swap/string#> .
16
16
  @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
17
17
 
18
+ :000_md_title log:outputString "# wind-turbine\n\n## Source files\n\n- [N3 rules](../wind-turbine.n3)\n\n" .
19
+
18
20
  # --- Sensor data ---
19
21
  :turbine1
20
22
  :label "North field turbine" ;
@@ -97,13 +99,13 @@
97
99
  :check :c1 ?C1; :c2 ?C2; :c3 ?C3; :c4 ?C4; :c5 ?C5; :c6 ?C6; :c7 ?C7; :c8 ?C8; :c9 ?C9.
98
100
  (
99
101
  "Wind turbine — Predictive maintenance\n\n"
100
- "Answer\n"
102
+ "## Answer\n"
101
103
  ?Outcome "\n\n"
102
- "Reason Why\n"
104
+ "## Reason Why\n"
103
105
  ?Label " reports vibration " ?V " against a threshold of " ?VT ", temperature " ?Temp
104
106
  " against a threshold of " ?TT ", and rotor speed " ?RPM " against a critical limit of " ?RT ". "
105
107
  ?Reason "\n\n"
106
- "Check\n"
108
+ "## Check\n"
107
109
  "C1 " ?C1 "\n"
108
110
  "C2 " ?C2 "\n"
109
111
  "C3 " ?C3 "\n"
package/eyeling.js CHANGED
@@ -9209,6 +9209,19 @@ function makeExplain(deps) {
9209
9209
  return 0;
9210
9210
  }
9211
9211
 
9212
+ function addMarkdownHardBreaks(text) {
9213
+ const normalized = String(text).replace(/\r\n/g, '\n').replace(/\r/g, '\n');
9214
+ if (!normalized.startsWith('# ')) return text;
9215
+
9216
+ return normalized
9217
+ .split('\n')
9218
+ .map((line) => {
9219
+ if (line.length === 0) return line;
9220
+ return line.replace(/[ \t]+$/g, '') + ' ';
9221
+ })
9222
+ .join('\n');
9223
+ }
9224
+
9212
9225
  function collectOutputStringsFromFacts(facts, prefixes) {
9213
9226
  // Gather all (key, string) pairs from the saturated fact store.
9214
9227
  const pairs = [];
@@ -9229,7 +9242,7 @@ function makeExplain(deps) {
9229
9242
  return a.idx - b.idx; // stable tie-breaker
9230
9243
  });
9231
9244
 
9232
- return pairs.map((p) => p.text).join('');
9245
+ return addMarkdownHardBreaks(pairs.map((p) => p.text).join(''));
9233
9246
  }
9234
9247
 
9235
9248
  return { printExplanation, collectOutputStringsFromFacts };
package/lib/explain.js CHANGED
@@ -181,6 +181,19 @@ function makeExplain(deps) {
181
181
  return 0;
182
182
  }
183
183
 
184
+ function addMarkdownHardBreaks(text) {
185
+ const normalized = String(text).replace(/\r\n/g, '\n').replace(/\r/g, '\n');
186
+ if (!normalized.startsWith('# ')) return text;
187
+
188
+ return normalized
189
+ .split('\n')
190
+ .map((line) => {
191
+ if (line.length === 0) return line;
192
+ return line.replace(/[ \t]+$/g, '') + ' ';
193
+ })
194
+ .join('\n');
195
+ }
196
+
184
197
  function collectOutputStringsFromFacts(facts, prefixes) {
185
198
  // Gather all (key, string) pairs from the saturated fact store.
186
199
  const pairs = [];
@@ -201,7 +214,7 @@ function makeExplain(deps) {
201
214
  return a.idx - b.idx; // stable tie-breaker
202
215
  });
203
216
 
204
- return pairs.map((p) => p.text).join('');
217
+ return addMarkdownHardBreaks(pairs.map((p) => p.text).join(''));
205
218
  }
206
219
 
207
220
  return { printExplanation, collectOutputStringsFromFacts };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.24.7",
3
+ "version": "1.24.9",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [
@@ -30,18 +30,44 @@ function run(cmd, args, opts = {}) {
30
30
  });
31
31
  }
32
32
 
33
- // Normalize output for comparison.
33
+ function normalizeNewlines(text) {
34
+ return String(text).replace(/\r\n/g, '\n').replace(/\r/g, '\n');
35
+ }
36
+
37
+ function stripTrailingWhitespace(text) {
38
+ return normalizeNewlines(text)
39
+ .split('\n')
40
+ .map((line) => line.replace(/[\t ]+$/g, ''))
41
+ .join('\n');
42
+ }
43
+
44
+ function normalizeTextForCompare(text) {
45
+ return stripTrailingWhitespace(text).trim();
46
+ }
47
+
48
+ function normalizeMarkdownForCompare(text) {
49
+ return normalizeNewlines(text).replace(/^\n+|\n+$/g, '');
50
+ }
51
+
52
+ // Normalize N3 output for comparison.
34
53
  // Eyeling (and other N3 tools) may emit the same closure with different
35
54
  // triple ordering. Examples tests should verify content, not presentation.
36
- function normalizeForCompare(n3Text) {
37
- return String(n3Text)
38
- .split(/\r?\n/)
39
- .map((l) => l.replace(/[\t ]+$/g, '')) // trim trailing whitespace
55
+ function normalizeN3ForCompare(n3Text) {
56
+ return stripTrailingWhitespace(n3Text)
57
+ .split('\n')
40
58
  .filter((l) => l.length > 0)
41
59
  .sort((a, b) => a.localeCompare(b))
42
60
  .join('\n');
43
61
  }
44
62
 
63
+ function normalizeForCompare(text, expectedPath) {
64
+ const ext = path.extname(expectedPath);
65
+ const value = text;
66
+ if (ext === '.md') return normalizeMarkdownForCompare(value);
67
+ if (ext === '.txt') return normalizeTextForCompare(value);
68
+ return normalizeN3ForCompare(value);
69
+ }
70
+
45
71
  // Expectation logic (robust, long-term):
46
72
  // 1) If file contains: # expect-exit: N -> use N
47
73
  // 2) Else -> expect exit 0
@@ -79,23 +105,26 @@ function showDiff({ examplesDir, expectedPath, generatedPath }) {
79
105
  }
80
106
 
81
107
  function resolveExpectedPath(outputDir, inputFile) {
82
- const exactPath = path.join(outputDir, inputFile);
83
- if (fs.existsSync(exactPath)) return exactPath;
84
-
85
108
  const stem = path.basename(inputFile, path.extname(inputFile));
109
+ const preference = new Map([
110
+ ['.md', 0],
111
+ ['.txt', 1],
112
+ ['.n3', 2],
113
+ ]);
86
114
  const candidates = fs
87
115
  .readdirSync(outputDir)
88
116
  .filter((name) => path.basename(name, path.extname(name)) === stem)
89
117
  .sort((a, b) => {
90
- if (path.extname(a) === '.txt' && path.extname(b) !== '.txt') return -1;
91
- if (path.extname(a) !== '.txt' && path.extname(b) === '.txt') return 1;
92
- return a.localeCompare(b);
118
+ const pa = preference.get(path.extname(a)) ?? 99;
119
+ const pb = preference.get(path.extname(b)) ?? 99;
120
+ return pa - pb || a.localeCompare(b);
93
121
  });
94
122
 
95
123
  if (candidates.length === 0) return null;
96
124
  return path.join(outputDir, candidates[0]);
97
125
  }
98
126
 
127
+
99
128
  function resolveExampleTrigInput(root, inputFile) {
100
129
  const stem = path.basename(inputFile, path.extname(inputFile));
101
130
  const rel = path.join('input', `${stem}.trig`);
@@ -229,13 +258,15 @@ function main() {
229
258
 
230
259
  const ms = Date.now() - start;
231
260
 
232
- // Compare output (order-insensitive)
261
+ // Compare output. N3 outputs are order-insensitive; Markdown outputs are order-sensitive.
233
262
  let diffOk = false;
234
263
  try {
235
264
  const expectedText = fs.readFileSync(expectedPath, 'utf8');
236
265
  const generatedText = fs.readFileSync(generatedPath, 'utf8');
237
266
  if (expectedText == null) throw new Error('missing expected output');
238
- diffOk = normalizeForCompare(expectedText) === normalizeForCompare(generatedText);
267
+ diffOk =
268
+ normalizeForCompare(expectedText, expectedPath) ===
269
+ normalizeForCompare(generatedText, expectedPath);
239
270
  } catch {
240
271
  diffOk = false;
241
272
  }
@@ -58,8 +58,23 @@ function runChecked(cmd, args, opts = {}) {
58
58
  return res;
59
59
  }
60
60
 
61
- function normalizeNewlines(s) {
62
- return String(s).replace(/\r\n/g, '\n');
61
+ function normalizeNewlines(text) {
62
+ return String(text).replace(/\r\n/g, '\n').replace(/\r/g, '\n');
63
+ }
64
+
65
+ function stripTrailingWhitespace(text) {
66
+ return normalizeNewlines(text)
67
+ .split('\n')
68
+ .map((line) => line.replace(/[\t ]+$/g, ''))
69
+ .join('\n');
70
+ }
71
+
72
+ function normalizeTextForCompare(text) {
73
+ return stripTrailingWhitespace(text).trim();
74
+ }
75
+
76
+ function normalizeMarkdownForCompare(text) {
77
+ return normalizeNewlines(text).replace(/^\n+|\n+$/g, '');
63
78
  }
64
79
 
65
80
  // Expectation logic (shared with test/examples.test.js):
@@ -81,6 +96,26 @@ function resolveExampleTrigInput(examplesDir, inputFile) {
81
96
  return { abs, rel };
82
97
  }
83
98
 
99
+ function resolveExpectedPath(outputDir, inputFile) {
100
+ const stem = path.basename(inputFile, path.extname(inputFile));
101
+ const preference = new Map([
102
+ ['.md', 0],
103
+ ['.txt', 1],
104
+ ['.n3', 2],
105
+ ]);
106
+ const candidates = fs
107
+ .readdirSync(outputDir)
108
+ .filter((name) => path.basename(name, path.extname(name)) === stem)
109
+ .sort((a, b) => {
110
+ const pa = preference.get(path.extname(a)) ?? 99;
111
+ const pb = preference.get(path.extname(b)) ?? 99;
112
+ return pa - pb || a.localeCompare(b);
113
+ });
114
+
115
+ if (candidates.length === 0) return null;
116
+ return path.join(outputDir, candidates[0]);
117
+ }
118
+
84
119
  function hasGit() {
85
120
  const r = run('git', ['--version']);
86
121
  return r.status === 0;
@@ -191,11 +226,11 @@ function main() {
191
226
  try {
192
227
  for (const file of SMOKE_EXAMPLES) {
193
228
  const inputPath = path.join(examplesDir, file);
194
- const expectedPath = path.join(outputDir, file);
229
+ const expectedPath = resolveExpectedPath(outputDir, file);
195
230
 
196
231
  if (!fs.existsSync(inputPath)) throw new Error(`Missing example in installed package: ${inputPath}`);
197
- if (!fs.existsSync(expectedPath))
198
- throw new Error(`Missing golden output in installed package: ${expectedPath}`);
232
+ if (!expectedPath || !fs.existsSync(expectedPath))
233
+ throw new Error(`Missing golden output in installed package for ${file}`);
199
234
 
200
235
  const n3Text = fs.readFileSync(inputPath, 'utf8');
201
236
  const expectedRc = expectedExitCode(n3Text);
@@ -229,9 +264,10 @@ ${stderr}`
229
264
  // Normalize newlines so this is stable across platforms.
230
265
  const got = normalizeNewlines(r.stdout || '');
231
266
  const exp = normalizeNewlines(fs.readFileSync(expectedPath, 'utf8'));
267
+ const compare = path.extname(expectedPath) === '.md' ? normalizeMarkdownForCompare : normalizeTextForCompare;
232
268
 
233
- if (got !== exp) {
234
- const genPath = path.join(tmpExamplesOut, file);
269
+ if (compare(got) !== compare(exp)) {
270
+ const genPath = path.join(tmpExamplesOut, path.basename(expectedPath));
235
271
  fs.writeFileSync(genPath, got, 'utf8');
236
272
  console.error(`
237
273
  Output differs for ${file}:`);
@@ -1,25 +0,0 @@
1
- ACT barley seed lineage — can and can't
2
-
3
- Answer
4
- YES for the viable barley lineage.
5
- NO for the contrast lineages when digital heredity, repair, protected dormancy, or heritable variation are missing.
6
-
7
- Reason Why
8
- The main lineage can achieve genome copying under no-design laws because its hereditary information is digitally instantiated. It can also pass through protected dormancy, germinate, produce propagules, reproduce accurately, close its life cycle, and adaptively persist under saline selection. But the contrast lineages show the "can't" side: non-digital heredity blocks accurate genome copying under no-design laws, lack of repair blocks accurate self-reproduction, lack of dormancy protection blocks lineage closure through a protected seed phase, and lack of heritable variation blocks adaptive evolution and thus blocks evolvability.
9
-
10
- Check
11
- C1 OK - no-design laws are assumed
12
- C2 OK - the viable genome can be copied under no-design laws
13
- C3 OK - the viable seed can achieve protected dormancy
14
- C4 OK - the viable seed can germinate
15
- C5 OK - the viable adult can produce propagules
16
- C6 OK - the viable lineage can achieve accurate self-reproduction
17
- C7 OK - the viable lineage can achieve lineage closure
18
- C8 OK - the viable lineage can exhibit heritable variation
19
- C9 OK - the viable lineage can adaptively persist
20
- C10 OK - the viable lineage is evolvable
21
- C11 OK - the non-digital lineage cannot achieve accurate self-reproduction
22
- C12 OK - the repair-deficient lineage cannot achieve accurate self-reproduction
23
- C13 OK - the coatless lineage cannot achieve lineage closure through protected dormancy
24
- C14 OK - the static lineage cannot achieve adaptive evolution
25
- C15 OK - the static lineage cannot be an evolvable lineage
File without changes
@@ -1,149 +0,0 @@
1
- AuroraCare — Purpose-based Medical Data Exchange
2
-
3
- === A – Primary care visit ===
4
- Clinician in the patient's care team accessing the patient summary for primary care management.
5
-
6
- Answer
7
- PERMIT
8
-
9
- Reason Why
10
- Permitted: clinician in the patient's care team, and the primary-care policy matched.
11
-
12
- Check
13
- C1 SKIPPED - not a prohibited purpose
14
- C2 OK - clinician
15
- C3 OK - care-team linked
16
- C4 SKIPPED
17
- C5 OK - operator=isAnyOf, allowed=["https://example.org/health#PATIENT_SUMMARY","https://example.org/health#LAB_RESULTS"], requested=["https://example.org/health#PATIENT_SUMMARY"]
18
- C6 SKIPPED - no prohibition matched
19
- C7 OK - trace shows matching permission
20
- C8 SKIPPED - no matched policy or no duties
21
- C9 SKIPPED - policy has no environment constraint
22
- C10 INFO - matched policy: urn:policy:primary-care-001
23
-
24
- === B – Quality improvement (in scope) ===
25
- QI analyst using lab results + summary in a secure environment.
26
-
27
- Answer
28
- PERMIT
29
-
30
- Reason Why
31
- Permitted: ODRL/DPV policy matched for secondary use.
32
-
33
- Check
34
- C1 SKIPPED - not a prohibited purpose
35
- C2 SKIPPED
36
- C3 SKIPPED
37
- C4 OK - opt-in present and policy matched
38
- C5 OK - operator=isAllOf, allowed=["https://example.org/health#LAB_RESULTS","https://example.org/health#PATIENT_SUMMARY"], requested=["https://example.org/health#LAB_RESULTS","https://example.org/health#PATIENT_SUMMARY"]
39
- C6 SKIPPED - no prohibition matched
40
- C7 OK - trace shows matching permission
41
- C8 INFO - duties attached: duty:https://w3id.org/dpv/legal/eu/ehds#requireConsent, duty:https://w3id.org/dpv/legal/eu/ehds#noExfiltration
42
- C9 OK - operator=eq, allowed="secure_env", requested="secure_env"
43
- C10 INFO - matched policy: urn:policy:qi-2025-aurora
44
-
45
- === C – Quality improvement (out of scope) ===
46
- QI analyst with only lab results; policy expects labs + summary.
47
-
48
- Answer
49
- DENY
50
-
51
- Reason Why
52
- Denied: no policy matched (purpose, environment, TOMs, or categories out of scope).
53
-
54
- Check
55
- C1 SKIPPED - not a prohibited purpose
56
- C2 SKIPPED
57
- C3 SKIPPED
58
- C4 OK - denied because opt-in missing or no policy match
59
- C5 SKIPPED
60
- C6 SKIPPED - no prohibition matched
61
- C7 SKIPPED
62
- C8 SKIPPED - no matched policy or no duties
63
- C9 SKIPPED
64
- C10 SKIPPED - no matched policy
65
-
66
- === D – Insurance management ===
67
- Insurance bot attempting to use health data for insurance management (prohibited purpose).
68
-
69
- Answer
70
- DENY
71
-
72
- Reason Why
73
- Denied: the requested purpose (insurance management) is prohibited by policy.
74
-
75
- Check
76
- C1 OK - denied prohibited purpose
77
- C2 SKIPPED
78
- C3 SKIPPED
79
- C4 SKIPPED
80
- C5 SKIPPED
81
- C6 OK - denied due to prohibition
82
- C7 SKIPPED
83
- C8 SKIPPED - no matched policy or no duties
84
- C9 SKIPPED
85
- C10 SKIPPED - no matched policy
86
-
87
- === E – GP checks labs ===
88
- GP for the same patient checking lab results via the API gateway.
89
-
90
- Answer
91
- PERMIT
92
-
93
- Reason Why
94
- Permitted: clinician in the patient's care team, and the primary-care policy matched.
95
-
96
- Check
97
- C1 SKIPPED - not a prohibited purpose
98
- C2 OK - clinician
99
- C3 OK - care-team linked
100
- C4 SKIPPED
101
- C5 OK - operator=isAnyOf, allowed=["https://example.org/health#PATIENT_SUMMARY","https://example.org/health#LAB_RESULTS"], requested=["https://example.org/health#LAB_RESULTS"]
102
- C6 SKIPPED - no prohibition matched
103
- C7 OK - trace shows matching permission
104
- C8 SKIPPED - no matched policy or no duties
105
- C9 SKIPPED - policy has no environment constraint
106
- C10 INFO - matched policy: urn:policy:primary-care-001
107
-
108
- === F – Research on anonymised dataset ===
109
- Researcher using anonymised labs + summary in a secure environment, with opt-in.
110
-
111
- Answer
112
- PERMIT
113
-
114
- Reason Why
115
- Permitted: subject opted in and an ODRL/DPV policy matched (anonymised dataset in secure environment).
116
-
117
- Check
118
- C1 SKIPPED - not a prohibited purpose
119
- C2 SKIPPED
120
- C3 SKIPPED
121
- C4 OK - opt-in present and policy matched
122
- C5 OK - operator=isAnyOf, allowed=["https://example.org/health#LAB_RESULTS","https://example.org/health#PATIENT_SUMMARY","https://example.org/health#IMAGING_REPORT"], requested=["https://example.org/health#PATIENT_SUMMARY","https://example.org/health#LAB_RESULTS"]
123
- C6 SKIPPED - no prohibition matched
124
- C7 OK - trace shows matching permission
125
- C8 INFO - duties attached: duty:https://w3id.org/dpv/legal/eu/ehds#annualOutcomeReport, duty:https://w3id.org/dpv/legal/eu/ehds#noReidentification, duty:https://w3id.org/dpv/legal/eu/ehds#noExfiltration
126
- C9 OK - operator=eq, allowed="secure_env", requested="secure_env"
127
- C10 INFO - matched policy: urn:policy:research-aurora-diabetes
128
-
129
- === G – AI training (opt-out) ===
130
- Data user wants to train AI, but the subject opted out of AI training.
131
-
132
- Answer
133
- DENY
134
-
135
- Reason Why
136
- Denied: you opted out of your data being used to train AI systems.
137
-
138
- Check
139
- C1 SKIPPED - not a prohibited purpose
140
- C2 SKIPPED
141
- C3 SKIPPED
142
- C4 OK - denied because opt-in missing or no policy match
143
- C5 SKIPPED
144
- C6 SKIPPED - no prohibition matched
145
- C7 SKIPPED
146
- C8 SKIPPED - no matched policy or no duties
147
- C9 SKIPPED
148
- C10 SKIPPED - no matched policy
149
-
@@ -1,4 +0,0 @@
1
- @prefix : <urn:example#> .
2
-
3
- :a :reaches :b .
4
- :a :reaches :c .