eyelang 1.7.9 → 1.7.10

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/docs/guide.md CHANGED
@@ -360,9 +360,9 @@ Use `holds/2` when you want to match the member term directly, for example `name
360
360
  | [`derived-backward-rule.eye`](../examples/derived-backward-rule.eye) | Derives an inverse-property backward rule from rule data. | [`output/derived-backward-rule.eye`](../examples/output/derived-backward-rule.eye) |
361
361
  | [`derived-rule.eye`](../examples/derived-rule.eye) | Derives conclusions from rule data. | [`output/derived-rule.eye`](../examples/output/derived-rule.eye) |
362
362
  | [`diamond-property.eye`](../examples/diamond-property.eye) | Checks the diamond property of a relation. | [`output/diamond-property.eye`](../examples/output/diamond-property.eye) |
363
- | [`dijkstra.eye`](../examples/dijkstra.eye) | Enumerates weighted simple paths. | [`output/dijkstra.eye`](../examples/output/dijkstra.eye) |
364
363
  | [`dijkstra-findall-sort.eye`](../examples/dijkstra-findall-sort.eye) | Finds shortest paths using collected candidates. | [`output/dijkstra-findall-sort.eye`](../examples/output/dijkstra-findall-sort.eye) |
365
364
  | [`dijkstra-risk-path.eye`](../examples/dijkstra-risk-path.eye) | Ranks routes by cost and trust. | [`output/dijkstra-risk-path.eye`](../examples/output/dijkstra-risk-path.eye) |
365
+ | [`dijkstra.eye`](../examples/dijkstra.eye) | Enumerates weighted simple paths. | [`output/dijkstra.eye`](../examples/output/dijkstra.eye) |
366
366
  | [`dining-philosophers.eye`](../examples/dining-philosophers.eye) | Simulates Chandy-Misra fork exchanges. | [`output/dining-philosophers.eye`](../examples/output/dining-philosophers.eye) |
367
367
  | [`dog.eye`](../examples/dog.eye) | Counts dogs and derives when a license is required. | [`output/dog.eye`](../examples/output/dog.eye) |
368
368
  | [`dpv-odrl-purpose-mapping.eye`](../examples/dpv-odrl-purpose-mapping.eye) | Maps a DPV process into an ODRL permission view. | [`output/dpv-odrl-purpose-mapping.eye`](../examples/output/dpv-odrl-purpose-mapping.eye) |
@@ -389,8 +389,8 @@ Use `holds/2` when you want to match the member term directly, for example `name
389
389
  | [`gdpr-compliance.eye`](../examples/gdpr-compliance.eye) | Checks GDPR-style processing compliance. | [`output/gdpr-compliance.eye`](../examples/output/gdpr-compliance.eye) |
390
390
  | [`good-cobbler.eye`](../examples/good-cobbler.eye) | Demonstrates term-level structure with a good-cobbler statement. | [`output/good-cobbler.eye`](../examples/output/good-cobbler.eye) |
391
391
  | [`gps.eye`](../examples/gps.eye) | Finds and verifies route paths. | [`output/gps.eye`](../examples/output/gps.eye) |
392
- | [`graph.eye`](../examples/graph.eye) | Derives transitive paths over French-city road links while showing the productive recursive rule order. | [`output/graph.eye`](../examples/output/graph.eye) |
393
392
  | [`graph-reachability.eye`](../examples/graph-reachability.eye) | Derives reachable nodes in a graph. | [`output/graph-reachability.eye`](../examples/output/graph-reachability.eye) |
393
+ | [`graph.eye`](../examples/graph.eye) | Derives transitive paths over French-city road links while showing the productive recursive rule order. | [`output/graph.eye`](../examples/output/graph.eye) |
394
394
  | [`gray-code-counter.eye`](../examples/gray-code-counter.eye) | Generates Gray-code counter states. | [`output/gray-code-counter.eye`](../examples/output/gray-code-counter.eye) |
395
395
  | [`greatest-lower-bound-uniqueness.eye`](../examples/greatest-lower-bound-uniqueness.eye) | Shows uniqueness of greatest lower bounds in a finite order instance. | [`output/greatest-lower-bound-uniqueness.eye`](../examples/output/greatest-lower-bound-uniqueness.eye) |
396
396
  | [`group-inverse-uniqueness.eye`](../examples/group-inverse-uniqueness.eye) | Shows uniqueness of inverses in a finite group instance. | [`output/group-inverse-uniqueness.eye`](../examples/output/group-inverse-uniqueness.eye) |
