eyeling 1.34.3 → 1.34.4
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 +7 -9
- package/docs/eyelang-guide.md +5 -10
- package/docs/eyelang-language-reference.md +31 -5
- package/examples/eyelang/bayes-therapy.pl +4 -4
- package/examples/eyelang/output/reusable-builtins.pl +5 -0
- package/examples/eyelang/output/term-tools.pl +6 -0
- package/examples/eyelang/reusable-builtins.pl +32 -0
- package/examples/eyelang/term-tools.pl +23 -0
- package/lib/eyelang/builtins/arithmetic.js +19 -6
- package/lib/eyelang/builtins/control.js +12 -0
- package/lib/eyelang/builtins/lists.js +146 -7
- package/lib/eyelang/builtins/registry.js +2 -3
- package/lib/eyelang/builtins/strings.js +165 -1
- package/lib/eyelang/builtins/terms.js +66 -0
- package/package.json +1 -1
- package/test/eyelang/conformance/README.md +1 -1
- package/test/eyelang/conformance/cases/extension/036_reusable_numeric_builtins.pl +10 -0
- package/test/eyelang/conformance/cases/extension/037_reusable_list_builtins.pl +11 -0
- package/test/eyelang/conformance/cases/extension/038_reusable_string_builtins.pl +12 -0
- package/test/eyelang/conformance/cases/extension/039_reusable_term_control_builtins.pl +11 -0
- package/test/eyelang/conformance/expected/extension/036_reusable_numeric_builtins.out +8 -0
- package/test/eyelang/conformance/expected/extension/037_reusable_list_builtins.out +9 -0
- package/test/eyelang/conformance/expected/extension/038_reusable_string_builtins.out +10 -0
- package/test/eyelang/conformance/expected/extension/039_reusable_term_control_builtins.out +6 -0
- package/examples/eyelang/collatz-1000.pl +0 -14
- package/examples/eyelang/complex-matrix-stability.pl +0 -45
- package/examples/eyelang/gcd-bezout-identity.pl +0 -48
- package/examples/eyelang/goldbach-1000.pl +0 -185
- package/examples/eyelang/kaprekar.pl +0 -32
- package/examples/eyelang/matrix.pl +0 -296
- package/examples/eyelang/output/collatz-1000.pl +0 -1000
- package/examples/eyelang/output/complex-matrix-stability.pl +0 -5
- package/examples/eyelang/output/gcd-bezout-identity.pl +0 -36
- package/examples/eyelang/output/goldbach-1000.pl +0 -667
- package/examples/eyelang/output/kaprekar.pl +0 -8
- package/examples/eyelang/output/matrix.pl +0 -10
- package/lib/eyelang/builtins/matrix.js +0 -226
- package/lib/eyelang/builtins/number-theory.js +0 -114
- package/test/eyelang/conformance/cases/extension/036_extended_gcd.pl +0 -3
- package/test/eyelang/conformance/cases/extension/037_collatz_trajectory.pl +0 -3
- package/test/eyelang/conformance/cases/extension/038_kaprekar_steps.pl +0 -3
- package/test/eyelang/conformance/cases/extension/039_goldbach_pair.pl +0 -3
- package/test/eyelang/conformance/cases/extension/040_matrix_operations.pl +0 -5
- package/test/eyelang/conformance/expected/extension/036_extended_gcd.out +0 -1
- package/test/eyelang/conformance/expected/extension/037_collatz_trajectory.out +0 -1
- package/test/eyelang/conformance/expected/extension/038_kaprekar_steps.out +0 -1
- package/test/eyelang/conformance/expected/extension/039_goldbach_pair.out +0 -2
- package/test/eyelang/conformance/expected/extension/040_matrix_operations.out +0 -3
|
@@ -7,8 +7,7 @@ import { listBuiltins } from './lists.js';
|
|
|
7
7
|
import { aggregationBuiltins } from './aggregation.js';
|
|
8
8
|
import { contextBuiltins } from './context.js';
|
|
9
9
|
import { controlBuiltins } from './control.js';
|
|
10
|
-
import {
|
|
11
|
-
import { matrixBuiltins } from './matrix.js';
|
|
10
|
+
import { termBuiltins } from './terms.js';
|
|
12
11
|
|
|
13
12
|
export class BuiltinRegistry {
|
|
14
13
|
constructor() {
|
|
@@ -35,7 +34,7 @@ export class BuiltinRegistry {
|
|
|
35
34
|
|
|
36
35
|
export function createDefaultRegistry() {
|
|
37
36
|
const registry = new BuiltinRegistry();
|
|
38
|
-
for (const mod of [coreBuiltins, arithmeticBuiltins, stringBuiltins, listBuiltins, aggregationBuiltins, contextBuiltins, controlBuiltins,
|
|
37
|
+
for (const mod of [coreBuiltins, arithmeticBuiltins, stringBuiltins, listBuiltins, aggregationBuiltins, contextBuiltins, controlBuiltins, termBuiltins]) {
|
|
39
38
|
mod.register(registry);
|
|
40
39
|
}
|
|
41
40
|
return registry;
|
|
@@ -1,16 +1,76 @@
|
|
|
1
1
|
// String builtins.
|
|
2
2
|
// They mostly project from already-ground terms to avoid guessing string domains.
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
atom,
|
|
5
|
+
compound,
|
|
6
|
+
deref,
|
|
7
|
+
isDecimalInteger,
|
|
8
|
+
lexicalValue,
|
|
9
|
+
listFromItems,
|
|
10
|
+
numberTerm,
|
|
11
|
+
parseFiniteNumber,
|
|
12
|
+
properListItems,
|
|
13
|
+
stringTerm,
|
|
14
|
+
termToString,
|
|
15
|
+
unify,
|
|
16
|
+
} from '../term.js';
|
|
4
17
|
|
|
5
18
|
export const stringBuiltins = {
|
|
6
19
|
register(registry) {
|
|
7
20
|
registry.add('str_concat', 3, concat, { deterministic: true });
|
|
8
21
|
for (const name of ['contains', 'matches', 'not_matches']) registry.add(name, 2, contains(name), { deterministic: true });
|
|
9
22
|
registry.add('matches', 3, matchCaptures, { deterministic: true });
|
|
23
|
+
registry.add('split', 3, split, { deterministic: true, fallbackWhenNotReady: true, ready: firstTwoLexicalReady });
|
|
24
|
+
registry.add('join', 3, join, { deterministic: true, fallbackWhenNotReady: true, ready: listAndSecondLexicalReady });
|
|
25
|
+
registry.add('substring', 4, substring, { deterministic: true, fallbackWhenNotReady: true, ready: substringReady });
|
|
26
|
+
registry.add('replace', 4, replace, { deterministic: true, fallbackWhenNotReady: true, ready: firstThreeLexicalReady });
|
|
27
|
+
registry.add('lowercase', 2, caseFold('lower'), { deterministic: true, fallbackWhenNotReady: true, ready: firstLexicalReady });
|
|
28
|
+
registry.add('uppercase', 2, caseFold('upper'), { deterministic: true, fallbackWhenNotReady: true, ready: firstLexicalReady });
|
|
29
|
+
registry.add('trim', 2, trim, { deterministic: true, fallbackWhenNotReady: true, ready: firstLexicalReady });
|
|
30
|
+
registry.add('number_string', 2, numberString, { deterministic: true, fallbackWhenNotReady: true, ready: numberStringReady });
|
|
31
|
+
registry.add('atom_string', 2, atomString, { deterministic: true, fallbackWhenNotReady: true, ready: atomStringReady });
|
|
32
|
+
registry.add('term_string', 2, termString, { deterministic: true, fallbackWhenNotReady: true, ready: firstNonvarReady });
|
|
10
33
|
}
|
|
11
34
|
};
|
|
12
35
|
|
|
13
36
|
|
|
37
|
+
|
|
38
|
+
function firstLexicalReady(goal, env) {
|
|
39
|
+
return lexicalValue(goal.args[0], env) !== null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function firstTwoLexicalReady(goal, env) {
|
|
43
|
+
return lexicalValue(goal.args[0], env) !== null && lexicalValue(goal.args[1], env) !== null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function firstThreeLexicalReady(goal, env) {
|
|
47
|
+
return firstTwoLexicalReady(goal, env) && lexicalValue(goal.args[2], env) !== null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function listAndSecondLexicalReady(goal, env) {
|
|
51
|
+
return properListItems(goal.args[0], env) !== null && lexicalValue(goal.args[1], env) !== null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function substringReady(goal, env) {
|
|
55
|
+
return lexicalValue(goal.args[0], env) !== null && safeIndex(goal.args[1], env) !== null && safeIndex(goal.args[2], env) !== null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function numberStringReady(goal, env) {
|
|
59
|
+
const left = deref(goal.args[0], env);
|
|
60
|
+
const right = deref(goal.args[1], env);
|
|
61
|
+
return left.type === 'number' || right.type === 'string' || right.type === 'atom';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function atomStringReady(goal, env) {
|
|
65
|
+
const left = deref(goal.args[0], env);
|
|
66
|
+
const right = deref(goal.args[1], env);
|
|
67
|
+
return left.type === 'atom' || right.type === 'string' || right.type === 'atom' || right.type === 'number';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function firstNonvarReady(goal, env) {
|
|
71
|
+
return deref(goal.args[0], env).type !== 'var';
|
|
72
|
+
}
|
|
73
|
+
|
|
14
74
|
function* concat({ goal, env }) {
|
|
15
75
|
const left = lexicalValue(goal.args[0], env);
|
|
16
76
|
const right = lexicalValue(goal.args[1], env);
|
|
@@ -53,6 +113,99 @@ function* matchCaptures({ goal, env }) {
|
|
|
53
113
|
if (unify(goal.args[2], context, next)) yield next;
|
|
54
114
|
}
|
|
55
115
|
|
|
116
|
+
function* split({ goal, env }) {
|
|
117
|
+
const text = lexicalValue(goal.args[0], env);
|
|
118
|
+
const separator = lexicalValue(goal.args[1], env);
|
|
119
|
+
if (text == null || separator == null) return;
|
|
120
|
+
const parts = text.split(separator).map(stringTerm);
|
|
121
|
+
const next = env.clone();
|
|
122
|
+
if (unify(goal.args[2], listFromItems(parts), next)) yield next;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function* join({ goal, env }) {
|
|
126
|
+
const items = properListItems(goal.args[0], env);
|
|
127
|
+
const separator = lexicalValue(goal.args[1], env);
|
|
128
|
+
if (!items || separator == null) return;
|
|
129
|
+
const strings = [];
|
|
130
|
+
for (const item of items) {
|
|
131
|
+
const value = lexicalValue(item, env);
|
|
132
|
+
if (value == null) return;
|
|
133
|
+
strings.push(value);
|
|
134
|
+
}
|
|
135
|
+
const next = env.clone();
|
|
136
|
+
if (unify(goal.args[2], stringTerm(strings.join(separator)), next)) yield next;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function* substring({ goal, env }) {
|
|
140
|
+
const text = lexicalValue(goal.args[0], env);
|
|
141
|
+
const start = safeIndex(goal.args[1], env);
|
|
142
|
+
const count = safeIndex(goal.args[2], env);
|
|
143
|
+
if (text == null || start == null || count == null || start + count > text.length) return;
|
|
144
|
+
const next = env.clone();
|
|
145
|
+
if (unify(goal.args[3], stringTerm(text.slice(start, start + count)), next)) yield next;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function* replace({ goal, env }) {
|
|
149
|
+
const text = lexicalValue(goal.args[0], env);
|
|
150
|
+
const search = lexicalValue(goal.args[1], env);
|
|
151
|
+
const replacement = lexicalValue(goal.args[2], env);
|
|
152
|
+
if (text == null || search == null || replacement == null) return;
|
|
153
|
+
const out = search === '' ? text : text.split(search).join(replacement);
|
|
154
|
+
const next = env.clone();
|
|
155
|
+
if (unify(goal.args[3], stringTerm(out), next)) yield next;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function caseFold(direction) {
|
|
159
|
+
return function* ({ goal, env }) {
|
|
160
|
+
const text = lexicalValue(goal.args[0], env);
|
|
161
|
+
if (text == null) return;
|
|
162
|
+
const next = env.clone();
|
|
163
|
+
const out = direction === 'lower' ? text.toLowerCase() : text.toUpperCase();
|
|
164
|
+
if (unify(goal.args[1], stringTerm(out), next)) yield next;
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function* trim({ goal, env }) {
|
|
169
|
+
const text = lexicalValue(goal.args[0], env);
|
|
170
|
+
if (text == null) return;
|
|
171
|
+
const next = env.clone();
|
|
172
|
+
if (unify(goal.args[1], stringTerm(text.trim()), next)) yield next;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function* numberString({ goal, env }) {
|
|
176
|
+
const left = deref(goal.args[0], env);
|
|
177
|
+
const right = deref(goal.args[1], env);
|
|
178
|
+
const next = env.clone();
|
|
179
|
+
if (left.type === 'number') {
|
|
180
|
+
if (unify(goal.args[1], stringTerm(left.name), next)) yield next;
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (right.type === 'string' || right.type === 'atom') {
|
|
184
|
+
if (!numericText(right.name)) return;
|
|
185
|
+
if (unify(goal.args[0], numberTerm(right.name), next)) yield next;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function* atomString({ goal, env }) {
|
|
190
|
+
const left = deref(goal.args[0], env);
|
|
191
|
+
const right = deref(goal.args[1], env);
|
|
192
|
+
const next = env.clone();
|
|
193
|
+
if (left.type === 'atom') {
|
|
194
|
+
if (unify(goal.args[1], stringTerm(left.name), next)) yield next;
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (right.type === 'string' || right.type === 'atom' || right.type === 'number') {
|
|
198
|
+
if (unify(goal.args[0], atom(right.name), next)) yield next;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function* termString({ goal, env }) {
|
|
203
|
+
const term = deref(goal.args[0], env);
|
|
204
|
+
if (term.type === 'var') return;
|
|
205
|
+
const next = env.clone();
|
|
206
|
+
if (unify(goal.args[1], stringTerm(termToString(term, env, true)), next)) yield next;
|
|
207
|
+
}
|
|
208
|
+
|
|
56
209
|
function contextFromGroups(groups) {
|
|
57
210
|
const terms = [];
|
|
58
211
|
for (const [name, value] of Object.entries(groups)) {
|
|
@@ -68,3 +221,14 @@ function contextFromGroups(groups) {
|
|
|
68
221
|
function simpleAlternationMatch(haystack, pattern) {
|
|
69
222
|
return pattern.split('|').some((part) => part === '' || haystack.includes(part));
|
|
70
223
|
}
|
|
224
|
+
|
|
225
|
+
function safeIndex(term, env) {
|
|
226
|
+
const text = lexicalValue(term, env);
|
|
227
|
+
if (!/^-?\d+$/.test(text ?? '')) return null;
|
|
228
|
+
const index = Number(text);
|
|
229
|
+
return Number.isSafeInteger(index) && index >= 0 ? index : null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function numericText(text) {
|
|
233
|
+
return isDecimalInteger(text) || parseFiniteNumber(text) != null;
|
|
234
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Term-inspection builtins for reusable meta-programming over eyelang terms.
|
|
2
|
+
import { atom, compound, deref, listFromItems, lexicalValue, numberTerm, properListItems, stringTerm, unify } from '../term.js';
|
|
3
|
+
|
|
4
|
+
export const termBuiltins = {
|
|
5
|
+
register(registry) {
|
|
6
|
+
registry.add('functor', 3, functorBuiltin, { deterministic: true, fallbackWhenNotReady: true, ready: firstNonvarReady });
|
|
7
|
+
registry.add('arg', 3, argBuiltin, { deterministic: true, fallbackWhenNotReady: true, ready: argReady });
|
|
8
|
+
registry.add('compound_name_arguments', 3, compoundNameArguments, { deterministic: true, fallbackWhenNotReady: true, ready: compoundNameArgumentsReady });
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
function firstNonvarReady(goal, env) {
|
|
14
|
+
return deref(goal.args[0], env).type !== 'var';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function argReady(goal, env) {
|
|
18
|
+
return /^\d+$/.test(lexicalValue(goal.args[0], env) ?? '') && deref(goal.args[1], env).type === 'compound';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function compoundNameArgumentsReady(goal, env) {
|
|
22
|
+
const term = deref(goal.args[0], env);
|
|
23
|
+
if (term.type === 'compound') return true;
|
|
24
|
+
return term.type === 'var' && lexicalValue(goal.args[1], env) !== null && properListItems(goal.args[2], env) !== null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function* functorBuiltin({ goal, env }) {
|
|
28
|
+
const term = deref(goal.args[0], env);
|
|
29
|
+
if (term.type === 'var') return;
|
|
30
|
+
const nameTerm = term.type === 'compound' ? atom(term.name) : scalarNameTerm(term);
|
|
31
|
+
const arity = term.type === 'compound' ? term.arity : 0;
|
|
32
|
+
const next = env.clone();
|
|
33
|
+
if (unify(goal.args[1], nameTerm, next) && unify(goal.args[2], numberTerm(arity), next)) yield next;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function* argBuiltin({ goal, env }) {
|
|
37
|
+
const indexText = lexicalValue(goal.args[0], env);
|
|
38
|
+
if (!/^\d+$/.test(indexText ?? '')) return;
|
|
39
|
+
const index = Number(indexText);
|
|
40
|
+
const term = deref(goal.args[1], env);
|
|
41
|
+
if (term.type !== 'compound' || !Number.isSafeInteger(index) || index < 1 || index > term.arity) return;
|
|
42
|
+
const next = env.clone();
|
|
43
|
+
if (unify(goal.args[2], term.args[index - 1], next)) yield next;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function* compoundNameArguments({ goal, env }) {
|
|
47
|
+
const term = deref(goal.args[0], env);
|
|
48
|
+
if (term.type === 'compound') {
|
|
49
|
+
const next = env.clone();
|
|
50
|
+
if (unify(goal.args[1], atom(term.name), next) && unify(goal.args[2], listFromItems(term.args), next)) yield next;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (term.type !== 'var') return;
|
|
54
|
+
|
|
55
|
+
const name = lexicalValue(goal.args[1], env);
|
|
56
|
+
const args = properListItems(goal.args[2], env);
|
|
57
|
+
if (name == null || !args) return;
|
|
58
|
+
const next = env.clone();
|
|
59
|
+
if (unify(goal.args[0], compound(name, args), next)) yield next;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function scalarNameTerm(term) {
|
|
63
|
+
if (term.type === 'atom') return atom(term.name);
|
|
64
|
+
if (term.type === 'number') return numberTerm(term.name);
|
|
65
|
+
return stringTerm(term.name);
|
|
66
|
+
}
|
package/package.json
CHANGED
|
@@ -36,7 +36,7 @@ The runner executes materialized programs in-process through the public JavaScri
|
|
|
36
36
|
|
|
37
37
|
`core` covers the portable core language profile from the [eyelang language reference](../../../docs/eyelang-language-reference.md): lexical syntax, facts, definite clauses, first-order terms, lists, conjunction, structured unification through user predicates, left-to-right goal-directed proof search, materialized output, and read-back printing.
|
|
38
38
|
|
|
39
|
-
`extension` covers the standard built-in and host behavior exercised by the current reference implementation: arithmetic, comparison, strings, list relations, aggregation, context-term helpers,
|
|
39
|
+
`extension` covers the standard built-in and host behavior exercised by the current reference implementation: arithmetic, comparison, strings, list relations, aggregation, context-term helpers, term-inspection helpers, search-control helpers, `memoize/2`, `materialize/2`, and default derived output.
|
|
40
40
|
|
|
41
41
|
The profile name `extension` is a test-suite grouping name. It does not mean that these cases are outside the eyelang language reference; most of them correspond to the standard built-in profile and standard host profile in the [eyelang language reference](../../../docs/eyelang-language-reference.md).
|
|
42
42
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
% Reference 9.1: reusable numeric functions and max/3.
|
|
2
|
+
materialize(answer, 2).
|
|
3
|
+
answer(max, X) :- max(17, 42, X).
|
|
4
|
+
answer(sqrt, X) :- sqrt(81, X).
|
|
5
|
+
answer(floor, X) :- floor(3.9, X).
|
|
6
|
+
answer(ceiling, X) :- ceiling(3.1, X).
|
|
7
|
+
answer(trunc, X) :- trunc(-3.9, X).
|
|
8
|
+
answer(exp, X) :- exp(0, X).
|
|
9
|
+
answer(tan, X) :- tan(0, X).
|
|
10
|
+
answer(atan2, X) :- atan2(0, -1, X).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
% Reference 9.1: reusable list selectors, slices, summaries, and stable set conversion.
|
|
2
|
+
materialize(answer, 2).
|
|
3
|
+
answer(head, X) :- head([alpha, beta, gamma, beta], X).
|
|
4
|
+
answer(last, X) :- last([alpha, beta, gamma, beta], X).
|
|
5
|
+
answer(take, X) :- take(2, [alpha, beta, gamma, beta], X).
|
|
6
|
+
answer(drop, X) :- drop(2, [alpha, beta, gamma, beta], X).
|
|
7
|
+
answer(slice, X) :- slice(1, 2, [alpha, beta, gamma, beta], X).
|
|
8
|
+
answer(sum, X) :- sum_list([1, 2, 3.5], X).
|
|
9
|
+
answer(min, X) :- min_list([3, 1, 2], X).
|
|
10
|
+
answer(max, X) :- max_list([3, 1, 2], X).
|
|
11
|
+
answer(set, X) :- list_to_set([beta, alpha, beta, gamma, alpha], X).
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
% Reference 9.1: reusable string normalization, splitting, joining, replacement, and conversions.
|
|
2
|
+
materialize(answer, 2).
|
|
3
|
+
answer(trim, X) :- trim(" Hello Eyelang ", X).
|
|
4
|
+
answer(lower, X) :- lowercase("Hello Eyelang", X).
|
|
5
|
+
answer(upper, X) :- uppercase("Hello Eyelang", X).
|
|
6
|
+
answer(split, X) :- split("red,green,blue", ",", X).
|
|
7
|
+
answer(join, X) :- join([red, green, blue], ":", X).
|
|
8
|
+
answer(substring, X) :- substring("abcdef", 2, 3, X).
|
|
9
|
+
answer(replace, X) :- replace("red-green-red", "red", "blue", X).
|
|
10
|
+
answer(number_to_string, X) :- number_string(42, X).
|
|
11
|
+
answer(string_to_number, X) :- number_string(X, "3.5").
|
|
12
|
+
answer(atom_string, X) :- atom_string(eyelang, X).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
% Reference 9.1: term introspection/construction, term strings, and forall/2.
|
|
2
|
+
materialize(answer, 2).
|
|
3
|
+
item(1).
|
|
4
|
+
item(2).
|
|
5
|
+
item(3).
|
|
6
|
+
answer(functor, pair(Name, Arity)) :- functor(edge(a, b), Name, Arity).
|
|
7
|
+
answer(arg, X) :- arg(2, edge(a, b), X).
|
|
8
|
+
answer(decompose, pair(Name, Args)) :- compound_name_arguments(edge(a, b), Name, Args).
|
|
9
|
+
answer(compose, X) :- compound_name_arguments(X, edge, [a, b]).
|
|
10
|
+
answer(term_string, X) :- term_string(edge(a, [b, c]), X).
|
|
11
|
+
answer(forall, ok) :- forall(item(X), lt(X, 4)).
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
answer(trim, "Hello Eyelang").
|
|
2
|
+
answer(lower, "hello eyelang").
|
|
3
|
+
answer(upper, "HELLO EYELANG").
|
|
4
|
+
answer(split, ["red", "green", "blue"]).
|
|
5
|
+
answer(join, "red:green:blue").
|
|
6
|
+
answer(substring, "cde").
|
|
7
|
+
answer(replace, "blue-green-blue").
|
|
8
|
+
answer(number_to_string, "42").
|
|
9
|
+
answer(string_to_number, 3.5).
|
|
10
|
+
answer(atom_string, "eyelang").
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
% Memoize trajectories because different start values quickly merge into
|
|
2
|
-
% shared Collatz tails.
|
|
3
|
-
% Output declarations: materialize/2 selects the relations written to this example's golden output.
|
|
4
|
-
materialize(collatzTrajectory, 2).
|
|
5
|
-
|
|
6
|
-
% Program structure: facts set up the scenario, and rules derive the materialized conclusions.
|
|
7
|
-
% Collatz trajectory benchmark adapted from Eyeling collatz-1000.n3.
|
|
8
|
-
% The reusable builtin keeps this large output example focused on data volume
|
|
9
|
-
% rather than recursive integer arithmetic overhead.
|
|
10
|
-
|
|
11
|
-
% Derivation rules: each rule below contributes one logical step toward the displayed results.
|
|
12
|
-
collatzTrajectory(N, Trajectory) :-
|
|
13
|
-
between(1, 1000, N),
|
|
14
|
-
collatz_trajectory(N, Trajectory).
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
% 2x2 continuous-time stability check.
|
|
2
|
-
% For matrix [[a,b],[c,d]], a stable second-order linear system has
|
|
3
|
-
% trace < 0 and determinant > 0. A negative discriminant indicates a
|
|
4
|
-
% complex-conjugate eigenvalue pair.
|
|
5
|
-
|
|
6
|
-
% Output declarations: materialize/2 selects the relations written to this example's golden output.
|
|
7
|
-
materialize(trace, 2).
|
|
8
|
-
materialize(determinant, 2).
|
|
9
|
-
materialize(discriminant, 2).
|
|
10
|
-
materialize(eigenShape, 2).
|
|
11
|
-
materialize(status, 2).
|
|
12
|
-
|
|
13
|
-
% Program structure: facts set up the scenario, and rules derive the materialized conclusions.
|
|
14
|
-
matrix(controller_loop, -0.7, 1.2, -0.4, -0.5).
|
|
15
|
-
|
|
16
|
-
% Derivation rules: each rule below contributes one logical step toward the displayed results.
|
|
17
|
-
trace(Matrix, Trace) :-
|
|
18
|
-
matrix(Matrix, A, _B, _C, D),
|
|
19
|
-
add(A, D, Trace).
|
|
20
|
-
|
|
21
|
-
determinant(Matrix, Determinant) :-
|
|
22
|
-
matrix(Matrix, A, B, C, D),
|
|
23
|
-
mul(A, D, AD),
|
|
24
|
-
mul(B, C, BC),
|
|
25
|
-
sub(AD, BC, Determinant).
|
|
26
|
-
|
|
27
|
-
discriminant(Matrix, Disc) :-
|
|
28
|
-
trace(Matrix, T),
|
|
29
|
-
determinant(Matrix, Det),
|
|
30
|
-
mul(T, T, T2),
|
|
31
|
-
mul(4, Det, FourDet),
|
|
32
|
-
sub(T2, FourDet, Disc).
|
|
33
|
-
|
|
34
|
-
stable(Matrix) :-
|
|
35
|
-
trace(Matrix, T),
|
|
36
|
-
determinant(Matrix, Det),
|
|
37
|
-
lt(T, 0),
|
|
38
|
-
gt(Det, 0).
|
|
39
|
-
|
|
40
|
-
complex_pair(Matrix) :-
|
|
41
|
-
discriminant(Matrix, Disc),
|
|
42
|
-
lt(Disc, 0).
|
|
43
|
-
|
|
44
|
-
eigenShape(Matrix, complex_conjugate_pair) :- complex_pair(Matrix).
|
|
45
|
-
status(Matrix, asymptotically_stable) :- stable(Matrix).
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
% EYE reasoning-inspired example: greatest common divisor and Bézout identity.
|
|
2
|
-
%
|
|
3
|
-
% This ports the extended Euclidean algorithm idea into ordinary eyelang rules.
|
|
4
|
-
% Each case derives gcd(a,b), coefficients s,t, and validation checks for
|
|
5
|
-
% a*s + b*t = gcd(a,b) and divisibility.
|
|
6
|
-
|
|
7
|
-
% Output declarations: materialize/2 selects the relations written to this example's golden output.
|
|
8
|
-
materialize(gcd, 2).
|
|
9
|
-
materialize(bezoutCoefficients, 2).
|
|
10
|
-
materialize(check, 2).
|
|
11
|
-
materialize(status, 2).
|
|
12
|
-
|
|
13
|
-
% Program structure: facts set up the scenario, and rules derive the materialized conclusions.
|
|
14
|
-
case(c1, 48, 18).
|
|
15
|
-
case(c2, 101, 462).
|
|
16
|
-
case(c3, 0, 5).
|
|
17
|
-
case(c4, 270, 192).
|
|
18
|
-
case(c5, -27, 36).
|
|
19
|
-
case(c6, 123456, 7890).
|
|
20
|
-
|
|
21
|
-
% Derivation rules: each rule below contributes one logical step toward the displayed results.
|
|
22
|
-
answer(Case, Gcd, S, T) :-
|
|
23
|
-
case(Case, A, B),
|
|
24
|
-
extended_gcd(A, B, Gcd, S, T).
|
|
25
|
-
|
|
26
|
-
bezout_ok(Case) :-
|
|
27
|
-
case(Case, A, B),
|
|
28
|
-
answer(Case, Gcd, S, T),
|
|
29
|
-
mul(A, S, AS),
|
|
30
|
-
mul(B, T, BT),
|
|
31
|
-
add(AS, BT, Gcd).
|
|
32
|
-
|
|
33
|
-
divides_ok(Case) :-
|
|
34
|
-
case(Case, A, B),
|
|
35
|
-
answer(Case, Gcd, S, T),
|
|
36
|
-
mod(A, Gcd, 0),
|
|
37
|
-
mod(B, Gcd, 0).
|
|
38
|
-
|
|
39
|
-
nonnegative_ok(Case) :-
|
|
40
|
-
answer(Case, Gcd, S, T),
|
|
41
|
-
ge(Gcd, 0).
|
|
42
|
-
|
|
43
|
-
gcd(Case, Gcd) :- answer(Case, Gcd, S, T).
|
|
44
|
-
bezoutCoefficients(Case, [S, T]) :- answer(Case, Gcd, S, T).
|
|
45
|
-
check(Case, bezout_identity) :- bezout_ok(Case).
|
|
46
|
-
check(Case, divides_inputs) :- divides_ok(Case).
|
|
47
|
-
check(Case, nonnegative_gcd) :- nonnegative_ok(Case).
|
|
48
|
-
status(Case, done) :- answer(Case, Gcd, S, T), bezout_ok(Case), divides_ok(Case), nonnegative_ok(Case).
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
% Goldbach pairs up to 1000.
|
|
2
|
-
% Prime numbers are input data; the rule below derives all Goldbach pairs.
|
|
3
|
-
% Output declarations: materialize/2 selects the relations written to this example's golden output.
|
|
4
|
-
materialize(isPrime, 2).
|
|
5
|
-
materialize(goldbachOk, 2).
|
|
6
|
-
|
|
7
|
-
% Program structure: facts set up the scenario, and rules derive the materialized conclusions.
|
|
8
|
-
prime(2).
|
|
9
|
-
prime(3).
|
|
10
|
-
prime(5).
|
|
11
|
-
prime(7).
|
|
12
|
-
prime(11).
|
|
13
|
-
prime(13).
|
|
14
|
-
prime(17).
|
|
15
|
-
prime(19).
|
|
16
|
-
prime(23).
|
|
17
|
-
prime(29).
|
|
18
|
-
prime(31).
|
|
19
|
-
prime(37).
|
|
20
|
-
prime(41).
|
|
21
|
-
prime(43).
|
|
22
|
-
prime(47).
|
|
23
|
-
prime(53).
|
|
24
|
-
prime(59).
|
|
25
|
-
prime(61).
|
|
26
|
-
prime(67).
|
|
27
|
-
prime(71).
|
|
28
|
-
prime(73).
|
|
29
|
-
prime(79).
|
|
30
|
-
prime(83).
|
|
31
|
-
prime(89).
|
|
32
|
-
prime(97).
|
|
33
|
-
prime(101).
|
|
34
|
-
prime(103).
|
|
35
|
-
prime(107).
|
|
36
|
-
prime(109).
|
|
37
|
-
prime(113).
|
|
38
|
-
prime(127).
|
|
39
|
-
prime(131).
|
|
40
|
-
prime(137).
|
|
41
|
-
prime(139).
|
|
42
|
-
prime(149).
|
|
43
|
-
prime(151).
|
|
44
|
-
prime(157).
|
|
45
|
-
prime(163).
|
|
46
|
-
prime(167).
|
|
47
|
-
prime(173).
|
|
48
|
-
prime(179).
|
|
49
|
-
prime(181).
|
|
50
|
-
prime(191).
|
|
51
|
-
prime(193).
|
|
52
|
-
prime(197).
|
|
53
|
-
prime(199).
|
|
54
|
-
prime(211).
|
|
55
|
-
prime(223).
|
|
56
|
-
prime(227).
|
|
57
|
-
prime(229).
|
|
58
|
-
prime(233).
|
|
59
|
-
prime(239).
|
|
60
|
-
prime(241).
|
|
61
|
-
prime(251).
|
|
62
|
-
prime(257).
|
|
63
|
-
prime(263).
|
|
64
|
-
prime(269).
|
|
65
|
-
prime(271).
|
|
66
|
-
prime(277).
|
|
67
|
-
prime(281).
|
|
68
|
-
prime(283).
|
|
69
|
-
prime(293).
|
|
70
|
-
prime(307).
|
|
71
|
-
prime(311).
|
|
72
|
-
prime(313).
|
|
73
|
-
prime(317).
|
|
74
|
-
prime(331).
|
|
75
|
-
prime(337).
|
|
76
|
-
prime(347).
|
|
77
|
-
prime(349).
|
|
78
|
-
prime(353).
|
|
79
|
-
prime(359).
|
|
80
|
-
prime(367).
|
|
81
|
-
prime(373).
|
|
82
|
-
prime(379).
|
|
83
|
-
prime(383).
|
|
84
|
-
prime(389).
|
|
85
|
-
prime(397).
|
|
86
|
-
prime(401).
|
|
87
|
-
prime(409).
|
|
88
|
-
prime(419).
|
|
89
|
-
prime(421).
|
|
90
|
-
prime(431).
|
|
91
|
-
prime(433).
|
|
92
|
-
prime(439).
|
|
93
|
-
prime(443).
|
|
94
|
-
prime(449).
|
|
95
|
-
prime(457).
|
|
96
|
-
prime(461).
|
|
97
|
-
prime(463).
|
|
98
|
-
prime(467).
|
|
99
|
-
prime(479).
|
|
100
|
-
prime(487).
|
|
101
|
-
prime(491).
|
|
102
|
-
prime(499).
|
|
103
|
-
prime(503).
|
|
104
|
-
prime(509).
|
|
105
|
-
prime(521).
|
|
106
|
-
prime(523).
|
|
107
|
-
prime(541).
|
|
108
|
-
prime(547).
|
|
109
|
-
prime(557).
|
|
110
|
-
prime(563).
|
|
111
|
-
prime(569).
|
|
112
|
-
prime(571).
|
|
113
|
-
prime(577).
|
|
114
|
-
prime(587).
|
|
115
|
-
prime(593).
|
|
116
|
-
prime(599).
|
|
117
|
-
prime(601).
|
|
118
|
-
prime(607).
|
|
119
|
-
prime(613).
|
|
120
|
-
prime(617).
|
|
121
|
-
prime(619).
|
|
122
|
-
prime(631).
|
|
123
|
-
prime(641).
|
|
124
|
-
prime(643).
|
|
125
|
-
prime(647).
|
|
126
|
-
prime(653).
|
|
127
|
-
prime(659).
|
|
128
|
-
prime(661).
|
|
129
|
-
prime(673).
|
|
130
|
-
prime(677).
|
|
131
|
-
prime(683).
|
|
132
|
-
prime(691).
|
|
133
|
-
prime(701).
|
|
134
|
-
prime(709).
|
|
135
|
-
prime(719).
|
|
136
|
-
prime(727).
|
|
137
|
-
prime(733).
|
|
138
|
-
prime(739).
|
|
139
|
-
prime(743).
|
|
140
|
-
prime(751).
|
|
141
|
-
prime(757).
|
|
142
|
-
prime(761).
|
|
143
|
-
prime(769).
|
|
144
|
-
prime(773).
|
|
145
|
-
prime(787).
|
|
146
|
-
prime(797).
|
|
147
|
-
prime(809).
|
|
148
|
-
prime(811).
|
|
149
|
-
prime(821).
|
|
150
|
-
prime(823).
|
|
151
|
-
prime(827).
|
|
152
|
-
prime(829).
|
|
153
|
-
prime(839).
|
|
154
|
-
prime(853).
|
|
155
|
-
prime(857).
|
|
156
|
-
prime(859).
|
|
157
|
-
prime(863).
|
|
158
|
-
prime(877).
|
|
159
|
-
prime(881).
|
|
160
|
-
prime(883).
|
|
161
|
-
prime(887).
|
|
162
|
-
prime(907).
|
|
163
|
-
prime(911).
|
|
164
|
-
prime(919).
|
|
165
|
-
prime(929).
|
|
166
|
-
prime(937).
|
|
167
|
-
prime(941).
|
|
168
|
-
prime(947).
|
|
169
|
-
prime(953).
|
|
170
|
-
prime(967).
|
|
171
|
-
prime(971).
|
|
172
|
-
prime(977).
|
|
173
|
-
prime(983).
|
|
174
|
-
prime(991).
|
|
175
|
-
prime(997).
|
|
176
|
-
|
|
177
|
-
% Derivation rules: each rule below contributes one logical step toward the displayed results.
|
|
178
|
-
even_between_4_1000(N) :- between(4, 1000, N), mod(N, 2, 0).
|
|
179
|
-
|
|
180
|
-
isPrime(N, true) :-
|
|
181
|
-
prime(N).
|
|
182
|
-
|
|
183
|
-
goldbachOk(N, true) :-
|
|
184
|
-
even_between_4_1000(N),
|
|
185
|
-
goldbach_pair(N, _P, _Q).
|