Skip to content

Commit 6ddee82

Browse files
committed
MeTTa TS 1.1.4
1 parent 9cf5280 commit 6ddee82

32 files changed

Lines changed: 1027 additions & 334 deletions

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ node packages/node/dist/cli.js examples/factorial.metta
278278

279279
## Performance
280280

281-
The pure-MeTTa path stays TypeScript throughout, with no escape to native code. The interpreter uses a precomputed-ground short-circuit, structural sharing in substitution, a cons-list instruction stack, and Prolog-style clause indexing (by head functor and by every ground-leaf argument position). A functor-and-argument-keyed query over a 1,000,000-atom knowledge base resolves in about 0.2 to 1.4 ms. See [`packages/node/bench/RESULTS.md`](packages/node/bench/RESULTS.md) for the full benchmark log.
281+
The pure-MeTTa path stays TypeScript throughout, with no escape to native code. The interpreter uses a precomputed-ground short-circuit, structural sharing in substitution, a cons-list instruction stack, and Prolog-style clause indexing by head functor, indexable ground-leaf arguments at every position, and one nested expression-head level. A functor-and-argument-keyed query over a 1,000,000-atom knowledge base resolves in about 0.2 to 1.4 ms. See [`packages/node/bench/RESULTS.md`](packages/node/bench/RESULTS.md) for the full benchmark log.
282282

283283
### Head-to-head with PeTTa
284284

@@ -325,7 +325,7 @@ That speed comes from general engine work:
325325
- an O(1)-stack worklist for nondeterminism;
326326
- ground-atom type memoisation;
327327
- an exact-match ground-fact index;
328-
- nested argument-functor indexing for ground runtime facts such as `(num (M $x))`;
328+
- nested argument-functor indexing for ground static and runtime facts such as `(num (M $x))`;
329329
- bounded automatic tabling of pure overlapping-recursive functions, with structural token keys, runtime rule-versioned entries, and one shared budget for completed and active tables;
330330
- consumer-directed distinct memoization and streaming choice deduplication only where `unique-atom(collapse(...))` makes duplicate derivations unobservable, while ordinary `collapse` keeps its exact ordered bag;
331331
- a slot-based evaluator for closed pure `let` and `superpose` products that preserves result order and multiplicity without allocating general binding frames;

RELEASE_NOTES.md

