eyelang 1.7.8 → 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/README.md +1 -1
- package/conformance-report.md +3 -3
- package/docs/guide.md +12 -3
- package/docs/language-reference.md +12 -0
- package/examples/existential-rule.eye +8 -15
- package/examples/herbrand-witnesses.eye +31 -0
- package/examples/map-four-color-search.eye +65 -0
- package/examples/matrix-noncommutativity.eye +43 -0
- package/examples/output/existential-rule.eye +2 -2
- package/examples/output/herbrand-witnesses.eye +7 -0
- package/examples/output/map-four-color-search.eye +1 -0
- package/examples/output/matrix-noncommutativity.eye +3 -0
- package/examples/output/peano-calculus.eye +3 -0
- package/examples/output/prime-range.eye +3 -0
- package/examples/output/route-planning.eye +4 -0
- package/examples/output/shoelace-polygon-area.eye +1 -0
- package/examples/output/symbolic-derivative.eye +4 -0
- package/examples/output/workplace-compliance.eye +4 -0
- package/examples/peano-calculus.eye +40 -0
- package/examples/prime-range.eye +45 -0
- package/examples/proof/existential-rule.eye +10 -18
- package/examples/route-planning.eye +33 -0
- package/examples/shoelace-polygon-area.eye +22 -0
- package/examples/symbolic-derivative.eye +39 -0
- package/examples/workplace-compliance.eye +41 -0
- package/package.json +1 -1
- package/playground.html +9 -0
- package/src/builtins/terms.js +1 -0
- package/test/conformance/cases/terms/herbrand_witness_different_inputs_distinct.eye +2 -0
- package/test/conformance/cases/terms/herbrand_witness_one_input.eye +5 -0
- package/test/conformance/cases/terms/herbrand_witness_same_inputs_same_term.eye +2 -0
- package/test/conformance/cases/terms/herbrand_witness_two_inputs.eye +5 -0
- package/test/conformance/expected/terms/herbrand_witness_different_inputs_distinct.eye +1 -0
- package/test/conformance/expected/terms/herbrand_witness_one_input.eye +2 -0
- package/test/conformance/expected/terms/herbrand_witness_same_inputs_same_term.eye +1 -0
- package/test/conformance/expected/terms/herbrand_witness_two_inputs.eye +2 -0
- package/test/conformance/expected-proofs/proofs/herbrand_witness.eye +16 -0
- package/test/conformance/proofs/proofs/herbrand_witness.eye +3 -0
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://doi.org/10.5281/zenodo.20761726)
|
|
5
5
|
|
|
6
6
|
Eyelang is a small logic programming language for rules, goals, answers, and proofs.
|
|
7
|
-
Its source syntax is Prolog-like Horn-clause syntax with deliberate eyelang choices, including `?x` variables for N3/SPARQL-style readability, explicit `table(path, 2).` declarations for tabled predicates, advisory `mode/3` declarations for host tooling, and stratified-negation diagnostics for portable `not/1` usage.
|
|
7
|
+
Its source syntax is Prolog-like Horn-clause syntax with deliberate eyelang choices, including `?x` variables for N3/SPARQL-style readability, explicit `table(path, 2).` declarations for tabled predicates, advisory `mode/3` declarations for host tooling, explicit Herbrand witness terms for executable existential-style consequences, and stratified-negation diagnostics for portable `not/1` usage.
|
|
8
8
|
It grew out of logic-language experiments in the EYE/N3 reasoning tradition, but is packaged here as its own project.
|
|
9
9
|
|
|
10
10
|
## Install and run
|
package/conformance-report.md
CHANGED
|
@@ -14,12 +14,12 @@ This report summarizes the file-based conformance corpus under `test/conformance
|
|
|
14
14
|
| lists | 54 | 3 | 0 | 0 | 57 |
|
|
15
15
|
| materialize | 8 | 0 | 0 | 0 | 8 |
|
|
16
16
|
| negation | 8 | 0 | 19 | 0 | 27 |
|
|
17
|
-
| proofs | 0 | 0 | 0 |
|
|
17
|
+
| proofs | 0 | 0 | 0 | 21 | 21 |
|
|
18
18
|
| rules | 12 | 3 | 0 | 0 | 15 |
|
|
19
19
|
| strings | 40 | 0 | 0 | 0 | 40 |
|
|
20
20
|
| syntax | 11 | 28 | 0 | 0 | 39 |
|
|
21
21
|
| table | 6 | 0 | 0 | 0 | 6 |
|
|
22
|
-
| terms |
|
|
22
|
+
| terms | 29 | 3 | 0 | 0 | 32 |
|
|
23
23
|
| unification | 16 | 0 | 0 | 0 | 16 |
|
|
24
24
|
| variables | 16 | 11 | 0 | 0 | 27 |
|
|
25
|
-
| **Total** | **
|
|
25
|
+
| **Total** | **321** | **56** | **19** | **21** | **417** |
|
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) |
|
|
@@ -373,7 +373,7 @@ Use `holds/2` when you want to match the member term directly, for example `name
|
|
|
373
373
|
| [`equivalence-classes-overlap-implies-same-class.eye`](../examples/equivalence-classes-overlap-implies-same-class.eye) | Packages the shared-member proof pattern for equivalence classes. | [`output/equivalence-classes-overlap-implies-same-class.eye`](../examples/output/equivalence-classes-overlap-implies-same-class.eye) |
|
|
374
374
|
| [`eulerian-path.eye`](../examples/eulerian-path.eye) | Finds an Eulerian path using each edge once. | [`output/eulerian-path.eye`](../examples/output/eulerian-path.eye) |
|
|
375
375
|
| [`ev-range-worlds.eye`](../examples/ev-range-worlds.eye) | Estimates electric-vehicle trip feasibility. | [`output/ev-range-worlds.eye`](../examples/output/ev-range-worlds.eye) |
|
|
376
|
-
| [`existential-rule.eye`](../examples/existential-rule.eye) | Represents existential witnesses with explicit
|
|
376
|
+
| [`existential-rule.eye`](../examples/existential-rule.eye) | Represents existential-style witnesses with explicit Herbrand terms. | [`output/existential-rule.eye`](../examples/output/existential-rule.eye) |
|
|
377
377
|
| [`exoplanet-validation-worlds.eye`](../examples/exoplanet-validation-worlds.eye) | Validates exoplanet candidates across worlds. | [`output/exoplanet-validation-worlds.eye`](../examples/output/exoplanet-validation-worlds.eye) |
|
|
378
378
|
| [`expression-eval.eye`](../examples/expression-eval.eye) | Evaluates a small arithmetic expression tree. | [`output/expression-eval.eye`](../examples/output/expression-eval.eye) |
|
|
379
379
|
| [`family-cousins.eye`](../examples/family-cousins.eye) | Derives cousin and family labels. | [`output/family-cousins.eye`](../examples/output/family-cousins.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,18 +433,22 @@ 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
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) |
|
|
@@ -452,6 +459,7 @@ Use `holds/2` when you want to match the member term directly, for example `name
|
|
|
452
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) |
|
|
453
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) |
|
|
454
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) |
|
|
455
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) |
|
|
456
464
|
| [`totient-summatory.eye`](../examples/totient-summatory.eye) | Computes Euler totients and their summatory function. | [`output/totient-summatory.eye`](../examples/output/totient-summatory.eye) |
|
|
457
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) |
|
|
@@ -462,6 +470,7 @@ Use `holds/2` when you want to match the member term directly, for example `name
|
|
|
462
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) |
|
|
463
471
|
| [`witch.eye`](../examples/witch.eye) | Derives the classic “burn the witch” rule chain. | [`output/witch.eye`](../examples/output/witch.eye) |
|
|
464
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) |
|
|
465
474
|
| [`zebra.eye`](../examples/zebra.eye) | Solves the zebra logic puzzle. | [`output/zebra.eye`](../examples/output/zebra.eye) |
|
|
466
475
|
|
|
467
476
|
## Golden outputs, tests, and conformance
|
|
@@ -333,6 +333,18 @@ Equivalently, the least Herbrand model is obtained by repeatedly applying the im
|
|
|
333
333
|
|
|
334
334
|
Variables do not range over external objects, records, pointers, or host-language values. In the logical reading, variables range over Herbrand terms. A rule is implicitly universally quantified over its variables. A selected goal is existential in the usual logic-programming sense: eyelang searches for substitutions of its variables by Herbrand terms that make the goal true with respect to the program.
|
|
335
335
|
|
|
336
|
+
eyelang has no blank nodes and no existential variables in rule heads. Existential-style consequences SHOULD be represented by explicit Herbrand witness terms written directly in rule heads:
|
|
337
|
+
|
|
338
|
+
```eyelang
|
|
339
|
+
has_parent(?child, parent_of(?child)) :-
|
|
340
|
+
person(?child).
|
|
341
|
+
|
|
342
|
+
registration(?student, ?course, registration_of(?student, ?course)) :-
|
|
343
|
+
takes(?student, ?course).
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
These rules may derive `parent_of(alice)` or `registration_of(alice, logic)` as ordinary visible Herbrand terms. The witness is deterministic: the same functor and inputs produce the same term, while different inputs produce different terms by normal syntactic identity. This is the practical executable form of existential-style consequences in Eyelang; it does not introduce hidden blank nodes or special quantifier syntax.
|
|
347
|
+
|
|
336
348
|
### 8.2 Equality, identity, and unification
|
|
337
349
|
|
|
338
350
|
Because the domain is Herbrand, equality in the pure language is syntactic identity of terms after substitution. Two distinct atom constants are distinct. Two compound terms are equal only when they have the same functor, the same arity, and pairwise equal arguments. Lists follow the same rule through their `[]` and `./2` representation.
|
|
@@ -1,21 +1,14 @@
|
|
|
1
|
-
% Existential introduction with explicit witnesses.
|
|
2
|
-
% Eyeling's original N3 rule creates existential blank nodes; in Eyelang the
|
|
3
|
-
% same idea is represented by deterministic Skolem-style witness terms so the
|
|
4
|
-
% generated individual is visible in ordinary output.
|
|
1
|
+
% Existential-style introduction with explicit Herbrand witnesses.
|
|
5
2
|
%
|
|
6
|
-
%
|
|
7
|
-
|
|
3
|
+
% Eyelang has no blank nodes and no existential variables in rule heads. A
|
|
4
|
+
% rule can still express the practical executable shape of an existential
|
|
5
|
+
% consequence by putting a named functional term directly in the head.
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
% each human. The single rule below is the existential-style introduction step.
|
|
7
|
+
materialize(is, 2).
|
|
11
8
|
|
|
12
9
|
type(socrates, human).
|
|
13
10
|
type(plato, human).
|
|
14
11
|
|
|
15
|
-
witness
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
% In proof output this rule is the step that explains why each witness exists.
|
|
19
|
-
is(?person, ?witness) :-
|
|
20
|
-
type(?person, human),
|
|
21
|
-
witness(?person, ?witness).
|
|
12
|
+
% In proof output this rule is the step that explains each visible witness.
|
|
13
|
+
is(?person, human_witness(?person)) :-
|
|
14
|
+
type(?person, human).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
% Existential-style consequences as explicit Herbrand witness terms.
|
|
2
|
+
%
|
|
3
|
+
% Eyelang has no blank nodes and no existential variables in rule heads. The
|
|
4
|
+
% practical executable form is to put a named functional term directly in the
|
|
5
|
+
% rule head. The term is ordinary data: stable, visible, and proof-friendly.
|
|
6
|
+
|
|
7
|
+
materialize(has_parent, 2).
|
|
8
|
+
materialize(registration, 3).
|
|
9
|
+
materialize(same_witness, 2).
|
|
10
|
+
materialize(distinct_witnesses, 2).
|
|
11
|
+
|
|
12
|
+
person(alice).
|
|
13
|
+
person(bob).
|
|
14
|
+
|
|
15
|
+
takes(alice, logic).
|
|
16
|
+
takes(alice, math).
|
|
17
|
+
takes(bob, logic).
|
|
18
|
+
|
|
19
|
+
% One variable: every person has a deterministic parent witness.
|
|
20
|
+
has_parent(?child, parent_of(?child)) :-
|
|
21
|
+
person(?child).
|
|
22
|
+
|
|
23
|
+
% Two variables: every student/course pair has its own registration witness.
|
|
24
|
+
registration(?student, ?course, registration_of(?student, ?course)) :-
|
|
25
|
+
takes(?student, ?course).
|
|
26
|
+
|
|
27
|
+
same_witness(parent_of_alice, true) :-
|
|
28
|
+
eq(parent_of(alice), parent_of(alice)).
|
|
29
|
+
|
|
30
|
+
distinct_witnesses(alice_logic_vs_alice_math, true) :-
|
|
31
|
+
neq(registration_of(alice, logic), registration_of(alice, math)).
|
|
@@ -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).
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
is(socrates,
|
|
2
|
-
is(plato,
|
|
1
|
+
is(socrates, human_witness(socrates)).
|
|
2
|
+
is(plato, human_witness(plato)).
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
has_parent(alice, parent_of(alice)).
|
|
2
|
+
has_parent(bob, parent_of(bob)).
|
|
3
|
+
registration(alice, logic, registration_of(alice, logic)).
|
|
4
|
+
registration(alice, math, registration_of(alice, math)).
|
|
5
|
+
registration(bob, logic, registration_of(bob, logic)).
|
|
6
|
+
same_witness(parent_of_alice, true).
|
|
7
|
+
distinct_witnesses(alice_logic_vs_alice_math, true).
|
|
@@ -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,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,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).
|
|
@@ -1,38 +1,30 @@
|
|
|
1
|
-
is(socrates,
|
|
1
|
+
is(socrates, human_witness(socrates)).
|
|
2
2
|
why(
|
|
3
|
-
is(socrates,
|
|
3
|
+
is(socrates, human_witness(socrates)),
|
|
4
4
|
proof(
|
|
5
|
-
goal(is(socrates,
|
|
6
|
-
by(rule("existential-rule.eye", clause(
|
|
7
|
-
bindings([binding("?person", socrates)
|
|
5
|
+
goal(is(socrates, human_witness(socrates))),
|
|
6
|
+
by(rule("existential-rule.eye", clause(4))),
|
|
7
|
+
bindings([binding("?person", socrates)]),
|
|
8
8
|
uses([
|
|
9
9
|
proof(
|
|
10
10
|
goal(type(socrates, human)),
|
|
11
11
|
by(fact("existential-rule.eye", clause(2)))
|
|
12
|
-
),
|
|
13
|
-
proof(
|
|
14
|
-
goal(witness(socrates, sk_0)),
|
|
15
|
-
by(fact("existential-rule.eye", clause(4)))
|
|
16
12
|
)
|
|
17
13
|
])
|
|
18
14
|
)
|
|
19
15
|
).
|
|
20
16
|
|
|
21
|
-
is(plato,
|
|
17
|
+
is(plato, human_witness(plato)).
|
|
22
18
|
why(
|
|
23
|
-
is(plato,
|
|
19
|
+
is(plato, human_witness(plato)),
|
|
24
20
|
proof(
|
|
25
|
-
goal(is(plato,
|
|
26
|
-
by(rule("existential-rule.eye", clause(
|
|
27
|
-
bindings([binding("?person", plato)
|
|
21
|
+
goal(is(plato, human_witness(plato))),
|
|
22
|
+
by(rule("existential-rule.eye", clause(4))),
|
|
23
|
+
bindings([binding("?person", plato)]),
|
|
28
24
|
uses([
|
|
29
25
|
proof(
|
|
30
26
|
goal(type(plato, human)),
|
|
31
27
|
by(fact("existential-rule.eye", clause(3)))
|
|
32
|
-
),
|
|
33
|
-
proof(
|
|
34
|
-
goal(witness(plato, sk_1)),
|
|
35
|
-
by(fact("existential-rule.eye", clause(5)))
|
|
36
28
|
)
|
|
37
29
|
])
|
|
38
30
|
)
|
|
@@ -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
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,18 +557,22 @@
|
|
|
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
578
|
"socket-age",
|
|
@@ -576,6 +583,7 @@
|
|
|
576
583
|
"stirling-bell-numbers",
|
|
577
584
|
"sudoku-4x4",
|
|
578
585
|
"superdense-coding",
|
|
586
|
+
"symbolic-derivative",
|
|
579
587
|
"term-tools",
|
|
580
588
|
"totient-summatory",
|
|
581
589
|
"trust-flow-provenance-threshold",
|
|
@@ -586,6 +594,7 @@
|
|
|
586
594
|
"weighted-interval-scheduling",
|
|
587
595
|
"witch",
|
|
588
596
|
"wolf-goat-cabbage",
|
|
597
|
+
"workplace-compliance",
|
|
589
598
|
"zebra"
|
|
590
599
|
];
|
|
591
600
|
const FALLBACK_SOURCE = `materialize(answer, 1).
|
package/src/builtins/terms.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
answer(true).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
answer(true).
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
has_parent(alice, parent_of(alice)).
|
|
2
|
+
why(
|
|
3
|
+
has_parent(alice, parent_of(alice)),
|
|
4
|
+
proof(
|
|
5
|
+
goal(has_parent(alice, parent_of(alice))),
|
|
6
|
+
by(rule("<stdin>", clause(2))),
|
|
7
|
+
bindings([binding("?child", alice)]),
|
|
8
|
+
uses([
|
|
9
|
+
proof(
|
|
10
|
+
goal(person(alice)),
|
|
11
|
+
by(fact("<stdin>", clause(1)))
|
|
12
|
+
)
|
|
13
|
+
])
|
|
14
|
+
)
|
|
15
|
+
).
|
|
16
|
+
|