Skip to content

Commit c5ec215

Browse files
committed
MeTTa TS 1.2.0
1 parent 8d0836a commit c5ec215

65 files changed

Lines changed: 4604 additions & 221 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 55 additions & 78 deletions
Large diffs are not rendered by default.

RELEASE_NOTES.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,90 @@
1+
# MeTTa TS 1.2.0
2+
3+
MeTTa TS 1.2.0 adds eight importable standard libraries and makes the core list
4+
operations run in linear time. Both changes keep the conformance oracle
5+
byte-identical: the libraries stay off the prelude, and the faster list
6+
operations return results equal to the prelude recursion up to variable renaming.
7+
8+
## Standard libraries
9+
10+
Eight libraries from the PeTTa distribution are now importable modules. Load one
11+
with `(import! &self <name>)`. They are kept off the prelude, so a program that
12+
imports none of them behaves exactly as before and the oracle is unchanged.
13+
14+
- `vector`, `roman`, `combinatorics`, `patrick`, `datastructures`, and `spaces`
15+
port the corresponding PeTTa utilities.
16+
- `nars` is a Non-Axiomatic Reasoning System belief engine.
17+
- `pln` is a Probabilistic Logic Networks reasoner with truth-value revision,
18+
negation, and deduction, reached through a `PLN.Query` entry point.
19+
20+
The ports follow Hyperon semantics rather than PeTTa's cons-cell representation:
21+
list construction uses `decons-atom`/`cons-atom`, `collapse` yields a comma
22+
tuple, and `foldl`/`msort` map to `foldl-atom`/`sort`.
23+
24+
## Linear-time list operations
25+
26+
`size-atom`, `map-atom`, `filter-atom`, and `foldl-atom` over a literal list of
27+
N elements now run in O(N) time on a constant native stack. The prelude
28+
recursion was quadratic to cubic and overflowed the stack before reaching a
29+
million elements.
30+
31+
`size-atom` gains a fast path that returns a ground tuple of inert data without
32+
threading each element through the interpreter. `map-atom`, `filter-atom`, and
33+
`foldl-atom` evaluate as grounded operations, and when the per-element function
34+
is compiled they call it directly on the compiled path. Every result is equal to
35+
the prelude recursion up to variable renaming, checked by an on/off differential.
36+
37+
A five-run minimum-time subprocess benchmark against PeTTa on SWI-Prolog, at
38+
N=100000 and including process startup, with a one-clause user function per
39+
element:
40+
41+
| Operation | PeTTa | MeTTa TS | Speedup |
42+
| ------------- | -----: | -------: | ------: |
43+
| `size-atom` | 887 ms | 170 ms | 5.23x |
44+
| `map-atom` | 999 ms | 348 ms | 2.87x |
45+
| `filter-atom` | 966 ms | 360 ms | 2.68x |
46+
| `foldl-atom` | 999 ms | 346 ms | 2.89x |
47+
48+
## Trace bus and metta-debug
49+
50+
The core exposes an optional trace bus: pass a `trace` sink to a run and the
51+
evaluator reports its reduce, rule-selection, grounded-dispatch, and
52+
specialization decisions, with no cost when no sink is set. The `@metta-ts/node`
53+
package adds a `metta-debug` command that runs a call under that sink and prints
54+
those decisions, so a depth or dispatch question is a one-command diagnosis.
55+
56+
## Fixes
57+
58+
A function that returns a control form such as `let` or `if` under
59+
`{tabling: true}` now reduces it fully instead of leaving it partially reduced.
60+
61+
## Verification
62+
63+
Checked on Linux with Node and pnpm.
64+
65+
- Build, type check, lint, and format checks pass across all ten packages.
66+
- `pnpm test` passes: 1,208 tests across 123 files, with 38 optional live
67+
integration tests (7 files) skipped.
68+
- The checked oracle passes all 23 corpus files. It is byte-identical to 1.1.7:
69+
the new libraries are opt-in and off the prelude, and the faster list
70+
operations equal the prelude recursion up to variable renaming.
71+
72+
## Packages
73+
74+
All public packages use version `1.2.0`:
75+
76+
```bash
77+
npm install @metta-ts/core@1.2.0
78+
npm install -g @metta-ts/node@1.2.0
79+
```
80+
81+
Optional host packages use the same version:
82+
83+
```bash
84+
npm install @metta-ts/py@1.2.0 pythonia
85+
npm install @metta-ts/prolog@1.2.0
86+
```
87+
188
# MeTTa TS 1.1.7
289

