eyelang 1.1.16 → 1.1.17
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 +10 -3
- package/docs/language-reference.md +1 -1
- package/examples/binomial-vandermonde.pl +45 -0
- package/examples/catalan-convolution.pl +33 -0
- package/examples/continued-fraction-sqrt2.pl +30 -0
- package/examples/integer-partitions.pl +30 -0
- package/examples/matrix-chain-order.pl +72 -0
- package/examples/modular-exponentiation.pl +31 -0
- package/examples/output/binomial-vandermonde.pl +4 -0
- package/examples/output/catalan-convolution.pl +4 -0
- package/examples/output/continued-fraction-sqrt2.pl +4 -0
- package/examples/output/integer-partitions.pl +4 -0
- package/examples/output/matrix-chain-order.pl +4 -0
- package/examples/output/modular-exponentiation.pl +4 -0
- package/examples/output/pell-equation.pl +4 -0
- package/examples/output/stirling-bell-numbers.pl +4 -0
- package/examples/output/totient-summatory.pl +4 -0
- package/examples/pell-equation.pl +29 -0
- package/examples/stirling-bell-numbers.pl +26 -0
- package/examples/totient-summatory.pl +29 -0
- package/package.json +1 -1
- package/playground.html +9 -0
- package/test/run-regression.mjs +10 -0
package/docs/guide.md
CHANGED
|
@@ -197,7 +197,7 @@ The default output is then:
|
|
|
197
197
|
answer(case1, accepted).
|
|
198
198
|
```
|
|
199
199
|
|
|
200
|
-
`materialize/2` is a declaration, not a logical rule to prove. It affects which predicates the CLI prints, not the meaning of the rules themselves.
|
|
200
|
+
`materialize/2` is a declaration, not a logical rule to prove. It affects which predicates the CLI prints, not the meaning of the rules themselves. Materialized output facts are not inserted back into the running program for later goals; if later output predicates reuse the same derived helper relation, eyelang proves it again unless that helper is declared with `memoize/2`. Source facts are indexed and reused normally, and memoized solved goals are reused inside the same solver run.
|
|
201
201
|
|
|
202
202
|
## Writing programs
|
|
203
203
|
|
|
@@ -321,6 +321,7 @@ Each example has a checked golden output in `examples/output`.
|
|
|
321
321
|
| [`bayes-diagnosis.pl`](../examples/bayes-diagnosis.pl) | Computes scaled Bayesian diagnosis posteriors. | [`output/bayes-diagnosis.pl`](../examples/output/bayes-diagnosis.pl) |
|
|
322
322
|
| [`bayes-therapy.pl`](../examples/bayes-therapy.pl) | Ranks therapies using Bayesian disease likelihoods. | [`output/bayes-therapy.pl`](../examples/output/bayes-therapy.pl) |
|
|
323
323
|
| [`beam-deflection.pl`](../examples/beam-deflection.pl) | Computes cantilever beam deflection. | [`output/beam-deflection.pl`](../examples/output/beam-deflection.pl) |
|
|
324
|
+
| [`binomial-vandermonde.pl`](../examples/binomial-vandermonde.pl) | Computes binomial coefficients and checks Vandermonde's identity. | [`output/binomial-vandermonde.pl`](../examples/output/binomial-vandermonde.pl) |
|
|
324
325
|
| [`blocks-world-planning.pl`](../examples/blocks-world-planning.pl) | Searches a finite blocks-world plan. | [`output/blocks-world-planning.pl`](../examples/output/blocks-world-planning.pl) |
|
|
325
326
|
| [`bmi.pl`](../examples/bmi.pl) | Normalizes BMI inputs and classifies weight. | [`output/bmi.pl`](../examples/output/bmi.pl) |
|
|
326
327
|
| [`braking-safety-worlds.pl`](../examples/braking-safety-worlds.pl) | Classifies braking safety under alternative worlds. | [`output/braking-safety-worlds.pl`](../examples/output/braking-safety-worlds.pl) |
|
|
@@ -328,6 +329,7 @@ Each example has a checked golden output in `examples/output`.
|
|
|
328
329
|
| [`cache-performance.pl`](../examples/cache-performance.pl) | Summarizes cache latency performance. | [`output/cache-performance.pl`](../examples/output/cache-performance.pl) |
|
|
329
330
|
| [`canary-release.pl`](../examples/canary-release.pl) | Decides canary rollout or rollback. | [`output/canary-release.pl`](../examples/output/canary-release.pl) |
|
|
330
331
|
| [`cat-koko.pl`](../examples/cat-koko.pl) | Demonstrates named existential witnesses from a Cat Koko rule pattern. | [`output/cat-koko.pl`](../examples/output/cat-koko.pl) |
|
|
332
|
+
| [`catalan-convolution.pl`](../examples/catalan-convolution.pl) | Computes Catalan numbers by memoized convolution. | [`output/catalan-convolution.pl`](../examples/output/catalan-convolution.pl) |
|
|
331
333
|
| [`chart-parser.pl`](../examples/chart-parser.pl) | Parses small sentences with a memoized chart parser. | [`output/chart-parser.pl`](../examples/output/chart-parser.pl) |
|
|
332
334
|
| [`clinical-trial-screening.pl`](../examples/clinical-trial-screening.pl) | Screens candidates for a trial. | [`output/clinical-trial-screening.pl`](../examples/output/clinical-trial-screening.pl) |
|
|
333
335
|
| [`collatz-1000.pl`](../examples/collatz-1000.pl) | Materializes Collatz trajectories for starts 1000 down to 1. | [`output/collatz-1000.pl`](../examples/output/collatz-1000.pl) |
|
|
@@ -337,6 +339,7 @@ Each example has a checked golden output in `examples/output`.
|
|
|
337
339
|
| [`composition-of-injective-functions-is-injective.pl`](../examples/composition-of-injective-functions-is-injective.pl) | Encodes composition and injectivity of finite functions. | [`output/composition-of-injective-functions-is-injective.pl`](../examples/output/composition-of-injective-functions-is-injective.pl) |
|
|
338
340
|
| [`context-association.pl`](../examples/context-association.pl) | Associates named contexts with their contents. | [`output/context-association.pl`](../examples/output/context-association.pl) |
|
|
339
341
|
| [`context-schema-audit.pl`](../examples/context-schema-audit.pl) | Audits mixed-arity context members with `holds/3`. | [`output/context-schema-audit.pl`](../examples/output/context-schema-audit.pl) |
|
|
342
|
+
| [`continued-fraction-sqrt2.pl`](../examples/continued-fraction-sqrt2.pl) | Computes sqrt(2) continued-fraction convergents and Pell errors. | [`output/continued-fraction-sqrt2.pl`](../examples/output/continued-fraction-sqrt2.pl) |
|
|
340
343
|
| [`control-system.pl`](../examples/control-system.pl) | Evaluates control-system measurements and targets. | [`output/control-system.pl`](../examples/output/control-system.pl) |
|
|
341
344
|
| [`critical-path-schedule.pl`](../examples/critical-path-schedule.pl) | Computes earliest starts and the critical path for a project network. | [`output/critical-path-schedule.pl`](../examples/output/critical-path-schedule.pl) |
|
|
342
345
|
| [`cyclic-path.pl`](../examples/cyclic-path.pl) | Computes paths in a cyclic graph. | [`output/cyclic-path.pl`](../examples/output/cyclic-path.pl) |
|
|
@@ -393,6 +396,7 @@ Each example has a checked golden output in `examples/output`.
|
|
|
393
396
|
| [`heron-theorem.pl`](../examples/heron-theorem.pl) | Computes triangle area by Heron's theorem. | [`output/heron-theorem.pl`](../examples/output/heron-theorem.pl) |
|
|
394
397
|
| [`ideal-gas-law.pl`](../examples/ideal-gas-law.pl) | Applies the ideal gas law. | [`output/ideal-gas-law.pl`](../examples/output/ideal-gas-law.pl) |
|
|
395
398
|
| [`illegitimate-reasoning.pl`](../examples/illegitimate-reasoning.pl) | Detects suspect reasoning patterns. | [`output/illegitimate-reasoning.pl`](../examples/output/illegitimate-reasoning.pl) |
|
|
399
|
+
| [`integer-partitions.pl`](../examples/integer-partitions.pl) | Counts integer partitions with memoized dynamic programming. | [`output/integer-partitions.pl`](../examples/output/integer-partitions.pl) |
|
|
396
400
|
| [`job-shop-scheduling.pl`](../examples/job-shop-scheduling.pl) | Searches a small job-shop schedule and minimizes makespan. | [`output/job-shop-scheduling.pl`](../examples/output/job-shop-scheduling.pl) |
|
|
397
401
|
| [`knapsack-optimization.pl`](../examples/knapsack-optimization.pl) | Optimizes a finite 0/1 knapsack pack with aggregation. | [`output/knapsack-optimization.pl`](../examples/output/knapsack-optimization.pl) |
|
|
398
402
|
| [`knowledge-engineering-alignment-flow.pl`](../examples/knowledge-engineering-alignment-flow.pl) | Specializes reusable alignment rules into a target-shaped flow view. | [`output/knowledge-engineering-alignment-flow.pl`](../examples/output/knowledge-engineering-alignment-flow.pl) |
|
|
@@ -401,8 +405,10 @@ Each example has a checked golden output in `examples/output`.
|
|
|
401
405
|
| [`list-collection.pl`](../examples/list-collection.pl) | Demonstrates list and collection built-ins. | [`output/list-collection.pl`](../examples/output/list-collection.pl) |
|
|
402
406
|
| [`lldm.pl`](../examples/lldm.pl) | Calculates leg-length discrepancy measurements. | [`output/lldm.pl`](../examples/output/lldm.pl) |
|
|
403
407
|
| [`manufacturing-quality-control.pl`](../examples/manufacturing-quality-control.pl) | Evaluates process capability and quality. | [`output/manufacturing-quality-control.pl`](../examples/output/manufacturing-quality-control.pl) |
|
|
408
|
+
| [`matrix-chain-order.pl`](../examples/matrix-chain-order.pl) | Finds an optimal matrix-chain multiplication order. | [`output/matrix-chain-order.pl`](../examples/output/matrix-chain-order.pl) |
|
|
404
409
|
| [`microgrid-dispatch.pl`](../examples/microgrid-dispatch.pl) | Plans microgrid dispatch and reserve. | [`output/microgrid-dispatch.pl`](../examples/output/microgrid-dispatch.pl) |
|
|
405
410
|
| [`missionaries-cannibals.pl`](../examples/missionaries-cannibals.pl) | Solves the missionaries-and-cannibals river crossing puzzle. | [`output/missionaries-cannibals.pl`](../examples/output/missionaries-cannibals.pl) |
|
|
411
|
+
| [`modular-exponentiation.pl`](../examples/modular-exponentiation.pl) | Computes modular powers by repeated squaring. | [`output/modular-exponentiation.pl`](../examples/output/modular-exponentiation.pl) |
|
|
406
412
|
| [`monkey-bananas.pl`](../examples/monkey-bananas.pl) | Solves the monkey-and-bananas puzzle. | [`output/monkey-bananas.pl`](../examples/output/monkey-bananas.pl) |
|
|
407
413
|
| [`n-queens-8.pl`](../examples/n-queens-8.pl) | Solves the 8-queens search problem with diagonal constraints. | [`output/n-queens-8.pl`](../examples/output/n-queens-8.pl) |
|
|
408
414
|
| [`network-sla.pl`](../examples/network-sla.pl) | Checks network path SLA compliance. | [`output/network-sla.pl`](../examples/output/network-sla.pl) |
|
|
@@ -416,6 +422,7 @@ Each example has a checked golden output in `examples/output`.
|
|
|
416
422
|
| [`path-discovery.pl`](../examples/path-discovery.pl) | Discovers bounded air-route paths. | [`output/path-discovery.pl`](../examples/output/path-discovery.pl) |
|
|
417
423
|
| [`peano-arithmetic.pl`](../examples/peano-arithmetic.pl) | Computes Peano addition, multiplication, and factorial. | [`output/peano-arithmetic.pl`](../examples/output/peano-arithmetic.pl) |
|
|
418
424
|
| [`peasant.pl`](../examples/peasant.pl) | Performs peasant multiplication and exponentiation. | [`output/peasant.pl`](../examples/output/peasant.pl) |
|
|
425
|
+
| [`pell-equation.pl`](../examples/pell-equation.pl) | Generates Pell-equation solutions by recurrence. | [`output/pell-equation.pl`](../examples/output/pell-equation.pl) |
|
|
419
426
|
| [`pendulum-period.pl`](../examples/pendulum-period.pl) | Computes simple pendulum periods. | [`output/pendulum-period.pl`](../examples/output/pendulum-period.pl) |
|
|
420
427
|
| [`polynomial.pl`](../examples/polynomial.pl) | Finds complex integer polynomial roots. | [`output/polynomial.pl`](../examples/output/polynomial.pl) |
|
|
421
428
|
| [`proof-contrapositive.pl`](../examples/proof-contrapositive.pl) | Models proof by contrapositive. | [`output/proof-contrapositive.pl`](../examples/output/proof-contrapositive.pl) |
|
|
@@ -433,9 +440,11 @@ Each example has a checked golden output in `examples/output`.
|
|
|
433
440
|
| [`socrates.pl`](../examples/socrates.pl) | Derives that Socrates is mortal. | [`output/socrates.pl`](../examples/output/socrates.pl) |
|
|
434
441
|
| [`stable-marriage.pl`](../examples/stable-marriage.pl) | Finds stable matchings by excluding blocking pairs. | [`output/stable-marriage.pl`](../examples/output/stable-marriage.pl) |
|
|
435
442
|
| [`statistics-summary.pl`](../examples/statistics-summary.pl) | Computes population statistics for a sample. | [`output/statistics-summary.pl`](../examples/output/statistics-summary.pl) |
|
|
443
|
+
| [`stirling-bell-numbers.pl`](../examples/stirling-bell-numbers.pl) | Computes Stirling numbers and Bell numbers. | [`output/stirling-bell-numbers.pl`](../examples/output/stirling-bell-numbers.pl) |
|
|
436
444
|
| [`sudoku-4x4.pl`](../examples/sudoku-4x4.pl) | Solves a compact 4x4 Sudoku by finite constraint search. | [`output/sudoku-4x4.pl`](../examples/output/sudoku-4x4.pl) |
|
|
437
445
|
| [`superdense-coding.pl`](../examples/superdense-coding.pl) | Models superdense-coding bit transmission. | [`output/superdense-coding.pl`](../examples/output/superdense-coding.pl) |
|
|
438
446
|
| [`term-tools.pl`](../examples/term-tools.pl) | Inspects, builds, renders, and validates terms with reusable term/control builtins. | [`output/term-tools.pl`](../examples/output/term-tools.pl) |
|
|
447
|
+
| [`totient-summatory.pl`](../examples/totient-summatory.pl) | Computes Euler totients and their summatory function. | [`output/totient-summatory.pl`](../examples/output/totient-summatory.pl) |
|
|
439
448
|
| [`trust-flow-provenance-threshold.pl`](../examples/trust-flow-provenance-threshold.pl) | Classifies message trust from provenance confidence scores. | [`output/trust-flow-provenance-threshold.pl`](../examples/output/trust-flow-provenance-threshold.pl) |
|
|
440
449
|
| [`turing.pl`](../examples/turing.pl) | Simulates a binary-increment Turing machine. | [`output/turing.pl`](../examples/output/turing.pl) |
|
|
441
450
|
| [`vector-similarity.pl`](../examples/vector-similarity.pl) | Computes dot product, norm, and cosine similarity. | [`output/vector-similarity.pl`](../examples/output/vector-similarity.pl) |
|
|
@@ -445,8 +454,6 @@ Each example has a checked golden output in `examples/output`.
|
|
|
445
454
|
| [`wolf-goat-cabbage.pl`](../examples/wolf-goat-cabbage.pl) | Solves the wolf-goat-cabbage river crossing. | [`output/wolf-goat-cabbage.pl`](../examples/output/wolf-goat-cabbage.pl) |
|
|
446
455
|
| [`zebra.pl`](../examples/zebra.pl) | Solves the zebra logic puzzle. | [`output/zebra.pl`](../examples/output/zebra.pl) |
|
|
447
456
|
|
|
448
|
-
|
|
449
|
-
|
|
450
457
|
## Golden outputs, tests, and conformance
|
|
451
458
|
|
|
452
459
|
Golden answer outputs live in [`examples/output`](../examples/output). `npm run test:eyelang` covers the eyelang integration check, conformance cases, regression checks, runnable examples, and proof-output examples. A curated proof-output suite for `.pl` examples lives in [`examples/proof`](../examples/proof). Example tests pin `local_time/1` to `2026-05-30` so date-dependent examples stay deterministic. Regenerate them after an intentional output or explanation change:
|
|
@@ -534,7 +534,7 @@ materialize(status, 2).
|
|
|
534
534
|
materialize(reason, 2).
|
|
535
535
|
```
|
|
536
536
|
|
|
537
|
-
`materialize/2` affects host output selection only; it does not change the logical meaning of the program.
|
|
537
|
+
`materialize/2` affects host output selection only; it does not change the logical meaning of the program. Materialized output facts are not asserted as new source facts for subsequent output goals. A host MAY solve several materialized predicates in one solver run, and memoized predicate answers MAY be reused within that run, but this reuse is controlled by `memoize/2`, not by materialization.
|
|
538
538
|
|
|
539
539
|
## 12. Eyelang Sockets
|
|
540
540
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
% Binomial coefficients and Vandermonde's identity.
|
|
2
|
+
% choose_step/5 uses the multiplicative recurrence
|
|
3
|
+
% C(N, I+1) = C(N, I) * (N-I) / (I+1)
|
|
4
|
+
% and is memoized because row sums and identities reuse prefixes.
|
|
5
|
+
materialize(binomial_answer, 2).
|
|
6
|
+
|
|
7
|
+
memoize(choose_step, 5).
|
|
8
|
+
|
|
9
|
+
choose(N, K, C) :-
|
|
10
|
+
ge(K, 0),
|
|
11
|
+
le(K, N),
|
|
12
|
+
choose_step(N, K, 0, 1, C).
|
|
13
|
+
|
|
14
|
+
choose_step(_N, K, K, Acc, Acc).
|
|
15
|
+
choose_step(N, K, I, Acc, C) :-
|
|
16
|
+
lt(I, K),
|
|
17
|
+
add(I, 1, I1),
|
|
18
|
+
sub(N, I, Factor),
|
|
19
|
+
mul(Acc, Factor, Numerator),
|
|
20
|
+
div(Numerator, I1, NextAcc),
|
|
21
|
+
choose_step(N, K, I1, NextAcc, C).
|
|
22
|
+
|
|
23
|
+
symmetric(N, K) :-
|
|
24
|
+
choose(N, K, C),
|
|
25
|
+
sub(N, K, OtherK),
|
|
26
|
+
choose(N, OtherK, C).
|
|
27
|
+
|
|
28
|
+
vandermonde_sum(N, M, R, Sum) :-
|
|
29
|
+
sumall(Product,
|
|
30
|
+
(between(0, R, K),
|
|
31
|
+
sub(R, K, RK),
|
|
32
|
+
choose(N, K, A),
|
|
33
|
+
choose(M, RK, B),
|
|
34
|
+
mul(A, B, Product)),
|
|
35
|
+
Sum).
|
|
36
|
+
|
|
37
|
+
vandermonde(N, M, R, Sum) :-
|
|
38
|
+
add(N, M, TotalN),
|
|
39
|
+
choose(TotalN, R, Sum),
|
|
40
|
+
vandermonde_sum(N, M, R, Sum).
|
|
41
|
+
|
|
42
|
+
binomial_answer(choose_24_12, C) :- choose(24, 12, C).
|
|
43
|
+
binomial_answer(symmetry_24_7, true) :- symmetric(24, 7).
|
|
44
|
+
binomial_answer(vandermonde_12_10_8, Sum) :- vandermonde(12, 10, 8, Sum).
|
|
45
|
+
binomial_answer(row_12_sum, Sum) :- sumall(C, (between(0, 12, K), choose(12, K, C)), Sum).
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
% Catalan numbers by memoized convolution.
|
|
2
|
+
% catalan/2 counts binary tree shapes, parenthesizations, and polygon
|
|
3
|
+
% triangulations with the usual index shifts.
|
|
4
|
+
materialize(catalan_answer, 2).
|
|
5
|
+
|
|
6
|
+
memoize(catalan, 2).
|
|
7
|
+
|
|
8
|
+
catalan(0, 1).
|
|
9
|
+
catalan(N, C) :-
|
|
10
|
+
gt(N, 0),
|
|
11
|
+
sub(N, 1, N1),
|
|
12
|
+
sumall(Product,
|
|
13
|
+
(between(0, N1, I),
|
|
14
|
+
sub(N1, I, J),
|
|
15
|
+
catalan(I, A),
|
|
16
|
+
catalan(J, B),
|
|
17
|
+
mul(A, B, Product)),
|
|
18
|
+
C).
|
|
19
|
+
|
|
20
|
+
polygon_triangulations(Sides, Count) :-
|
|
21
|
+
ge(Sides, 3),
|
|
22
|
+
sub(Sides, 2, N),
|
|
23
|
+
catalan(N, Count).
|
|
24
|
+
|
|
25
|
+
parenthesizations(Factors, Count) :-
|
|
26
|
+
ge(Factors, 1),
|
|
27
|
+
sub(Factors, 1, N),
|
|
28
|
+
catalan(N, Count).
|
|
29
|
+
|
|
30
|
+
catalan_answer(catalan_12, C) :- catalan(12, C).
|
|
31
|
+
catalan_answer(triangulations_14_gon, Count) :- polygon_triangulations(14, Count).
|
|
32
|
+
catalan_answer(parenthesizations_13_factors, Count) :- parenthesizations(13, Count).
|
|
33
|
+
catalan_answer(first_ten_sum, Sum) :- sumall(C, (between(0, 9, N), catalan(N, C)), Sum).
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
% Convergents of sqrt(2) by memoized recurrence.
|
|
2
|
+
% conv(N, P, Q) gives the Nth convergent numerator/denominator for [1;2,2,...].
|
|
3
|
+
materialize(convergent_answer, 2).
|
|
4
|
+
|
|
5
|
+
memoize(conv, 3).
|
|
6
|
+
|
|
7
|
+
conv(0, 1, 1).
|
|
8
|
+
conv(1, 3, 2).
|
|
9
|
+
conv(N, P, Q) :-
|
|
10
|
+
gt(N, 1),
|
|
11
|
+
sub(N, 1, N1),
|
|
12
|
+
sub(N, 2, N2),
|
|
13
|
+
conv(N1, P1, Q1),
|
|
14
|
+
conv(N2, P2, Q2),
|
|
15
|
+
mul(2, P1, TwiceP1),
|
|
16
|
+
add(TwiceP1, P2, P),
|
|
17
|
+
mul(2, Q1, TwiceQ1),
|
|
18
|
+
add(TwiceQ1, Q2, Q).
|
|
19
|
+
|
|
20
|
+
pell_error(N, Error) :-
|
|
21
|
+
conv(N, P, Q),
|
|
22
|
+
mul(P, P, P2),
|
|
23
|
+
mul(Q, Q, Q2),
|
|
24
|
+
mul(2, Q2, TwiceQ2),
|
|
25
|
+
sub(P2, TwiceQ2, Error).
|
|
26
|
+
|
|
27
|
+
convergent_answer(convergent_10, fraction(P, Q)) :- conv(10, P, Q).
|
|
28
|
+
convergent_answer(convergent_15, fraction(P, Q)) :- conv(15, P, Q).
|
|
29
|
+
convergent_answer(pell_error_15, Error) :- pell_error(15, Error).
|
|
30
|
+
convergent_answer(numerator_sum_0_to_10, Sum) :- sumall(P, (between(0, 10, N), conv(N, P, _Q)), Sum).
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
% Integer partition counts by memoized dynamic programming.
|
|
2
|
+
% partitions(N, K, Count) counts partitions of N using parts no larger than K.
|
|
3
|
+
materialize(partition_answer, 2).
|
|
4
|
+
|
|
5
|
+
memoize(partitions, 3).
|
|
6
|
+
|
|
7
|
+
partitions(0, _K, 1).
|
|
8
|
+
partitions(N, 0, 0) :- gt(N, 0).
|
|
9
|
+
partitions(N, K, Count) :-
|
|
10
|
+
gt(N, 0),
|
|
11
|
+
gt(K, 0),
|
|
12
|
+
gt(K, N),
|
|
13
|
+
sub(K, 1, K1),
|
|
14
|
+
partitions(N, K1, Count).
|
|
15
|
+
partitions(N, K, Count) :-
|
|
16
|
+
gt(N, 0),
|
|
17
|
+
gt(K, 0),
|
|
18
|
+
le(K, N),
|
|
19
|
+
sub(N, K, Remainder),
|
|
20
|
+
partitions(Remainder, K, WithK),
|
|
21
|
+
sub(K, 1, K1),
|
|
22
|
+
partitions(N, K1, WithoutK),
|
|
23
|
+
add(WithK, WithoutK, Count).
|
|
24
|
+
|
|
25
|
+
partition_count(N, Count) :- partitions(N, N, Count).
|
|
26
|
+
|
|
27
|
+
partition_answer(p_12, Count) :- partition_count(12, Count).
|
|
28
|
+
partition_answer(p_15, Count) :- partition_count(15, Count).
|
|
29
|
+
partition_answer(p_16_using_parts_at_most_5, Count) :- partitions(16, 5, Count).
|
|
30
|
+
partition_answer(cumulative_p_1_to_8, Sum) :- sumall(C, (between(1, 8, N), partition_count(N, C)), Sum).
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
% Matrix-chain multiplication order by memoized interval dynamic programming.
|
|
2
|
+
% cost(I, J, Cost) is the minimum scalar multiplication cost for matrices I..J.
|
|
3
|
+
materialize(matrix_chain_answer, 2).
|
|
4
|
+
|
|
5
|
+
memoize(cost, 3).
|
|
6
|
+
|
|
7
|
+
% Dimensions for the CLRS-style chain: A1 is 30x35, A2 is 35x15, ...
|
|
8
|
+
dim(0, 30).
|
|
9
|
+
dim(1, 35).
|
|
10
|
+
dim(2, 15).
|
|
11
|
+
dim(3, 5).
|
|
12
|
+
dim(4, 10).
|
|
13
|
+
dim(5, 20).
|
|
14
|
+
dim(6, 25).
|
|
15
|
+
|
|
16
|
+
matrix_count(6).
|
|
17
|
+
|
|
18
|
+
cost(I, I, 0) :- matrix_count(N), between(1, N, I).
|
|
19
|
+
cost(I, J, Cost) :-
|
|
20
|
+
lt(I, J),
|
|
21
|
+
aggregate_min(SplitCost, K,
|
|
22
|
+
(between(I, J, K),
|
|
23
|
+
lt(K, J),
|
|
24
|
+
cost(I, K, Left),
|
|
25
|
+
add(K, 1, K1),
|
|
26
|
+
cost(K1, J, Right),
|
|
27
|
+
sub(I, 1, I0),
|
|
28
|
+
dim(I0, Rows),
|
|
29
|
+
dim(K, Shared),
|
|
30
|
+
dim(J, Cols),
|
|
31
|
+
mul(Rows, Shared, First),
|
|
32
|
+
mul(First, Cols, MultCost),
|
|
33
|
+
add(Left, Right, Partial),
|
|
34
|
+
add(Partial, MultCost, SplitCost)),
|
|
35
|
+
Cost, _BestK).
|
|
36
|
+
|
|
37
|
+
best_split(I, J, K) :-
|
|
38
|
+
lt(I, J),
|
|
39
|
+
aggregate_min(SplitCost, K,
|
|
40
|
+
(between(I, J, K),
|
|
41
|
+
lt(K, J),
|
|
42
|
+
cost(I, K, Left),
|
|
43
|
+
add(K, 1, K1),
|
|
44
|
+
cost(K1, J, Right),
|
|
45
|
+
sub(I, 1, I0),
|
|
46
|
+
dim(I0, Rows),
|
|
47
|
+
dim(K, Shared),
|
|
48
|
+
dim(J, Cols),
|
|
49
|
+
mul(Rows, Shared, First),
|
|
50
|
+
mul(First, Cols, MultCost),
|
|
51
|
+
add(Left, Right, Partial),
|
|
52
|
+
add(Partial, MultCost, SplitCost)),
|
|
53
|
+
_Cost, K).
|
|
54
|
+
|
|
55
|
+
parenthesization(I, I, matrix(I)).
|
|
56
|
+
parenthesization(I, J, product(LeftTree, RightTree)) :-
|
|
57
|
+
lt(I, J),
|
|
58
|
+
best_split(I, J, K),
|
|
59
|
+
add(K, 1, K1),
|
|
60
|
+
parenthesization(I, K, LeftTree),
|
|
61
|
+
parenthesization(K1, J, RightTree).
|
|
62
|
+
|
|
63
|
+
matrix_chain_answer(min_cost, Cost) :- cost(1, 6, Cost).
|
|
64
|
+
matrix_chain_answer(best_split_1_6, K) :- best_split(1, 6, K).
|
|
65
|
+
matrix_chain_answer(best_order, Tree) :- parenthesization(1, 6, Tree).
|
|
66
|
+
subproblem(I, J, Cost) :-
|
|
67
|
+
matrix_count(N),
|
|
68
|
+
between(1, N, I),
|
|
69
|
+
between(I, N, J),
|
|
70
|
+
cost(I, J, Cost).
|
|
71
|
+
|
|
72
|
+
matrix_chain_answer(subproblem_count, Count) :- countall(subproblem(_I, _J, _Cost), Count).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
% Modular exponentiation by repeated squaring.
|
|
2
|
+
% pow_mod/4 is logarithmic in the exponent and memoized so repeated primality
|
|
3
|
+
% and congruence checks share subproblems.
|
|
4
|
+
materialize(modular_answer, 2).
|
|
5
|
+
|
|
6
|
+
memoize(pow_mod, 4).
|
|
7
|
+
|
|
8
|
+
pow_mod(_Base, 0, Mod, Result) :- mod(1, Mod, Result).
|
|
9
|
+
pow_mod(Base, Exp, Modulus, Result) :-
|
|
10
|
+
gt(Exp, 0),
|
|
11
|
+
mod(Exp, 2, 0),
|
|
12
|
+
div(Exp, 2, Half),
|
|
13
|
+
pow_mod(Base, Half, Modulus, HalfPower),
|
|
14
|
+
mul(HalfPower, HalfPower, Square),
|
|
15
|
+
mod(Square, Modulus, Result).
|
|
16
|
+
pow_mod(Base, Exp, Modulus, Result) :-
|
|
17
|
+
gt(Exp, 0),
|
|
18
|
+
mod(Exp, 2, 1),
|
|
19
|
+
sub(Exp, 1, EvenExp),
|
|
20
|
+
pow_mod(Base, EvenExp, Modulus, EvenPower),
|
|
21
|
+
mul(Base, EvenPower, Product),
|
|
22
|
+
mod(Product, Modulus, Result).
|
|
23
|
+
|
|
24
|
+
fermat_witness(Base, PrimeCandidate) :-
|
|
25
|
+
sub(PrimeCandidate, 1, Exponent),
|
|
26
|
+
pow_mod(Base, Exponent, PrimeCandidate, 1).
|
|
27
|
+
|
|
28
|
+
modular_answer(pow_7_560_mod_561, R) :- pow_mod(7, 560, 561, R).
|
|
29
|
+
modular_answer(pow_2_1000_mod_1009, R) :- pow_mod(2, 1000, 1009, R).
|
|
30
|
+
modular_answer(fermat_2_101, true) :- fermat_witness(2, 101).
|
|
31
|
+
modular_answer(fermat_3_101, true) :- fermat_witness(3, 101).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
% Pell equation x^2 - 2 y^2 = 1 by memoized recurrence.
|
|
2
|
+
% The fundamental solution (3,2) generates all positive solutions.
|
|
3
|
+
materialize(pell_answer, 2).
|
|
4
|
+
|
|
5
|
+
memoize(pell, 3).
|
|
6
|
+
|
|
7
|
+
pell(0, 1, 0).
|
|
8
|
+
pell(N, X, Y) :-
|
|
9
|
+
gt(N, 0),
|
|
10
|
+
sub(N, 1, N1),
|
|
11
|
+
pell(N1, X0, Y0),
|
|
12
|
+
mul(3, X0, AX),
|
|
13
|
+
mul(4, Y0, BY),
|
|
14
|
+
add(AX, BY, X),
|
|
15
|
+
mul(2, X0, CX),
|
|
16
|
+
mul(3, Y0, DY),
|
|
17
|
+
add(CX, DY, Y).
|
|
18
|
+
|
|
19
|
+
pell_holds(N, true) :-
|
|
20
|
+
pell(N, X, Y),
|
|
21
|
+
mul(X, X, X2),
|
|
22
|
+
mul(Y, Y, Y2),
|
|
23
|
+
mul(2, Y2, TwiceY2),
|
|
24
|
+
sub(X2, TwiceY2, 1).
|
|
25
|
+
|
|
26
|
+
pell_answer(solution_5, solution(X, Y)) :- pell(5, X, Y).
|
|
27
|
+
pell_answer(solution_8, solution(X, Y)) :- pell(8, X, Y).
|
|
28
|
+
pell_answer(check_8, true) :- pell_holds(8, true).
|
|
29
|
+
pell_answer(y_sum_1_to_8, Sum) :- sumall(Y, (between(1, 8, N), pell(N, _X, Y)), Sum).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
% Stirling numbers of the second kind and Bell numbers.
|
|
2
|
+
% stirling2(N, K, Count) partitions N labelled elements into K nonempty blocks.
|
|
3
|
+
materialize(stirling_bell_answer, 2).
|
|
4
|
+
|
|
5
|
+
memoize(stirling2, 3).
|
|
6
|
+
|
|
7
|
+
stirling2(0, 0, 1).
|
|
8
|
+
stirling2(N, 0, 0) :- gt(N, 0).
|
|
9
|
+
stirling2(0, K, 0) :- gt(K, 0).
|
|
10
|
+
stirling2(N, K, Count) :-
|
|
11
|
+
gt(N, 0),
|
|
12
|
+
gt(K, 0),
|
|
13
|
+
sub(N, 1, N1),
|
|
14
|
+
sub(K, 1, K1),
|
|
15
|
+
stirling2(N1, K1, NewBlock),
|
|
16
|
+
stirling2(N1, K, ExistingBlocks),
|
|
17
|
+
mul(K, ExistingBlocks, Extended),
|
|
18
|
+
add(NewBlock, Extended, Count).
|
|
19
|
+
|
|
20
|
+
bell(N, Count) :-
|
|
21
|
+
sumall(S, (between(0, N, K), stirling2(N, K, S)), Count).
|
|
22
|
+
|
|
23
|
+
stirling_bell_answer(stirling_10_4, Count) :- stirling2(10, 4, Count).
|
|
24
|
+
stirling_bell_answer(stirling_12_5, Count) :- stirling2(12, 5, Count).
|
|
25
|
+
stirling_bell_answer(bell_10, Count) :- bell(10, Count).
|
|
26
|
+
stirling_bell_answer(bell_12, Count) :- bell(12, Count).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
% Euler totients and coprimality by memoized Euclidean gcd.
|
|
2
|
+
% This is still ordinary Horn-clause search: phi(N) is the count of K <= N
|
|
3
|
+
% with gcd(N, K) = 1.
|
|
4
|
+
materialize(totient_answer, 2).
|
|
5
|
+
|
|
6
|
+
memoize(gcd, 3).
|
|
7
|
+
memoize(totient, 2).
|
|
8
|
+
|
|
9
|
+
gcd(A, 0, A) :- ge(A, 0).
|
|
10
|
+
gcd(A, B, G) :-
|
|
11
|
+
gt(B, 0),
|
|
12
|
+
mod(A, B, R),
|
|
13
|
+
gcd(B, R, G).
|
|
14
|
+
|
|
15
|
+
coprime_upto(N, K) :-
|
|
16
|
+
between(1, N, K),
|
|
17
|
+
gcd(N, K, 1).
|
|
18
|
+
|
|
19
|
+
totient(N, Count) :-
|
|
20
|
+
gt(N, 0),
|
|
21
|
+
countall(coprime_upto(N, _K), Count).
|
|
22
|
+
|
|
23
|
+
summatory_totient(Limit, Sum) :-
|
|
24
|
+
sumall(Phi, (between(1, Limit, N), totient(N, Phi)), Sum).
|
|
25
|
+
|
|
26
|
+
totient_answer(phi_36, Phi) :- totient(36, Phi).
|
|
27
|
+
totient_answer(phi_97, Phi) :- totient(97, Phi).
|
|
28
|
+
totient_answer(coprime_count_84, Count) :- totient(84, Count).
|
|
29
|
+
totient_answer(summatory_phi_30, Sum) :- summatory_totient(30, Sum).
|
package/package.json
CHANGED
package/playground.html
CHANGED
|
@@ -449,6 +449,7 @@
|
|
|
449
449
|
"bayes-diagnosis",
|
|
450
450
|
"bayes-therapy",
|
|
451
451
|
"beam-deflection",
|
|
452
|
+
"binomial-vandermonde",
|
|
452
453
|
"blocks-world-planning",
|
|
453
454
|
"bmi",
|
|
454
455
|
"braking-safety-worlds",
|
|
@@ -456,6 +457,7 @@
|
|
|
456
457
|
"cache-performance",
|
|
457
458
|
"canary-release",
|
|
458
459
|
"cat-koko",
|
|
460
|
+
"catalan-convolution",
|
|
459
461
|
"chart-parser",
|
|
460
462
|
"clinical-trial-screening",
|
|
461
463
|
"collatz-1000",
|
|
@@ -465,6 +467,7 @@
|
|
|
465
467
|
"composition-of-injective-functions-is-injective",
|
|
466
468
|
"context-association",
|
|
467
469
|
"context-schema-audit",
|
|
470
|
+
"continued-fraction-sqrt2",
|
|
468
471
|
"control-system",
|
|
469
472
|
"critical-path-schedule",
|
|
470
473
|
"cyclic-path",
|
|
@@ -521,6 +524,7 @@
|
|
|
521
524
|
"heron-theorem",
|
|
522
525
|
"ideal-gas-law",
|
|
523
526
|
"illegitimate-reasoning",
|
|
527
|
+
"integer-partitions",
|
|
524
528
|
"job-shop-scheduling",
|
|
525
529
|
"knapsack-optimization",
|
|
526
530
|
"knowledge-engineering-alignment-flow",
|
|
@@ -529,8 +533,10 @@
|
|
|
529
533
|
"list-collection",
|
|
530
534
|
"lldm",
|
|
531
535
|
"manufacturing-quality-control",
|
|
536
|
+
"matrix-chain-order",
|
|
532
537
|
"microgrid-dispatch",
|
|
533
538
|
"missionaries-cannibals",
|
|
539
|
+
"modular-exponentiation",
|
|
534
540
|
"monkey-bananas",
|
|
535
541
|
"n-queens-8",
|
|
536
542
|
"network-sla",
|
|
@@ -544,6 +550,7 @@
|
|
|
544
550
|
"path-discovery",
|
|
545
551
|
"peano-arithmetic",
|
|
546
552
|
"peasant",
|
|
553
|
+
"pell-equation",
|
|
547
554
|
"pendulum-period",
|
|
548
555
|
"polynomial",
|
|
549
556
|
"proof-contrapositive",
|
|
@@ -561,9 +568,11 @@
|
|
|
561
568
|
"socrates",
|
|
562
569
|
"stable-marriage",
|
|
563
570
|
"statistics-summary",
|
|
571
|
+
"stirling-bell-numbers",
|
|
564
572
|
"sudoku-4x4",
|
|
565
573
|
"superdense-coding",
|
|
566
574
|
"term-tools",
|
|
575
|
+
"totient-summatory",
|
|
567
576
|
"trust-flow-provenance-threshold",
|
|
568
577
|
"turing",
|
|
569
578
|
"vector-similarity",
|
package/test/run-regression.mjs
CHANGED
|
@@ -528,9 +528,19 @@ function whiteBoxCases() {
|
|
|
528
528
|
name: 'challenging examples keep dynamic-programming predicates memoized',
|
|
529
529
|
run: () => {
|
|
530
530
|
const checks = [
|
|
531
|
+
['binomial-vandermonde.pl', 'choose_step', 5, true],
|
|
532
|
+
['catalan-convolution.pl', 'catalan', 2, false],
|
|
531
533
|
['chart-parser.pl', 'span', 4, true],
|
|
534
|
+
['continued-fraction-sqrt2.pl', 'conv', 3, true],
|
|
532
535
|
['critical-path-schedule.pl', 'earliest_start', 2, false],
|
|
533
536
|
['critical-path-schedule.pl', 'finish_time', 2, false],
|
|
537
|
+
['integer-partitions.pl', 'partitions', 3, true],
|
|
538
|
+
['matrix-chain-order.pl', 'cost', 3, false],
|
|
539
|
+
['modular-exponentiation.pl', 'pow_mod', 4, true],
|
|
540
|
+
['pell-equation.pl', 'pell', 3, true],
|
|
541
|
+
['stirling-bell-numbers.pl', 'stirling2', 3, true],
|
|
542
|
+
['totient-summatory.pl', 'gcd', 3, true],
|
|
543
|
+
['totient-summatory.pl', 'totient', 2, false],
|
|
534
544
|
['weighted-interval-scheduling.pl', 'best_from', 2, true],
|
|
535
545
|
];
|
|
536
546
|
for (const [filename, name, arity, recursive] of checks) {
|