eyeprolog 1.3.78 → 1.3.80

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.
@@ -0,0 +1,103 @@
1
+ /**
2
+ Provides the predicate `when/2`.
3
+ */
4
+
5
+ :- module(when, [when/2]).
6
+
7
+ :- use_module(library(atts)).
8
+ :- use_module(library(dcgs)).
9
+ :- use_module(library(lists)).
10
+ :- use_module(library(format)).
11
+ :- use_module(library(debug)).
12
+
13
+ :- attribute when_list/1.
14
+
15
+ :- meta_predicate(when(+, 0)).
16
+
17
+ %% when(Condition, Goal).
18
+ %
19
+ % Executes Goal when Condition becomes true.
20
+ % Condition may consist of `ground(T)`, `nonvar(T)`, `C1,C2`, `C1;C2`.
21
+ when(Condition, Goal) :-
22
+ ( when_condition(Condition) ->
23
+ ( Condition ->
24
+ Goal
25
+ ; term_variables(Condition, Vars),
26
+ maplist(when_add_goal(Goal, Condition), Vars)
27
+ )
28
+ ; throw(error(domain_error(when_condition, Condition),_))
29
+ ).
30
+
31
+ when_add_goal(Goal, Condition, Var) :-
32
+ ( get_atts(Var, when_list(Whens0)) ->
33
+ Whens = [when(Condition, Goal) | Whens0],
34
+ put_atts(Var, when_list(Whens))
35
+ ; put_atts(Var, when_list([when(Condition, Goal)]))
36
+ ).
37
+
38
+ when_condition(Cond) :-
39
+ % Should this be delayed?
40
+ var(Cond), !, throw(error(instantiation_error,when_condition/1)).
41
+ when_condition(ground(_)).
42
+ when_condition(nonvar(_)).
43
+ when_condition((A, B)) :-
44
+ when_condition(A),
45
+ when_condition(B).
46
+ when_condition((A ; B)) :-
47
+ when_condition(A),
48
+ when_condition(B).
49
+
50
+ remove_goal([], _, []).
51
+ remove_goal([G0|G0s], Goal, Goals) :-
52
+ ( G0 == Goal ->
53
+ remove_goal(G0s, Goal, Goals)
54
+ ; Goals = [G0|Goals1],
55
+ remove_goal(G0s, Goal, Goals1)
56
+ ).
57
+
58
+ vars_remove_goal(Vars, Goal) :-
59
+ maplist(when_remove_goal(Goal), Vars).
60
+
61
+ when_remove_goal(Goal, Var) :-
62
+ ( get_atts(Var, when_list(Whens0)) ->
63
+ remove_goal(Whens0, Goal, Whens),
64
+ ( Whens = [] ->
65
+ put_atts(Var, -when_list(_))
66
+ ; put_atts(Var, when_list(Whens))
67
+ )
68
+ ; true
69
+ ).
70
+
71
+ reinforce_goal(Goal0, Goal) :-
72
+ Goal = (
73
+ term_variables(Goal0, Vars),
74
+ when:vars_remove_goal(Vars, Goal0),
75
+ Goal0
76
+ ).
77
+
78
+ verify_attributes(Var, Value, Goals) :-
79
+ ( get_atts(Var, when_list(Whens)) ->
80
+ ( var(Value) ->
81
+ ( get_atts(Value, when_list(WhensValue)) ->
82
+ append(Whens, WhensValue, WhensNew),
83
+ put_atts(Value, when_list(WhensNew))
84
+ ; put_atts(Value, when_list(Whens))
85
+ ),
86
+ Goals = []
87
+ ; maplist(reinforce_goal, Whens, Goals)
88
+ )
89
+ ; Goals = []
90
+ ).
91
+
92
+ gather_when_goals([], _) --> [].
93
+ gather_when_goals([When|Whens], Var) -->
94
+ ( { term_variables(When, [V0|_]), Var == V0 } ->
95
+ [when:When]
96
+ ; []
97
+ ),
98
+ gather_when_goals(Whens, Var).
99
+
100
+ attribute_goals(Var) -->
101
+ { get_atts(Var, when_list(Whens)) },
102
+ gather_when_goals(Whens, Var),
103
+ { put_atts(Var, -when_list(_)) }.
package/src/parser.js CHANGED
@@ -381,6 +381,12 @@ class Parser {
381
381
  // Scryer library(atts) exports this declaration operator. EyeProlog
382
382
  // handles the directive directly instead of relying on term expansion.
383
383
  this.defineOperator(1199, 'fx', 'attribute');
384
+ } else if (designation.args[0].name === 'tabling') {
385
+ this.defineOperator(1150, 'fx', 'table');
386
+ } else if (designation.args[0].name === 'debug') {
387
+ this.defineOperator(900, 'fx', '$');
388
+ this.defineOperator(900, 'fx', '$-');
389
+ this.defineOperator(950, 'fy', '*');
384
390
  }