@@ -398,6 +398,7 @@ Use `holds/2` when you want to match the member term directly, for example `name
398
398
  | [`hamming-code.eye`](../examples/hamming-code.eye) | Corrects a single-bit Hamming word. | [`output/hamming-code.eye`](../examples/output/hamming-code.eye) |
399
399
  | [`hanoi.eye`](../examples/hanoi.eye) | Derives the Towers of Hanoi moves. | [`output/hanoi.eye`](../examples/output/hanoi.eye) |
400
400
  | [`heat-loss.eye`](../examples/heat-loss.eye) | Computes conductive heat loss. | [`output/heat-loss.eye`](../examples/output/heat-loss.eye) |
401
+ | [`herbrand-witnesses.eye`](../examples/herbrand-witnesses.eye) | Represents existential-style consequences as stable Herbrand witness terms. | [`output/herbrand-witnesses.eye`](../examples/output/herbrand-witnesses.eye) |
401
402
  | [`heron-theorem.eye`](../examples/heron-theorem.eye) | Computes triangle area by Heron's theorem. | [`output/heron-theorem.eye`](../examples/output/heron-theorem.eye) |
402
403
  | [`ideal-gas-law.eye`](../examples/ideal-gas-law.eye) | Applies the ideal gas law. | [`output/ideal-gas-law.eye`](../examples/output/ideal-gas-law.eye) |
403
404
  | [`illegitimate-reasoning.eye`](../examples/illegitimate-reasoning.eye) | Detects suspect reasoning patterns. | [`output/illegitimate-reasoning.eye`](../examples/output/illegitimate-reasoning.eye) |
@@ -413,7 +414,9 @@ Use `holds/2` when you want to match the member term directly, for example `name
413
414
  | [`list-collection.eye`](../examples/list-collection.eye) | Demonstrates list and collection built-ins. | [`output/list-collection.eye`](../examples/output/list-collection.eye) |
414
415
  | [`lldm.eye`](../examples/lldm.eye) | Calculates leg-length discrepancy measurements. | [`output/lldm.eye`](../examples/output/lldm.eye) |
415
416
  | [`manufacturing-quality-control.eye`](../examples/manufacturing-quality-control.eye) | Evaluates process capability and quality. | [`output/manufacturing-quality-control.eye`](../examples/output/manufacturing-quality-control.eye) |
417
+ | [`map-four-color-search.eye`](../examples/map-four-color-search.eye) | Searches for a valid four-colouring of the EU neighbour graph. | [`output/map-four-color-search.eye`](../examples/output/map-four-color-search.eye) |
416
418
  | [`matrix-chain-order.eye`](../examples/matrix-chain-order.eye) | Finds an optimal matrix-chain multiplication order. | [`output/matrix-chain-order.eye`](../examples/output/matrix-chain-order.eye) |
419
+ | [`matrix-noncommutativity.eye`](../examples/matrix-noncommutativity.eye) | Multiplies 2x2 matrices and shows non-commutativity. | [`output/matrix-noncommutativity.eye`](../examples/output/matrix-noncommutativity.eye) |
417
420
  | [`microgrid-dispatch.eye`](../examples/microgrid-dispatch.eye) | Plans microgrid dispatch and reserve. | [`output/microgrid-dispatch.eye`](../examples/output/microgrid-dispatch.eye) |
418
421
  | [`missionaries-cannibals.eye`](../examples/missionaries-cannibals.eye) | Solves the missionaries-and-cannibals river crossing puzzle. | [`output/missionaries-cannibals.eye`](../examples/output/missionaries-cannibals.eye) |
419
422
  | [`modal-logic-kripke.eye`](../examples/modal-logic-kripke.eye) | Emulates modal box and diamond operators over a finite Kripke frame. | [`output/modal-logic-kripke.eye`](../examples/output/modal-logic-kripke.eye) |
