eyeling 1.34.5 → 1.34.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 (307) hide show
  1. package/README.md +3 -90
  2. package/bin/eyeling.cjs +4 -56
  3. package/dist/browser/eyeling.browser.js +0 -1
  4. package/examples/context-schema-audit.n3 +1 -1
  5. package/eyeling.js +0 -1
  6. package/index.d.ts +3 -37
  7. package/index.js +1 -90
  8. package/lib/cli.js +0 -1
  9. package/package.json +3 -12
  10. package/test/packlist.test.js +0 -2
  11. package/test/run.js +0 -2
  12. package/docs/eyelang-guide.md +0 -535
  13. package/docs/eyelang-language-reference.md +0 -697
  14. package/examples/eyelang/access-control-policy.pl +0 -52
  15. package/examples/eyelang/ackermann.pl +0 -46
  16. package/examples/eyelang/age.pl +0 -28
  17. package/examples/eyelang/aliases-and-namespaces.pl +0 -22
  18. package/examples/eyelang/alignment-demo.pl +0 -44
  19. package/examples/eyelang/allen-interval-calculus.pl +0 -64
  20. package/examples/eyelang/ancestor.pl +0 -21
  21. package/examples/eyelang/animal.pl +0 -21
  22. package/examples/eyelang/annotation.pl +0 -34
  23. package/examples/eyelang/auroracare.pl +0 -309
  24. package/examples/eyelang/backward.pl +0 -12
  25. package/examples/eyelang/basic-monadic.pl +0 -10032
  26. package/examples/eyelang/bayes-diagnosis.pl +0 -108
  27. package/examples/eyelang/bayes-therapy.pl +0 -182
  28. package/examples/eyelang/beam-deflection.pl +0 -50
  29. package/examples/eyelang/blocks-world-planning.pl +0 -75
  30. package/examples/eyelang/bmi.pl +0 -232
  31. package/examples/eyelang/braking-safety-worlds.pl +0 -69
  32. package/examples/eyelang/buck-converter-design.pl +0 -78
  33. package/examples/eyelang/cache-performance.pl +0 -54
  34. package/examples/eyelang/canary-release.pl +0 -49
  35. package/examples/eyelang/cat-koko.pl +0 -24
  36. package/examples/eyelang/clinical-trial-screening.pl +0 -92
  37. package/examples/eyelang/combinatorics-findall-sort.pl +0 -37
  38. package/examples/eyelang/competitive-enzyme-kinetics.pl +0 -78
  39. package/examples/eyelang/complex.pl +0 -121
  40. package/examples/eyelang/composition-of-injective-functions-is-injective.pl +0 -50
  41. package/examples/eyelang/context-association.pl +0 -53
  42. package/examples/eyelang/context-schema-audit.pl +0 -46
  43. package/examples/eyelang/control-system.pl +0 -72
  44. package/examples/eyelang/cyclic-path.pl +0 -16
  45. package/examples/eyelang/d3-group.pl +0 -100
  46. package/examples/eyelang/dairy-energy-balance.pl +0 -65
  47. package/examples/eyelang/data-negotiation.pl +0 -39
  48. package/examples/eyelang/deep-taxonomy-10.pl +0 -115
  49. package/examples/eyelang/deep-taxonomy-100.pl +0 -385
  50. package/examples/eyelang/deep-taxonomy-1000.pl +0 -3085
  51. package/examples/eyelang/deep-taxonomy-10000.pl +0 -30094
  52. package/examples/eyelang/deep-taxonomy-100000.pl +0 -300184
  53. package/examples/eyelang/delfour.pl +0 -281
  54. package/examples/eyelang/deontic-logic.pl +0 -52
  55. package/examples/eyelang/derived-backward-rule.pl +0 -30
  56. package/examples/eyelang/derived-rule.pl +0 -27
  57. package/examples/eyelang/diamond-property.pl +0 -38
  58. package/examples/eyelang/dijkstra-findall-sort.pl +0 -44
  59. package/examples/eyelang/dijkstra-risk-path.pl +0 -86
  60. package/examples/eyelang/dijkstra.pl +0 -46
  61. package/examples/eyelang/dining-philosophers.pl +0 -140
  62. package/examples/eyelang/dog.pl +0 -25
  63. package/examples/eyelang/dpv-odrl-purpose-mapping.pl +0 -46
  64. package/examples/eyelang/drone-corridor-planner.pl +0 -51
  65. package/examples/eyelang/easter-computus.pl +0 -89
  66. package/examples/eyelang/electrical-rc-filter.pl +0 -36
  67. package/examples/eyelang/epidemic-policy.pl +0 -67
  68. package/examples/eyelang/equivalence-classes-overlap-implies-same-class.pl +0 -27
  69. package/examples/eyelang/eulerian-path.pl +0 -85
  70. package/examples/eyelang/ev-range-worlds.pl +0 -82
  71. package/examples/eyelang/existential-rule.pl +0 -18
  72. package/examples/eyelang/exoplanet-validation-worlds.pl +0 -88
  73. package/examples/eyelang/expression-eval.pl +0 -43
  74. package/examples/eyelang/family-cousins.pl +0 -65
  75. package/examples/eyelang/fastpow.pl +0 -53
  76. package/examples/eyelang/fft8-numeric.pl +0 -83
  77. package/examples/eyelang/fibonacci.pl +0 -53
  78. package/examples/eyelang/field-nitrogen-balance.pl +0 -70
  79. package/examples/eyelang/flandor.pl +0 -296
  80. package/examples/eyelang/floating-point.pl +0 -23
  81. package/examples/eyelang/four-color-map.pl +0 -127
  82. package/examples/eyelang/fundamental-theorem-arithmetic.pl +0 -113
  83. package/examples/eyelang/gd-step-certified.pl +0 -158
  84. package/examples/eyelang/gdpr-compliance.pl +0 -69
  85. package/examples/eyelang/good-cobbler.pl +0 -14
  86. package/examples/eyelang/gps.pl +0 -152
  87. package/examples/eyelang/graph-reachability.pl +0 -36
  88. package/examples/eyelang/gray-code-counter.pl +0 -48
  89. package/examples/eyelang/greatest-lower-bound-uniqueness.pl +0 -28
  90. package/examples/eyelang/group-inverse-uniqueness.pl +0 -34
  91. package/examples/eyelang/hamiltonian-path.pl +0 -49
  92. package/examples/eyelang/hamming-code.pl +0 -105
  93. package/examples/eyelang/hanoi.pl +0 -20
  94. package/examples/eyelang/heat-loss.pl +0 -51
  95. package/examples/eyelang/heron-theorem.pl +0 -36
  96. package/examples/eyelang/ideal-gas-law.pl +0 -37
  97. package/examples/eyelang/illegitimate-reasoning.pl +0 -88
  98. package/examples/eyelang/knowledge-engineering-alignment-flow.pl +0 -40
  99. package/examples/eyelang/law-of-cosines.pl +0 -31
  100. package/examples/eyelang/least-squares-regression.pl +0 -81
  101. package/examples/eyelang/list-collection.pl +0 -33
  102. package/examples/eyelang/lldm.pl +0 -78
  103. package/examples/eyelang/manufacturing-quality-control.pl +0 -73
  104. package/examples/eyelang/microgrid-dispatch.pl +0 -85
  105. package/examples/eyelang/monkey-bananas.pl +0 -45
  106. package/examples/eyelang/network-sla.pl +0 -48
  107. package/examples/eyelang/newton-raphson.pl +0 -49
  108. package/examples/eyelang/nixon-diamond.pl +0 -37
  109. package/examples/eyelang/observability-log-correlation.pl +0 -34
  110. package/examples/eyelang/odrl-dpv-fpv-trust-flow.pl +0 -43
  111. package/examples/eyelang/odrl-dpv-healthcare-risk-ranked.pl +0 -266
  112. package/examples/eyelang/odrl-dpv-risk-ranked.pl +0 -320
  113. package/examples/eyelang/orbital-transfer-design.pl +0 -113
  114. package/examples/eyelang/output/access-control-policy.pl +0 -2
  115. package/examples/eyelang/output/ackermann.pl +0 -12
  116. package/examples/eyelang/output/age.pl +0 -2
  117. package/examples/eyelang/output/aliases-and-namespaces.pl +0 -5
  118. package/examples/eyelang/output/alignment-demo.pl +0 -32
  119. package/examples/eyelang/output/allen-interval-calculus.pl +0 -154
  120. package/examples/eyelang/output/ancestor.pl +0 -6
  121. package/examples/eyelang/output/animal.pl +0 -4
  122. package/examples/eyelang/output/annotation.pl +0 -4
  123. package/examples/eyelang/output/auroracare.pl +0 -117
  124. package/examples/eyelang/output/backward.pl +0 -1
  125. package/examples/eyelang/output/basic-monadic.pl +0 -1518
  126. package/examples/eyelang/output/bayes-diagnosis.pl +0 -13
  127. package/examples/eyelang/output/bayes-therapy.pl +0 -23
  128. package/examples/eyelang/output/beam-deflection.pl +0 -5
  129. package/examples/eyelang/output/blocks-world-planning.pl +0 -4
  130. package/examples/eyelang/output/bmi.pl +0 -32
  131. package/examples/eyelang/output/braking-safety-worlds.pl +0 -18
  132. package/examples/eyelang/output/buck-converter-design.pl +0 -6
  133. package/examples/eyelang/output/cache-performance.pl +0 -4
  134. package/examples/eyelang/output/canary-release.pl +0 -5
  135. package/examples/eyelang/output/cat-koko.pl +0 -3
  136. package/examples/eyelang/output/clinical-trial-screening.pl +0 -9
  137. package/examples/eyelang/output/combinatorics-findall-sort.pl +0 -2
  138. package/examples/eyelang/output/competitive-enzyme-kinetics.pl +0 -6
  139. package/examples/eyelang/output/complex.pl +0 -1
  140. package/examples/eyelang/output/composition-of-injective-functions-is-injective.pl +0 -2
  141. package/examples/eyelang/output/context-association.pl +0 -3
  142. package/examples/eyelang/output/context-schema-audit.pl +0 -12
  143. package/examples/eyelang/output/control-system.pl +0 -6
  144. package/examples/eyelang/output/cyclic-path.pl +0 -16
  145. package/examples/eyelang/output/d3-group.pl +0 -2
  146. package/examples/eyelang/output/dairy-energy-balance.pl +0 -13
  147. package/examples/eyelang/output/data-negotiation.pl +0 -1
  148. package/examples/eyelang/output/deep-taxonomy-10.pl +0 -16
  149. package/examples/eyelang/output/deep-taxonomy-100.pl +0 -16
  150. package/examples/eyelang/output/deep-taxonomy-1000.pl +0 -16
  151. package/examples/eyelang/output/deep-taxonomy-10000.pl +0 -16
  152. package/examples/eyelang/output/deep-taxonomy-100000.pl +0 -16
  153. package/examples/eyelang/output/delfour.pl +0 -31
  154. package/examples/eyelang/output/deontic-logic.pl +0 -4
  155. package/examples/eyelang/output/derived-backward-rule.pl +0 -3
  156. package/examples/eyelang/output/derived-rule.pl +0 -2
  157. package/examples/eyelang/output/diamond-property.pl +0 -4
  158. package/examples/eyelang/output/dijkstra-findall-sort.pl +0 -2
  159. package/examples/eyelang/output/dijkstra-risk-path.pl +0 -29
  160. package/examples/eyelang/output/dijkstra.pl +0 -16
  161. package/examples/eyelang/output/dining-philosophers.pl +0 -350
  162. package/examples/eyelang/output/dog.pl +0 -1
  163. package/examples/eyelang/output/dpv-odrl-purpose-mapping.pl +0 -18
  164. package/examples/eyelang/output/drone-corridor-planner.pl +0 -17
  165. package/examples/eyelang/output/easter-computus.pl +0 -30
  166. package/examples/eyelang/output/electrical-rc-filter.pl +0 -3
  167. package/examples/eyelang/output/epidemic-policy.pl +0 -14
  168. package/examples/eyelang/output/equivalence-classes-overlap-implies-same-class.pl +0 -18
  169. package/examples/eyelang/output/eulerian-path.pl +0 -3
  170. package/examples/eyelang/output/ev-range-worlds.pl +0 -19
  171. package/examples/eyelang/output/existential-rule.pl +0 -2
  172. package/examples/eyelang/output/exoplanet-validation-worlds.pl +0 -22
  173. package/examples/eyelang/output/expression-eval.pl +0 -1
  174. package/examples/eyelang/output/family-cousins.pl +0 -28
  175. package/examples/eyelang/output/fastpow.pl +0 -6
  176. package/examples/eyelang/output/fft8-numeric.pl +0 -4
  177. package/examples/eyelang/output/fibonacci.pl +0 -6
  178. package/examples/eyelang/output/field-nitrogen-balance.pl +0 -21
  179. package/examples/eyelang/output/flandor.pl +0 -43
  180. package/examples/eyelang/output/floating-point.pl +0 -9
  181. package/examples/eyelang/output/four-color-map.pl +0 -3
  182. package/examples/eyelang/output/fundamental-theorem-arithmetic.pl +0 -9
  183. package/examples/eyelang/output/gd-step-certified.pl +0 -79
  184. package/examples/eyelang/output/gdpr-compliance.pl +0 -6
  185. package/examples/eyelang/output/good-cobbler.pl +0 -1
  186. package/examples/eyelang/output/gps.pl +0 -21
  187. package/examples/eyelang/output/graph-reachability.pl +0 -3
  188. package/examples/eyelang/output/gray-code-counter.pl +0 -1
  189. package/examples/eyelang/output/greatest-lower-bound-uniqueness.pl +0 -2
  190. package/examples/eyelang/output/group-inverse-uniqueness.pl +0 -2
  191. package/examples/eyelang/output/hamiltonian-path.pl +0 -121
  192. package/examples/eyelang/output/hamming-code.pl +0 -6
  193. package/examples/eyelang/output/hanoi.pl +0 -1
  194. package/examples/eyelang/output/heat-loss.pl +0 -5
  195. package/examples/eyelang/output/heron-theorem.pl +0 -4
  196. package/examples/eyelang/output/ideal-gas-law.pl +0 -3
  197. package/examples/eyelang/output/illegitimate-reasoning.pl +0 -15
  198. package/examples/eyelang/output/knowledge-engineering-alignment-flow.pl +0 -17
  199. package/examples/eyelang/output/law-of-cosines.pl +0 -3
  200. package/examples/eyelang/output/least-squares-regression.pl +0 -5
  201. package/examples/eyelang/output/list-collection.pl +0 -3
  202. package/examples/eyelang/output/lldm.pl +0 -6
  203. package/examples/eyelang/output/manufacturing-quality-control.pl +0 -6
  204. package/examples/eyelang/output/microgrid-dispatch.pl +0 -6
  205. package/examples/eyelang/output/monkey-bananas.pl +0 -5
  206. package/examples/eyelang/output/network-sla.pl +0 -4
  207. package/examples/eyelang/output/newton-raphson.pl +0 -3
  208. package/examples/eyelang/output/nixon-diamond.pl +0 -5
  209. package/examples/eyelang/output/observability-log-correlation.pl +0 -28
  210. package/examples/eyelang/output/odrl-dpv-fpv-trust-flow.pl +0 -9
  211. package/examples/eyelang/output/odrl-dpv-healthcare-risk-ranked.pl +0 -42
  212. package/examples/eyelang/output/odrl-dpv-risk-ranked.pl +0 -120
  213. package/examples/eyelang/output/orbital-transfer-design.pl +0 -7
  214. package/examples/eyelang/output/path-discovery.pl +0 -3
  215. package/examples/eyelang/output/peano-arithmetic.pl +0 -3
  216. package/examples/eyelang/output/peasant.pl +0 -10
  217. package/examples/eyelang/output/pendulum-period.pl +0 -4
  218. package/examples/eyelang/output/polynomial.pl +0 -14
  219. package/examples/eyelang/output/proof-contrapositive.pl +0 -3
  220. package/examples/eyelang/output/quadratic-formula.pl +0 -6
  221. package/examples/eyelang/output/radioactive-decay.pl +0 -5
  222. package/examples/eyelang/output/reusable-builtins.pl +0 -5
  223. package/examples/eyelang/output/riemann-hypothesis.pl +0 -12
  224. package/examples/eyelang/output/security-incident-correlation.pl +0 -3
  225. package/examples/eyelang/output/service-impact.pl +0 -11
  226. package/examples/eyelang/output/sieve.pl +0 -1
  227. package/examples/eyelang/output/skolem-functions.pl +0 -16
  228. package/examples/eyelang/output/socket-age.pl +0 -1
  229. package/examples/eyelang/output/socket-family.pl +0 -3
  230. package/examples/eyelang/output/socrates.pl +0 -2
  231. package/examples/eyelang/output/statistics-summary.pl +0 -4
  232. package/examples/eyelang/output/superdense-coding.pl +0 -6
  233. package/examples/eyelang/output/term-tools.pl +0 -6
  234. package/examples/eyelang/output/trust-flow-provenance-threshold.pl +0 -6
  235. package/examples/eyelang/output/turing.pl +0 -12
  236. package/examples/eyelang/output/vector-similarity.pl +0 -4
  237. package/examples/eyelang/output/vulnerability-impact.pl +0 -20
  238. package/examples/eyelang/output/witch.pl +0 -7
  239. package/examples/eyelang/output/wolf-goat-cabbage.pl +0 -3
  240. package/examples/eyelang/output/zebra.pl +0 -3
  241. package/examples/eyelang/path-discovery.pl +0 -45013
  242. package/examples/eyelang/peano-arithmetic.pl +0 -31
  243. package/examples/eyelang/peasant.pl +0 -30
  244. package/examples/eyelang/pendulum-period.pl +0 -50
  245. package/examples/eyelang/polynomial.pl +0 -124
  246. package/examples/eyelang/proof/age.pl +0 -71
  247. package/examples/eyelang/proof/aliases-and-namespaces.pl +0 -78
  248. package/examples/eyelang/proof/ancestor.pl +0 -140
  249. package/examples/eyelang/proof/animal.pl +0 -68
  250. package/examples/eyelang/proof/annotation.pl +0 -80
  251. package/examples/eyelang/proof/backward.pl +0 -22
  252. package/examples/eyelang/proof/cat-koko.pl +0 -86
  253. package/examples/eyelang/proof/data-negotiation.pl +0 -76
  254. package/examples/eyelang/proof/derived-rule.pl +0 -43
  255. package/examples/eyelang/proof/dog.pl +0 -31
  256. package/examples/eyelang/proof/electrical-rc-filter.pl +0 -105
  257. package/examples/eyelang/proof/existential-rule.pl +0 -40
  258. package/examples/eyelang/proof/floating-point.pl +0 -160
  259. package/examples/eyelang/proof/good-cobbler.pl +0 -16
  260. package/examples/eyelang/proof/group-inverse-uniqueness.pl +0 -84
  261. package/examples/eyelang/proof/list-collection.pl +0 -52
  262. package/examples/eyelang/proof/proof-contrapositive.pl +0 -78
  263. package/examples/eyelang/proof/socket-age.pl +0 -32
  264. package/examples/eyelang/proof/socket-family.pl +0 -59
  265. package/examples/eyelang/proof/socrates.pl +0 -38
  266. package/examples/eyelang/proof-contrapositive.pl +0 -27
  267. package/examples/eyelang/quadratic-formula.pl +0 -54
  268. package/examples/eyelang/radioactive-decay.pl +0 -56
  269. package/examples/eyelang/reusable-builtins.pl +0 -32
  270. package/examples/eyelang/riemann-hypothesis.pl +0 -110
  271. package/examples/eyelang/security-incident-correlation.pl +0 -69
  272. package/examples/eyelang/service-impact.pl +0 -41
  273. package/examples/eyelang/sieve.pl +0 -20
  274. package/examples/eyelang/skolem-functions.pl +0 -52
  275. package/examples/eyelang/socket-age.pl +0 -39
  276. package/examples/eyelang/socket-family.pl +0 -28
  277. package/examples/eyelang/socrates.pl +0 -19
  278. package/examples/eyelang/statistics-summary.pl +0 -54
  279. package/examples/eyelang/superdense-coding.pl +0 -84
  280. package/examples/eyelang/term-tools.pl +0 -23
  281. package/examples/eyelang/trust-flow-provenance-threshold.pl +0 -40
  282. package/examples/eyelang/turing.pl +0 -67
  283. package/examples/eyelang/vector-similarity.pl +0 -56
  284. package/examples/eyelang/vulnerability-impact.pl +0 -70
  285. package/examples/eyelang/witch.pl +0 -38
  286. package/examples/eyelang/wolf-goat-cabbage.pl +0 -56
  287. package/examples/eyelang/zebra.pl +0 -44
  288. package/eyelang.d.ts +0 -80
  289. package/lib/eyelang/bin.js +0 -7
  290. package/lib/eyelang/builtins/aggregation.js +0 -81
  291. package/lib/eyelang/builtins/arithmetic.js +0 -208
  292. package/lib/eyelang/builtins/context.js +0 -42
  293. package/lib/eyelang/builtins/control.js +0 -34
  294. package/lib/eyelang/builtins/core.js +0 -78
  295. package/lib/eyelang/builtins/lists.js +0 -283
  296. package/lib/eyelang/builtins/registry.js +0 -48
  297. package/lib/eyelang/builtins/strings.js +0 -234
  298. package/lib/eyelang/builtins/terms.js +0 -66
  299. package/lib/eyelang/cli.js +0 -180
  300. package/lib/eyelang/explain.js +0 -324
  301. package/lib/eyelang/hash.js +0 -294
  302. package/lib/eyelang/index.js +0 -47
  303. package/lib/eyelang/package.json +0 -3
  304. package/lib/eyelang/parser.js +0 -428
  305. package/lib/eyelang/program.js +0 -237
  306. package/lib/eyelang/solver.js +0 -237
  307. package/lib/eyelang/term.js +0 -328
