eyelang 1.1.15 → 1.1.16
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 +6 -0
- package/examples/chart-parser.pl +59 -0
- package/examples/critical-path-schedule.pl +77 -0
- package/examples/job-shop-scheduling.pl +44 -0
- package/examples/knapsack-optimization.pl +40 -0
- package/examples/missionaries-cannibals.pl +47 -0
- package/examples/n-queens-8.pl +31 -0
- package/examples/output/chart-parser.pl +6 -0
- package/examples/output/critical-path-schedule.pl +19 -0
- package/examples/output/job-shop-scheduling.pl +3 -0
- package/examples/output/knapsack-optimization.pl +4 -0
- package/examples/output/missionaries-cannibals.pl +3 -0
- package/examples/output/n-queens-8.pl +1 -0
- package/examples/output/send-more-money.pl +3 -0
- package/examples/output/stable-marriage.pl +2 -0
- package/examples/output/sudoku-4x4.pl +2 -0
- package/examples/output/weighted-interval-scheduling.pl +5 -0
- package/examples/send-more-money.pl +66 -0
- package/examples/stable-marriage.pl +86 -0
- package/examples/sudoku-4x4.pl +48 -0
- package/examples/weighted-interval-scheduling.pl +76 -0
- package/package.json +1 -1
- package/playground.html +5 -0
- package/test/run-regression.mjs +19 -0
package/docs/guide.md
CHANGED
|
@@ -328,6 +328,7 @@ Each example has a checked golden output in `examples/output`.
|
|
|
328
328
|
| [`cache-performance.pl`](../examples/cache-performance.pl) | Summarizes cache latency performance. | [`output/cache-performance.pl`](../examples/output/cache-performance.pl) |
|
|
329
329
|
| [`canary-release.pl`](../examples/canary-release.pl) | Decides canary rollout or rollback. | [`output/canary-release.pl`](../examples/output/canary-release.pl) |
|
|
330
330
|
| [`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) |
|
|
331
|
+
| [`chart-parser.pl`](../examples/chart-parser.pl) | Parses small sentences with a memoized chart parser. | [`output/chart-parser.pl`](../examples/output/chart-parser.pl) |
|
|
331
332
|
| [`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) |
|
|
332
333
|
| [`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) |
|
|
333
334
|
| [`combinatorics-findall-sort.pl`](../examples/combinatorics-findall-sort.pl) | Collects and sorts finite combinations. | [`output/combinatorics-findall-sort.pl`](../examples/output/combinatorics-findall-sort.pl) |
|
|
@@ -337,6 +338,7 @@ Each example has a checked golden output in `examples/output`.
|
|
|
337
338
|
| [`context-association.pl`](../examples/context-association.pl) | Associates named contexts with their contents. | [`output/context-association.pl`](../examples/output/context-association.pl) |
|
|
338
339
|
| [`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) |
|
|
339
340
|
| [`control-system.pl`](../examples/control-system.pl) | Evaluates control-system measurements and targets. | [`output/control-system.pl`](../examples/output/control-system.pl) |
|
|
341
|
+
| [`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) |
|
|
340
342
|
| [`cyclic-path.pl`](../examples/cyclic-path.pl) | Computes paths in a cyclic graph. | [`output/cyclic-path.pl`](../examples/output/cyclic-path.pl) |
|
|
341
343
|
| [`d3-group.pl`](../examples/d3-group.pl) | Enumerates subgroups of the D3 group. | [`output/d3-group.pl`](../examples/output/d3-group.pl) |
|
|
342
344
|
| [`dairy-energy-balance.pl`](../examples/dairy-energy-balance.pl) | Classifies dairy cow energy balance. | [`output/dairy-energy-balance.pl`](../examples/output/dairy-energy-balance.pl) |
|
|
@@ -400,6 +402,7 @@ Each example has a checked golden output in `examples/output`.
|
|
|
400
402
|
| [`lldm.pl`](../examples/lldm.pl) | Calculates leg-length discrepancy measurements. | [`output/lldm.pl`](../examples/output/lldm.pl) |
|
|
401
403
|
| [`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) |
|
|
402
404
|
| [`microgrid-dispatch.pl`](../examples/microgrid-dispatch.pl) | Plans microgrid dispatch and reserve. | [`output/microgrid-dispatch.pl`](../examples/output/microgrid-dispatch.pl) |
|
|
405
|
+
| [`missionaries-cannibals.pl`](../examples/missionaries-cannibals.pl) | Solves the missionaries-and-cannibals river crossing puzzle. | [`output/missionaries-cannibals.pl`](../examples/output/missionaries-cannibals.pl) |
|
|
403
406
|
| [`monkey-bananas.pl`](../examples/monkey-bananas.pl) | Solves the monkey-and-bananas puzzle. | [`output/monkey-bananas.pl`](../examples/output/monkey-bananas.pl) |
|
|
404
407
|
| [`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) |
|
|
405
408
|
| [`network-sla.pl`](../examples/network-sla.pl) | Checks network path SLA compliance. | [`output/network-sla.pl`](../examples/output/network-sla.pl) |
|
|
@@ -430,17 +433,20 @@ Each example has a checked golden output in `examples/output`.
|
|
|
430
433
|
| [`socrates.pl`](../examples/socrates.pl) | Derives that Socrates is mortal. | [`output/socrates.pl`](../examples/output/socrates.pl) |
|
|
431
434
|
| [`stable-marriage.pl`](../examples/stable-marriage.pl) | Finds stable matchings by excluding blocking pairs. | [`output/stable-marriage.pl`](../examples/output/stable-marriage.pl) |
|
|
432
435
|
| [`statistics-summary.pl`](../examples/statistics-summary.pl) | Computes population statistics for a sample. | [`output/statistics-summary.pl`](../examples/output/statistics-summary.pl) |
|
|
436
|
+
| [`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) |
|
|
433
437
|
| [`superdense-coding.pl`](../examples/superdense-coding.pl) | Models superdense-coding bit transmission. | [`output/superdense-coding.pl`](../examples/output/superdense-coding.pl) |
|
|
434
438
|
| [`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) |
|
|
435
439
|
| [`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) |
|
|
436
440
|
| [`turing.pl`](../examples/turing.pl) | Simulates a binary-increment Turing machine. | [`output/turing.pl`](../examples/output/turing.pl) |
|
|
437
441
|
| [`vector-similarity.pl`](../examples/vector-similarity.pl) | Computes dot product, norm, and cosine similarity. | [`output/vector-similarity.pl`](../examples/output/vector-similarity.pl) |
|
|
438
442
|
| [`vulnerability-impact.pl`](../examples/vulnerability-impact.pl) | Analyzes vulnerable transitive dependencies and urgent patch impact. | [`output/vulnerability-impact.pl`](../examples/output/vulnerability-impact.pl) |
|
|
443
|
+
| [`weighted-interval-scheduling.pl`](../examples/weighted-interval-scheduling.pl) | Selects the best non-overlapping weighted intervals with memoized dynamic programming. | [`output/weighted-interval-scheduling.pl`](../examples/output/weighted-interval-scheduling.pl) |
|
|
439
444
|
| [`witch.pl`](../examples/witch.pl) | Derives the classic “burn the witch” rule chain. | [`output/witch.pl`](../examples/output/witch.pl) |
|
|
440
445
|
| [`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) |
|
|
441
446
|
| [`zebra.pl`](../examples/zebra.pl) | Solves the zebra logic puzzle. | [`output/zebra.pl`](../examples/output/zebra.pl) |
|
|
442
447
|
|
|
443
448
|
|
|
449
|
+
|
|
444
450
|
## Golden outputs, tests, and conformance
|
|
445
451
|
|
|
446
452
|
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:
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
% A tiny memoized chart parser for a context-free grammar.
|
|
2
|
+
% span/4 is the dynamic-programming chart relation: sentence, category,
|
|
3
|
+
% start index, and end index.
|
|
4
|
+
materialize(chart_parser_answer, 2).
|
|
5
|
+
|
|
6
|
+
memoize(span, 4).
|
|
7
|
+
|
|
8
|
+
sentence(command, 5).
|
|
9
|
+
sentence(ambiguous_pp, 8).
|
|
10
|
+
|
|
11
|
+
word(command, 0, the).
|
|
12
|
+
word(command, 1, robot).
|
|
13
|
+
word(command, 2, moves).
|
|
14
|
+
word(command, 3, the).
|
|
15
|
+
word(command, 4, box).
|
|
16
|
+
|
|
17
|
+
word(ambiguous_pp, 0, the).
|
|
18
|
+
word(ambiguous_pp, 1, robot).
|
|
19
|
+
word(ambiguous_pp, 2, sees).
|
|
20
|
+
word(ambiguous_pp, 3, the).
|
|
21
|
+
word(ambiguous_pp, 4, box).
|
|
22
|
+
word(ambiguous_pp, 5, with).
|
|
23
|
+
word(ambiguous_pp, 6, the).
|
|
24
|
+
word(ambiguous_pp, 7, telescope).
|
|
25
|
+
|
|
26
|
+
terminal(det, the).
|
|
27
|
+
terminal(noun, robot).
|
|
28
|
+
terminal(noun, box).
|
|
29
|
+
terminal(noun, telescope).
|
|
30
|
+
terminal(verb, moves).
|
|
31
|
+
terminal(verb, sees).
|
|
32
|
+
terminal(prep, with).
|
|
33
|
+
|
|
34
|
+
rule(s, np, vp).
|
|
35
|
+
rule(np, det, noun).
|
|
36
|
+
rule(np, np, pp).
|
|
37
|
+
rule(vp, verb, np).
|
|
38
|
+
rule(vp, vp, pp).
|
|
39
|
+
rule(pp, prep, np).
|
|
40
|
+
|
|
41
|
+
span(Sentence, Category, Start, End) :-
|
|
42
|
+
word(Sentence, Start, Token),
|
|
43
|
+
terminal(Category, Token),
|
|
44
|
+
add(Start, 1, End).
|
|
45
|
+
span(Sentence, Category, Start, End) :-
|
|
46
|
+
rule(Category, Left, Right),
|
|
47
|
+
span(Sentence, Left, Start, Middle),
|
|
48
|
+
span(Sentence, Right, Middle, End).
|
|
49
|
+
|
|
50
|
+
chart_parser_answer(parsed, Sentence) :-
|
|
51
|
+
sentence(Sentence, Length),
|
|
52
|
+
span(Sentence, s, 0, Length).
|
|
53
|
+
chart_parser_answer(parse_count, count(Sentence, Count)) :-
|
|
54
|
+
sentence(Sentence, Length),
|
|
55
|
+
countall(span(Sentence, s, 0, Length), Count).
|
|
56
|
+
chart_parser_answer(noun_phrase_count, count(Sentence, Count)) :-
|
|
57
|
+
sentence(Sentence, Length),
|
|
58
|
+
countall(span(Sentence, np, _Start, _End), Count),
|
|
59
|
+
gt(Length, 0).
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
% Critical-path scheduling for a small project network.
|
|
2
|
+
% earliest_start/2 and finish_time/2 are memoized because many schedule and
|
|
3
|
+
% critical-path queries reuse the same predecessor subproblems.
|
|
4
|
+
materialize(critical_path_answer, 2).
|
|
5
|
+
|
|
6
|
+
memoize(earliest_start, 2).
|
|
7
|
+
memoize(finish_time, 2).
|
|
8
|
+
|
|
9
|
+
task(requirements, 2).
|
|
10
|
+
task(architecture, 3).
|
|
11
|
+
task(api_design, 2).
|
|
12
|
+
task(database, 4).
|
|
13
|
+
task(backend, 6).
|
|
14
|
+
task(frontend, 5).
|
|
15
|
+
task(auth, 3).
|
|
16
|
+
task(integration, 4).
|
|
17
|
+
task(security_review, 3).
|
|
18
|
+
task(load_test, 2).
|
|
19
|
+
task(launch, 1).
|
|
20
|
+
|
|
21
|
+
depends(architecture, requirements).
|
|
22
|
+
depends(api_design, requirements).
|
|
23
|
+
depends(database, architecture).
|
|
24
|
+
depends(backend, api_design).
|
|
25
|
+
depends(backend, database).
|
|
26
|
+
depends(frontend, api_design).
|
|
27
|
+
depends(auth, architecture).
|
|
28
|
+
depends(integration, backend).
|
|
29
|
+
depends(integration, frontend).
|
|
30
|
+
depends(integration, auth).
|
|
31
|
+
depends(security_review, integration).
|
|
32
|
+
depends(load_test, integration).
|
|
33
|
+
depends(launch, security_review).
|
|
34
|
+
depends(launch, load_test).
|
|
35
|
+
|
|
36
|
+
earliest_start(Task, 0) :-
|
|
37
|
+
task(Task, _Duration),
|
|
38
|
+
not(depends(Task, _Pred)).
|
|
39
|
+
earliest_start(Task, Start) :-
|
|
40
|
+
depends(Task, _Pred),
|
|
41
|
+
aggregate_max(Finish, Pred,
|
|
42
|
+
(depends(Task, Pred), finish_time(Pred, Finish)),
|
|
43
|
+
Start, _CriticalPred).
|
|
44
|
+
|
|
45
|
+
finish_time(Task, Finish) :-
|
|
46
|
+
task(Task, Duration),
|
|
47
|
+
earliest_start(Task, Start),
|
|
48
|
+
add(Start, Duration, Finish).
|
|
49
|
+
|
|
50
|
+
critical_predecessor(Task, Pred) :-
|
|
51
|
+
depends(Task, _AnyPred),
|
|
52
|
+
aggregate_max(Finish, P,
|
|
53
|
+
(depends(Task, P), finish_time(P, Finish)),
|
|
54
|
+
_BestFinish, Pred).
|
|
55
|
+
|
|
56
|
+
project_finish(Finish) :-
|
|
57
|
+
aggregate_max(FinishTime, Task, finish_time(Task, FinishTime), Finish, _LastTask).
|
|
58
|
+
|
|
59
|
+
final_task(Task) :-
|
|
60
|
+
project_finish(Finish),
|
|
61
|
+
finish_time(Task, Finish).
|
|
62
|
+
|
|
63
|
+
critical_chain(Task, Task).
|
|
64
|
+
critical_chain(Task, Pred) :-
|
|
65
|
+
critical_predecessor(Task, Parent),
|
|
66
|
+
critical_chain(Parent, Pred).
|
|
67
|
+
|
|
68
|
+
critical_task(Task) :-
|
|
69
|
+
final_task(Final),
|
|
70
|
+
critical_chain(Final, Task).
|
|
71
|
+
|
|
72
|
+
critical_path_answer(project_finish, Finish) :- project_finish(Finish).
|
|
73
|
+
critical_path_answer(critical_task, Task) :- critical_task(Task).
|
|
74
|
+
critical_path_answer(schedule, task(Task, Start, Finish)) :-
|
|
75
|
+
task(Task, _Duration),
|
|
76
|
+
earliest_start(Task, Start),
|
|
77
|
+
finish_time(Task, Finish).
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
% Tiny job-shop scheduling benchmark.
|
|
2
|
+
% Three jobs each need one mill operation and one lathe operation; the solver
|
|
3
|
+
% searches start times and minimizes the makespan.
|
|
4
|
+
materialize(job_shop_answer, 2).
|
|
5
|
+
|
|
6
|
+
nonoverlap(_StartA, EndA, StartB, _EndB) :- le(EndA, StartB).
|
|
7
|
+
nonoverlap(StartA, _EndA, _StartB, EndB) :- le(EndB, StartA).
|
|
8
|
+
|
|
9
|
+
feasible_schedule(Makespan, [
|
|
10
|
+
op(j1_mill, J1MillStart, J1MillEnd),
|
|
11
|
+
op(j1_lathe, J1LatheStart, J1LatheEnd),
|
|
12
|
+
op(j2_lathe, J2LatheStart, J2LatheEnd),
|
|
13
|
+
op(j2_mill, J2MillStart, J2MillEnd),
|
|
14
|
+
op(j3_mill, J3MillStart, J3MillEnd),
|
|
15
|
+
op(j3_lathe, J3LatheStart, J3LatheEnd)
|
|
16
|
+
]) :-
|
|
17
|
+
between(0, 6, J1MillStart), add(J1MillStart, 3, J1MillEnd),
|
|
18
|
+
between(0, 6, J1LatheStart), add(J1LatheStart, 2, J1LatheEnd),
|
|
19
|
+
le(J1MillEnd, J1LatheStart),
|
|
20
|
+
|
|
21
|
+
between(0, 6, J2LatheStart), add(J2LatheStart, 2, J2LatheEnd),
|
|
22
|
+
between(0, 6, J2MillStart), add(J2MillStart, 4, J2MillEnd),
|
|
23
|
+
le(J2LatheEnd, J2MillStart),
|
|
24
|
+
|
|
25
|
+
between(0, 6, J3MillStart), add(J3MillStart, 2, J3MillEnd),
|
|
26
|
+
between(0, 6, J3LatheStart), add(J3LatheStart, 3, J3LatheEnd),
|
|
27
|
+
le(J3MillEnd, J3LatheStart),
|
|
28
|
+
|
|
29
|
+
nonoverlap(J1MillStart, J1MillEnd, J2MillStart, J2MillEnd),
|
|
30
|
+
nonoverlap(J1MillStart, J1MillEnd, J3MillStart, J3MillEnd),
|
|
31
|
+
nonoverlap(J2MillStart, J2MillEnd, J3MillStart, J3MillEnd),
|
|
32
|
+
nonoverlap(J1LatheStart, J1LatheEnd, J2LatheStart, J2LatheEnd),
|
|
33
|
+
nonoverlap(J1LatheStart, J1LatheEnd, J3LatheStart, J3LatheEnd),
|
|
34
|
+
nonoverlap(J2LatheStart, J2LatheEnd, J3LatheStart, J3LatheEnd),
|
|
35
|
+
|
|
36
|
+
max(J1LatheEnd, J2MillEnd, PartialMakespan),
|
|
37
|
+
max(PartialMakespan, J3LatheEnd, Makespan).
|
|
38
|
+
|
|
39
|
+
best_schedule(Makespan, Schedule) :-
|
|
40
|
+
aggregate_min(Makespan, Schedule, feasible_schedule(Makespan, Schedule), Makespan, Schedule).
|
|
41
|
+
|
|
42
|
+
job_shop_answer(best_makespan, Makespan) :- best_schedule(Makespan, _Schedule).
|
|
43
|
+
job_shop_answer(best_schedule, Schedule) :- best_schedule(_Makespan, Schedule).
|
|
44
|
+
job_shop_answer(feasible_schedule_count, Count) :- countall(feasible_schedule(_Makespan, _Schedule), Count).
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
% 0/1 knapsack search with an aggregate maximum over all feasible packs.
|
|
2
|
+
materialize(knapsack_answer, 2).
|
|
3
|
+
|
|
4
|
+
capacity(15).
|
|
5
|
+
items([atlas, battery, camera, drone, emergency_radio, field_laptop, medkit, sensor]).
|
|
6
|
+
|
|
7
|
+
item(atlas, 2, 6).
|
|
8
|
+
item(battery, 4, 10).
|
|
9
|
+
item(camera, 3, 8).
|
|
10
|
+
item(drone, 6, 13).
|
|
11
|
+
item(emergency_radio, 5, 11).
|
|
12
|
+
item(field_laptop, 7, 16).
|
|
13
|
+
item(medkit, 4, 9).
|
|
14
|
+
item(sensor, 2, 7).
|
|
15
|
+
|
|
16
|
+
subset([], []).
|
|
17
|
+
subset([Item|Rest], [Item|Chosen]) :- subset(Rest, Chosen).
|
|
18
|
+
subset([_Item|Rest], Chosen) :- subset(Rest, Chosen).
|
|
19
|
+
|
|
20
|
+
item_weight(Item, Weight) :- item(Item, Weight, _Value).
|
|
21
|
+
item_value(Item, Value) :- item(Item, _Weight, Value).
|
|
22
|
+
|
|
23
|
+
total_weight(Items, Weight) :- findall(W, (member(Item, Items), item_weight(Item, W)), Weights), sum_list(Weights, Weight).
|
|
24
|
+
total_value(Items, Value) :- findall(V, (member(Item, Items), item_value(Item, V)), Values), sum_list(Values, Value).
|
|
25
|
+
|
|
26
|
+
feasible_pack(Pack, Weight, Value) :-
|
|
27
|
+
items(All),
|
|
28
|
+
subset(All, Pack),
|
|
29
|
+
total_weight(Pack, Weight),
|
|
30
|
+
capacity(Capacity),
|
|
31
|
+
le(Weight, Capacity),
|
|
32
|
+
total_value(Pack, Value).
|
|
33
|
+
|
|
34
|
+
best_pack(Pack, Weight, Value) :-
|
|
35
|
+
aggregate_max(Value, pack(Pack, Weight), feasible_pack(Pack, Weight, Value), Value, pack(Pack, Weight)).
|
|
36
|
+
|
|
37
|
+
knapsack_answer(best_pack, Pack) :- best_pack(Pack, _Weight, _Value).
|
|
38
|
+
knapsack_answer(total_weight, Weight) :- best_pack(_Pack, Weight, _Value).
|
|
39
|
+
knapsack_answer(total_value, Value) :- best_pack(_Pack, _Weight, Value).
|
|
40
|
+
knapsack_answer(feasible_pack_count, Count) :- countall(feasible_pack(_Pack, _Weight, _Value), Count).
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
% Missionaries-and-cannibals river crossing as a guarded state-space search.
|
|
2
|
+
materialize(missionaries_cannibals_answer, 2).
|
|
3
|
+
|
|
4
|
+
move(1, 0).
|
|
5
|
+
move(0, 1).
|
|
6
|
+
move(2, 0).
|
|
7
|
+
move(0, 2).
|
|
8
|
+
move(1, 1).
|
|
9
|
+
|
|
10
|
+
bank_safe(0, _C).
|
|
11
|
+
bank_safe(M, C) :- gt(M, 0), ge(M, C).
|
|
12
|
+
|
|
13
|
+
state_safe(state(MLeft, CLeft, _Boat)) :-
|
|
14
|
+
between(0, 3, MLeft),
|
|
15
|
+
between(0, 3, CLeft),
|
|
16
|
+
sub(3, MLeft, MRight),
|
|
17
|
+
sub(3, CLeft, CRight),
|
|
18
|
+
bank_safe(MLeft, CLeft),
|
|
19
|
+
bank_safe(MRight, CRight).
|
|
20
|
+
|
|
21
|
+
crossing(state(MLeft, CLeft, left), state(NextM, NextC, right), carry(MoveM, MoveC)) :-
|
|
22
|
+
move(MoveM, MoveC),
|
|
23
|
+
sub(MLeft, MoveM, NextM),
|
|
24
|
+
sub(CLeft, MoveC, NextC),
|
|
25
|
+
state_safe(state(NextM, NextC, right)).
|
|
26
|
+
crossing(state(MLeft, CLeft, right), state(NextM, NextC, left), carry(MoveM, MoveC)) :-
|
|
27
|
+
move(MoveM, MoveC),
|
|
28
|
+
add(MLeft, MoveM, NextM),
|
|
29
|
+
add(CLeft, MoveC, NextC),
|
|
30
|
+
state_safe(state(NextM, NextC, left)).
|
|
31
|
+
|
|
32
|
+
journey(Goal, Goal, Visited, Visited).
|
|
33
|
+
journey(State, Goal, Visited, Path) :-
|
|
34
|
+
crossing(State, Next, _Carry),
|
|
35
|
+
not_member(Next, Visited),
|
|
36
|
+
journey(Next, Goal, [Next|Visited], Path).
|
|
37
|
+
|
|
38
|
+
solution(Path) :-
|
|
39
|
+
journey(state(3, 3, left), state(0, 0, right), [state(3, 3, left)], ReversePath),
|
|
40
|
+
reverse(ReversePath, Path).
|
|
41
|
+
|
|
42
|
+
missionaries_cannibals_answer(first_solution, Path) :- once(solution(Path)).
|
|
43
|
+
missionaries_cannibals_answer(state_count, Count) :- countall(state_safe(state(_M, _C, _Boat)), Count).
|
|
44
|
+
missionaries_cannibals_answer(step_count, Steps) :-
|
|
45
|
+
once(solution(Path)),
|
|
46
|
+
length(Path, States),
|
|
47
|
+
sub(States, 1, Steps).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
% N-queens search for the 8x8 board.
|
|
2
|
+
% This example enumerates all row permutations and filters diagonal attacks.
|
|
3
|
+
materialize(n_queens_answer, 2).
|
|
4
|
+
|
|
5
|
+
% Cache diagonal checks; the same row/distance/suffix states recur across
|
|
6
|
+
% many candidate permutations during the 8-queens search.
|
|
7
|
+
memoize(no_diagonal_attack, 3).
|
|
8
|
+
|
|
9
|
+
perm([], []).
|
|
10
|
+
perm(Items, [X|Rest]) :-
|
|
11
|
+
select(X, Items, Remaining),
|
|
12
|
+
perm(Remaining, Rest).
|
|
13
|
+
|
|
14
|
+
safe_rows([]).
|
|
15
|
+
safe_rows([Row|Rest]) :-
|
|
16
|
+
no_diagonal_attack(Row, 1, Rest),
|
|
17
|
+
safe_rows(Rest).
|
|
18
|
+
|
|
19
|
+
no_diagonal_attack(_Row, _Distance, []).
|
|
20
|
+
no_diagonal_attack(Row, Distance, [Other|Rest]) :-
|
|
21
|
+
sub(Row, Other, Delta),
|
|
22
|
+
abs(Delta, AbsDelta),
|
|
23
|
+
neq(AbsDelta, Distance),
|
|
24
|
+
add(Distance, 1, NextDistance),
|
|
25
|
+
no_diagonal_attack(Row, NextDistance, Rest).
|
|
26
|
+
|
|
27
|
+
queen_solution(Rows) :-
|
|
28
|
+
perm([1, 2, 3, 4, 5, 6, 7, 8], Rows),
|
|
29
|
+
safe_rows(Rows).
|
|
30
|
+
|
|
31
|
+
n_queens_answer(first_solution, Rows) :- once(queen_solution(Rows)).
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
chart_parser_answer(parsed, command).
|
|
2
|
+
chart_parser_answer(parsed, ambiguous_pp).
|
|
3
|
+
chart_parser_answer(parse_count, count(command, 1)).
|
|
4
|
+
chart_parser_answer(parse_count, count(ambiguous_pp, 1)).
|
|
5
|
+
chart_parser_answer(noun_phrase_count, count(command, 2)).
|
|
6
|
+
chart_parser_answer(noun_phrase_count, count(ambiguous_pp, 3)).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
critical_path_answer(project_finish, 23).
|
|
2
|
+
critical_path_answer(critical_task, launch).
|
|
3
|
+
critical_path_answer(critical_task, security_review).
|
|
4
|
+
critical_path_answer(critical_task, integration).
|
|
5
|
+
critical_path_answer(critical_task, backend).
|
|
6
|
+
critical_path_answer(critical_task, database).
|
|
7
|
+
critical_path_answer(critical_task, architecture).
|
|
8
|
+
critical_path_answer(critical_task, requirements).
|
|
9
|
+
critical_path_answer(schedule, task(requirements, 0, 2)).
|
|
10
|
+
critical_path_answer(schedule, task(architecture, 2, 5)).
|
|
11
|
+
critical_path_answer(schedule, task(api_design, 2, 4)).
|
|
12
|
+
critical_path_answer(schedule, task(database, 5, 9)).
|
|
13
|
+
critical_path_answer(schedule, task(backend, 9, 15)).
|
|
14
|
+
critical_path_answer(schedule, task(frontend, 4, 9)).
|
|
15
|
+
critical_path_answer(schedule, task(auth, 5, 8)).
|
|
16
|
+
critical_path_answer(schedule, task(integration, 15, 19)).
|
|
17
|
+
critical_path_answer(schedule, task(security_review, 19, 22)).
|
|
18
|
+
critical_path_answer(schedule, task(load_test, 19, 21)).
|
|
19
|
+
critical_path_answer(schedule, task(launch, 22, 23)).
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
missionaries_cannibals_answer(first_solution, [state(3, 3, left), state(3, 1, right), state(3, 2, left), state(3, 0, right), state(3, 1, left), state(1, 1, right), state(2, 2, left), state(0, 2, right), state(0, 3, left), state(0, 1, right), state(1, 1, left), state(0, 0, right)]).
|
|
2
|
+
missionaries_cannibals_answer(state_count, 10).
|
|
3
|
+
missionaries_cannibals_answer(step_count, 11).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
n_queens_answer(first_solution, [1, 5, 8, 6, 3, 7, 2, 4]).
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
weighted_interval_answer(best_value, 13).
|
|
2
|
+
weighted_interval_answer(chosen_interval, interval(1, 1, 4, 5)).
|
|
3
|
+
weighted_interval_answer(chosen_interval, interval(4, 4, 7, 4)).
|
|
4
|
+
weighted_interval_answer(chosen_interval, interval(8, 8, 11, 4)).
|
|
5
|
+
weighted_interval_answer(candidate_count, 8).
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
% Cryptarithm search for SEND + MORE = MONEY.
|
|
2
|
+
% Column constraints prune the digit assignment search.
|
|
3
|
+
materialize(cryptarithm_answer, 2).
|
|
4
|
+
|
|
5
|
+
all_digits([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).
|
|
6
|
+
|
|
7
|
+
send_more_money(solution(S, E, N, D, M, O, R, Y)) :-
|
|
8
|
+
all_digits(Digits),
|
|
9
|
+
eq(M, 1),
|
|
10
|
+
eq(O, 0),
|
|
11
|
+
select(M, Digits, D0),
|
|
12
|
+
select(O, D0, D1),
|
|
13
|
+
|
|
14
|
+
select(D, D1, D2),
|
|
15
|
+
select(E, D2, D3),
|
|
16
|
+
add(D, E, OnesSum),
|
|
17
|
+
mod(OnesSum, 10, Y),
|
|
18
|
+
div(OnesSum, 10, Carry1),
|
|
19
|
+
select(Y, D3, D4),
|
|
20
|
+
|
|
21
|
+
select(N, D4, D5),
|
|
22
|
+
select(R, D5, D6),
|
|
23
|
+
add(N, R, TensPartial),
|
|
24
|
+
add(TensPartial, Carry1, TensSum),
|
|
25
|
+
mod(TensSum, 10, E),
|
|
26
|
+
div(TensSum, 10, Carry2),
|
|
27
|
+
|
|
28
|
+
add(E, O, HundredsPartial),
|
|
29
|
+
add(HundredsPartial, Carry2, HundredsSum),
|
|
30
|
+
mod(HundredsSum, 10, N),
|
|
31
|
+
div(HundredsSum, 10, Carry3),
|
|
32
|
+
|
|
33
|
+
select(S, D6, _D7),
|
|
34
|
+
neq(S, 0),
|
|
35
|
+
add(S, M, ThousandsPartial),
|
|
36
|
+
add(ThousandsPartial, Carry3, ThousandsSum),
|
|
37
|
+
mod(ThousandsSum, 10, O),
|
|
38
|
+
div(ThousandsSum, 10, M).
|
|
39
|
+
|
|
40
|
+
number4(A, B, C, D, Value) :-
|
|
41
|
+
mul(A, 1000, APart),
|
|
42
|
+
mul(B, 100, BPart),
|
|
43
|
+
mul(C, 10, CPart),
|
|
44
|
+
add(APart, BPart, AB),
|
|
45
|
+
add(AB, CPart, ABC),
|
|
46
|
+
add(ABC, D, Value).
|
|
47
|
+
|
|
48
|
+
number5(A, B, C, D, E, Value) :-
|
|
49
|
+
mul(A, 10000, APart),
|
|
50
|
+
mul(B, 1000, BPart),
|
|
51
|
+
mul(C, 100, CPart),
|
|
52
|
+
mul(D, 10, DPart),
|
|
53
|
+
add(APart, BPart, AB),
|
|
54
|
+
add(AB, CPart, ABC),
|
|
55
|
+
add(ABC, DPart, ABCD),
|
|
56
|
+
add(ABCD, E, Value).
|
|
57
|
+
|
|
58
|
+
cryptarithm_answer(assignments, solution(S, E, N, D, M, O, R, Y)) :-
|
|
59
|
+
send_more_money(solution(S, E, N, D, M, O, R, Y)).
|
|
60
|
+
cryptarithm_answer(equation, equation(Send, More, Money)) :-
|
|
61
|
+
send_more_money(solution(S, E, N, D, M, O, R, Y)),
|
|
62
|
+
number4(S, E, N, D, Send),
|
|
63
|
+
number4(M, O, R, E, More),
|
|
64
|
+
number5(M, O, N, E, Y, Money).
|
|
65
|
+
cryptarithm_answer(solution_count, Count) :-
|
|
66
|
+
countall(send_more_money(_Solution), Count).
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
% Stable-marriage search with blocking-pair detection.
|
|
2
|
+
materialize(stable_marriage_answer, 2).
|
|
3
|
+
|
|
4
|
+
man(adam).
|
|
5
|
+
man(brian).
|
|
6
|
+
man(cole).
|
|
7
|
+
man(drew).
|
|
8
|
+
|
|
9
|
+
woman(amy).
|
|
10
|
+
woman(bea).
|
|
11
|
+
woman(cora).
|
|
12
|
+
woman(dana).
|
|
13
|
+
|
|
14
|
+
rank_man(adam, bea, 1).
|
|
15
|
+
rank_man(adam, amy, 2).
|
|
16
|
+
rank_man(adam, dana, 3).
|
|
17
|
+
rank_man(adam, cora, 4).
|
|
18
|
+
rank_man(brian, amy, 1).
|
|
19
|
+
rank_man(brian, cora, 2).
|
|
20
|
+
rank_man(brian, bea, 3).
|
|
21
|
+
rank_man(brian, dana, 4).
|
|
22
|
+
rank_man(cole, amy, 1).
|
|
23
|
+
rank_man(cole, bea, 2).
|
|
24
|
+
rank_man(cole, dana, 3).
|
|
25
|
+
rank_man(cole, cora, 4).
|
|
26
|
+
rank_man(drew, cora, 1).
|
|
27
|
+
rank_man(drew, dana, 2).
|
|
28
|
+
rank_man(drew, bea, 3).
|
|
29
|
+
rank_man(drew, amy, 4).
|
|
30
|
+
|
|
31
|
+
rank_woman(amy, cole, 1).
|
|
32
|
+
rank_woman(amy, adam, 2).
|
|
33
|
+
rank_woman(amy, brian, 3).
|
|
34
|
+
rank_woman(amy, drew, 4).
|
|
35
|
+
rank_woman(bea, adam, 1).
|
|
36
|
+
rank_woman(bea, cole, 2).
|
|
37
|
+
rank_woman(bea, drew, 3).
|
|
38
|
+
rank_woman(bea, brian, 4).
|
|
39
|
+
rank_woman(cora, drew, 1).
|
|
40
|
+
rank_woman(cora, brian, 2).
|
|
41
|
+
rank_woman(cora, adam, 3).
|
|
42
|
+
rank_woman(cora, cole, 4).
|
|
43
|
+
rank_woman(dana, brian, 1).
|
|
44
|
+
rank_woman(dana, drew, 2).
|
|
45
|
+
rank_woman(dana, cole, 3).
|
|
46
|
+
rank_woman(dana, adam, 4).
|
|
47
|
+
|
|
48
|
+
perm([], []).
|
|
49
|
+
perm(Items, [X|Rest]) :-
|
|
50
|
+
select(X, Items, Remaining),
|
|
51
|
+
perm(Remaining, Rest).
|
|
52
|
+
|
|
53
|
+
matching([
|
|
54
|
+
pair(adam, W1),
|
|
55
|
+
pair(brian, W2),
|
|
56
|
+
pair(cole, W3),
|
|
57
|
+
pair(drew, W4)
|
|
58
|
+
]) :-
|
|
59
|
+
perm([amy, bea, cora, dana], [W1, W2, W3, W4]).
|
|
60
|
+
|
|
61
|
+
assigned(Matching, Man, Woman) :- member(pair(Man, Woman), Matching).
|
|
62
|
+
|
|
63
|
+
prefers_man(Man, Candidate, Current) :-
|
|
64
|
+
rank_man(Man, Candidate, CandidateRank),
|
|
65
|
+
rank_man(Man, Current, CurrentRank),
|
|
66
|
+
lt(CandidateRank, CurrentRank).
|
|
67
|
+
|
|
68
|
+
prefers_woman(Woman, Candidate, Current) :-
|
|
69
|
+
rank_woman(Woman, Candidate, CandidateRank),
|
|
70
|
+
rank_woman(Woman, Current, CurrentRank),
|
|
71
|
+
lt(CandidateRank, CurrentRank).
|
|
72
|
+
|
|
73
|
+
blocking_pair(Matching, Man, Woman) :-
|
|
74
|
+
assigned(Matching, Man, CurrentWoman),
|
|
75
|
+
woman(Woman),
|
|
76
|
+
neq(Woman, CurrentWoman),
|
|
77
|
+
prefers_man(Man, Woman, CurrentWoman),
|
|
78
|
+
assigned(Matching, CurrentMan, Woman),
|
|
79
|
+
prefers_woman(Woman, Man, CurrentMan).
|
|
80
|
+
|
|
81
|
+
stable_matching(Matching) :-
|
|
82
|
+
matching(Matching),
|
|
83
|
+
not(blocking_pair(Matching, _Man, _Woman)).
|
|
84
|
+
|
|
85
|
+
stable_marriage_answer(first_stable_matching, Matching) :- once(stable_matching(Matching)).
|
|
86
|
+
stable_marriage_answer(stable_matching_count, Count) :- countall(stable_matching(_Matching), Count).
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
% A compact 4x4 Sudoku search with row permutations and column/box constraints.
|
|
2
|
+
materialize(sudoku_answer, 2).
|
|
3
|
+
|
|
4
|
+
perm([], []).
|
|
5
|
+
perm(Items, [X|Rest]) :-
|
|
6
|
+
select(X, Items, Remaining),
|
|
7
|
+
perm(Remaining, Rest).
|
|
8
|
+
|
|
9
|
+
distinct([]).
|
|
10
|
+
distinct([X|Xs]) :-
|
|
11
|
+
not_member(X, Xs),
|
|
12
|
+
distinct(Xs).
|
|
13
|
+
|
|
14
|
+
row1([1, B, C, 4]) :- perm([1, 2, 3, 4], [1, B, C, 4]).
|
|
15
|
+
row2([A, 4, 1, D]) :- perm([1, 2, 3, 4], [A, 4, 1, D]).
|
|
16
|
+
row3([B, 1, 4, C]) :- perm([1, 2, 3, 4], [B, 1, 4, C]).
|
|
17
|
+
row4([4, C, B, 1]) :- perm([1, 2, 3, 4], [4, C, B, 1]).
|
|
18
|
+
|
|
19
|
+
column([R1, R2, R3, R4], Index, [A, B, C, D]) :-
|
|
20
|
+
nth0(Index, R1, A),
|
|
21
|
+
nth0(Index, R2, B),
|
|
22
|
+
nth0(Index, R3, C),
|
|
23
|
+
nth0(Index, R4, D).
|
|
24
|
+
|
|
25
|
+
boxes([R1, R2, R3, R4], [Box1, Box2, Box3, Box4]) :-
|
|
26
|
+
nth0(0, R1, A), nth0(1, R1, B), nth0(0, R2, C), nth0(1, R2, D),
|
|
27
|
+
eq(Box1, [A, B, C, D]),
|
|
28
|
+
nth0(2, R1, E), nth0(3, R1, F), nth0(2, R2, G), nth0(3, R2, H),
|
|
29
|
+
eq(Box2, [E, F, G, H]),
|
|
30
|
+
nth0(0, R3, I), nth0(1, R3, J), nth0(0, R4, K), nth0(1, R4, L),
|
|
31
|
+
eq(Box3, [I, J, K, L]),
|
|
32
|
+
nth0(2, R3, M), nth0(3, R3, N), nth0(2, R4, O), nth0(3, R4, P),
|
|
33
|
+
eq(Box4, [M, N, O, P]).
|
|
34
|
+
|
|
35
|
+
sudoku_solution([R1, R2, R3, R4]) :-
|
|
36
|
+
row1(R1),
|
|
37
|
+
row2(R2),
|
|
38
|
+
row3(R3),
|
|
39
|
+
row4(R4),
|
|
40
|
+
column([R1, R2, R3, R4], 0, C0), distinct(C0),
|
|
41
|
+
column([R1, R2, R3, R4], 1, C1), distinct(C1),
|
|
42
|
+
column([R1, R2, R3, R4], 2, C2), distinct(C2),
|
|
43
|
+
column([R1, R2, R3, R4], 3, C3), distinct(C3),
|
|
44
|
+
boxes([R1, R2, R3, R4], [B1, B2, B3, B4]),
|
|
45
|
+
distinct(B1), distinct(B2), distinct(B3), distinct(B4).
|
|
46
|
+
|
|
47
|
+
sudoku_answer(solution, Grid) :- once(sudoku_solution(Grid)).
|
|
48
|
+
sudoku_answer(solution_count, Count) :- countall(sudoku_solution(_Grid), Count).
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
% Weighted interval scheduling via memoized dynamic programming.
|
|
2
|
+
% Intervals are already ordered by finish time; best_from/2 chooses take/skip.
|
|
3
|
+
materialize(weighted_interval_answer, 2).
|
|
4
|
+
|
|
5
|
+
memoize(best_from, 2).
|
|
6
|
+
|
|
7
|
+
last_interval(8).
|
|
8
|
+
sentinel(9).
|
|
9
|
+
|
|
10
|
+
interval(1, 1, 4, 5).
|
|
11
|
+
interval(2, 3, 5, 1).
|
|
12
|
+
interval(3, 0, 6, 8).
|
|
13
|
+
interval(4, 4, 7, 4).
|
|
14
|
+
interval(5, 3, 9, 6).
|
|
15
|
+
interval(6, 5, 9, 3).
|
|
16
|
+
interval(7, 6, 10, 2).
|
|
17
|
+
interval(8, 8, 11, 4).
|
|
18
|
+
|
|
19
|
+
next_compatible(I, J) :-
|
|
20
|
+
interval(I, _Start, Finish, _Value),
|
|
21
|
+
aggregate_min(K, K,
|
|
22
|
+
(interval(K, StartK, _FinishK, _ValueK), gt(K, I), ge(StartK, Finish)),
|
|
23
|
+
J, J).
|
|
24
|
+
next_compatible(I, 9) :-
|
|
25
|
+
interval(I, _Start, Finish, _Value),
|
|
26
|
+
not((interval(K, StartK, _FinishK, _ValueK), gt(K, I), ge(StartK, Finish))).
|
|
27
|
+
|
|
28
|
+
best_from(9, 0).
|
|
29
|
+
best_from(I, Best) :-
|
|
30
|
+
last_interval(Last),
|
|
31
|
+
le(I, Last),
|
|
32
|
+
add(I, 1, Next),
|
|
33
|
+
best_from(Next, Skip),
|
|
34
|
+
next_compatible(I, Compatible),
|
|
35
|
+
best_from(Compatible, Tail),
|
|
36
|
+
interval(I, _Start, _Finish, Value),
|
|
37
|
+
add(Value, Tail, Take),
|
|
38
|
+
max(Take, Skip, Best).
|
|
39
|
+
|
|
40
|
+
chosen_from(I, I) :-
|
|
41
|
+
best_from(I, Best),
|
|
42
|
+
add(I, 1, Next),
|
|
43
|
+
best_from(Next, Skip),
|
|
44
|
+
next_compatible(I, Compatible),
|
|
45
|
+
best_from(Compatible, Tail),
|
|
46
|
+
interval(I, _Start, _Finish, Value),
|
|
47
|
+
add(Value, Tail, Take),
|
|
48
|
+
eq(Best, Take),
|
|
49
|
+
ge(Take, Skip).
|
|
50
|
+
chosen_from(I, Chosen) :-
|
|
51
|
+
best_from(I, Best),
|
|
52
|
+
add(I, 1, Next),
|
|
53
|
+
best_from(Next, Skip),
|
|
54
|
+
next_compatible(I, Compatible),
|
|
55
|
+
best_from(Compatible, Tail),
|
|
56
|
+
interval(I, _Start, _Finish, Value),
|
|
57
|
+
add(Value, Tail, Take),
|
|
58
|
+
eq(Best, Take),
|
|
59
|
+
ge(Take, Skip),
|
|
60
|
+
chosen_from(Compatible, Chosen).
|
|
61
|
+
chosen_from(I, Chosen) :-
|
|
62
|
+
best_from(I, Best),
|
|
63
|
+
add(I, 1, Next),
|
|
64
|
+
best_from(Next, Skip),
|
|
65
|
+
next_compatible(I, Compatible),
|
|
66
|
+
best_from(Compatible, Tail),
|
|
67
|
+
interval(I, _Start, _Finish, Value),
|
|
68
|
+
add(Value, Tail, Take),
|
|
69
|
+
gt(Skip, Take),
|
|
70
|
+
chosen_from(Next, Chosen).
|
|
71
|
+
|
|
72
|
+
weighted_interval_answer(best_value, Best) :- best_from(1, Best).
|
|
73
|
+
weighted_interval_answer(chosen_interval, interval(I, Start, Finish, Value)) :-
|
|
74
|
+
chosen_from(1, I),
|
|
75
|
+
interval(I, Start, Finish, Value).
|
|
76
|
+
weighted_interval_answer(candidate_count, Count) :- countall(interval(_I, _Start, _Finish, _Value), Count).
|
package/package.json
CHANGED
package/playground.html
CHANGED
|
@@ -456,6 +456,7 @@
|
|
|
456
456
|
"cache-performance",
|
|
457
457
|
"canary-release",
|
|
458
458
|
"cat-koko",
|
|
459
|
+
"chart-parser",
|
|
459
460
|
"clinical-trial-screening",
|
|
460
461
|
"collatz-1000",
|
|
461
462
|
"combinatorics-findall-sort",
|
|
@@ -465,6 +466,7 @@
|
|
|
465
466
|
"context-association",
|
|
466
467
|
"context-schema-audit",
|
|
467
468
|
"control-system",
|
|
469
|
+
"critical-path-schedule",
|
|
468
470
|
"cyclic-path",
|
|
469
471
|
"d3-group",
|
|
470
472
|
"dairy-energy-balance",
|
|
@@ -528,6 +530,7 @@
|
|
|
528
530
|
"lldm",
|
|
529
531
|
"manufacturing-quality-control",
|
|
530
532
|
"microgrid-dispatch",
|
|
533
|
+
"missionaries-cannibals",
|
|
531
534
|
"monkey-bananas",
|
|
532
535
|
"n-queens-8",
|
|
533
536
|
"network-sla",
|
|
@@ -558,12 +561,14 @@
|
|
|
558
561
|
"socrates",
|
|
559
562
|
"stable-marriage",
|
|
560
563
|
"statistics-summary",
|
|
564
|
+
"sudoku-4x4",
|
|
561
565
|
"superdense-coding",
|
|
562
566
|
"term-tools",
|
|
563
567
|
"trust-flow-provenance-threshold",
|
|
564
568
|
"turing",
|
|
565
569
|
"vector-similarity",
|
|
566
570
|
"vulnerability-impact",
|
|
571
|
+
"weighted-interval-scheduling",
|
|
567
572
|
"witch",
|
|
568
573
|
"wolf-goat-cabbage",
|
|
569
574
|
"zebra"
|
package/test/run-regression.mjs
CHANGED
|
@@ -524,6 +524,25 @@ function whiteBoxCases() {
|
|
|
524
524
|
assertEqual(termToString(candidates.primary[0].head, new Env(), true), 'edge(a, b)', 'primary head');
|
|
525
525
|
},
|
|
526
526
|
},
|
|
527
|
+
{
|
|
528
|
+
name: 'challenging examples keep dynamic-programming predicates memoized',
|
|
529
|
+
run: () => {
|
|
530
|
+
const checks = [
|
|
531
|
+
['chart-parser.pl', 'span', 4, true],
|
|
532
|
+
['critical-path-schedule.pl', 'earliest_start', 2, false],
|
|
533
|
+
['critical-path-schedule.pl', 'finish_time', 2, false],
|
|
534
|
+
['weighted-interval-scheduling.pl', 'best_from', 2, true],
|
|
535
|
+
];
|
|
536
|
+
for (const [filename, name, arity, recursive] of checks) {
|
|
537
|
+
const text = fs.readFileSync(path.join(packageRoot, 'examples', filename), 'utf8');
|
|
538
|
+
const program = Program.parseSources([{ text, filename }]);
|
|
539
|
+
const group = program.findGroup(name, arity);
|
|
540
|
+
assertEqual(Boolean(group), true, `${filename} ${name}/${arity} group exists`);
|
|
541
|
+
assertEqual(group.memoized, true, `${filename} ${name}/${arity} memoized`);
|
|
542
|
+
assertEqual(group.recursive, recursive, `${filename} ${name}/${arity} recursive`);
|
|
543
|
+
}
|
|
544
|
+
},
|
|
545
|
+
},
|
|
527
546
|
{
|
|
528
547
|
name: 'n-queens example keeps diagonal checks memoized',
|
|
529
548
|
run: () => {
|