@@ -430,21 +433,24 @@ Use `holds/2` when you want to match the member term directly, for example `name
430
433
  | [`orbital-transfer-design.eye`](../examples/orbital-transfer-design.eye) | Designs a Hohmann orbital transfer. | [`output/orbital-transfer-design.eye`](../examples/output/orbital-transfer-design.eye) |
431
434
  | [`path-discovery.eye`](../examples/path-discovery.eye) | Discovers bounded air-route paths. | [`output/path-discovery.eye`](../examples/output/path-discovery.eye) |
432
435
  | [`peano-arithmetic.eye`](../examples/peano-arithmetic.eye) | Computes Peano addition, multiplication, and factorial. | [`output/peano-arithmetic.eye`](../examples/output/peano-arithmetic.eye) |
436
+ | [`peano-calculus.eye`](../examples/peano-calculus.eye) | Computes Peano addition, multiplication, and factorial. | [`output/peano-calculus.eye`](../examples/output/peano-calculus.eye) |
433
437
  | [`peasant.eye`](../examples/peasant.eye) | Performs peasant multiplication and exponentiation. | [`output/peasant.eye`](../examples/output/peasant.eye) |
434
438
  | [`pell-equation.eye`](../examples/pell-equation.eye) | Generates Pell-equation solutions by recurrence. | [`output/pell-equation.eye`](../examples/output/pell-equation.eye) |
435
439
  | [`pendulum-period.eye`](../examples/pendulum-period.eye) | Computes simple pendulum periods. | [`output/pendulum-period.eye`](../examples/output/pendulum-period.eye) |
436
440
  | [`polynomial.eye`](../examples/polynomial.eye) | Finds complex integer polynomial roots. | [`output/polynomial.eye`](../examples/output/polynomial.eye) |
441
+ | [`prime-range.eye`](../examples/prime-range.eye) | Finds primes in a finite range and computes a totient value. | [`output/prime-range.eye`](../examples/output/prime-range.eye) |
437
442
  | [`proof-contrapositive.eye`](../examples/proof-contrapositive.eye) | Models proof by contrapositive. | [`output/proof-contrapositive.eye`](../examples/output/proof-contrapositive.eye) |
438
443
  | [`quadratic-formula.eye`](../examples/quadratic-formula.eye) | Solves sample quadratic equations. | [`output/quadratic-formula.eye`](../examples/output/quadratic-formula.eye) |
439
444
  | [`radioactive-decay.eye`](../examples/radioactive-decay.eye) | Computes radioactive decay over time. | [`output/radioactive-decay.eye`](../examples/output/radioactive-decay.eye) |
440
445
  | [`reusable-builtins.eye`](../examples/reusable-builtins.eye) | Tours reusable numeric, list, and string builtins. | [`output/reusable-builtins.eye`](../examples/output/reusable-builtins.eye) |
441
446
  | [`riemann-hypothesis.eye`](../examples/riemann-hypothesis.eye) | Checks a finite catalogue of non-trivial zeta zeros against the Riemann-hypothesis condition. | [`output/riemann-hypothesis.eye`](../examples/output/riemann-hypothesis.eye) |
447
+ | [`route-planning.eye`](../examples/route-planning.eye) | Finds routes and records them as explicit route terms. | [`output/route-planning.eye`](../examples/output/route-planning.eye) |
442
448
  | [`security-incident-correlation.eye`](../examples/security-incident-correlation.eye) | Correlates security incidents across signals. | [`output/security-incident-correlation.eye`](../examples/output/security-incident-correlation.eye) |
443
449
  | [`send-more-money.eye`](../examples/send-more-money.eye) | Solves the SEND + MORE = MONEY cryptarithm. | [`output/send-more-money.eye`](../examples/output/send-more-money.eye) |
444
450
  | [`service-impact.eye`](../examples/service-impact.eye) | Analyzes service impact over cyclic dependencies. | [`output/service-impact.eye`](../examples/output/service-impact.eye) |
451
+ | [`shoelace-polygon-area.eye`](../examples/shoelace-polygon-area.eye) | Computes polygon area with a recursive shoelace calculation. | [`output/shoelace-polygon-area.eye`](../examples/output/shoelace-polygon-area.eye) |
445
452
  | [`sieve.eye`](../examples/sieve.eye) | Enumerates primes with a sieve-style program. | [`output/sieve.eye`](../examples/output/sieve.eye) |
446
453
  | [`skolem-functions.eye`](../examples/skolem-functions.eye) | Generates deterministic functional terms. | [`output/skolem-functions.eye`](../examples/output/skolem-functions.eye) |
447
- | [`herbrand-witnesses.eye`](../examples/herbrand-witnesses.eye) | Represents existential-style consequences as stable Herbrand witness terms. | [`output/herbrand-witnesses.eye`](../examples/output/herbrand-witnesses.eye) |
448
454
  | [`socket-age.eye`](../examples/socket-age.eye) | Shows socket-declared age reasoning inputs and plugs. | [`output/socket-age.eye`](../examples/output/socket-age.eye) |
449
455
  | [`socket-family.eye`](../examples/socket-family.eye) | Shows socket-declared family-source inputs and ancestry rules. | [`output/socket-family.eye`](../examples/output/socket-family.eye) |
450
456
  | [`socrates.eye`](../examples/socrates.eye) | Derives that Socrates is mortal. | [`output/socrates.eye`](../examples/output/socrates.eye) |
@@ -453,6 +459,7 @@ Use `holds/2` when you want to match the member term directly, for example `name
453
459
  | [`stirling-bell-numbers.eye`](../examples/stirling-bell-numbers.eye) | Computes Stirling numbers and Bell numbers. | [`output/stirling-bell-numbers.eye`](../examples/output/stirling-bell-numbers.eye) |
454
460
  | [`sudoku-4x4.eye`](../examples/sudoku-4x4.eye) | Solves a compact 4x4 Sudoku by finite constraint search. | [`output/sudoku-4x4.eye`](../examples/output/sudoku-4x4.eye) |