Lines changed: 54 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,152 +1,70 @@
1-
# MeTTa TS 1.1.3
2-
3-
MeTTa TS 1.1.3 improves nondeterministic evaluation and bounds every automatic
4-
table allocation. The default evaluator is faster than PeTTa on the four
5-
reported nondeterministic workloads while preserving Hyperon semantics. There
6-
is no benchmark mode, PeTTa mode, curry mode, or manually selected fast path.
7-
8-
## Tested on Linux
9-
10-
This release is prepared on Linux with Node 22 and pnpm 11. The release gate
11-
builds every package, typechecks the workspace, runs the full Vitest suite,
12-
builds the GitHub Pages documentation, runs the Hyperon oracle, runs the scale
13-
proof, and runs the benchmark suite before tagging.
14-
15-
The final suite passed 109 test files and 1,063 tests, with 38 optional live
16-
integration tests skipped. The checked 270-assertion oracle passed all 23
17-
corpus files.
18-
19-
The external Core/ST conformance result is unchanged from the untouched 1.1.2
20-
baseline: 431 passed, 77 failed, 60 manifest expected failures, and 0 skipped.
21-
The remaining failures are existing parser, directive, kernel, typing, and
22-
stdlib contract differences. This release does not claim full specification
23-
conformance.
24-
25-
## Nondeterministic execution
26-
27-
The new checked benchmark keeps four query shapes reported by Patrick Hammer
28-
as ordinary `.metta` files. Five-run subprocess medians include startup:
29-
30-
| Program | PeTTa | MeTTa TS | Speedup |
31-
| -------------------------------- | --------: | --------: | ------: |
32-
| filtered `matespacefast` matches | 5738.1 ms | 3344.2 ms | 1.72x |
33-
| 22^4 `superpose` cross product | 388.7 ms | 148.5 ms | 2.62x |
34-
| nondeterministic tabled `fib(7)` | 180.1 ms | 99.6 ms | 1.81x |
35-
| duplicate-heavy `TupleConcat` | 178.8 ms | 101.1 ms | 1.77x |
36-
37-
The harness validates 234,256 cross-product results, 196 distinct Fibonacci
38-
answers, the exact `TupleConcat` sequence, and the embedded matespace
39-
assertion. Run it with `pnpm bench:nondeterminism`.
40-
41-
A slot-based choice evaluator handles closed pure `let`, `let*`, `superpose`,
42-
integer arithmetic, comparisons, `if`, and constructor tuples. Unsupported,
43-
redefined, ill-typed, async, or executable-grounded forms stay on the normal
44-
interpreter path. Result order and multiplicity are unchanged.
45-
46-
`unique-atom(collapse(call))` can evaluate a supported static pure integer
47-
recurrence as a first-seen answer set. Closed pure choice products also retain
48-
first-seen answers as they emit instead of materializing a duplicate bag first.
49-
An ordinary `collapse(call)` still returns its exact ordered bag with duplicate
50-
derivations. Ground answer deduplication uses structural hashes with equality
51-
checks instead of a quadratic scan.
52-
53-
## Bounded automatic tabling
54-
55-
Automatic table admission remains conservative. The whole rule dependency
56-
graph must be pure, the call key must be safe, and the recursive component must
57-
branch back into itself at least twice. Linear recursion stays on the normal
58-
compiled path.
59-
60-
The policy does not assume that every recursive program is safe to memoize and
61-
does not let admitted tables grow until the process runs out of memory. It
62-
combines the static overlap test with one global runtime budget. Exceeding the
63-
active-state budget returns `TableResourceLimit`; it does not continue toward
64-
an out-of-memory failure.
65-
66-
Completed and active tables now share these default ceilings:
67-
68-
- 50,000 entries
69-
- 1,000,000 answers
70-
- 1,000,000 retained atom cells
71-
- 100,000 cells in one entry
72-
- 250,000 interned leaves
73-
74-
Completed tables are removed in least-recently-used order. Active tables are
75-
not evicted while their producer runs, so they return `TableResourceLimit` when
76-
the shared budget cannot fit more state. The consumer-directed recurrence memo
77-
uses the same entry, answer, cell, and per-entry limits. Interner generations
78-
prevent stale tail-call keys from writing after a reset.
79-
80-
Direct active variant recursion still uses local-linear fixed-point completion.
81-
Non-cyclic calls preserve exact ordered bags. The evaluator does not infer
82-
Picat-style `min` or `max` answer subsumption.
83-
84-
## Matching and scale
85-
86-
Ground runtime facts now have a nested argument-functor index. A pattern such
87-
as `(num (M $x))` selects the `M` bucket instead of scanning every `num` fact.
88-
The matcher falls back to complete candidates when a non-ground fact could
89-
unify.
90-
91-
A finite in-memory match whose result is discarded by a standard
92-
`let ... (empty)` is removed before enumeration. The optimization declines for
93-
custom grounded matchers, mutable state handles, changed standard forms, and
94-
non-memory spaces.
95-
96-
The 30,000-fact scale gate also runs larger actual MeTTa workloads:
97-
98-
| Program | Checked result | Time |
99-
| -------------------------- | ------------------------------: | -------: |
100-
| 24^4 pure choice product | 331,776 answers | 81.2 ms |
101-
| duplicate tuple product | 50 values from 500,000 branches | 30.8 ms |
102-
| nondeterministic `fib(10)` | 2,817 distinct answers | 73.4 ms |
103-
| nested runtime match | 30,000 answers | 647.3 ms |
104-
105-
## Correctness fixes
106-
107-
- `superpose` in the choice evaluator now strips a collapsed bag's leading
108-
comma marker. The recursive `supercollapse` corpus case remains empty as
109-
Hyperon requires.
110-
- Choice planning now respects application type errors, expression-headed
111-
rewrite rules, and replaced sync or async grounded operations.
112-
- Nested indexing no longer changes candidate enumeration when a pattern has
113-
no nested-head constraint.
114-
- Active table entries and answers count against the same global resource
115-
budget as completed entries.
116-
- The purity firewall now treats custom sync and async grounded operations as
117-
effectful unless they are the unchanged implementation of a known-pure
118-
built-in. File, catalog, random, time, output, fresh-identity, and host calls
119-
cannot enter automatic tables transitively.
120-
- File handles can be closed immediately with `file-close!` and are also closed
121-
when their grounded atom is collected. Dictionary spaces and file records use
122-
weak-key storage instead of lifetime-unbounded global maps. Grounded behavior
123-
and non-default grounded types remain on the lossless atomspace path.
124-
- Grounded-operation registration invalidates evaluated terms, table analyses,
125-
and compiled closures that may encode the previous dispatch behavior.
126-
- DAS gateway binding responses must contain exactly one MeTTa atom per value.
127-
Malformed or multi-atom wire values now fail at the decode boundary.
128-
- Git imports pass an end-of-options marker before the repository path.
129-
- The unused `streamEmit`, `tableBackchain`, and `trieSpace` experimental
130-
options have been removed. They never selected an implementation.
1+
# MeTTa TS 1.1.4
2+
3+
MeTTa TS 1.1.4 adds selective nested-head indexing for immutable static facts.
4+
Queries such as `(num (M $x))` can select the matching `M` bucket while the
5+
normal unifier preserves MeTTa result order, multiplicity, and fallback
6+
semantics.
7+
8+
## Static nested matching
9+
10+
Static `&self` facts now have a nested argument-functor candidate index. A
11+
pattern such as `(num (M $x))` selects the `M` bucket instead of scanning every
12+
static `num` fact. The path applies to one match pattern over an immutable
13+
ground fact bucket. Static removals, state cells, runtime additions,
14+
variable-headed facts, non-ground facts, and conjunctions disable the new
15+
static nested path. Runtime additions retain their separate compact-store
16+
index. Static candidate selection then follows the existing complete or
17+
leaf-indexed paths. Existing leaf-key selection retains precedence. The full
18+
unifier remains authoritative.
19+
20+
Indexed and custom-grounded residual candidates merge by source occurrence,
21+
so the nested path retains insertion order and duplicate multiplicity. Skipped
22+
ground candidate attempts are restored to the evaluator counter. Leaf index
23+
keys now retain custom grounded matchers as residual candidates and use one
24+
numeric key for integer and float values, matching ground equality.
25+
26+
The selective static nested scale case passed at the 30,000-fact default and
27+
with `node packages/node/bench/scale-proof.mjs --size=100000`.
28+
`pnpm bench:nested-index` validates complete ordered result sequences and
29+
counters while measuring selective and dense cases up to 1,000,000 facts.
30+
Detailed measurements are in
31+
[`packages/node/bench/RESULTS.md`](packages/node/bench/RESULTS.md).
32+
33+
## Verification
34+
35+
The workspace build, typecheck, lint, formatting check, documentation build,
36+
benchmark suite, and 270-assertion oracle pass. The full suite passes 109 test
37+
files and 1,079 tests, with 38 optional live integration tests skipped.
38+
39+
The concurrency benchmark status now states both parts of its regression gate:
40+
the median must exceed 1.5 times the baseline and add more than 1 millisecond.
41+
42+
## Repository links
43+
44+
Package metadata, documentation links, and the GitHub Pages base path now use
45+
the canonical [`MesTTo/MeTTa-TS`](https://github.com/MesTTo/MeTTa-TS)
46+
repository name.
47+
48+
`@metta-ts/grapher` now ships a package README. Its examples distinguish
49+
starting a reduction trace from scheduling later trace steps, and its GIF
50+
example contains a reducible expression.
13151

13252
## Install
13353

13454
```bash
135-
npm install @metta-ts/core@1.1.3
136-
npm install -g @metta-ts/node@1.1.3
55+
npm install @metta-ts/core@1.1.4
56+
npm install -g @metta-ts/node@1.1.4
13757
```
13858

13959
Optional host packages use the same version:
14060

14161
```bash
142-
npm install @metta-ts/py@1.1.3 pythonia
143-
npm install @metta-ts/prolog@1.1.3
62+
npm install @metta-ts/py@1.1.4 pythonia
63+
npm install @metta-ts/prolog@1.1.4
14464
```
14565

14666
## Provenance
14767

14868
- Semantics: [hyperon-experimental](https://github.com/trueagi-io/hyperon-experimental).
14969
- Verified differential semantics: [LeaTTa](https://github.com/MesTTo/LeaTTa).
150-
- Host compatibility: PeTTa-compatible Python and Prolog bridge forms where
151-
they do not depend on PeTTa's evaluator.
15270
- License: [MIT](LICENSE).

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"oracle": "vitest run packages/core/src/oracle.test.ts",
1919
"bench": "pnpm -r --filter @metta-ts/core --filter @metta-ts/node --filter @metta-ts/browser build && node packages/node/bench/suite.mjs && node packages/node/bench/nondeterminism.mjs --engine=ts --runs=1 && node packages/node/bench/concurrency.mjs && node packages/browser/bench/concurrency.mjs",
2020
"bench:nondeterminism": "pnpm -r --filter @metta-ts/core --filter @metta-ts/node build && node packages/node/bench/nondeterminism.mjs",
21+
"bench:nested-index": "pnpm --filter @metta-ts/core build && node packages/node/bench/nested-static-index.mjs",
2122
"bench:scale": "pnpm -r --filter @metta-ts/core --filter @metta-ts/node build && node packages/node/bench/scale-proof.mjs",
2223
"bench:prolog": "pnpm -r --filter @metta-ts/core --filter @metta-ts/hyperon --filter @metta-ts/prolog --filter @metta-ts/node build && node packages/node/bench/prolog.mjs"
2324
},

packages/bench/concurrency-harness.mjs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,12 @@ export function writeOrCheckReport({
126126
}
127127

128128
if (regressions.length > 0) {
129-
printErr(`\n${regressions.length} operation(s) slower than ${regressionRatio}x baseline.`);
129+
printErr(
130+
`\n${regressions.length} operation(s) exceeded both ${regressionRatio}x baseline and a ${ms(regressionMinMs)} ms slowdown.`,
131+
);
130132
process.exit(1);
131133
}
132-
print(`\nNo regression over ${regressionRatio}x baseline.`);
134+
print(
135+
`\nNo operation exceeded both ${regressionRatio}x baseline and a ${ms(regressionMinMs)} ms slowdown.`,
136+
);
133137
}

packages/browser/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# @metta-ts/browser
22

3-
Browser entry for [MeTTa TS](https://github.com/MesTTo/Meta-TypeScript-Talk). Re-exports everything from [`@metta-ts/core`](https://github.com/MesTTo/Meta-TypeScript-Talk/tree/main/packages/core) and adds an in-memory virtual file system so `import!` works without disk access.
3+
Browser entry for [MeTTa TS](https://github.com/MesTTo/MeTTa-TS). Re-exports everything from [`@metta-ts/core`](https://github.com/MesTTo/MeTTa-TS/tree/main/packages/core) and adds an in-memory virtual file system so `import!` works without disk access.
44

55
## Install
66

@@ -123,4 +123,4 @@ check.
123123

124124
## License
125125

126-
[MIT](https://github.com/MesTTo/Meta-TypeScript-Talk/blob/main/LICENSE).
126+
[MIT](https://github.com/MesTTo/MeTTa-TS/blob/main/LICENSE).

packages/browser/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@metta-ts/browser",
3-
"version": "1.1.3",
3+
"version": "1.1.4",
44
"license": "MIT",
55
"type": "module",
66
"main": "./dist/index.js",
@@ -54,11 +54,11 @@
5454
],
5555
"repository": {
5656
"type": "git",
57-
"url": "git+https://github.com/MesTTo/Meta-TypeScript-Talk.git",
57+
"url": "git+https://github.com/MesTTo/MeTTa-TS.git",
5858
"directory": "packages/browser"
5959
},
60-
"homepage": "https://github.com/MesTTo/Meta-TypeScript-Talk#readme",
60+
"homepage": "https://github.com/MesTTo/MeTTa-TS#readme",
6161
"bugs": {
62-
"url": "https://github.com/MesTTo/Meta-TypeScript-Talk/issues"
62+
"url": "https://github.com/MesTTo/MeTTa-TS/issues"
6363
}
6464
}

packages/core/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
The MeTTa (OpenCog Hyperon) interpreter in pure TypeScript: atoms, spaces, the type system, pattern matching, evaluation, and the standard library. No native addons and no required WASM. Runs in any JavaScript runtime (browser, Node, Deno, Bun, edge).
44

5-
Part of [MeTTa TS](https://github.com/MesTTo/Meta-TypeScript-Talk).
5+
Part of [MeTTa TS](https://github.com/MesTTo/MeTTa-TS).
66

77
## Install
88

@@ -26,8 +26,8 @@ for (const { query, results: rs } of results) {
2626
// (fact 5) => [ '120' ]
2727
```
2828

29-
`runProgram` parses the source, adds every non-bang atom to the knowledge base, evaluates each `!`-query, and returns one result group per query. For a higher-level class API modeled on Python's `hyperon`, see [`@metta-ts/hyperon`](https://github.com/MesTTo/Meta-TypeScript-Talk/tree/main/packages/hyperon).
29+
`runProgram` parses the source, adds every non-bang atom to the knowledge base, evaluates each `!`-query, and returns one result group per query. For a higher-level class API modeled on Python's `hyperon`, see [`@metta-ts/hyperon`](https://github.com/MesTTo/MeTTa-TS/tree/main/packages/hyperon).
3030

3131
## License
3232

33-
[MIT](https://github.com/MesTTo/Meta-TypeScript-Talk/blob/main/LICENSE).
33+
[MIT](https://github.com/MesTTo/MeTTa-TS/blob/main/LICENSE).

packages/core/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@metta-ts/core",
3-
"version": "1.1.3",
3+
"version": "1.1.4",
44
"license": "MIT",
55
"type": "module",
66
"main": "./dist/index.js",
@@ -46,11 +46,11 @@
4646
],
4747
"repository": {
4848
"type": "git",
49-
"url": "git+https://github.com/MesTTo/Meta-TypeScript-Talk.git",
49+
"url": "git+https://github.com/MesTTo/MeTTa-TS.git",
5050
"directory": "packages/core"
5151
},
52-
"homepage": "https://github.com/MesTTo/Meta-TypeScript-Talk#readme",
52+
"homepage": "https://github.com/MesTTo/MeTTa-TS#readme",
5353
"bugs": {
54-
"url": "https://github.com/MesTTo/Meta-TypeScript-Talk/issues"
54+
"url": "https://github.com/MesTTo/MeTTa-TS/issues"
5555
}
5656
}

0 commit comments

Comments
 (0)