eyeprolog 1.5.1 → 1.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/index.d.ts +6 -0
- package/package.json +3 -2
- package/src/cli.js +1 -1
- package/src/index.js +3 -0
- package/src/library-autoload-index.js +346 -0
- package/src/program.js +37 -15
- package/src/repl.js +38 -3
- package/src/solver.js +7 -6
- package/src/standard-library.js +11 -6
- package/test/conformance/ISO-IMPLEMENTATION-DEFINED.md +1 -1
- package/test/run-regression.mjs +115 -8
- package/the-art-of-eyeprolog.md +88 -53
- package/tools/generate-library-autoload-index.mjs +107 -0
- package/why-eyeprolog.md +8 -0
package/README.md
CHANGED
|
@@ -31,8 +31,6 @@ Run EyeProlog without installing it globally:
|
|
|
31
31
|
|
|
32
32
|
```sh
|
|
33
33
|
npx --yes eyeprolog
|
|
34
|
-
?- use_module(library(lists)).
|
|
35
|
-
true.
|
|
36
34
|
?- member(X, [prolog, logic]).
|
|
37
35
|
X = prolog
|
|
38
36
|
; X = logic.
|
|
@@ -63,7 +61,9 @@ printf 'human(socrates).\nmortal(X) :- human(X).\n' |
|
|
|
63
61
|
Normal mode executes top-level `Conclusion :+ Premise` rules natively when no explicit
|
|
64
62
|
`-g/--goal` is supplied. `true :+ Goal` prints answers and `false :+ Goal` emits a
|
|
65
63
|
`fuse/1`; JavaScript `run()` follows the same rule. Strict ISO mode disables this
|
|
66
|
-
extension.
|
|
64
|
+
extension. Bundled `src/lib/` predicates autoload in files, CLI/API goals, and the REPL;
|
|
65
|
+
use `--no-autoload` to require explicit imports, and explicitly import libraries that introduce
|
|
66
|
+
operators before using their syntax. See [*The Art of EyeProlog*](the-art-of-eyeprolog.md) for the full semantics.
|
|
67
67
|
|
|
68
68
|
## Links
|
|
69
69
|
|
package/index.d.ts
CHANGED
|
@@ -289,6 +289,9 @@ export const eyePrologLibraryIndicators: readonly string[];
|
|
|
289
289
|
export const eyePrologNativeLibraryIndicators: readonly string[];
|
|
290
290
|
export const eyePrologPortableLibraryIndicators: readonly string[];
|
|
291
291
|
export const eyePrologInteropAutoload: Readonly<Record<string, string>>;
|
|
292
|
+
export const eyePrologLibraryAutoload: Readonly<Record<string, string>>;
|
|
293
|
+
export const eyePrologAmbiguousLibraryAutoload: Readonly<Record<string, readonly string[]>>;
|
|
294
|
+
export const eyePrologLibraryAutoloadModules: readonly string[];
|
|
292
295
|
export const eyePrologInteropLibraryIndicators: readonly string[];
|
|
293
296
|
export const eyePrologInteropLibraryModules: readonly string[];
|
|
294
297
|
export class PrologError extends Error {
|
|
@@ -374,6 +377,9 @@ declare const eyeprolog: {
|
|
|
374
377
|
eyePrologNativeLibraryIndicators: typeof eyePrologNativeLibraryIndicators;
|
|
375
378
|
eyePrologPortableLibraryIndicators: typeof eyePrologPortableLibraryIndicators;
|
|
376
379
|
eyePrologInteropAutoload: typeof eyePrologInteropAutoload;
|
|
380
|
+
eyePrologLibraryAutoload: typeof eyePrologLibraryAutoload;
|
|
381
|
+
eyePrologAmbiguousLibraryAutoload: typeof eyePrologAmbiguousLibraryAutoload;
|
|
382
|
+
eyePrologLibraryAutoloadModules: typeof eyePrologLibraryAutoloadModules;
|
|
377
383
|
eyePrologInteropLibraryIndicators: typeof eyePrologInteropLibraryIndicators;
|
|
378
384
|
eyePrologInteropLibraryModules: typeof eyePrologInteropLibraryModules;
|
|
379
385
|
run: typeof run;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.5.
|
|
6
|
+
"version": "1.5.3",
|
|
7
7
|
"description": "EyeProlog turns facts and rules into answers and proofs.",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"main": "./index.js",
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"test": "node test/run-all.mjs",
|
|
49
|
-
"generate": "node tools/extract-book-examples.mjs",
|
|
49
|
+
"generate": "node tools/generate-library-autoload-index.mjs && node tools/extract-book-examples.mjs",
|
|
50
|
+
"generate:autoload": "node tools/generate-library-autoload-index.mjs",
|
|
50
51
|
"test:eyeprolog": "node test/run-all.mjs",
|
|
51
52
|
"test:conformance": "node test/run-conformance.mjs",
|
|
52
53
|
"test:iso-strict": "node test/run-iso-strict.mjs",
|
package/src/cli.js
CHANGED
|
@@ -281,7 +281,7 @@ Options:
|
|
|
281
281
|
--iso-strict Use ISO/IEC 13211-1 core + Corrigenda 1-3 only;
|
|
282
282
|
reject EyeProlog language extensions.
|
|
283
283
|
--portable Enforce the EyeProlog/Trealla/Scryer interop profile.
|
|
284
|
-
--no-autoload Disable
|
|
284
|
+
--no-autoload Disable bundled library predicate autoloading.
|
|
285
285
|
-v, --version Show the package version and exit.
|
|
286
286
|
-w, --warnings Print non-fatal portability warnings to stderr.
|
|
287
287
|
-g, --goal goal Solve goal and print its ground answers; may be repeated.
|
package/src/index.js
CHANGED
|
@@ -21,6 +21,9 @@ export {
|
|
|
21
21
|
eyePrologNativeLibraryIndicators,
|
|
22
22
|
eyePrologPortableLibraryIndicators,
|
|
23
23
|
eyePrologInteropAutoload,
|
|
24
|
+
eyePrologLibraryAutoload,
|
|
25
|
+
eyePrologAmbiguousLibraryAutoload,
|
|
26
|
+
eyePrologLibraryAutoloadModules,
|
|
24
27
|
eyePrologInteropLibraryIndicators,
|
|
25
28
|
eyePrologInteropLibraryModules,
|
|
26
29
|
} from './standard-library.js';
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
// Generated by tools/generate-library-autoload-index.mjs.
|
|
2
|
+
// Do not edit by hand; module/2 export lists under src/lib/ are the source of truth.
|
|
3
|
+
|
|
4
|
+
export const eyePrologLibraryAutoload = Object.freeze({
|
|
5
|
+
",/3": "reif",
|
|
6
|
+
";/3": "reif",
|
|
7
|
+
".../2": "iso_ext",
|
|
8
|
+
"*/1": "debug",
|
|
9
|
+
"\\/1": "lambda",
|
|
10
|
+
"\\/2": "lambda",
|
|
11
|
+
"\\/3": "lambda",
|
|
12
|
+
"\\/4": "lambda",
|
|
13
|
+
"\\/5": "lambda",
|
|
14
|
+
"\\/6": "lambda",
|
|
15
|
+
"\\/7": "lambda",
|
|
16
|
+
"\\/8": "lambda",
|
|
17
|
+
"#/\\/2": "clpz",
|
|
18
|
+
"#\\//2": "clpz",
|
|
19
|
+
"#\\/1": "clpz",
|
|
20
|
+
"#\\/2": "clpz",
|
|
21
|
+
"#\\=/2": "clpz",
|
|
22
|
+
"#</2": "clpz",
|
|
23
|
+
"#</3": "clpz",
|
|
24
|
+
"#<==/2": "clpz",
|
|
25
|
+
"#<==>/2": "clpz",
|
|
26
|
+
"#=/2": "clpz",
|
|
27
|
+
"#=/3": "clpz",
|
|
28
|
+
"#=</2": "clpz",
|
|
29
|
+
"#==>/2": "clpz",
|
|
30
|
+
"#>/2": "clpz",
|
|
31
|
+
"#>=/2": "clpz",
|
|
32
|
+
"^/10": "lambda",
|
|
33
|
+
"^/3": "lambda",
|
|
34
|
+
"^/4": "lambda",
|
|
35
|
+
"^/5": "lambda",
|
|
36
|
+
"^/6": "lambda",
|
|
37
|
+
"^/7": "lambda",
|
|
38
|
+
"^/8": "lambda",
|
|
39
|
+
"^/9": "lambda",
|
|
40
|
+
"+\\/2": "lambda",
|
|
41
|
+
"+\\/3": "lambda",
|
|
42
|
+
"+\\/4": "lambda",
|
|
43
|
+
"+\\/5": "lambda",
|
|
44
|
+
"+\\/6": "lambda",
|
|
45
|
+
"+\\/7": "lambda",
|
|
46
|
+
"+\\/8": "lambda",
|
|
47
|
+
"+\\/9": "lambda",
|
|
48
|
+
"=/3": "reif",
|
|
49
|
+
"$-/1": "debug",
|
|
50
|
+
"$/1": "debug",
|
|
51
|
+
"abolish_all_tables/0": "tabling",
|
|
52
|
+
"add_edges/3": "ugraphs",
|
|
53
|
+
"add_vertices/3": "ugraphs",
|
|
54
|
+
"aggregate_max/5": "aggregate",
|
|
55
|
+
"aggregate_min/5": "aggregate",
|
|
56
|
+
"all_different/1": "clpz",
|
|
57
|
+
"all_distinct/1": "clpz",
|
|
58
|
+
"append/2": "lists",
|
|
59
|
+
"append/3": "lists",
|
|
60
|
+
"assoc_to_keys/2": "assoc",
|
|
61
|
+
"assoc_to_list/2": "assoc",
|
|
62
|
+
"assoc_to_values/2": "assoc",
|
|
63
|
+
"atom_si/1": "si",
|
|
64
|
+
"atom_string/2": "strings",
|
|
65
|
+
"atomic_si/1": "si",
|
|
66
|
+
"automaton/3": "clpz",
|
|
67
|
+
"automaton/8": "clpz",
|
|
68
|
+
"bb_b_put/2": "debug",
|
|
69
|
+
"bb_get/2": "debug",
|
|
70
|
+
"bb_global_get/2": "debug",
|
|
71
|
+
"bb_put/2": "debug",
|
|
72
|
+
"between/3": "between",
|
|
73
|
+
"call_nth/2": "iso_ext",
|
|
74
|
+
"call_residue_vars/2": "atts",
|
|
75
|
+
"call_with_error_context/2": "error",
|
|
76
|
+
"can_be/2": "error",
|
|
77
|
+
"cfor/3": "iso_ext",
|
|
78
|
+
"chain/2": "clpz",
|
|
79
|
+
"char_type/2": "charsio",
|
|
80
|
+
"character_si/1": "si",
|
|
81
|
+
"chars_si/1": "si",
|
|
82
|
+
"circuit/1": "clpz",
|
|
83
|
+
"clpz_t/2": "clpz",
|
|
84
|
+
"complement/2": "ugraphs",
|
|
85
|
+
"compose/3": "ugraphs",
|
|
86
|
+
"cond_t/3": "reif",
|
|
87
|
+
"connect_ugraph/3": "ugraphs",
|
|
88
|
+
"contains/2": "strings",
|
|
89
|
+
"copy_term_nat/2": "terms",
|
|
90
|
+
"countall/2": "iso_ext",
|
|
91
|
+
"cumulative/1": "clpz",
|
|
92
|
+
"cumulative/2": "clpz",
|
|
93
|
+
"current_time/1": "time",
|
|
94
|
+
"debug/1": "debug",
|
|
95
|
+
"debug/3": "debug",
|
|
96
|
+
"del_assoc/4": "assoc",
|
|
97
|
+
"del_attr/2": "atts",
|
|
98
|
+
"del_edges/3": "ugraphs",
|
|
99
|
+
"del_max_assoc/4": "assoc",
|
|
100
|
+
"del_min_assoc/4": "assoc",
|
|
101
|
+
"del_vertices/3": "ugraphs",
|
|
102
|
+
"dif_si/2": "si",
|
|
103
|
+
"dif/2": "dif",
|
|
104
|
+
"dif/3": "reif",
|
|
105
|
+
"difference/3": "dates",
|
|
106
|
+
"disjoint2/1": "clpz",
|
|
107
|
+
"domain_error/2": "error",
|
|
108
|
+
"domain_error/3": "error",
|
|
109
|
+
"drop/3": "lists",
|
|
110
|
+
"edges/2": "ugraphs",
|
|
111
|
+
"element/3": "clpz",
|
|
112
|
+
"empty_assoc/1": "assoc",
|
|
113
|
+
"fd_dom/2": "clpz",
|
|
114
|
+
"fd_inf/2": "clpz",
|
|
115
|
+
"fd_size/2": "clpz",
|
|
116
|
+
"fd_sup/2": "clpz",
|
|
117
|
+
"fd_var/1": "clpz",
|
|
118
|
+
"findall/4": "iso_ext",
|
|
119
|
+
"foldl/4": "lists",
|
|
120
|
+
"foldl/5": "lists",
|
|
121
|
+
"foldl/6": "lists",
|
|
122
|
+
"forall/2": "iso_ext",
|
|
123
|
+
"format_/4": "format",
|
|
124
|
+
"format_time/4": "time",
|
|
125
|
+
"format/2": "format",
|
|
126
|
+
"format/3": "format",
|
|
127
|
+
"freeze/2": "freeze",
|
|
128
|
+
"ge/2": "comparison",
|
|
129
|
+
"gen_assoc/3": "assoc",
|
|
130
|
+
"gen_int/1": "between",
|
|
131
|
+
"gen_nat/1": "between",
|
|
132
|
+
"gensym/2": "gensym",
|
|
133
|
+
"get_assoc/3": "assoc",
|
|
134
|
+
"get_assoc/5": "assoc",
|
|
135
|
+
"get_attr/3": "atts",
|
|
136
|
+
"get_atts/2": "atts",
|
|
137
|
+
"get_line_to_chars/3": "charsio",
|
|
138
|
+
"get_n_chars/3": "charsio",
|
|
139
|
+
"get_single_char/1": "charsio",
|
|
140
|
+
"global_cardinality/2": "clpz",
|
|
141
|
+
"global_cardinality/3": "clpz",
|
|
142
|
+
"group_pairs_by_key/2": "pairs",
|
|
143
|
+
"gt/2": "comparison",
|
|
144
|
+
"if_/3": "reif",
|
|
145
|
+
"in/2": "clpz",
|
|
146
|
+
"indomain/1": "clpz",
|
|
147
|
+
"ins/2": "clpz",
|
|
148
|
+
"instantiation_error/0": "error",
|
|
149
|
+
"instantiation_error/1": "error",
|
|
150
|
+
"integer_si/1": "si",
|
|
151
|
+
"is_assoc/1": "assoc",
|
|
152
|
+
"is_ordset/1": "ordsets",
|
|
153
|
+
"join/3": "strings",
|
|
154
|
+
"label/1": "clpz",
|
|
155
|
+
"labeling/1": "clpb",
|
|
156
|
+
"labeling/2": "clpz",
|
|
157
|
+
"last/2": "lists",
|
|
158
|
+
"le/2": "comparison",
|
|
159
|
+
"length/2": "lists",
|
|
160
|
+
"lex_chain/1": "clpz",
|
|
161
|
+
"list_max/2": "lists",
|
|
162
|
+
"list_min/2": "lists",
|
|
163
|
+
"list_si/1": "si",
|
|
164
|
+
"list_to_assoc/2": "assoc",
|
|
165
|
+
"list_to_ord_set/2": "ordsets",
|
|
166
|
+
"list_to_set/2": "lists",
|
|
167
|
+
"listing/1": "format",
|
|
168
|
+
"lowercase/2": "strings",
|
|
169
|
+
"lsb/2": "arithmetic",
|
|
170
|
+
"lt/2": "comparison",
|
|
171
|
+
"map_assoc/2": "assoc",
|
|
172
|
+
"map_assoc/3": "assoc",
|
|
173
|
+
"map_list_to_pairs/3": "pairs",
|
|
174
|
+
"maplist/2": "lists",
|
|
175
|
+
"maplist/3": "lists",
|
|
176
|
+
"maplist/4": "lists",
|
|
177
|
+
"maplist/5": "lists",
|
|
178
|
+
"maplist/6": "lists",
|
|
179
|
+
"maplist/7": "lists",
|
|
180
|
+
"maplist/8": "lists",
|
|
181
|
+
"matches/2": "strings",
|
|
182
|
+
"matches/3": "strings",
|
|
183
|
+
"max_assoc/3": "assoc",
|
|
184
|
+
"max_list/2": "lists",
|
|
185
|
+
"maybe/0": "random",
|
|
186
|
+
"member/2": "lists",
|
|
187
|
+
"memberchk/2": "lists",
|
|
188
|
+
"memberd_t/3": "reif",
|
|
189
|
+
"min_assoc/3": "assoc",
|
|
190
|
+
"min_list/2": "lists",
|
|
191
|
+
"msb/2": "arithmetic",
|
|
192
|
+
"must_be/2": "error",
|
|
193
|
+
"neighbors/3": "ugraphs",
|
|
194
|
+
"neighbours/3": "ugraphs",
|
|
195
|
+
"nodebug/1": "debug",
|
|
196
|
+
"not_si/1": "si",
|
|
197
|
+
"nth0/3": "lists",
|
|
198
|
+
"nth0/4": "lists",
|
|
199
|
+
"nth1/3": "lists",
|
|
200
|
+
"nth1/4": "lists",
|
|
201
|
+
"number_string/2": "strings",
|
|
202
|
+
"numbervars/3": "terms",
|
|
203
|
+
"numlist/2": "between",
|
|
204
|
+
"numlist/3": "between",
|
|
205
|
+
"nvalue/2": "clpz",
|
|
206
|
+
"ord_add_element/3": "ordsets",
|
|
207
|
+
"ord_del_element/3": "ordsets",
|
|
208
|
+
"ord_disjoint/2": "ordsets",
|
|
209
|
+
"ord_empty/1": "ordsets",
|
|
210
|
+
"ord_intersect/2": "ordsets",
|
|
211
|
+
"ord_intersect/3": "ordsets",
|
|
212
|
+
"ord_intersection/2": "ordsets",
|
|
213
|
+
"ord_intersection/3": "ordsets",
|
|
214
|
+
"ord_intersection/4": "ordsets",
|
|
215
|
+
"ord_list_to_assoc/2": "assoc",
|
|
216
|
+
"ord_memberchk/2": "ordsets",
|
|
217
|
+
"ord_selectchk/3": "ordsets",
|
|
218
|
+
"ord_seteq/2": "ordsets",
|
|
219
|
+
"ord_subset/2": "ordsets",
|
|
220
|
+
"ord_subtract/3": "ordsets",
|
|
221
|
+
"ord_symdiff/3": "ordsets",
|
|
222
|
+
"ord_union/2": "ordsets",
|
|
223
|
+
"ord_union/3": "ordsets",
|
|
224
|
+
"ord_union/4": "ordsets",
|
|
225
|
+
"pairs_keys_values/3": "pairs",
|
|
226
|
+
"pairs_keys/2": "pairs",
|
|
227
|
+
"pairs_values/2": "pairs",
|
|
228
|
+
"permutation/2": "lists",
|
|
229
|
+
"phrase_from_file/2": "pio",
|
|
230
|
+
"phrase_from_file/3": "pio",
|
|
231
|
+
"phrase_to_file/2": "pio",
|
|
232
|
+
"phrase_to_file/3": "pio",
|
|
233
|
+
"phrase_to_stream/2": "pio",
|
|
234
|
+
"phrase/2": "dcgs",
|
|
235
|
+
"phrase/3": "dcgs",
|
|
236
|
+
"popcount/2": "arithmetic",
|
|
237
|
+
"portray_clause_/3": "format",
|
|
238
|
+
"portray_clause/1": "format",
|
|
239
|
+
"portray_clause/2": "format",
|
|
240
|
+
"put_assoc/4": "assoc",
|
|
241
|
+
"put_attr/3": "atts",
|
|
242
|
+
"put_atts/2": "atts",
|
|
243
|
+
"random_integer/3": "random",
|
|
244
|
+
"random_labeling/2": "clpb",
|
|
245
|
+
"random/1": "random",
|
|
246
|
+
"random/3": "random",
|
|
247
|
+
"reachable/3": "ugraphs",
|
|
248
|
+
"repeat/1": "between",
|
|
249
|
+
"replace/4": "strings",
|
|
250
|
+
"representation_error/1": "error",
|
|
251
|
+
"reset_gensym/1": "gensym",
|
|
252
|
+
"resource_error/1": "error",
|
|
253
|
+
"reverse/2": "lists",
|
|
254
|
+
"same_length/2": "lists",
|
|
255
|
+
"sat_count/2": "clpb",
|
|
256
|
+
"sat/1": "clpb",
|
|
257
|
+
"scalar_product/4": "clpz",
|
|
258
|
+
"select/3": "lists",
|
|
259
|
+
"seq/3": "dcgs",
|
|
260
|
+
"seqq/3": "dcgs",
|
|
261
|
+
"serialized/2": "clpz",
|
|
262
|
+
"set_nth0/4": "lists",
|
|
263
|
+
"set_random/1": "random",
|
|
264
|
+
"slice/4": "lists",
|
|
265
|
+
"smallest_divisor_from/3": "primes",
|
|
266
|
+
"split/3": "strings",
|
|
267
|
+
"start_tabling/2": "tabling",
|
|
268
|
+
"string_concat/3": "strings",
|
|
269
|
+
"substring/4": "strings",
|
|
270
|
+
"succ/2": "iso_ext",
|
|
271
|
+
"sum_list/2": "lists",
|
|
272
|
+
"sum/3": "clpz",
|
|
273
|
+
"sumall/3": "aggregate",
|
|
274
|
+
"take/3": "lists",
|
|
275
|
+
"taut/2": "clpb",
|
|
276
|
+
"term_attributed_variables/2": "atts",
|
|
277
|
+
"term_si/1": "si",
|
|
278
|
+
"term_string/2": "strings",
|
|
279
|
+
"tfilter/3": "reif",
|
|
280
|
+
"time/1": "iso_ext",
|
|
281
|
+
"tmember_t/3": "reif",
|
|
282
|
+
"tmember/2": "reif",
|
|
283
|
+
"top_sort/2": "ugraphs",
|
|
284
|
+
"top_sort/3": "ugraphs",
|
|
285
|
+
"tpartition/4": "reif",
|
|
286
|
+
"transitive_closure/2": "ugraphs",
|
|
287
|
+
"transpose_ugraph/2": "ugraphs",
|
|
288
|
+
"transpose/2": "lists",
|
|
289
|
+
"trim/2": "strings",
|
|
290
|
+
"tuples_in/2": "clpz",
|
|
291
|
+
"type_error/2": "error",
|
|
292
|
+
"type_error/3": "error",
|
|
293
|
+
"ugraph_union/3": "ugraphs",
|
|
294
|
+
"uppercase/2": "strings",
|
|
295
|
+
"uuid_string/2": "uuid",
|
|
296
|
+
"uuid/3": "uuid",
|
|
297
|
+
"uuidv4_string/1": "uuid",
|
|
298
|
+
"uuidv4/1": "uuid",
|
|
299
|
+
"variant/2": "iso_ext",
|
|
300
|
+
"vertices_edges_to_ugraph/3": "ugraphs",
|
|
301
|
+
"vertices/2": "ugraphs",
|
|
302
|
+
"weighted_maximum/3": "clpb",
|
|
303
|
+
"when_si/2": "si",
|
|
304
|
+
"when/2": "when",
|
|
305
|
+
"zcompare/3": "clpz"
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
export const eyePrologAmbiguousLibraryAutoload = Object.freeze({});
|
|
309
|
+
|
|
310
|
+
export const eyePrologLibraryAutoloadModules = Object.freeze([
|
|
311
|
+
"aggregate",
|
|
312
|
+
"arithmetic",
|
|
313
|
+
"assoc",
|
|
314
|
+
"atts",
|
|
315
|
+
"between",
|
|
316
|
+
"charsio",
|
|
317
|
+
"clpb",
|
|
318
|
+
"clpz",
|
|
319
|
+
"comparison",
|
|
320
|
+
"dates",
|
|
321
|
+
"dcgs",
|
|
322
|
+
"debug",
|
|
323
|
+
"dif",
|
|
324
|
+
"error",
|
|
325
|
+
"format",
|
|
326
|
+
"freeze",
|
|
327
|
+
"gensym",
|
|
328
|
+
"iso_ext",
|
|
329
|
+
"lambda",
|
|
330
|
+
"lists",
|
|
331
|
+
"ordsets",
|
|
332
|
+
"pairs",
|
|
333
|
+
"pio",
|
|
334
|
+
"primes",
|
|
335
|
+
"prologue",
|
|
336
|
+
"random",
|
|
337
|
+
"reif",
|
|
338
|
+
"si",
|
|
339
|
+
"strings",
|
|
340
|
+
"tabling",
|
|
341
|
+
"terms",
|
|
342
|
+
"time",
|
|
343
|
+
"ugraphs",
|
|
344
|
+
"uuid",
|
|
345
|
+
"when"
|
|
346
|
+
]);
|
package/src/program.js
CHANGED
|
@@ -12,11 +12,12 @@ import {
|
|
|
12
12
|
parseGoalText,
|
|
13
13
|
tryParseClausesFastInto,
|
|
14
14
|
} from './parser.js';
|
|
15
|
-
import { PrologError, convertClauseBodyTerm, getStrictIsoRegistry } from './iso.js';
|
|
15
|
+
import { PrologError, convertClauseBodyTerm, getDefaultRegistry, getStrictIsoRegistry } from './iso.js';
|
|
16
16
|
import { currentWorkingDirectory, fs, path } from './platform.js';
|
|
17
17
|
import {
|
|
18
18
|
standardLibrarySources,
|
|
19
|
-
|
|
19
|
+
eyePrologAmbiguousLibraryAutoload,
|
|
20
|
+
eyePrologLibraryAutoload,
|
|
20
21
|
eyePrologInteropLibraryIndicators,
|
|
21
22
|
eyePrologInteropLibraryModules,
|
|
22
23
|
} from './standard-library.js';
|
|
@@ -255,7 +256,10 @@ export class Program {
|
|
|
255
256
|
}
|
|
256
257
|
}
|
|
257
258
|
this.initializations = [];
|
|
258
|
-
|
|
259
|
+
// Track how many initialization/1 directives have run so a REPL can
|
|
260
|
+
// autoload a library after startup and execute only that library's newly
|
|
261
|
+
// appended initializations without repeating earlier side effects.
|
|
262
|
+
this._initializationsExecutedCount = 0;
|
|
259
263
|
this.quads = [];
|
|
260
264
|
this.prologFlagDirectives = [];
|
|
261
265
|
this.charConversionDirectives = [];
|
|
@@ -1045,7 +1049,7 @@ export function autoloadProgramGoals(program, inputs, options = {}) {
|
|
|
1045
1049
|
const builder = new ProgramBuilder({ ...options, isoStrict: false }, program);
|
|
1046
1050
|
const loadedModules = new Set([...program.modules.keys()].filter((name) => name !== 'user'));
|
|
1047
1051
|
const autoloadCount = program.autoloadedPredicates.length;
|
|
1048
|
-
|
|
1052
|
+
autoloadLibraryDependencies(builder, {
|
|
1049
1053
|
...options,
|
|
1050
1054
|
isoStrict: false,
|
|
1051
1055
|
operatorState,
|
|
@@ -1094,7 +1098,7 @@ function loadSourcesIntoBuilder(builder, sources, options, fast) {
|
|
|
1094
1098
|
parserFlagState,
|
|
1095
1099
|
}, builder.program);
|
|
1096
1100
|
if (options.isoStrict !== true && options.autoload !== false) {
|
|
1097
|
-
|
|
1101
|
+
autoloadLibraryDependencies(builder, {
|
|
1098
1102
|
...options,
|
|
1099
1103
|
operatorState,
|
|
1100
1104
|
parserFlagState,
|
|
@@ -1164,14 +1168,32 @@ function extraGoalDependencies(goals) {
|
|
|
1164
1168
|
return dependencies;
|
|
1165
1169
|
}
|
|
1166
1170
|
|
|
1167
|
-
function
|
|
1171
|
+
function procedureResolvedBeforeAutoload(program, dependency, targetModule) {
|
|
1172
|
+
if (program.findGroup(dependency.name, dependency.arity, targetModule)) return true;
|
|
1173
|
+
return program.moduleImports.get(targetModule)?.has(dependency.key) === true;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
function autoloadLibraryFor(dependency) {
|
|
1177
|
+
// ISO built-ins always take precedence over optional library autoloading.
|
|
1178
|
+
if (getDefaultRegistry().get(dependency.name, dependency.arity) != null) return null;
|
|
1179
|
+
const ambiguous = eyePrologAmbiguousLibraryAutoload[dependency.key];
|
|
1180
|
+
if (ambiguous != null) {
|
|
1181
|
+
throw new PrologError(
|
|
1182
|
+
'permission_error(import, procedure)',
|
|
1183
|
+
compound('/', [atom(dependency.name), numberTerm(dependency.arity)]),
|
|
1184
|
+
);
|
|
1185
|
+
}
|
|
1186
|
+
return eyePrologLibraryAutoload[dependency.key] ?? null;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
function libraryAutoloadRequests(program, extraGoals = []) {
|
|
1168
1190
|
const requests = new Map();
|
|
1169
1191
|
for (const group of program.groups.values()) {
|
|
1170
1192
|
if (bundledLibraryModule(program, group.module)) continue;
|
|
1171
1193
|
for (const dependency of groupDependencies(group)) {
|
|
1172
1194
|
const targetModule = dependency.module ?? group.module;
|
|
1173
|
-
if (program
|
|
1174
|
-
const library =
|
|
1195
|
+
if (procedureResolvedBeforeAutoload(program, dependency, targetModule)) continue;
|
|
1196
|
+
const library = autoloadLibraryFor(dependency);
|
|
1175
1197
|
if (library == null) continue;
|
|
1176
1198
|
const requestKey = `${targetModule}\u0000${dependency.key}`;
|
|
1177
1199
|
requests.set(requestKey, {
|
|
@@ -1186,8 +1208,8 @@ function interopAutoloadRequests(program, extraGoals = []) {
|
|
|
1186
1208
|
for (const goal of program.initializations) {
|
|
1187
1209
|
for (const dependency of collectGoalDependencies(goal, false, true)) {
|
|
1188
1210
|
const targetModule = dependency.module ?? 'user';
|
|
1189
|
-
if (program
|
|
1190
|
-
const library =
|
|
1211
|
+
if (procedureResolvedBeforeAutoload(program, dependency, targetModule)) continue;
|
|
1212
|
+
const library = autoloadLibraryFor(dependency);
|
|
1191
1213
|
if (library == null) continue;
|
|
1192
1214
|
const requestKey = `${targetModule}\u0000${dependency.key}`;
|
|
1193
1215
|
requests.set(requestKey, {
|
|
@@ -1201,8 +1223,8 @@ function interopAutoloadRequests(program, extraGoals = []) {
|
|
|
1201
1223
|
}
|
|
1202
1224
|
for (const dependency of extraGoalDependencies(extraGoals)) {
|
|
1203
1225
|
const targetModule = dependency.module ?? 'user';
|
|
1204
|
-
if (program
|
|
1205
|
-
const library =
|
|
1226
|
+
if (procedureResolvedBeforeAutoload(program, dependency, targetModule)) continue;
|
|
1227
|
+
const library = autoloadLibraryFor(dependency);
|
|
1206
1228
|
if (library == null) continue;
|
|
1207
1229
|
const requestKey = `${targetModule}\u0000${dependency.key}`;
|
|
1208
1230
|
requests.set(requestKey, {
|
|
@@ -1216,14 +1238,14 @@ function interopAutoloadRequests(program, extraGoals = []) {
|
|
|
1216
1238
|
return [...requests.values()];
|
|
1217
1239
|
}
|
|
1218
1240
|
|
|
1219
|
-
function
|
|
1241
|
+
function autoloadLibraryDependencies(builder, options, ensured, loadedModules, extraGoals = []) {
|
|
1220
1242
|
const program = builder.program;
|
|
1221
1243
|
while (true) {
|
|
1222
|
-
const requests =
|
|
1244
|
+
const requests = libraryAutoloadRequests(program, extraGoals);
|
|
1223
1245
|
if (requests.length === 0) return;
|
|
1224
1246
|
let changed = false;
|
|
1225
1247
|
for (const request of requests) {
|
|
1226
|
-
if (program
|
|
1248
|
+
if (procedureResolvedBeforeAutoload(program, request, request.targetModule)) continue;
|
|
1227
1249
|
if (!loadedModules.has(request.library)) {
|
|
1228
1250
|
const designation = compound('library', [atom(request.library)]);
|
|
1229
1251
|
const loaded = readModuleSource(designation, options);
|
package/src/repl.js
CHANGED
|
@@ -4,6 +4,7 @@ import { readSync } from 'node:fs';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { createInterface } from 'node:readline';
|
|
6
6
|
import { formalErrorTerm } from './iso.js';
|
|
7
|
+
import { autoloadProgramGoals } from './program.js';
|
|
7
8
|
import {
|
|
8
9
|
characterCodeConstantEnd, continuesGraphicToken, isTerminatingFullStop, quotedEscapeEnd,
|
|
9
10
|
} from './syntax-scan.js';
|
|
@@ -67,6 +68,19 @@ export async function runRepl(engine, options = {}) {
|
|
|
67
68
|
continue;
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
// Queries entered after the initial Program was prepared need the same
|
|
72
|
+
// bundled-library autoload resolution as file and -g execution. This
|
|
73
|
+
// is intentionally after parsing: predicate autoloading cannot provide
|
|
74
|
+
// syntax operators retroactively (libraries such as clpz must still be
|
|
75
|
+
// imported explicitly before their operators are used).
|
|
76
|
+
if (!state.strictIso && options.autoload !== false) {
|
|
77
|
+
autoloadProgramGoals(state.program, [goal], {
|
|
78
|
+
autoload: true,
|
|
79
|
+
doubleQuotes: state.solver.prologFlags.get('double_quotes')?.value?.name ?? 'chars',
|
|
80
|
+
});
|
|
81
|
+
runWithTerminalSignals(reader, () => state.solver.runInitializations());
|
|
82
|
+
}
|
|
83
|
+
|
|
70
84
|
const flagsBefore = snapshotFlagValues(state.solver);
|
|
71
85
|
try {
|
|
72
86
|
await prepareInteractiveTermInput(state, goal, reader);
|
|
@@ -284,7 +298,11 @@ function runWithTerminalSignals(reader, operation) {
|
|
|
284
298
|
|
|
285
299
|
function makeState(engine, sources, output, options = {}, previousState = null, reader = null) {
|
|
286
300
|
const strictIso = options.isoStrict === true;
|
|
287
|
-
const program = engine.Program.parseSources(sources, {
|
|
301
|
+
const program = engine.Program.parseSources(sources, {
|
|
302
|
+
isoStrict: strictIso,
|
|
303
|
+
sourceMetadata: strictIso,
|
|
304
|
+
autoload: !strictIso && options.autoload !== false,
|
|
305
|
+
});
|
|
288
306
|
const solver = new engine.Solver(program, {
|
|
289
307
|
registry: strictIso ? engine.getStrictIsoRegistry() : engine.getEyePrologRegistry(),
|
|
290
308
|
isoStrict: strictIso,
|
|
@@ -756,12 +774,29 @@ function formatAnswer(engine, state, variables, env) {
|
|
|
756
774
|
collectUnboundVariables(engine, residual, env, names, () => `_${letterName(generated++)}`);
|
|
757
775
|
bindings.push(engine.formatTermForWrite(residual, env, answerWriteOptions));
|
|
758
776
|
}
|
|
777
|
+
// Residual attributes are part of the answer even when the attributed
|
|
778
|
+
// variable was created inside a called predicate and is not itself a query
|
|
779
|
+
// variable (issue #87). First retain visible query names for attributed
|
|
780
|
+
// roots, then project every remaining live attributed root with a generated
|
|
781
|
+
// top-level variable name. This also makes call_residue_vars/2 useful at the
|
|
782
|
+
// top level: variables returned through its list share the same name with the
|
|
783
|
+
// projected constraint instead of appearing unconstrained.
|
|
759
784
|
const projectedAttributeRoots = new Set();
|
|
785
|
+
const attributeRoots = [];
|
|
760
786
|
for (const variable of variables) {
|
|
761
787
|
const root = engine.deref(variable, env);
|
|
762
|
-
if (root.type !== 'var' ||
|
|
763
|
-
projectedAttributeRoots.add(root.name);
|
|
788
|
+
if (root.type !== 'var' || !env.hasPrologAttributes?.(root.name)) continue;
|
|
764
789
|
names.set(root.name, variable.name);
|
|
790
|
+
attributeRoots.push(root);
|
|
791
|
+
}
|
|
792
|
+
for (const name of env.attributedVariableNames?.() ?? []) {
|
|
793
|
+
const root = engine.deref(engine.variable(name), env);
|
|
794
|
+
if (root.type === 'var') attributeRoots.push(root);
|
|
795
|
+
}
|
|
796
|
+
for (const root of attributeRoots) {
|
|
797
|
+
if (projectedAttributeRoots.has(root.name) || !env.hasPrologAttributes?.(root.name)) continue;
|
|
798
|
+
projectedAttributeRoots.add(root.name);
|
|
799
|
+
if (!names.has(root.name)) names.set(root.name, `_${letterName(generated++)}`);
|
|
765
800
|
for (const residual of state.solver.attributeResidualGoals(root, env)) {
|
|
766
801
|
collectUnboundVariables(engine, residual, env, names, () => `_${letterName(generated++)}`);
|
|
767
802
|
bindings.push(engine.formatTermForWrite(residual, env, answerWriteOptions));
|
package/src/solver.js
CHANGED
|
@@ -375,18 +375,19 @@ export class Solver {
|
|
|
375
375
|
}
|
|
376
376
|
|
|
377
377
|
runInitializations() {
|
|
378
|
-
|
|
379
|
-
|
|
378
|
+
const goals = this.program.initializations ?? [];
|
|
379
|
+
let index = this.program._initializationsExecutedCount ?? 0;
|
|
380
|
+
for (; index < goals.length; index++) {
|
|
380
381
|
let succeeded = false;
|
|
381
|
-
for (const _ of this.solve([
|
|
382
|
+
for (const _ of this.solve([goals[index]], new Env(), 0)) {
|
|
382
383
|
succeeded = true;
|
|
383
384
|
break;
|
|
384
385
|
}
|
|
385
386
|
if (!succeeded) throw new PrologError('initialization_error');
|
|
387
|
+
// Mark each successful initialization immediately. If a later one fails,
|
|
388
|
+
// retrying does not repeat already completed initialization side effects.
|
|
389
|
+
this.program._initializationsExecutedCount = index + 1;
|
|
386
390
|
}
|
|
387
|
-
// 7.4.2.6 attaches initialization to preparation of the Prolog text, not
|
|
388
|
-
// to each later Solver instance created for the same prepared Program.
|
|
389
|
-
this.program._initializationsExecuted = true;
|
|
390
391
|
}
|
|
391
392
|
|
|
392
393
|
*solve(goals, env = new Env(), depth = 0) {
|