@@ -1,180 +0,0 @@
1
- // Command-line interface for eyelang.
2
- // It loads programs from files, URLs, or stdin, then materializes derived output predicates.
3
- import fs from 'node:fs/promises';
4
- import path from 'node:path';
5
- import process from 'node:process';
6
-
7
- let engineModule = null;
8
- let explanationModule = null;
9
-
10
- export async function main(argv) {
11
- if (argv.length === 0) {
12
- await usage(process.stdout);
13
- return;
14
- }
15
-
16
- const options = {
17
- files: [],
18
- proof: false,
19
- stats: false,
20
- version: false,
21
- };
22
-
23
- let endOptions = false;
24
-
25
- for (let i = 0; i < argv.length; i++) {
26
- const arg = argv[i];
27
-
28
- if (!endOptions && arg === '--') {
29
- endOptions = true;
30
- } else if (!endOptions && (arg === '--version' || arg === '-v')) {
31
- options.version = true;
32
- } else if (!endOptions && (arg === '--help' || arg === '-h')) {
33
- await usage(process.stdout);
34
- return;
35
- } else if (!endOptions && (arg === '--proof' || arg === '-p')) {
36
- options.proof = true;
37
- } else if (!endOptions && (arg === '--stats' || arg === '-s')) {
38
- options.stats = true;
39
- } else if (!endOptions && arg.startsWith('-') && arg !== '-') {
40
- throw new Error(`unknown option: ${arg}`);
41
- } else {
42
- options.files.push(arg);
43
- }
44
- }
45
-
46
- if (options.version) {
47
- process.stdout.write(`eyelang ${await packageVersion()}\n`);
48
- return;
49
- }
50
-
51
- if (options.files.length === 0) {
52
- options.files.push('-');
53
- }
54
-
55
- const sourceParts = [];
56
- let usedStdin = false;
57
-
58
- for (const file of options.files) {
59
- if (file === '-') {
60
- if (usedStdin) throw new Error("stdin input '-' can only be used once");
61
- usedStdin = true;
62
- sourceParts.push({ text: await readStdin(), filename: '<stdin>' });
63
- } else if (/^https?:\/\//.test(file)) {
64
- const response = await fetch(file);
65
- if (!response.ok) throw new Error(`could not fetch URL: ${file}`);
66
- sourceParts.push({ text: await response.text(), filename: file });
67
- } else {
68
- sourceParts.push({ text: await fs.readFile(file, 'utf8'), filename: path.basename(file) || file });
69
- }
70
- }
71
-
72
- const engine = await loadEngine();
73
- const program = engine.Program.parseSources(sourceParts, { sourceMetadata: options.proof, markRecursive: options.proof });
74
-
75
- await runDefault(engine, program, options);
76
- }
77
-
78
- async function loadEngine() {
79
- if (engineModule == null) {
80
- const [term, program, solver, registry] = await Promise.all([
81
- import('./term.js'),
82
- import('./program.js'),
83
- import('./solver.js'),
84
- import('./builtins/registry.js'),
85
- ]);
86
- engineModule = { ...term, ...program, ...solver, ...registry };
87
- }
88
- return engineModule;
89
- }
90
-
91
- async function loadExplanation() {
92
- if (explanationModule == null) explanationModule = await import('./explain.js');
93
- return explanationModule;
94
- }
95
-
96
- async function runDefault(engine, program, options) {
97
- const goals = program.materializationGoals();
98
- const materializedKeys = new Set(goals.map((goal) => `${goal.name}/${goal.arity}`));
99
- const facts = program.sourceFactLines(materializedKeys);
100
- const lines = new Set();
101
- let lastStats = null;
102
- const registry = engine.getDefaultRegistry();
103
- const explanation = options.proof ? await loadExplanation() : null;
104
-
105
- for (const goal of goals) {
106
- const solver = new engine.Solver(program, { registry });
107
-
108
- for (const env of solver.solve([goal], new engine.Env(), 0)) {
109
- if (!engine.termIsGround(goal, env)) continue;
110
-
111
- const line = `${engine.termToString(goal, env, true)}.\n`;
112
- if (facts.has(line) || lines.has(line)) continue;
113
-
114
- lines.add(line);
115
-
116
- process.stdout.write(line);
117
- if (options.proof) writeExplanation(explanation, program, engine.copyResolved(goal, env), registry);
118
- }
119
-
120
- lastStats = solver.stats;
121
- }
122
-
123
- if (options.stats && lastStats) printStats(lastStats);
124
- }
125
-
126
- function writeExplanation(explanation, program, resolved, registry) {
127
- const proof = explanation.whyProof(program, resolved, { registry });
128
- process.stdout.write(proof.text);
129
- if (!proof.ok) process.stdout.write(explanation.whyNoProof(resolved));
130
- }
131
-
132
- async function usage(stream) {
133
- stream.write(`eyelang ${await packageVersion()}
134
-
135
- Usage:
136
- eyelang [options] [file-or-url.pl|- ...]
137
-
138
- Input:
139
- file-or-url.pl Read an eyelang program from a local file or http(s) URL.
140
- - Read an eyelang program from standard input.
141
-
142
- Options:
143
- -h, --help Show this help text and exit.
144
- -p, --proof Enable proof explanations.
145
- -s, --stats Print solver statistics to stderr after execution.
146
- -v, --version Show the package version and exit.
147
- -- Stop option parsing; following arguments are treated as files.
148
- `);
149
- }
150
-
151
- function readStdin() {
152
- return new Promise((resolve, reject) => {
153
- let data = '';
154
- process.stdin.setEncoding('utf8');
155
- process.stdin.on('data', (chunk) => {
156
- data += chunk;
157
- });
158
- process.stdin.on('end', () => resolve(data));
159
- process.stdin.on('error', reject);
160
- });
161
- }
162
-
163
- function printStats(stats) {
164
- process.stderr.write('eyelang stats:\n');
165
- for (const [key, value] of Object.entries(stats)) {
166
- process.stderr.write(` ${key}: ${value}\n`);
167
- }
168
- }
169
-
170
- async function packageVersion() {
171
- try {
172
- const text = await fs.readFile(new URL('../../package.json', import.meta.url), 'utf8');
173
- const pkg = JSON.parse(text);
174
- if (pkg && typeof pkg.version === 'string' && pkg.version) return pkg.version;
175
- } catch (_) {
176
- // Fall through to a stable marker if package metadata is unavailable.
177
- }
178
-
179
- return 'unknown';
180
- }
@@ -1,324 +0,0 @@
1
- // eyelang proof output helpers.
2
- // The explanation printer replays a successful goal against the program and emits
3
- // ordinary eyelang facts with nested proof terms. Explanations are therefore both
4
- // human-readable and machine-readable.
5
- import { COMPOUND, Env, Term, VAR, deref, flattenConjunction, freshTerm, termToString, unify, variantTerms } from './term.js';
6
- import { selectClauseCandidates } from './program.js';
7
- import { createDefaultRegistry } from './builtins/registry.js';
8
- import { Solver, nextFreshId } from './solver.js';
9
-
10
- export function whyProof(program, goal, options = {}) {
11
- const maxDepth = options.maxDepth ?? 256;
12
- const registry = options.registry ?? createDefaultRegistry();
13
- const env = options.env ?? new Env();
14
- for (const proof of proveGoalAll(program, goal, env, 0, maxDepth, registry, [])) {
15
- return { ok: true, text: renderWhyFacts(goal, proof.node, proof.env) };
16
- }
17
- return { ok: false, text: '' };
18
- }
19
-
20
- export function whyNoProof(goal) {
21
- return renderWhyNoProof(goal);
22
- }
23
-
24
- // Kept for embedders that already import explainProof. The CLI exposes machine-readable output through whyProof.
25
- export function explainProof(program, goal, options = {}) {
26
- return whyProof(program, goal, options);
27
- }
28
-
29
- function* proveGoalAll(program, goal, env, depth, maxDepth, registry, active) {
30
- if (depth > maxDepth) return;
31
-
32
- if (goal.type === COMPOUND && goal.name === ',' && goal.arity === 2) {
33
- for (const proved of proveGoalsAll(program, flattenConjunction(goal), env, depth + 1, maxDepth, registry, active)) {
34
- yield {
35
- env: proved.env,
36
- node: {
37
- goal: resolveForProof(goal, proved.env),
38
- method: 'conjunction',
39
- sourceHead: null,
40
- sourceBody: flattenConjunction(goal),
41
- bindings: [],
42
- children: proved.children,
43
- },
44
- };
45
- }
46
- return;
47
- }
48
-
49
- const builtin = builtinDefinition(program, goal, env, registry);
50
- if (builtin.handled) {
51
- for (const next of builtinEnvs(builtin.def, builtin.solver, goal, env)) {
52
- const proofEnv = next.clone ? next.clone() : next;
53
- yield {
54
- env: proofEnv,
55
- node: {
56
- goal: resolveForProof(goal, proofEnv),
57
- method: builtinMethod(goal),
58
- sourceHead: resolveForProof(goal, proofEnv),
59
- sourceBody: [],
60
- bindings: [],
61
- children: builtinChildren(program, goal, proofEnv, depth + 1, maxDepth, registry, active),
62
- },
63
- };
64
- }
65
- return;
66
- }
67
-
68
- if (goal.type !== COMPOUND) return;
69
-
70
- const group = program.findGroup(goal.name, goal.arity);
71
- if (!group) return;
72
- if (!group.memoized && activeVariant(goal, env, active)) return;
73
-
74
- const candidates = selectClauseCandidates(group, goal, env);
75
- for (const pass of [candidates.primary, candidates.fallback]) {
76
- for (const clause of pass) {
77
- const id = nextFreshId();
78
- const freshHead = freshTerm(clause.head, id);
79
- const freshBody = clause.body.map((term) => freshTerm(term, id));
80
- const next = env.clone();
81
- if (!unify(goal, freshHead, next)) continue;
82
-
83
- const substitutions = collectClauseSubstitutions(clause, freshHead, freshBody);
84
- const bindings = resolvedSubstitutions(substitutions, next);
85
-
86
- if (freshBody.length === 0) {
87
- yield {
88
- env: next,
89
- node: {
90
- goal: resolveForProof(goal, next),
91
- method: sourceMethod(clause, 'fact'),
92
- sourceHead: clause.head,
93
- sourceBody: [],
94
- bindings,
95
- children: [],
96
- },
97
- };
98
- continue;
99
- }
100
-
101
- let activePushed = true;
102
- active.push({ goal, env });
103
- try {
104
- for (const proved of proveGoalsAll(program, freshBody, next, depth + 1, maxDepth, registry, active)) {
105
- active.pop();
106
- activePushed = false;
107
- yield {
108
- env: proved.env,
109
- node: {
110
- goal: resolveForProof(goal, proved.env),
111
- method: sourceMethod(clause, 'rule'),
112
- sourceHead: clause.head,
113
- sourceBody: clause.body,
114
- bindings: resolvedSubstitutions(substitutions, proved.env),
115
- children: proved.children,
116
- },
117
- };
118
- active.push({ goal, env });
119
- activePushed = true;
120
- }
121
- } finally {
122
- if (activePushed) active.pop();
123
- }
124
- }
125
- }
126
- }
127
-
128
- function* proveGoalsAll(program, goals, env, depth, maxDepth, registry, active) {
129
- if (goals.length === 0) {
130
- yield { env: env.clone(), children: [] };
131
- return;
132
- }
133
-
134
- const selectedIndex = selectReadyDeterministicBuiltin(goals, env, registry);
135
- const goal = goals[selectedIndex];
136
- const rest = selectedIndex === 0 ? goals.slice(1) : [...goals.slice(0, selectedIndex), ...goals.slice(selectedIndex + 1)];
137
-
138
- for (const proved of proveGoalAll(program, goal, env, depth, maxDepth, registry, active)) {
139
- for (const tail of proveGoalsAll(program, rest, proved.env, depth, maxDepth, registry, active)) {
140
- const children = tail.children.slice();
141
- children.splice(selectedIndex, 0, proved.node);
142
- yield { env: tail.env, children };
143
- }
144
- }
145
- }
146
-
147
- function builtinDefinition(program, goal, env, registry) {
148
- if (goal.type !== COMPOUND) return { handled: false, def: null, solver: null };
149
- const def = registry.get(goal.name, goal.arity);
150
- if (!def) return { handled: false, def: null, solver: null };
151
-
152
- const solver = new Solver(program, { registry });
153
- if (!builtinIsUsedForGoal(def, solver, goal, env)) return { handled: false, def: null, solver: null };
154
- return { handled: true, def, solver };
155
- }
156
-
157
- function* builtinEnvs(def, solver, goal, env) {
158
- for (const next of def.handler({ solver, goal, env })) yield next;
159
- }
160
-
161
- function builtinIsUsedForGoal(def, solver, goal, env) {
162
- if (typeof def.shouldUse === 'function' && !def.shouldUse({ solver, goal, env })) return false;
163
- if (typeof def.ready !== 'function') return true;
164
- if (def.ready(goal, env)) return true;
165
- return !def.fallbackWhenNotReady;
166
- }
167
-
168
- function selectReadyDeterministicBuiltin(goals, env, registry) {
169
- for (let i = 0; i < goals.length; i++) {
170
- const goal = goals[i];
171
- if (goal.type !== COMPOUND) continue;
172
- const def = registry.get(goal.name, goal.arity);
173
- if (!def?.deterministic || typeof def.ready !== 'function') continue;
174
- if (typeof def.shouldUse === 'function') continue;
175
- if (def.ready(goal, env)) return i;
176
- }
177
- return 0;
178
- }
179
-
180
- function builtinChildren(program, goal, env, depth, maxDepth, registry, active) {
181
- if (goal.type !== COMPOUND) return [];
182
- if (goal.name === 'once' && goal.arity === 1) {
183
- for (const proved of proveGoalAll(program, goal.args[0], env.clone(), depth, maxDepth, registry, active)) return [proved.node];
184
- }
185
- return [];
186
- }
187
-
188
- function activeVariant(goal, env, active) {
189
- return active.some((entry) => variantTerms(goal, env, entry.goal, entry.env));
190
- }
191
-
192
- function sourceMethod(clause, kind) {
193
- const source = clause.source ?? {};
194
- return {
195
- type: 'source',
196
- kind,
197
- filename: source.filename ?? '<input>',
198
- clause: source.clause ?? ((clause.index ?? 0) + 1),
199
- };
200
- }
201
-
202
- function builtinMethod(goal) {
203
- return {
204
- type: 'builtin',
205
- name: goal.type === COMPOUND ? goal.name : 'goal',
206
- arity: goal.type === COMPOUND ? goal.arity : 0,
207
- };
208
- }
209
-
210
- function renderMethodTerm(method) {
211
- if (method && method.type === 'source') return `${method.kind}(${quoteString(method.filename)}, clause(${method.clause}))`;
212
- if (method && method.type === 'builtin') return `builtin(${quoteAtomText(method.name)}, ${method.arity})`;
213
- return String(method);
214
- }
215
-
216
- function renderWhyFacts(answerGoal, rootNode, env) {
217
- const answer = termToString(resolveForProof(answerGoal, env), new Env(), true);
218
- return renderWhyTerm(answer, renderAbstractProofTerm(rootNode, 1));
219
- }
220
-
221
- function renderWhyNoProof(goal) {
222
- const answer = termToString(resolveForProof(goal, new Env()), new Env(), true);
223
- return renderWhyTerm(answer, `${indent(1)}no_proof`);
224
- }
225
-
226
- function renderWhyTerm(answer, proofTerm) {
227
- return ['why(', `${indent(1)}${answer},`, proofTerm, ').', '', ''].join('\n');
228
- }
229
-
230
- function renderAbstractProofTerm(node, level) {
231
- const goal = termToString(node.goal, new Env(), true);
232
- const hasTail = node.bindings.length || node.children.length;
233
- const lines = [
234
- `${indent(level)}proof(`,
235
- `${indent(level + 1)}goal(${goal}),`,
236
- `${indent(level + 1)}by(${renderMethodTerm(node.method)})${hasTail ? ',' : ''}`,
237
- ];
238
-
239
- if (node.bindings.length) lines.push(`${indent(level + 1)}${renderBindingsTerm(node.bindings)}${node.children.length ? ',' : ''}`);
240
- if (node.children.length) lines.push(renderUsesTerm(node.children, level + 1));
241
-
242
- lines.push(`${indent(level)})`);
243
- return lines.join('\n');
244
- }
245
-
246
- function renderUsesTerm(children, level) {
247
- const lines = [`${indent(level)}uses([`];
248
- for (let i = 0; i < children.length; i++) {
249
- const item = renderAbstractProofTerm(children[i], level + 1);
250
- lines.push(i === children.length - 1 ? item : withTrailingComma(item));
251
- }
252
- lines.push(`${indent(level)}])`);
253
- return lines.join('\n');
254
- }
255
-
256
- function renderBindingsTerm(bindings) {
257
- return `bindings(${renderProofListInline(bindings, binding => `binding(${quoteString(binding.name)}, ${termToString(binding.value, new Env(), true)})`)})`;
258
- }
259
-
260
- function renderProofListInline(items, renderItem) {
261
- return `[${items.map(item => renderItem(item)).join(', ')}]`;
262
- }
263
-
264
- function withTrailingComma(text) {
265
- const lines = String(text).split('\n');
266
- lines[lines.length - 1] += ',';
267
- return lines.join('\n');
268
- }
269
-
270
- function indent(level) {
271
- return ' '.repeat(level);
272
- }
273
-
274
- function quoteAtomText(text) {
275
- return termToString({ type: 'atom', name: String(text), args: [] }, new Env(), true);
276
- }
277
-
278
- function quoteString(value) {
279
- return JSON.stringify(String(value));
280
- }
281
-
282
- function originalVariableName(name) {
283
- return String(name).replace(/#\d+$/, '');
284
- }
285
-
286
- function resolveForProof(term, env) {
287
- const resolved = deref(term, env);
288
- if (resolved.type === VAR) return new Term(VAR, originalVariableName(resolved.name), []);
289
- return new Term(resolved.type, resolved.name, resolved.args.map((arg) => resolveForProof(arg, env)));
290
- }
291
-
292
- function collectClauseSubstitutions(clause, freshHead, freshBody) {
293
- const substitutions = [];
294
- const seen = new Set();
295
- collectSubstitutions(clause.head, freshHead, substitutions, seen);
296
- for (let i = 0; i < clause.body.length && i < freshBody.length; i++) {
297
- collectSubstitutions(clause.body[i], freshBody[i], substitutions, seen);
298
- }
299
- return substitutions;
300
- }
301
-
302
- function collectSubstitutions(original, fresh, substitutions, seen) {
303
- if (!original || !fresh) return;
304
- if (original.type === VAR) {
305
- if (!seen.has(original.name)) {
306
- seen.add(original.name);
307
- substitutions.push({ name: original.name, fresh });
308
- }
309
- return;
310
- }
311
- if (original.type !== COMPOUND || fresh.type !== COMPOUND) return;
312
- const arity = Math.min(original.arity, fresh.arity);
313
- for (let i = 0; i < arity; i++) collectSubstitutions(original.args[i], fresh.args[i], substitutions, seen);
314
- }
315
-
316
- function resolvedSubstitutions(substitutions, env) {
317
- const out = [];
318
- for (const substitution of substitutions) {
319
- const resolved = deref(substitution.fresh, env);
320
- if (resolved.type === VAR) continue;
321
- out.push({ name: substitution.name, value: resolveForProof(substitution.fresh, env) });
322
- }
323
- return out;
324
- }