390
MeTTa TS 1.1.7 fixes a unification soundness bug in grounded substitution.

examples/concurrency.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const last = async (src: string): Promise<string[]> =>
2020
(await runProgramAsync(src, new Map([["aw", aw]]))).at(-1)!.results.map(format);
2121

2222
// par: three branches run concurrently; collapse gathers the union.
23-
console.log("par:", await last("!(collapse (par (aw 3) (aw 4) (aw 2)))")); // [ '(3 4 2)' ]
23+
console.log("par:", await last("!(collapse (par (aw 3) (aw 4) (aw 2)))")); // [ '(, 3 4 2)' ]
2424

2525
// race: the fast branch (3ms) wins over the slow one (40ms).
2626
console.log("race:", await last("!(race (aw 40) (aw 3))")); // [ '3' ]

examples/nondeterminism.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@ for (const { query, results: rs } of results) {
3030
}
3131
// !(bin) => [ '0', '1' ]
3232
// !(superpose (red green blue))=> [ 'red', 'green', 'blue' ]
33-
// !(collapse (bin)) => [ '(0 1)' ]
33+
// !(collapse (bin)) => [ '(, 0 1)' ]
3434
// !(double (superpose (1 2 3)))=> [ '2', '4', '6' ]

examples/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"matching": "tsx matching.ts",
1414
"nondeterminism": "tsx nondeterminism.ts",
1515
"stdlib": "tsx stdlib.ts",
16+
"standard-libraries": "metta-ts standard-libraries.metta",
1617
"types": "tsx types.ts",
1718
"js-interop": "tsx js-interop.ts",
1819
"python-interop": "tsx python-interop.ts",
@@ -25,6 +26,7 @@
2526
"transactions": "tsx transactions.ts",
2627
"scaling": "tsx scaling.ts",
2728
"parallel-matcher": "tsx parallel-matcher.ts",
29+
"grapher": "tsx grapher.ts",
2830
"grapher-gif": "tsx grapher-gif.ts",
2931
"typecheck": "tsc --noEmit"
3032
},

examples/standard-libraries.metta

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
; SPDX-FileCopyrightText: 2026 MesTTo
2+
; SPDX-License-Identifier: MIT
3+
4+
; The 1.2.0 importable libraries are opt-in. Each import adds its functions to &self.
5+
; Run it after building packages:
6+
; pnpm --filter @metta-ts/examples standard-libraries
7+
8+
!(import! &self vector)
9+
!(dot (1.0 2.0 3.0) (4.0 5.0 6.0)) ; [32.0]
10+
11+
!(import! &self combinatorics)
12+
!(collapse (range 1 4)) ; [(, 1 2 3)]
13+
14+
!(import! &self roman)
15+
(= (double $x) (* $x 2))
16+
!(map-flat double (1 2 3)) ; [(2 4 6)]
17+
18+
!(import! &self patrick)
19+
(= (inc $x) (+ $x 1))
20+
!(compose (double inc) (5)) ; [12]
21+
22+
!(import! &self datastructures)
23+
!(dequeue (enqueue b (enqueue a (empty-queue)))) ; [(Pair a (queue () (b) 1))]
24+
25+
!(import! &self spaces)
26+
!(add-atom &warehouse (box 1))
27+
!(migrateAtoms &warehouse &shipped (box $n))
28+
!(collapse (match &shipped $x $x)) ; [(, (box 1))]
29+
30+
!(import! &self nars)
31+
!(Truth_Expectation (stv 0.8 0.9)) ; [0.77]
32+
33+
!(import! &self pln)
34+
!(Truth_ModusPonens (stv 0.8 0.9) (stv 0.7 0.6)) ; [(stv 0.564 0.54)]