455
461
  | [`superdense-coding.eye`](../examples/superdense-coding.eye) | Models superdense-coding bit transmission. | [`output/superdense-coding.eye`](../examples/output/superdense-coding.eye) |
462
+ | [`symbolic-derivative.eye`](../examples/symbolic-derivative.eye) | Symbolically differentiates explicit expression terms, including products and logs. | [`output/symbolic-derivative.eye`](../examples/output/symbolic-derivative.eye) |
456
463
  | [`term-tools.eye`](../examples/term-tools.eye) | Inspects, builds, renders, and validates terms with reusable term/control builtins. | [`output/term-tools.eye`](../examples/output/term-tools.eye) |
457
464
  | [`totient-summatory.eye`](../examples/totient-summatory.eye) | Computes Euler totients and their summatory function. | [`output/totient-summatory.eye`](../examples/output/totient-summatory.eye) |
458
465
  | [`trust-flow-provenance-threshold.eye`](../examples/trust-flow-provenance-threshold.eye) | Classifies message trust from provenance confidence scores. | [`output/trust-flow-provenance-threshold.eye`](../examples/output/trust-flow-provenance-threshold.eye) |
@@ -463,6 +470,7 @@ Use `holds/2` when you want to match the member term directly, for example `name
463
470
  | [`weighted-interval-scheduling.eye`](../examples/weighted-interval-scheduling.eye) | Selects the best non-overlapping weighted intervals with tabled dynamic programming. | [`output/weighted-interval-scheduling.eye`](../examples/output/weighted-interval-scheduling.eye) |
464
471
  | [`witch.eye`](../examples/witch.eye) | Derives the classic “burn the witch” rule chain. | [`output/witch.eye`](../examples/output/witch.eye) |
465
472
  | [`wolf-goat-cabbage.eye`](../examples/wolf-goat-cabbage.eye) | Solves the wolf-goat-cabbage river crossing. | [`output/wolf-goat-cabbage.eye`](../examples/output/wolf-goat-cabbage.eye) |
473
+ | [`workplace-compliance.eye`](../examples/workplace-compliance.eye) | Classifies workplace compliance from explicit action facts. | [`output/workplace-compliance.eye`](../examples/output/workplace-compliance.eye) |
466
474
  | [`zebra.eye`](../examples/zebra.eye) | Solves the zebra logic puzzle. | [`output/zebra.eye`](../examples/output/zebra.eye) |
467
475
 
468
476
  ## Golden outputs, tests, and conformance
@@ -0,0 +1,65 @@
1
+ % Four-colour search for the European Union neighbour graph.
2
+ %
3
+ % This is a finite executable version of the source map-colouring example. The
4
+ % neighbour facts are the EU country graph from the original input, represented
5
+ % with lowercase atom names. `once/1` asks for one valid colouring rather than
6
+ % enumerating all possible four-colour assignments.
7
+
8
+ materialize(four_color_answer, 2).
9
+
10
+ color(red).
11
+ color(green).
12
+ color(blue).
13
+ color(yellow).
14
+
15
+ place_order([belgium, netherlands, luxemburg, france, germany, italy, denmark, ireland, greece, spain, portugal, austria, sweden, finland, cyprus, malta, poland, hungary, czech_republic, slovakia, slovenia, estonia, latvia, lithuania, bulgaria, romania, croatia]).
16
+
17
+ neighbours(belgium, [france, netherlands, luxemburg, germany]).
18
+ neighbours(netherlands, [belgium, germany]).
19
+ neighbours(luxemburg, [belgium, france, germany]).
20
+ neighbours(france, [spain, belgium, luxemburg, germany, italy]).
21
+ neighbours(germany, [netherlands, belgium, luxemburg, denmark, france, austria, poland, czech_republic]).
22
+ neighbours(italy, [france, austria, slovenia]).
23
+ neighbours(denmark, [germany]).
24
+ neighbours(ireland, []).
25
+ neighbours(greece, [bulgaria]).
26
+ neighbours(spain, [france, portugal]).
27
+ neighbours(portugal, [spain]).
28
+ neighbours(austria, [czech_republic, germany, hungary, italy, slovenia, slovakia]).
29
+ neighbours(sweden, [finland]).
30
+ neighbours(finland, [sweden]).
31
+ neighbours(cyprus, []).
32
+ neighbours(malta, []).
33
+ neighbours(poland, [germany, czech_republic, slovakia, lithuania]).
34
+ neighbours(hungary, [austria, slovakia, romania, croatia, slovenia]).
35
+ neighbours(czech_republic, [germany, poland, slovakia, austria]).
36
+ neighbours(slovakia, [czech_republic, poland, hungary, austria]).
37
+ neighbours(slovenia, [austria, italy, hungary, croatia]).
38
+ neighbours(estonia, [latvia]).
39
+ neighbours(latvia, [estonia, lithuania]).
40
+ neighbours(lithuania, [latvia, poland]).
41
+ neighbours(bulgaria, [romania, greece]).
42
+ neighbours(romania, [hungary, bulgaria]).
43
+ neighbours(croatia, [slovenia, hungary]).
44
+
45
+ % Colour the tail first, like the source Prolog program. That gives each
46
+ % colour choice the already-coloured suffix to check against and avoids
47
+ % generating many doomed prefixes.
48
+ valid_color(?place, ?color, ?assigned) :-
49
+ neighbours(?place, ?neighbors),
50
+ not((member([?neighbor, ?color], ?assigned), member(?neighbor, ?neighbors))).
51
+
52
+ place_pairs([], []).
53
+ place_pairs([?place|?rest], [[?place, ?_]|?pairs]) :-
54
+ place_pairs(?rest, ?pairs).
55
+
56
+ color_places([]).
57
+ color_places([[?place, ?color]|?tail]) :-
58
+ color_places(?tail),
59
+ color(?color),
60
+ valid_color(?place, ?color, ?tail).
61
+
62
+ four_color_answer(european_union, ?coloring) :-
63
+ place_order(?places),
64
+ place_pairs(?places, ?coloring),
65
+ once(color_places(?coloring)).
@@ -0,0 +1,43 @@
1
+ % Matrix multiplication and non-commutativity.
2
+ %
3
+ % The original matrix example contains a larger matrix library. This compact
4
+ % Eyelang case keeps the core operation visible: multiply two 2x2 matrices and
5
+ % show that, in general, A*B is not the same matrix as B*A.
6
+
7
+ materialize(matrix_result, 2).
8
+
9
+ matrix_a([[1, 2], [0, 1]]).
10
+ matrix_b([[1, 0], [3, 1]]).
11
+
12
+ dot2([?x1, ?x2], [?y1, ?y2], ?r) :-
13
+ mul(?x1, ?y1, ?p1),
14
+ mul(?x2, ?y2, ?p2),
15
+ add(?p1, ?p2, ?r).
16
+
17
+ transpose2([[?a, ?b], [?c, ?d]], [[?a, ?c], [?b, ?d]]).
18
+
19
+ row_times_matrix(?row, ?matrix, [?r1, ?r2]) :-
20
+ transpose2(?matrix, [?col1, ?col2]),
21
+ dot2(?row, ?col1, ?r1),
22
+ dot2(?row, ?col2, ?r2).
23
+
24
+ matrix_mul([?row1, ?row2], ?matrix, [?out1, ?out2]) :-
25
+ row_times_matrix(?row1, ?matrix, ?out1),
26
+ row_times_matrix(?row2, ?matrix, ?out2).
27
+
28
+ matrix_result(ab, ?ab) :-
29
+ matrix_a(?a),
30
+ matrix_b(?b),
31
+ matrix_mul(?a, ?b, ?ab).
32
+
33
+ matrix_result(ba, ?ba) :-
34
+ matrix_a(?a),
35
+ matrix_b(?b),
36
+ matrix_mul(?b, ?a, ?ba).
37
+
38
+ matrix_result(commutative, false) :-
39
+ matrix_a(?a),
40
+ matrix_b(?b),
41
+ matrix_mul(?a, ?b, ?ab),
42
+ matrix_mul(?b, ?a, ?ba),
43
+ neq(?ab, ?ba).
@@ -0,0 +1 @@
1
+ four_color_answer(european_union, [[belgium, yellow], [netherlands, green], [luxemburg, green], [france, blue], [germany, red], [italy, red], [denmark, green], [ireland, red], [greece, red], [spain, green], [portugal, red], [austria, yellow], [sweden, green], [finland, red], [cyprus, red], [malta, red], [poland, blue], [hungary, blue], [czech_republic, green], [slovakia, red], [slovenia, green], [estonia, red], [latvia, green], [lithuania, red], [bulgaria, green], [romania, red], [croatia, red]]).
@@ -0,0 +1,3 @@
1
+ matrix_result(ab, [[7, 2], [3, 1]]).
2
+ matrix_result(ba, [[1, 2], [3, 7]]).
3
+ matrix_result(commutative, false).
@@ -0,0 +1,3 @@
1
+ peano_answer(two_plus_three, s(s(s(s(s(z)))))).
2
+ peano_answer(two_times_three, s(s(s(s(s(s(z))))))).
3
+ peano_answer(factorial_four, s(s(s(s(s(s(s(s(s(s(s(s(s(s(s(s(s(s(s(s(s(s(s(s(z))))))))))))))))))))))))).
@@ -0,0 +1,3 @@
1
+ prime_result(range_2_30, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]).
2
+ prime_result(count_2_30, 10).
3
+ prime_result(totient_271, 270).
@@ -0,0 +1,4 @@
1
+ route_to_nantes(angers, go(angers, nantes, goal)).
2
+ route_to_nantes(paris, go(paris, chartres, go(chartres, lemans, go(lemans, angers, go(angers, nantes, goal))))).
3
+ route_to_nantes(chartres, go(chartres, lemans, go(lemans, angers, go(angers, nantes, goal)))).
4
+ route_to_nantes(lemans, go(lemans, angers, go(angers, nantes, goal))).
@@ -0,0 +1 @@
1
+ polygon_area(sample, 7.5).
@@ -0,0 +1,4 @@
1
+ derivative_result(square, add(mul(const(1), var(x)), mul(var(x), const(1)))).
2
+ derivative_result(linear_plus_const, add(const(1), const(0))).
3
+ derivative_result(product, add(mul(add(const(1), const(0)), mul(add(pow(var(x), 2), const(2)), add(pow(var(x), 3), const(3)))), mul(add(var(x), const(1)), add(mul(add(mul(mul(const(2), pow(var(x), 1)), const(1)), const(0)), add(pow(var(x), 3), const(3))), mul(add(pow(var(x), 2), const(2)), add(mul(mul(const(3), pow(var(x), 2)), const(1)), const(0))))))).
4
+ derivative_result(nested_log, divide(divide(const(1), var(x)), log(var(x)))).
@@ -0,0 +1,4 @@
1
+ status(bob, compliant).
2
+ status(alice, compliant).
3
+ status(dave, non_compliant).
4
+ status(carol, non_compliant).
@@ -0,0 +1,40 @@
1
+ % Peano addition, multiplication, and factorial over explicit Herbrand terms.
2
+ %
3
+ % The original logic-programming example uses `0` and `s(...)`. Here zero is
4
+ % the atom `z`, so every natural number is an ordinary Eyelang term: z, s(z),
5
+ % s(s(z)), and so on. The rules are relational; the materialized facts choose
6
+ % a few finite calculations as readable examples.
7
+
8
+ materialize(peano_answer, 2).
9
+ table(padd, 3).
10
+ table(pmul, 3).
11
+ table(pfact, 2).
12
+
13
+ % Addition.
14
+ padd(?a, z, ?a).
15
+ padd(?a, s(?b), s(?c)) :-
16
+ padd(?a, ?b, ?c).
17
+
18
+ % Multiplication by repeated addition.
19
+ pmul(?_a, z, z).
20
+ pmul(?a, s(?b), ?c) :-
21
+ pmul(?a, ?b, ?d),
22
+ padd(?a, ?d, ?c).
23
+
24
+ % Factorial with an accumulator.
25
+ pfact(?n, ?value) :-
26
+ pfac(?n, s(z), ?value).
27
+
28
+ pfac(z, ?acc, ?acc).
29
+ pfac(s(?n), ?acc, ?value) :-
30
+ pmul(?acc, s(?n), ?next),
31
+ pfac(?n, ?next, ?value).
32
+
33
+ peano_answer(two_plus_three, ?n) :-
34
+ padd(s(s(z)), s(s(s(z))), ?n).
35
+
36
+ peano_answer(two_times_three, ?n) :-
37
+ pmul(s(s(z)), s(s(s(z))), ?n).
38
+
39
+ peano_answer(factorial_four, ?n) :-
40
+ pfact(s(s(s(s(z)))), ?n).
@@ -0,0 +1,45 @@
1
+ % Prime ranges and Euler totient over finite integer domains.
2
+ %
3
+ % The source example combines prime search with Euler's totient function. This
4
+ % Eyelang version keeps the computation finite and declarative: composite
5
+ % numbers are described by proper divisors, primes are candidates that are not
6
+ % composite, and `totient/2` counts numbers coprime with the input.
7
+
8
+ materialize(prime_result, 2).
9
+ table(gcd, 3).
10
+
11
+ candidate(?n) :-
12
+ between(2, 30, ?n).
13
+
14
+ composite(?n) :-
15
+ candidate(?n),
16
+ between(2, ?n, ?d),
17
+ lt(?d, ?n),
18
+ mod(?n, ?d, 0).
19
+
20
+ prime(?n) :-
21
+ candidate(?n),
22
+ not(composite(?n)).
23
+
24
+ % Euclid's algorithm, used for the totient calculation.
25
+ gcd(?n, 0, ?n).
26
+ gcd(?n, ?m, ?g) :-
27
+ gt(?m, 0),
28
+ mod(?n, ?m, ?r),
29
+ gcd(?m, ?r, ?g).
30
+
31
+ coprime(?n, ?k) :-
32
+ between(1, ?n, ?k),
33
+ gcd(?n, ?k, 1).
34
+
35
+ totient(?n, ?phi) :-
36
+ countall(coprime(?n, ?_k), ?phi).
37
+
38
+ prime_result(range_2_30, ?primes) :-
39
+ findall(?p, prime(?p), ?primes).
40
+
41
+ prime_result(count_2_30, ?count) :-
42
+ countall(prime(?p), ?count).
43
+
44
+ prime_result(totient_271, ?phi) :-
45
+ totient(271, ?phi).
@@ -0,0 +1,33 @@
1
+ % Route planning with explicit route terms.
2
+ %
3
+ % This is the Eyelang version of the classic Paris-to-Nantes path example: the
4
+ % facts describe one-way road links, and `path/2` derives both the endpoint pair
5
+ % and a structured `go(..., ..., ...)` plan. The plan is ordinary data, so the
6
+ % route can be inspected, stored, or used by later rules.
7
+
8
+ materialize(route_to_nantes, 2).
9
+ table(path, 2).
10
+ mode(path, 2, [in, out]).
11
+
12
+ oneway(paris, orleans).
13
+ oneway(paris, chartres).
14
+ oneway(paris, amiens).
15
+ oneway(orleans, blois).
16
+ oneway(orleans, bourges).
17
+ oneway(blois, tours).
18
+ oneway(chartres, lemans).
19
+ oneway(lemans, angers).
20
+ oneway(lemans, tours).
21
+ oneway(angers, nantes).
22
+
23
+ % A direct edge is a one-step plan.
24
+ path([?a, ?b], go(?a, ?b, goal)) :-
25
+ oneway(?a, ?b).
26
+
27
+ % A longer path prepends one edge to the remaining plan.
28
+ path([?a, ?c], go(?a, ?b, ?rest)) :-
29
+ oneway(?a, ?b),
30
+ path([?b, ?c], ?rest).
31
+
32
+ route_to_nantes(?from, ?plan) :-
33
+ path([?from, nantes], ?plan).
@@ -0,0 +1,22 @@
1
+ % Polygon area by the shoelace formula.
2
+ %
3
+ % The input polygon is the same closed polygon shape used by the source example:
4
+ % the final point repeats the first point. Each recursive step consumes one
5
+ % adjacent pair and contributes `(x1*y2 - y1*x2) / 2` to the oriented area.
6
+
7
+ materialize(polygon_area, 2).
8
+
9
+ sample_polygon([[3, 2], [6, 2], [7, 6], [4, 6], [5, 5], [5, 3], [3, 2]]).
10
+
11
+ area([?_point], 0).
12
+ area([[?a, ?b], [?c, ?d]|?rest], ?total) :-
13
+ area([[?c, ?d]|?rest], ?subtotal),
14
+ mul(?a, ?d, ?ad),
15
+ mul(?b, ?c, ?bc),
16
+ sub(?ad, ?bc, ?cross),
17
+ div(?cross, 2.0, ?half),
18
+ add(?half, ?subtotal, ?total).
19
+
20
+ polygon_area(sample, ?area) :-
21
+ sample_polygon(?points),
22
+ area(?points, ?area).
@@ -0,0 +1,39 @@
1
+ % Symbolic differentiation over explicit expression terms.
2
+ %
3
+ % The source derivative example uses Prolog operators such as `+`, `*`, `^`, and
4
+ % cut. Eyelang keeps expressions as ordinary terms: `add/2`, `mul/2`, `pow/2`,
5
+ % `log/1`, and so on. The result is intentionally unsimplified so the rule that
6
+ % produced each part remains visible.
7
+
8
+ materialize(derivative_result, 2).
9
+
10
+ expr(square, mul(var(x), var(x))).
11
+ expr(linear_plus_const, add(var(x), const(3))).
12
+ expr(product, mul(add(var(x), const(1)), mul(add(pow(var(x), 2), const(2)), add(pow(var(x), 3), const(3))))).
13
+ expr(nested_log, log(log(var(x)))).
14
+
15
+ d(const(?_c), ?_x, const(0)).
16
+ d(var(?x), ?x, const(1)).
17
+ d(var(?y), ?x, const(0)) :-
18
+ neq(?x, ?y).
19
+ d(add(?u, ?v), ?x, add(?du, ?dv)) :-
20
+ d(?u, ?x, ?du),
21
+ d(?v, ?x, ?dv).
22
+ d(sub(?u, ?v), ?x, sub(?du, ?dv)) :-
23
+ d(?u, ?x, ?du),
24
+ d(?v, ?x, ?dv).
25
+ d(mul(?u, ?v), ?x, add(mul(?du, ?v), mul(?u, ?dv))) :-
26
+ d(?u, ?x, ?du),
27
+ d(?v, ?x, ?dv).
28
+ d(divide(?u, ?v), ?x, divide(sub(mul(?du, ?v), mul(?u, ?dv)), pow(?v, 2))) :-
29
+ d(?u, ?x, ?du),
30
+ d(?v, ?x, ?dv).
31
+ d(pow(?u, ?n), ?x, mul(mul(const(?n), pow(?u, ?n1)), ?du)) :-
32
+ sub(?n, 1, ?n1),
33
+ d(?u, ?x, ?du).
34
+ d(log(?u), ?x, divide(?du, ?u)) :-
35
+ d(?u, ?x, ?du).
36
+
37
+ derivative_result(?name, ?derivative) :-
38
+ expr(?name, ?expr),
39
+ d(?expr, x, ?derivative).
@@ -0,0 +1,41 @@
1
+ % Workplace compliance from explicit action facts.
2
+ %
3
+ % The source example generated a large dynamic dataset. Eyelang keeps the data
4
+ % explicit and reproducible: each `does/2` fact records an observed employee
5
+ % action, and the rules classify compliant and non-compliant behaviour.
6
+
7
+ materialize(status, 2).
8
+
9
+ employee(alice).
10
+ employee(bob).
11
+ employee(carol).
12
+ employee(dave).
13
+
14
+ does(alice, log_off_at_end_of_shift).
15
+ does(bob, work_related_task).
16
+ does(bob, log_off_at_end_of_shift).
17
+ does(carol, access_social_media).
18
+ does(dave, work_related_task).
19
+
20
+ % Work-related activity is compliant when the employee also logs off.
21
+ status(?person, compliant) :-
22
+ employee(?person),
23
+ does(?person, work_related_task),
24
+ does(?person, log_off_at_end_of_shift).
25
+
26
+ % Logging off is compliant by itself when no work task was observed.
27
+ status(?person, compliant) :-
28
+ employee(?person),
29
+ does(?person, log_off_at_end_of_shift),
30
+ not(does(?person, work_related_task)).
31
+
32
+ % A work task without the required log-off is non-compliant.
33
+ status(?person, non_compliant) :-
34
+ employee(?person),
35
+ does(?person, work_related_task),
36
+ not(does(?person, log_off_at_end_of_shift)).
37
+
38
+ % Accessing social media is non-compliant in this policy.
39
+ status(?person, non_compliant) :-
40
+ employee(?person),
41
+ does(?person, access_social_media).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyelang",
3
- "version": "1.7.9",
3
+ "version": "1.7.10",
4
4
  "description": "A small Prolog-like logic programming language for rules, goals, answers, and proofs.",
5
5
  "type": "module",
6
6
  "main": "./index.js",
package/playground.html CHANGED
@@ -522,6 +522,7 @@
522
522
  "hamming-code",
523
523
  "hanoi",
524
524
  "heat-loss",
525
+ "herbrand-witnesses",
525
526
  "heron-theorem",
526
527
  "ideal-gas-law",
527
528
  "illegitimate-reasoning",
@@ -537,7 +538,9 @@
537
538
  "list-collection",
538
539
  "lldm",
539
540
  "manufacturing-quality-control",
541
+ "map-four-color-search",
540
542
  "matrix-chain-order",
543
+ "matrix-noncommutativity",
541
544
  "microgrid-dispatch",
542
545
  "missionaries-cannibals",
543
546
  "modal-logic-kripke",
@@ -554,21 +557,24 @@
554
557
  "orbital-transfer-design",
555
558
  "path-discovery",
556
559
  "peano-arithmetic",
560
+ "peano-calculus",
557
561
  "peasant",
558
562
  "pell-equation",
559
563
  "pendulum-period",
560
564
  "polynomial",
565
+ "prime-range",
561
566
  "proof-contrapositive",
562
567
  "quadratic-formula",
563
568
  "radioactive-decay",
564
569
  "reusable-builtins",
565
570
  "riemann-hypothesis",
571
+ "route-planning",
566
572
  "security-incident-correlation",
567
573
  "send-more-money",
568
574
  "service-impact",
575
+ "shoelace-polygon-area",
569
576
  "sieve",
570
577
  "skolem-functions",
571
- "herbrand-witnesses",
572
578
  "socket-age",
573
579
  "socket-family",
574
580
  "socrates",
@@ -577,6 +583,7 @@
577
583
  "stirling-bell-numbers",
578
584
  "sudoku-4x4",
579
585
  "superdense-coding",
586
+ "symbolic-derivative",
580
587
  "term-tools",
581
588
  "totient-summatory",
582
589
  "trust-flow-provenance-threshold",
@@ -587,6 +594,7 @@
587
594
  "weighted-interval-scheduling",
588
595
  "witch",
589
596
  "wolf-goat-cabbage",
597
+ "workplace-compliance",
590
598
  "zebra"
591
599
  ];
592
600
  const FALLBACK_SOURCE = `materialize(answer, 1).