385
391
  }
386
392
  operatorTokenName(token = this.token) {
@@ -1041,7 +1047,7 @@ class Parser {
1041
1047
  (['char_conversion', 'set_prolog_flag'].includes(directive.name) && directive.arity === 2)
1042
1048
  );
1043
1049
  const extensionDirective = directive.type === 'compound' && (
1044
- (['use_module', 'meta_predicate', 'attribute'].includes(directive.name) && directive.arity === 1) ||
1050
+ (['use_module', 'meta_predicate', 'attribute', 'table'].includes(directive.name) && directive.arity === 1) ||
1045
1051
  (['module', 'use_module'].includes(directive.name) && directive.arity === 2)
1046
1052
  );
1047
1053
  if (this.strictIso && extensionDirective) {
@@ -1,7 +1,7 @@
1
1
  // Browser worker entry used by playground.html.
2
2
  // Keep this module free of Node-only imports: it is fetched directly by the
3
3
  // browser and is also exercised by test/run-playground.mjs.
4
- import { createEyePrologRegistry, run } from './index.js?playground=20260811c';
4
+ import { createEyePrologRegistry, run } from './index.js?playground=20260825a';
5
5
 
6
6
  const registry = createEyePrologRegistry();
7
7
 
package/src/program.js CHANGED
@@ -1412,8 +1412,9 @@ function annotateGoalModule(term, module) {
1412
1412
  if (!term || (term.type !== ATOM && term.type !== COMPOUND)) return term;
1413
1413
  term.module = module;
1414
1414
  const callableArguments = (term.name === ',' || term.name === ';' || term.name === '->') ? term.args
1415
- : (['call', 'once', '\\+', 'not', 'catch', 'forall', 'findall', 'bagof', 'setof',
1416
- 'countall', 'sumall', 'aggregate_min', 'aggregate_max', 'maplist'].includes(term.name)
1415
+ : (['call', 'once', '\\+', 'not', 'catch', 'call_cleanup', 'setup_call_cleanup',
1416
+ 'forall', 'findall', 'bagof', 'setof', 'countall', 'sumall',
1417
+ 'aggregate_min', 'aggregate_max', 'maplist', 'phrase'].includes(term.name)
1417
1418
  ? term.args
1418
1419
  : []);
1419
1420
  for (const arg of callableArguments) annotateGoalModule(arg, module);
@@ -4,8 +4,9 @@
4
4
  // backtrackable blackboard lives in Env so ordinary Prolog choice points undo
5
5
  // writes automatically.
6
6
 
7
- import { ATOM, NUMBER, STRING, deref, unify } from './term.js';
7
+ import { ATOM, COMPOUND, NUMBER, STRING, VAR, atom, compound, deref, listFromItems, unify } from './term.js';
8
8
  import { PrologError } from './errors.js';
9
+ import { formatTermForWrite } from './write.js';
9
10
 
10
11
  function blackboardKey(term, env) {
11
12
  const value = deref(term, env);
@@ -31,9 +32,188 @@ function* bbPutBuiltin({ goal, env }) {
31
32
  yield next;
32
33
  }
33
34
 
35
+ function* bbGlobalGetBuiltin({ solver, goal, env }) {
36
+ const key = blackboardKey(goal.args[0], env);
37
+ const stored = solver.nonBacktrackableBlackboard.get(key);
38
+ if (stored === undefined) return;
39
+ const next = env.clone();
40
+ if (unify(goal.args[1], stored, next)) yield next;
41
+ }
42
+
43
+ function* bbGlobalPutBuiltin({ solver, goal, env }) {
44
+ const key = blackboardKey(goal.args[0], env);
45
+ solver.nonBacktrackableBlackboard.set(key, deref(goal.args[1], env));
46
+ yield env;
47
+ }
48
+
49
+ const charTypeNames = new Set([
50
+ 'alnum', 'alpha', 'alphabetic', 'alphanumeric', 'ascii', 'ascii_graphic',
51
+ 'ascii_punctuation', 'binary_digit', 'control', 'decimal_digit', 'exponent',
52
+ 'graphic', 'graphic_token', 'hexadecimal_digit', 'layout', 'lower', 'meta',
53
+ 'numeric', 'octal_digit', 'octet', 'prolog', 'sign', 'solo',
54
+ 'symbolic_control', 'symbolic_hexadecimal', 'upper', 'whitespace',
55
+ ]);
56
+
57
+ function charTypeCandidates(ch) {
58
+ const code = ch.codePointAt(0);
59
+ const letter = /\p{L}/u.test(ch);
60
+ const decimal = /\p{Nd}/u.test(ch);
61
+ const numeric = /\p{N}/u.test(ch);
62
+ const whitespace = /\s/u.test(ch);
63
+ const control = /\p{Cc}/u.test(ch);
64
+ const lower = /\p{Ll}/u.test(ch);
65
+ const upper = /\p{Lu}/u.test(ch);
66
+ const asciiGraphic = code >= 0x21 && code <= 0x7e;
67
+ const out = [];
68
+ const add = (name, yes) => { if (yes) out.push(atom(name)); };
69
+ add('alnum', letter || decimal);
70
+ add('alpha', letter);
71
+ add('alphabetic', letter);
72
+ add('alphanumeric', letter || decimal);
73
+ add('ascii', code <= 0x7f);
74
+ add('ascii_graphic', asciiGraphic);
75
+ add('ascii_punctuation', asciiGraphic && !letter && !decimal);
76
+ add('binary_digit', ch === '0' || ch === '1');
77
+ add('control', control);
78
+ add('decimal_digit', decimal);
79
+ add('exponent', ch === 'e' || ch === 'E');
80
+ add('graphic', !whitespace && !control);
81
+ add('graphic_token', '#$&*+-./:<=>?@\\^~'.includes(ch));
82
+ add('hexadecimal_digit', /^[0-9A-Fa-f]$/.test(ch));
83
+ add('layout', whitespace);
84
+ add('lower', lower);
85
+ add('meta', "\\'\"`".includes(ch));
86
+ add('numeric', numeric);
87
+ add('octal_digit', /^[0-7]$/.test(ch));
88
+ add('octet', code <= 0xff);
89
+ add('prolog', true);
90
+ add('sign', ch === '+' || ch === '-');
91
+ add('solo', '!,;[]{}()|'.includes(ch));
92
+ add('symbolic_control', '#$&*+-./:<=>?@\\^~'.includes(ch));
93
+ add('symbolic_hexadecimal', /^[A-Fa-f]$/.test(ch));
94
+ add('upper', upper);
95
+ add('whitespace', whitespace);
96
+ out.push(compound('lower', [listFromItems([...ch.toLowerCase()].map(atom))]));
97
+ out.push(compound('upper', [listFromItems([...ch.toUpperCase()].map(atom))]));
98
+ return out;
99
+ }
100
+
101
+ function validCharType(term) {
102
+ return (term.type === ATOM && charTypeNames.has(term.name)) ||
103
+ (term.type === COMPOUND && ['lower', 'upper'].includes(term.name) && term.arity === 1);
104
+ }
105
+
106
+ function* charTypeBuiltin({ goal, env }) {
107
+ const char = deref(goal.args[0], env);
108
+ const type = deref(goal.args[1], env);
109
+ if (char.type === VAR && type.type === VAR) throw new PrologError('instantiation_error');
110
+ if (char.type !== VAR && (char.type !== ATOM || [...char.name].length !== 1)) {
111
+ throw new PrologError('type_error(character)', char);
112
+ }
113
+ if (type.type !== VAR && !validCharType(type)) throw new PrologError('domain_error(char_type)', type);
114
+
115
+ const chars = char.type === VAR
116
+ ? (function* unicodeScalars() {
117
+ for (let code = 0; code <= 0x10ffff; code++) {
118
+ if (code >= 0xd800 && code <= 0xdfff) continue;
119
+ yield String.fromCodePoint(code);
120
+ }
121
+ })()
122
+ : [char.name];
123
+ for (const ch of chars) {
124
+ for (const candidate of charTypeCandidates(ch)) {
125
+ const next = env.clone();
126
+ if (unify(goal.args[0], atom(ch), next) && unify(goal.args[1], candidate, next)) yield next;
127
+ }
128
+ }
129
+ }
130
+
131
+ const shortMonths = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
132
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
133
+ const longMonths = ['January', 'February', 'March', 'April', 'May', 'June',
134
+ 'July', 'August', 'September', 'October', 'November', 'December'];
135
+ const shortWeekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
136
+ const longWeekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
137
+
138
+ function chars(value) {
139
+ return listFromItems([...String(value)].map(atom));
140
+ }
141
+
142
+ function* currentTimeBuiltin({ goal, env }) {
143
+ const now = new Date();
144
+ const pad = (value, width = 2) => String(value).padStart(width, '0');
145
+ const dayOfYear = Math.floor((
146
+ Date.UTC(now.getFullYear(), now.getMonth(), now.getDate()) -
147
+ Date.UTC(now.getFullYear(), 0, 1)
148
+ ) / 86400000) + 1;
149
+ const entries = [
150
+ ['Y', String(now.getFullYear())],
151
+ ['m', pad(now.getMonth() + 1)],
152
+ ['d', pad(now.getDate())],
153
+ ['H', pad(now.getHours())],
154
+ ['M', pad(now.getMinutes())],
155
+ ['S', pad(now.getSeconds())],
156
+ ['y', pad(now.getFullYear() % 100)],
157
+ ['b', shortMonths[now.getMonth()]],
158
+ ['B', longMonths[now.getMonth()]],
159
+ ['a', shortWeekdays[now.getDay()]],
160
+ ['A', longWeekdays[now.getDay()]],
161
+ ['w', String(now.getDay())],
162
+ ['u', String(now.getDay() === 0 ? 7 : now.getDay())],
163
+ ['j', pad(dayOfYear, 3)],
164
+ ].map(([key, value]) => compound('=', [atom(key), chars(value)]));
165
+ const next = env.clone();
166
+ if (unify(goal.args[0], listFromItems(entries), next)) yield next;
167
+ }
168
+
169
+ function* abolishAllTablesBuiltin({ solver, env }) {
170
+ solver.memo.clear();
171
+ solver.subsumptiveMemo.clear();
172
+ solver.wfsModels.clear();
173
+ solver.datalogModels.clear();
174
+ solver.tableCoordinator = null;
175
+ solver.groundChainSuccess.clear();
176
+ solver.compactChainSuccess.clear();
177
+ for (const scope of solver.innerTableScopes.values()) {
178
+ scope.memo.clear();
179
+ scope.subsumptiveMemo.clear();
180
+ }
181
+ yield env;
182
+ }
183
+
184
+ function* termCharsBuiltin({ solver, goal, env }) {
185
+ const mode = deref(goal.args[0], env);
186
+ if (mode.type !== ATOM || !['a', 'd', 'q', 'w'].includes(mode.name)) {
187
+ throw new PrologError('domain_error(format_control)', mode);
188
+ }
189
+ const value = deref(goal.args[1], env);
190
+ if (mode.name === 'd' && value.type !== NUMBER) throw new PrologError('type_error(integer)', value);
191
+ if (mode.name === 'a' && ![ATOM, NUMBER, STRING].includes(value.type)) {
192
+ throw new PrologError('type_error(atomic)', value);
193
+ }
194
+ const text = formatTermForWrite(goal.args[1], env, {
195
+ quoted: mode.name === 'q',
196
+ numbervars: true,
197
+ compact: true,
198
+ minimalOperatorSpacing: true,
199
+ operatorAtomsAsArgs: true,
200
+ generateVariableNames: true,
201
+ variableNameState: solver.writeVariableState,
202
+ operators: solver.program.operators.values(),
203
+ });
204
+ const next = env.clone();
205
+ if (unify(goal.args[2], chars(text), next)) yield next;
206
+ }
207
+
34
208
  export const scryerCompatibilityBuiltins = {
35
209
  register(registry) {
36
210
  registry.add('eyeprolog__bb_get', 2, bbGetBuiltin, { eyePrologLibrary: true });
37
211
  registry.add('eyeprolog__bb_b_put', 2, bbPutBuiltin, { deterministic: true, eyePrologLibrary: true });
212
+ registry.add('eyeprolog__bb_global_get', 2, bbGlobalGetBuiltin, { eyePrologLibrary: true });
213
+ registry.add('eyeprolog__bb_global_put', 2, bbGlobalPutBuiltin, { deterministic: true, eyePrologLibrary: true });
214
+ registry.add('eyeprolog__char_type', 2, charTypeBuiltin, { eyePrologLibrary: true });
215
+ registry.add('eyeprolog__current_time', 1, currentTimeBuiltin, { deterministic: true, eyePrologLibrary: true });
216
+ registry.add('eyeprolog__abolish_all_tables', 0, abolishAllTablesBuiltin, { deterministic: true, eyePrologLibrary: true });
217
+ registry.add('eyeprolog__term_chars', 3, termCharsBuiltin, { deterministic: true, eyePrologLibrary: true });
38
218
  },
39
219
  };
package/src/solver.js CHANGED
@@ -185,6 +185,9 @@ export class Solver {
185
185
  // distinct meta-call inputs must not turn completed table variants into
186
186
  // process-lifetime roots.
187
187
  this.innerTableScopes = options.innerTableScopes ?? new Map();
188
+ // Non-backtrackable library state (for example gensym/2 and CLP(B) node
189
+ // identifiers) is shared by nested solvers for the lifetime of this run.
190
+ this.nonBacktrackableBlackboard = options.nonBacktrackableBlackboard ?? new Map();
188
191
  this.stats = {
189
192
  completed_goal_lists: 0,
190
193
  solve_goals_calls: 0,
@@ -216,6 +219,7 @@ export class Solver {
216
219
  charConversions: this.charConversions,
217
220
  io: this.io,
218
221
  innerTableScopes: this.innerTableScopes,
222
+ nonBacktrackableBlackboard: this.nonBacktrackableBlackboard,
219
223
  inferenceObservation: this.inferenceObservation,
220
224
  writeVariableState: this.writeVariableState,
221
225
  skipListTailTabling: options.skipListTailTabling ?? this.skipListTailTabling,
@@ -16,30 +16,41 @@ const moduleFiles = Object.freeze({
16
16
  assoc: 'assoc.pl',
17
17
  atts: 'atts.pl',
18
18
  between: 'between.pl',
19
+ charsio: 'charsio.pl',
20
+ clpb: 'clpb.pl',
19
21
  clpz: 'clpz.pl',
20
22
  comparison: 'comparison.pl',
21
23
  dates: 'dates.pl',
22
24
  dcgs: 'dcgs.pl',
23
25
  debug: 'debug.pl',
26
+ dif: 'dif.pl',
24
27
  error: 'error.pl',
25
28
  format: 'format.pl',
26
29
  freeze: 'freeze.pl',
30
+ gensym: 'gensym.pl',
27
31
  iso_ext: 'iso_ext.pl',
28
32
  lambda: 'lambda.pl',
29
33
  lists: 'lists.pl',
34
+ ordsets: 'ordsets.pl',
30
35
  pairs: 'pairs.pl',
36
+ pio: 'pio.pl',
31
37
  primes: 'primes.pl',
32
38
  prologue: 'prologue.pl',
33
39
  random: 'random.pl',
40
+ reif: 'reif.pl',
34
41
  si: 'si.pl',
35
42
  strings: 'strings.pl',
36
43
  terms: 'terms.pl',
44
+ tabling: 'tabling.pl',
45
+ time: 'time.pl',
46
+ ugraphs: 'ugraphs.pl',
37
47
  uuid: 'uuid.pl',
48
+ when: 'when.pl',
38
49
  });
39
50
 
40
51
  const cacheKey = isNode
41
52
  ? null
42
- : (new URL(import.meta.url).searchParams.get('playground') ?? '20260811c');
53
+ : (new URL(import.meta.url).searchParams.get('playground') ?? '20260825a');
43
54
 
44
55
  export const standardLibrarySources = new Map(await Promise.all(
45
56
  Object.entries(moduleFiles).map(async ([name, filename]) => [name, {
@@ -69,25 +80,70 @@ export const eyePrologNativeLibraryIndicators = Object.freeze([
69
80
  'in/2', 'ins/2', 'all_different/1', 'all_distinct/1', 'nvalue/2', 'sum/3',
70
81
  'scalar_product/4', 'tuples_in/2', 'labeling/2', 'label/1',
71
82
  'indomain/1', 'lex_chain/1', 'serialized/2', 'global_cardinality/2',
72
- 'global_cardinality/3', 'circuit/1', 'chain/2', 'element/3', 'zcompare/3',
83
+ 'global_cardinality/3', 'circuit/1', 'cumulative/1', 'cumulative/2',
84
+ 'disjoint2/1', 'automaton/3', 'automaton/8', 'chain/2', 'element/3', 'zcompare/3',
73
85
  'fd_var/1', 'fd_inf/2', 'fd_sup/2', 'fd_size/2', 'fd_dom/2',
86
+ 'clpz_t/2', '#=/3', '#</3',
74
87
  ]);
75
88
  export const eyePrologPortableLibraryIndicators = Object.freeze([
76
89
  'sumall/3', 'aggregate_min/5', 'aggregate_max/5',
77
- 'lt/2', 'gt/2', 'le/2', 'ge/2', 'difference/3',
78
- 'maplist/2', 'maplist/3', 'maplist/4', 'maplist/5',
79
- 'maplist/6', 'maplist/7', 'maplist/8', 'between/3',
80
- 'smallest_divisor_from/3', 'random/3', 'matches/3', 'split/3',
81
- 'replace/4', 'lowercase/2', 'uppercase/2', 'trim/2', 'number_string/2',
82
- 'atom_string/2', 'term_string/2', 'append/2', 'append/3', 'string_concat/3', 'contains/2',
83
- 'matches/2', 'join/3', 'substring/4', 'member/2', 'memberchk/2', 'select/3', 'last/2', 'same_length/2',
84
- 'nth0/3', 'nth0/4', 'nth1/3', 'nth1/4', 'set_nth0/4', 'take/3', 'drop/3', 'slice/4', 'reverse/2',
85
- 'length/2', 'sum_list/2', 'min_list/2', 'max_list/2', 'list_to_set/2',
86
- 'succ/2', 'foldl/4', 'foldl/5', 'foldl/6',
87
- 'forall/2', 'cfor/3', 'findall/4', 'variant/2', '.../2', 'uuid/3',
90
+ 'lsb/2', 'msb/2', 'popcount/2',
91
+ 'empty_assoc/1', 'assoc_to_list/2', 'get_assoc/3', 'put_assoc/4',
92
+ 'assoc_to_keys/2', 'assoc_to_values/2', 'del_assoc/4', 'del_max_assoc/4',
93
+ 'del_min_assoc/4', 'gen_assoc/3', 'get_assoc/5', 'is_assoc/1',
94
+ 'list_to_assoc/2', 'map_assoc/2', 'map_assoc/3', 'max_assoc/3',
95
+ 'min_assoc/3', 'ord_list_to_assoc/2',
96
+ 'between/3', 'gen_int/1', 'gen_nat/1', 'numlist/2', 'numlist/3', 'repeat/1',
97
+ 'char_type/2', 'get_line_to_chars/3', 'get_n_chars/3', 'get_single_char/1',
98
+ 'sat/1', 'taut/2', 'labeling/1', 'sat_count/2', 'random_labeling/2', 'weighted_maximum/3',
99
+ 'lt/2', 'gt/2', 'le/2', 'ge/2',
100
+ 'difference/3',
101
+ 'seq/3', 'seqq/3',
102
+ 'debug/1', 'debug/3', 'nodebug/1', 'bb_get/2', 'bb_put/2', 'bb_b_put/2', 'bb_global_get/2',
103
+ '*/1', '$/1', '$-/1',
104
+ 'must_be/2', 'can_be/2', 'instantiation_error/0', 'instantiation_error/1',
105
+ 'domain_error/2', 'domain_error/3', 'type_error/2', 'type_error/3',
106
+ 'representation_error/1', 'resource_error/1', 'call_with_error_context/2',
107
+ 'format_/4', 'format/2', 'format/3', 'portray_clause_/3',
108
+ 'portray_clause/1', 'portray_clause/2', 'listing/1',
109
+ 'gensym/2', 'reset_gensym/1',
110
+ 'forall/2', 'succ/2', 'cfor/3', 'findall/4', 'variant/2', '.../2',
88
111
  '^/3', '^/4', '^/5', '^/6', '^/7', '^/8', '^/9', '^/10',
89
112
  '\\/1', '\\/2', '\\/3', '\\/4', '\\/5', '\\/6', '\\/7', '\\/8',
90
113
  '+\\/2', '+\\/3', '+\\/4', '+\\/5', '+\\/6', '+\\/7', '+\\/8', '+\\/9',
114
+ 'member/2', 'memberchk/2', 'select/3', 'append/2', 'append/3', 'last/2', 'same_length/2',
115
+ 'nth0/3', 'nth0/4', 'nth1/3', 'nth1/4', 'set_nth0/4', 'take/3', 'drop/3', 'slice/4', 'reverse/2',
116
+ 'length/2', 'maplist/2', 'maplist/3', 'maplist/4', 'maplist/5',
117
+ 'maplist/6', 'maplist/7', 'maplist/8', 'foldl/4', 'foldl/5', 'foldl/6',
118
+ 'sum_list/2', 'min_list/2', 'max_list/2', 'list_to_set/2',
119
+ 'transpose/2', 'list_max/2', 'list_min/2', 'permutation/2',
120
+ 'is_ordset/1', 'list_to_ord_set/2', 'ord_add_element/3', 'ord_del_element/3',
121
+ 'ord_disjoint/2', 'ord_empty/1', 'ord_intersect/2', 'ord_intersect/3',
122
+ 'ord_intersection/2', 'ord_intersection/3', 'ord_intersection/4',
123
+ 'ord_memberchk/2', 'ord_selectchk/3', 'ord_seteq/2', 'ord_subset/2',
124
+ 'ord_subtract/3', 'ord_symdiff/3', 'ord_union/2', 'ord_union/3', 'ord_union/4',
125
+ 'pairs_keys_values/3', 'pairs_keys/2', 'pairs_values/2',
126
+ 'group_pairs_by_key/2', 'map_list_to_pairs/3',
127
+ 'phrase_from_file/2', 'phrase_from_file/3', 'phrase_to_file/2',
128
+ 'phrase_to_file/3', 'phrase_to_stream/2',
129
+ 'smallest_divisor_from/3',
130
+ 'maybe/0', 'random/3', 'random_integer/3', 'set_random/1',
131
+ ',/3', ';/3', '=/3', 'cond_t/3', 'dif/3', 'if_/3', 'memberd_t/3',
132
+ 'tfilter/3', 'tmember/2', 'tmember_t/3', 'tpartition/4',
133
+ 'atom_si/1', 'integer_si/1', 'atomic_si/1', 'list_si/1', 'character_si/1',
134
+ 'term_si/1', 'chars_si/1', 'dif_si/2', 'not_si/1', 'when_si/2',
135
+ 'matches/3', 'split/3', 'replace/4', 'lowercase/2', 'uppercase/2', 'trim/2',
136
+ 'number_string/2', 'atom_string/2', 'term_string/2', 'string_concat/3',
137
+ 'contains/2', 'matches/2', 'join/3', 'substring/4',
138
+ 'numbervars/3', 'copy_term_nat/2',
139
+ 'start_tabling/2', 'abolish_all_tables/0',
140
+ 'current_time/1', 'format_time/4',
141
+ 'add_edges/3', 'add_vertices/3', 'complement/2', 'compose/3', 'connect_ugraph/3',
142
+ 'del_edges/3', 'del_vertices/3', 'edges/2', 'neighbors/3', 'neighbours/3',
143
+ 'reachable/3', 'top_sort/2', 'top_sort/3', 'transitive_closure/2',
144
+ 'transpose_ugraph/2', 'ugraph_union/3', 'vertices/2', 'vertices_edges_to_ugraph/3',
145
+ 'uuid/3', 'uuid_string/2', 'uuidv4/1', 'uuidv4_string/1',
146
+ 'when/2',
91
147
  ]);
92
148
  export const eyePrologLibraryIndicators = Object.freeze([
93
149
  ...eyePrologPortableLibraryIndicators,
@@ -147,14 +203,58 @@ export const eyePrologInteropAutoload = Object.freeze({
147
203
  'between/3': 'between',
148
204
  });
149
205
 
150
- export const eyePrologInteropLibraryIndicators = Object.freeze(
151
- Object.keys(eyePrologInteropAutoload),
152
- );
206
+ const eyePrologSharedLibraryIndicators = [
207
+ 'lsb/2', 'msb/2', 'popcount/2',
208
+ 'empty_assoc/1', 'assoc_to_keys/2', 'assoc_to_list/2', 'assoc_to_values/2',
209
+ 'del_assoc/4', 'del_max_assoc/4', 'del_min_assoc/4', 'gen_assoc/3',
210
+ 'get_assoc/3', 'get_assoc/5', 'is_assoc/1', 'list_to_assoc/2',
211
+ 'map_assoc/2', 'map_assoc/3', 'max_assoc/3', 'min_assoc/3',
212
+ 'ord_list_to_assoc/2', 'put_assoc/4',
213
+ 'char_type/2', 'get_line_to_chars/3', 'get_n_chars/3', 'get_single_char/1',
214
+ 'sat/1', 'taut/2', 'labeling/1', 'sat_count/2', 'random_labeling/2', 'weighted_maximum/3',
215
+ '#>/2', '#</2', '#>=/2', '#=</2', '#=/2', '#\\=/2', '#\\/1',
216
+ '#<==>/2', '#==>/2', '#<==/2', '#\\//2', '#\\/2', '#/\\/2',
217
+ 'in/2', 'ins/2', 'all_different/1', 'all_distinct/1', 'nvalue/2', 'sum/3',
218
+ 'scalar_product/4', 'tuples_in/2', 'labeling/2', 'label/1', 'indomain/1',
219
+ 'lex_chain/1', 'serialized/2', 'global_cardinality/2', 'global_cardinality/3',
220
+ 'circuit/1', 'cumulative/1', 'cumulative/2', 'disjoint2/1', 'automaton/3',
221
+ 'automaton/8', 'chain/2', 'element/3', 'zcompare/3', 'fd_var/1', 'fd_inf/2',
222
+ 'fd_sup/2', 'fd_size/2', 'fd_dom/2', 'clpz_t/2', '#=/3', '#</3',
223
+ '*/1', '$/1', '$-/1', 'dif/2',
224
+ 'format_/4', 'format/2', 'format/3', 'portray_clause_/3',
225
+ 'portray_clause/1', 'portray_clause/2', 'listing/1',
226
+ 'gensym/2', 'reset_gensym/1',
227
+ 'transpose/2', 'list_max/2', 'list_min/2', 'permutation/2',
228
+ 'is_ordset/1', 'list_to_ord_set/2', 'ord_add_element/3', 'ord_del_element/3',
229
+ 'ord_disjoint/2', 'ord_empty/1', 'ord_intersect/2', 'ord_intersect/3',
230
+ 'ord_intersection/2', 'ord_intersection/3', 'ord_intersection/4',
231
+ 'ord_memberchk/2', 'ord_selectchk/3', 'ord_seteq/2', 'ord_subset/2',
232
+ 'ord_subtract/3', 'ord_symdiff/3', 'ord_union/2', 'ord_union/3', 'ord_union/4',
233
+ 'phrase_from_file/2', 'phrase_from_file/3', 'phrase_to_file/2',
234
+ 'phrase_to_file/3', 'phrase_to_stream/2',
235
+ 'maybe/0', 'random_integer/3', 'set_random/1',
236
+ ',/3', ';/3', '=/3', 'cond_t/3', 'dif/3', 'if_/3', 'memberd_t/3',
237
+ 'tfilter/3', 'tmember/2', 'tmember_t/3', 'tpartition/4',
238
+ 'start_tabling/2', 'abolish_all_tables/0', 'current_time/1', 'format_time/4',
239
+ 'add_edges/3', 'add_vertices/3', 'complement/2', 'compose/3', 'connect_ugraph/3',
240
+ 'del_edges/3', 'del_vertices/3', 'edges/2', 'neighbors/3', 'neighbours/3',
241
+ 'reachable/3', 'top_sort/2', 'top_sort/3', 'transitive_closure/2',
242
+ 'transpose_ugraph/2', 'ugraph_union/3', 'vertices/2', 'vertices_edges_to_ugraph/3',
243
+ 'uuid_string/2', 'uuidv4/1', 'uuidv4_string/1', 'when/2',
244
+ ];
245
+
246
+ export const eyePrologInteropLibraryIndicators = Object.freeze([
247
+ ...new Set([...Object.keys(eyePrologInteropAutoload), ...eyePrologSharedLibraryIndicators]),
248
+ ]);
153
249
 
154
250
  // Libraries whose *name* is part of the current interop profile. A program
155
251
  // may freely use_module/1 with these common module names; predicates in those
156
252
  // modules outside eyePrologInteropLibraryIndicators are still diagnosed when used.
157
- export const eyePrologInteropLibraryModules = Object.freeze(['lists', 'iso_ext', 'lambda', 'atts', 'freeze']);
253
+ export const eyePrologInteropLibraryModules = Object.freeze([
254
+ 'arithmetic', 'assoc', 'atts', 'charsio', 'clpb', 'clpz', 'debug', 'dif',
255
+ 'format', 'freeze', 'gensym', 'iso_ext', 'lambda', 'lists', 'ordsets', 'pio',
256
+ 'random', 'reif', 'tabling', 'time', 'ugraphs', 'uuid', 'when',
257
+ ]);
158
258
 
159
259
  function* tabledNegationBuiltin({ solver, goal, env }) {
160
260
  yield* solver.solveTabledNegation(goal.args[0], env);