examples/transactions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ console.log(
1919
!(transaction (add-atom &self (cnt 7)))
2020
!(collapse (match &self (cnt $v) $v))
2121
`),
22-
); // [ '(5 7)' ]
22+
); // [ '(, 5 7)' ]
2323

2424
// Rollback: the body adds (cnt 6) then produces zero results, so the add is undone.
2525
console.log(
@@ -30,4 +30,4 @@ console.log(
3030
!(transaction (let $u (add-atom &self (cnt 6)) (superpose ())))
3131
!(collapse (match &self (cnt $v) $v))
3232
`),
33-
); // [ '(5)' ]
33+
); // [ '(, 5)' ]

packages/browser/README.md

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -74,53 +74,6 @@ await runner.dispose();
7474
See `examples/browser-interop` for a runnable smoke check and a bundle isolation
7575
check.
7676

77-
For embedders that already resolved imports, `@metta-ts/browser/source` exposes source runners:
78-
79-
```ts
80-
import { runSourceAsync } from "@metta-ts/browser/source";
81-
82-
const results = await runSourceAsync(`
83-
!(import! &self concurrency)
84-
!(par (+ 1 1) (+ 2 2))
85-
`);
86-
```
87-
88-
The async runner supports MeTTa's async forms (`par`, `race`, `with-mutex`) and uses Web Workers for
89-
`(once (hyperpose ...))` when the browser host provides them.
90-
91-
## Host Interop
92-
93-
`@metta-ts/browser/host` composes optional host runtimes such as Pyodide and
94-
SWI-Prolog WASM. The base browser package stays pure TypeScript. Import a host
95-
adapter only when the page needs it.
96-
97-
```ts
98-
import { createBrowserRunner, createBrowserTextLoader } from "@metta-ts/browser/host";
99-
import { createPyodideInterop } from "@metta-ts/py/pyodide";
100-
import { createSwiWasmInterop } from "@metta-ts/prolog/swi-wasm";
101-
102-
const files = new Map([
103-
["math.py", "def add(a, b):\n return a + b\n"],
104-
["facts.pl", "edge(alice, bob).\n"],
105-
]);
106-
const loadText = createBrowserTextLoader({ files, baseUrl: import.meta.url });
107-
const py = await createPyodideInterop({ loadText });
108-
const prolog = await createSwiWasmInterop({ loadText });
109-
const runner = createBrowserRunner({ files, interops: [py, prolog] });
110-
111-
const results = await runner.run(`
112-
!(import! &self "math.py")
113-
!(py-call (math.add 40 2))
114-
!(import! &self "facts.pl")
115-
!(prolog-call (edge alice $x))
116-
`);
117-
118-
await runner.dispose();
119-
```
120-
121-
See `examples/browser-interop` for a runnable smoke check and a bundle isolation
122-
check.
123-
12477
## License
12578

12679
[MIT](https://github.com/MesTTo/MeTTa-TS/blob/main/LICENSE).

packages/browser/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@metta-ts/browser",
3-
"version": "1.1.7",
3+
"version": "1.2.0",
44
"license": "MIT",
55
"type": "module",
66
"main": "./dist/index.js",

packages/core/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ for (const { query, results: rs } of results) {
2828

2929
`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

31+
The experimental line adds a pull-based streaming grounded-operation protocol on the `experimental` npm tag; see [Experimental features](https://mestto.github.io/MeTTa-TS/guide/experimental).
32+
3133
## License
3234

3335
[MIT](https://github.com/MesTTo/MeTTa-TS/blob/main/LICENSE).

0 commit comments

Comments
 (0)