eyeprolog 1.5.6 → 1.5.8

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 CHANGED
@@ -57,10 +57,12 @@ printf 'human(socrates).\nmortal(X) :- human(X).\n' |
57
57
  ```
58
58
 
59
59
  ## Eyelet forward rules (`:+`)
60
- Normal mode executes top-level `Conclusion :+ Premise` rules through the bundled Prolog `library(eyelet)` driver when no explicit `-g/--goal` is supplied. `true :+ Goal` prints answers and `false :+ Goal` emits a `fuse/1`; JavaScript `run()` follows the same rule. The module exports `:+`, `stable/1`, and `becomes/2`, and implements rule selection, fixed-point rounds, skolemization, state replacement, and duplicate suppression in Prolog. JavaScript only loads the driver and provides private mutability/output adapters. Strict ISO mode disables this extension.
60
+ Normal mode executes top-level `Conclusion :+ Premise` rules through the bundled Prolog `library(eyelet)` driver when no explicit `-g/--goal` is supplied. `true :+ Goal` prints answers and `false :+ Goal` emits a `fuse/1`; JavaScript `run()` follows the same rule. The module exports `:+`, `stable/1`, and `becomes/2`, and implements rule selection, fixed-point rounds, skolemization, state replacement, and duplicate suppression in Prolog. JavaScript retains only syntax recognition, static dependency/autoload planning, driver bootstrap, and private mutability/output adapters; it does not implement the fixed-point semantics. Strict ISO mode disables this extension.
61
61
 
62
62
  Bundled `src/lib/` predicates autoload in files, CLI/API goals, and the REPL; use `--no-autoload` to require explicit imports, and explicitly import libraries that introduce operators before using their syntax. See [*The Art of EyeProlog*](the-art-of-eyeprolog.md) for the full semantics.
63
63
 
64
+ The Trealla/Scryer compatibility surface now also includes chars-based term I/O and Base64 helpers, rational-form conversion in `library(arithmetic)`, `sleep/1`, the shared `library(iso_ext)` control/term re-exports, and focused `library(files)` and `library(os)` modules. Filesystem and OS side effects require Node; browser calls report an unavailable host resource instead. Non-integral `number_to_rational/2` results are represented structurally as `rdiv(Numerator,Denominator)` until rational numbers become processor numeric values.
65
+
64
66
  ## Links
65
67
 
66
68
  - [The Art of EyeProlog](https://eyereasoner.github.io/eyeprolog/the-art-of-eyeprolog) — complete reference
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.5.6",
6
+ "version": "1.5.8",
7
7
  "description": "EyeProlog turns facts and rules into answers and proofs.",
8
8
  "type": "module",
9
9
  "main": "./index.js",
@@ -16,7 +16,7 @@ higher-level frontends.
16
16
  iterators and registers the normal-profile cleanup controls without making
17
17
  `solver.js` depend back on the language registry.
18
18
  4. **Language services** — `iso.js`, `iso-arithmetic.js`, `dcg.js`, `atts.js`,
19
- `standard-library.js`, and `src/lib/`.
19
+ `scryer-compat.js`, `library-host.js`, `standard-library.js`, and `src/lib/`.
20
20
  5. **Frontends/tools** — `execute.js`, `repl.js`, `cli.js`, `quads.js`,
21
21
  `explain.js`, and the playground worker.
22
22
 
@@ -1,6 +1,12 @@
1
1
  /** Integer arithmetic helpers used by Scryer's CLP(Z) source. */
2
2
 
3
- :- module(arithmetic, [lsb/2, msb/2, popcount/2]).
3
+ :- module(arithmetic, [
4
+ lsb/2,
5
+ msb/2,
6
+ number_to_rational/2,
7
+ popcount/2,
8
+ rational_numerator_denominator/3
9
+ ]).
4
10
 
5
11
  :- use_module(library(error), [must_be/2, domain_error/3]).
6
12
 
@@ -34,3 +40,13 @@ arithmetic__popcount(X, Count0, Count) :-
34
40
  Count1 is Count0 + Bit,
35
41
  X1 is X >> 1,
36
42
  arithmetic__popcount(X1, Count1, Count).
43
+
44
+
45
+ % Rational-form compatibility. EyeProlog currently has integer and float
46
+ % processor values; non-integral results are represented canonically as the
47
+ % ordinary term rdiv(Numerator, Denominator).
48
+ number_to_rational(Number, Rational) :-
49
+ eyeprolog__number_to_rational(Number, Rational).
50
+
51
+ rational_numerator_denominator(Rational, Numerator, Denominator) :-
52
+ eyeprolog__rational_numerator_denominator(Rational, Numerator, Denominator).
@@ -4,7 +4,11 @@
4
4
  char_type/2,
5
5
  get_line_to_chars/3,
6
6
  get_single_char/1,
7
- get_n_chars/3
7
+ get_n_chars/3,
8
+ read_from_chars/2,
9
+ read_term_from_chars/3,
10
+ write_term_to_chars/3,
11
+ chars_base64/3
8
12
  ]).
9
13
 
10
14
  :- use_module(library(error), [can_be/2]).
@@ -47,3 +51,16 @@ charsio__to_eof(Stream, Chars) :-
47
51
  ( Char == end_of_file -> Chars = []
48
52
  ; Chars = [Char|Rest], charsio__to_eof(Stream, Rest)
49
53
  ).
54
+
55
+
56
+ read_from_chars(Chars, Term) :-
57
+ eyeprolog__read_from_chars(Chars, Term).
58
+
59
+ read_term_from_chars(Chars, Term, Options) :-
60
+ eyeprolog__read_term_from_chars(Chars, Term, Options).
61
+
62
+ write_term_to_chars(Term, Options, Chars) :-
63
+ eyeprolog__write_term_to_chars(Term, Options, Chars).
64
+
65
+ chars_base64(Chars, Base64, Options) :-
66
+ eyeprolog__chars_base64(Chars, Base64, Options).
@@ -0,0 +1,53 @@
1
+ /** Trealla/Scryer common filesystem relations.
2
+
3
+ Paths are represented as lists of characters, matching Scryer's library(files)
4
+ and EyeProlog's default double_quotes=chars profile. The exported surface is the
5
+ intersection currently documented by both Trealla and Scryer.
6
+ */
7
+
8
+ :- module(files, [
9
+ directory_files/2,
10
+ delete_file/1,
11
+ rename_file/2,
12
+ make_directory/1,
13
+ make_directory_path/1,
14
+ working_directory/2
15
+ ]).
16
+
17
+ :- use_module(library(error), [can_be/2]).
18
+
19
+ files__chars([]).
20
+ files__chars([C|Cs]) :- atom(C), atom_length(C, 1), files__chars(Cs).
21
+
22
+ files__must_be_chars(Term) :-
23
+ ( var(Term) -> throw(error(instantiation_error, files))
24
+ ; files__chars(Term) -> true
25
+ ; throw(error(type_error(list, Term), files))
26
+ ).
27
+
28
+ directory_files(Directory, Files) :-
29
+ files__must_be_chars(Directory),
30
+ can_be(list, Files),
31
+ eyeprolog__directory_files(Directory, Files).
32
+
33
+ delete_file(File) :-
34
+ files__must_be_chars(File),
35
+ eyeprolog__delete_file(File).
36
+
37
+ rename_file(File, Renamed) :-
38
+ files__must_be_chars(File),
39
+ files__must_be_chars(Renamed),
40
+ eyeprolog__rename_file(File, Renamed).
41
+
42
+ make_directory(Directory) :-
43
+ files__must_be_chars(Directory),
44
+ eyeprolog__make_directory(Directory).
45
+
46
+ make_directory_path(Directory) :-
47
+ files__must_be_chars(Directory),
48
+ eyeprolog__make_directory_path(Directory).
49
+
50
+ working_directory(Directory0, Directory) :-
51
+ can_be(list, Directory0),
52
+ can_be(list, Directory),
53
+ eyeprolog__working_directory(Directory0, Directory).
@@ -1,10 +1,14 @@
1
1
  /** Widely implemented extensions to the ISO Prolog core. */
2
2
 
3
3
  :- module(iso_ext, [
4
+ call_cleanup/2,
4
5
  call_nth/2,
6
+ call_residue_vars/2,
5
7
  countall/2,
8
+ copy_term_nat/2,
6
9
  forall/2,
7
10
  succ/2,
11
+ setup_call_cleanup/3,
8
12
  cfor/3,
9
13
  findall/4,
10
14
  variant/2,
@@ -12,7 +16,13 @@
12
16
  '...'/2
13
17
  ]).
14
18
 
19
+ :- use_module(library(atts), [call_residue_vars/2]).
20
+ :- use_module(library(terms), [copy_term_nat/2]).
21
+
22
+ :- meta_predicate(call_cleanup(0, 0)).
15
23
  :- meta_predicate(call_nth(0, '?')).
24
+ :- meta_predicate(call_residue_vars(0, '?')).
25
+ :- meta_predicate(setup_call_cleanup(0, 0, 0)).
16
26
  :- meta_predicate(countall(0, '?')).
17
27
  :- meta_predicate(forall(0, 0)).
18
28
  :- meta_predicate(findall('?', 0, '?', '?')).
package/src/lib/os.pl ADDED
@@ -0,0 +1,60 @@
1
+ /** Trealla/Scryer common operating-system relations.
2
+
3
+ Environment keys, values, commands and argv entries are lists of characters,
4
+ matching Scryer's library(os) and EyeProlog's default chars profile.
5
+ */
6
+
7
+ :- module(os, [
8
+ getenv/2,
9
+ setenv/2,
10
+ unsetenv/1,
11
+ shell/1,
12
+ shell/2,
13
+ pid/1,
14
+ raw_argv/1,
15
+ argv/1
16
+ ]).
17
+
18
+ :- use_module(library(error), [can_be/2]).
19
+
20
+ os__chars([]).
21
+ os__chars([C|Cs]) :- atom(C), atom_length(C, 1), os__chars(Cs).
22
+
23
+ os__must_be_chars(Term) :-
24
+ ( var(Term) -> throw(error(instantiation_error, os))
25
+ ; os__chars(Term) -> true
26
+ ; throw(error(type_error(list, Term), os))
27
+ ).
28
+
29
+ getenv(Key, Value) :-
30
+ os__must_be_chars(Key),
31
+ can_be(list, Value),
32
+ eyeprolog__getenv(Key, Value).
33
+
34
+ setenv(Key, Value) :-
35
+ os__must_be_chars(Key),
36
+ os__must_be_chars(Value),
37
+ eyeprolog__setenv(Key, Value).
38
+
39
+ unsetenv(Key) :-
40
+ os__must_be_chars(Key),
41
+ eyeprolog__unsetenv(Key).
42
+
43
+ shell(Command) :- shell(Command, 0).
44
+
45
+ shell(Command, Status) :-
46
+ os__must_be_chars(Command),
47
+ can_be(integer, Status),
48
+ eyeprolog__shell(Command, Status).
49
+
50
+ pid(Pid) :-
51
+ can_be(integer, Pid),
52
+ eyeprolog__pid(Pid).
53
+
54
+ raw_argv(Arguments) :-
55
+ can_be(list, Arguments),
56
+ eyeprolog__raw_argv(Arguments).
57
+
58
+ argv(Arguments) :-
59
+ can_be(list, Arguments),
60
+ eyeprolog__argv(Arguments).
package/src/lib/time.pl CHANGED
@@ -1,16 +1,26 @@
1
1
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2
2
  format_time//2 is reused from the common Scryer/Trealla library(time),
3
- written by Markus Triska. Only current_time/1's platform adapter is
4
- EyeProlog-specific.
3
+ written by Markus Triska. current_time/1 and sleep/1 use small
4
+ EyeProlog host adapters; time/1 and statistics/2 reuse existing runtime
5
+ services.
5
6
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
6
7
 
7
8
  /** Predicates for reasoning about time. */
8
9
 
9
- :- module(time, [current_time/1, format_time//2]).
10
+ :- module(time, [sleep/1, time/1, current_time/1, format_time//2, statistics/2]).
11
+
12
+ :- meta_predicate(time(0)).
10
13
 
11
14
  :- use_module(library(dcgs), [seq//1]).
12
15
  :- use_module(library(error), [domain_error/3]).
13
16
  :- use_module(library(lists), [member/2]).
17
+ :- use_module(library(iso_ext), [time/1]).
18
+
19
+ sleep(Seconds) :- eyeprolog__sleep(Seconds).
20
+
21
+ % time/1 is re-exported from library(iso_ext); statistics/2 is a
22
+ % normal-profile runtime predicate. This matches the Scryer module surface
23
+ % without duplicating either implementation.
14
24
 
15
25
  current_time(T) :-
16
26
  eyeprolog__current_time(T).
@@ -57,6 +57,7 @@ export const eyePrologLibraryAutoload = Object.freeze({
57
57
  "all_distinct/1": "clpz",
58
58
  "append/2": "lists",
59
59
  "append/3": "lists",
60
+ "argv/1": "os",
60
61
  "assoc_to_keys/2": "assoc",
61
62
  "assoc_to_list/2": "assoc",
62
63
  "assoc_to_values/2": "assoc",
@@ -71,6 +72,7 @@ export const eyePrologLibraryAutoload = Object.freeze({
71
72
  "bb_put/2": "debug",
72
73
  "becomes/2": "eyelet",
73
74
  "between/3": "between",
75
+ "call_cleanup/2": "iso_ext",
74
76
  "call_nth/2": "iso_ext",
75
77
  "call_residue_vars/2": "atts",
76
78
  "call_with_error_context/2": "error",
@@ -79,6 +81,7 @@ export const eyePrologLibraryAutoload = Object.freeze({
79
81
  "chain/2": "clpz",
80
82
  "char_type/2": "charsio",
81
83
  "character_si/1": "si",
84
+ "chars_base64/3": "charsio",
82
85
  "chars_si/1": "si",
83
86
  "circuit/1": "clpz",
84
87
  "clpz_t/2": "clpz",
@@ -100,10 +103,12 @@ export const eyePrologLibraryAutoload = Object.freeze({
100
103
  "del_max_assoc/4": "assoc",
101
104
  "del_min_assoc/4": "assoc",
102
105
  "del_vertices/3": "ugraphs",
106
+ "delete_file/1": "files",
103
107
  "dif_si/2": "si",
104
108
  "dif/2": "dif",
105
109
  "dif/3": "reif",
106
110
  "difference/3": "dates",
111
+ "directory_files/2": "files",
107
112
  "disjoint2/1": "clpz",
108
113
  "domain_error/2": "error",
109
114
  "domain_error/3": "error",
@@ -138,6 +143,7 @@ export const eyePrologLibraryAutoload = Object.freeze({
138
143
  "get_line_to_chars/3": "charsio",
139
144
  "get_n_chars/3": "charsio",
140
145
  "get_single_char/1": "charsio",
146
+ "getenv/2": "os",
141
147
  "global_cardinality/2": "clpz",
142
148
  "global_cardinality/3": "clpz",
143
149
  "group_pairs_by_key/2": "pairs",
@@ -169,6 +175,8 @@ export const eyePrologLibraryAutoload = Object.freeze({
169
175
  "lowercase/2": "strings",
170
176
  "lsb/2": "arithmetic",
171
177
  "lt/2": "comparison",
178
+ "make_directory_path/1": "files",
179
+ "make_directory/1": "files",
172
180
  "map_assoc/2": "assoc",
173
181
  "map_assoc/3": "assoc",
174
182
  "map_list_to_pairs/3": "pairs",
@@ -200,6 +208,7 @@ export const eyePrologLibraryAutoload = Object.freeze({
200
208
  "nth1/3": "lists",
201
209
  "nth1/4": "lists",
202
210
  "number_string/2": "strings",
211
+ "number_to_rational/2": "arithmetic",
203
212
  "numbervars/3": "terms",
204
213
  "numlist/2": "between",
205
214
  "numlist/3": "between",
@@ -234,6 +243,7 @@ export const eyePrologLibraryAutoload = Object.freeze({
234
243
  "phrase_to_stream/2": "pio",
235
244
  "phrase/2": "dcgs",
236
245
  "phrase/3": "dcgs",
246
+ "pid/1": "os",
237
247
  "popcount/2": "arithmetic",
238
248
  "portray_clause_/3": "format",
239
249
  "portray_clause/1": "format",
@@ -245,7 +255,12 @@ export const eyePrologLibraryAutoload = Object.freeze({
245
255
  "random_labeling/2": "clpb",
246
256
  "random/1": "random",
247
257
  "random/3": "random",
258
+ "rational_numerator_denominator/3": "arithmetic",
259
+ "raw_argv/1": "os",
248
260
  "reachable/3": "ugraphs",
261
+ "read_from_chars/2": "charsio",
262
+ "read_term_from_chars/3": "charsio",
263
+ "rename_file/2": "files",
249
264
  "repeat/1": "between",
250
265
  "replace/4": "strings",
251
266
  "representation_error/1": "error",
@@ -262,11 +277,17 @@ export const eyePrologLibraryAutoload = Object.freeze({
262
277
  "serialized/2": "clpz",
263
278
  "set_nth0/4": "lists",
264
279
  "set_random/1": "random",
280
+ "setenv/2": "os",
281
+ "setup_call_cleanup/3": "iso_ext",
282
+ "shell/1": "os",
283
+ "shell/2": "os",
284
+ "sleep/1": "time",
265
285
  "slice/4": "lists",
266
286
  "smallest_divisor_from/3": "primes",
267
287
  "split/3": "strings",
268
288
  "stable/1": "eyelet",
269
289
  "start_tabling/2": "tabling",
290
+ "statistics/2": "time",
270
291
  "string_concat/3": "strings",
271
292
  "substring/4": "strings",
272
293
  "succ/2": "iso_ext",
@@ -293,6 +314,7 @@ export const eyePrologLibraryAutoload = Object.freeze({
293
314
  "type_error/2": "error",
294
315
  "type_error/3": "error",
295
316
  "ugraph_union/3": "ugraphs",
317
+ "unsetenv/1": "os",
296
318
  "uppercase/2": "strings",
297
319
  "uuid_string/2": "uuid",
298
320
  "uuid/3": "uuid",
@@ -304,6 +326,8 @@ export const eyePrologLibraryAutoload = Object.freeze({
304
326
  "weighted_maximum/3": "clpb",
305
327
  "when_si/2": "si",
306
328
  "when/2": "when",
329
+ "working_directory/2": "files",
330
+ "write_term_to_chars/3": "charsio",
307
331
  "zcompare/3": "clpz"
308
332
  });
309
333
 
@@ -325,6 +349,7 @@ export const eyePrologLibraryAutoloadModules = Object.freeze([
325
349
  "dif",
326
350
  "error",
327
351
  "eyelet",
352
+ "files",
328
353
  "format",
329
354
  "freeze",
330
355
  "gensym",
@@ -332,6 +357,7 @@ export const eyePrologLibraryAutoloadModules = Object.freeze([
332
357
  "lambda",
333
358
  "lists",
334
359
  "ordsets",
360
+ "os",
335
361
  "pairs",
336
362
  "pio",
337
363
  "primes",