@metta-ts/edsl 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -24
- package/dist/index.d.ts +141 -41
- package/dist/index.js +176 -54
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @metta-ts/edsl
|
|
2
2
|
|
|
3
|
-
A typed TypeScript eDSL for [MeTTa TS](https://github.com/MesTTo/Meta-TypeScript-Talk).
|
|
3
|
+
A typed TypeScript eDSL for [MeTTa TS](https://github.com/MesTTo/Meta-TypeScript-Talk). Mint symbols, functors, and logic variables from proxies, build MeTTa with combinators or a tagged template, and run it on the real interpreter. Any TypeScript value drops in as a grounded atom automatically, and TypeScript functions bridge in both directions.
|
|
4
4
|
|
|
5
5
|
It is a thin layer over [`@metta-ts/hyperon`](https://github.com/MesTTo/Meta-TypeScript-Talk/tree/main/packages/hyperon): every builder produces an ordinary atom that runs on the existing engine, so you get MeTTa's full semantics: rewrite rules, nondeterminism, pattern matching, and types.
|
|
6
6
|
|
|
@@ -13,39 +13,87 @@ npm install @metta-ts/edsl
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
15
15
|
```ts
|
|
16
|
-
import { mettaDB,
|
|
16
|
+
import { mettaDB, names, vars, If, gt, lt, mul, sub, m } from "@metta-ts/edsl";
|
|
17
17
|
|
|
18
18
|
const db = mettaDB();
|
|
19
19
|
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
20
|
+
// `names()` mints symbols and functors on demand; `vars()` mints logic variables. No name is written
|
|
21
|
+
// twice: the JS binding IS the name. A bare name grounds to its symbol; a called name applies it.
|
|
22
|
+
const { Likes, fact, Ada, Coffee, Chocolate } = names();
|
|
23
|
+
const { thing, x } = vars();
|
|
24
|
+
|
|
25
|
+
// Facts + a match query. With no explicit vars, the row keys are inferred from the pattern.
|
|
26
|
+
db.add(Likes(Ada, Coffee), Likes(Ada, Chocolate));
|
|
27
|
+
db.query(Likes(Ada, thing)); // [{ thing: "Coffee" }, { thing: "Chocolate" }]
|
|
24
28
|
|
|
25
29
|
// Rewrite rules + grounded arithmetic, recursion, nondeterminism.
|
|
26
|
-
|
|
27
|
-
db.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
db.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
db.
|
|
35
|
-
|
|
36
|
-
//
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
db.rule(fact(x), If(gt(x, 0), mul(x, fact(sub(x, 1))), 1));
|
|
31
|
+
db.evalJs(fact(5)); // [120]
|
|
32
|
+
|
|
33
|
+
// Grounded functions: a plain typed function, args auto-unwrapped, result auto-grounded.
|
|
34
|
+
db.fn("balance-of", (a: { balance: number }) => a.balance);
|
|
35
|
+
db.evalJs(m`(balance-of ${{ owner: "Tom", balance: 100 }})`); // [100]
|
|
36
|
+
|
|
37
|
+
// Call MeTTa functions from TypeScript, quick or typed.
|
|
38
|
+
db.call.fact(5); // [120]
|
|
39
|
+
const factorial = db.import<[number], number>("fact");
|
|
40
|
+
factorial(6); // 720
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## The two term surfaces
|
|
44
|
+
|
|
45
|
+
- **Proxies + combinators.** `names()` and `vars()` mint names and variables (`const { parent, x } = ...`), and the capitalized combinators build the special forms: `If`, `Case`, `Let`, `LetStar`, `Match`, `Superpose`, `Collapse`, `Empty`, `Unify`, `Sealed`, `Quote`. Lowercase builders cover the grounded ops: `add`/`sub`/`mul`/`div`/`mod`, `eq`/`gt`/`lt`/`ge`/`le`, `and`/`or`/`not`, `carAtom`/`cdrAtom`/`consAtom`/`deconsAtom`, and `list`/`nil`/`e`. Builders compose, so nested patterns and repeated variables are just nested calls.
|
|
46
|
+
- **The tagged template `m\`...\`` (and `mAll` for several atoms)** runs the real parser, so it expresses every MeTTa form, and `${value}` auto-grounds, which is the easiest way to drop a TS object in.
|
|
47
|
+
|
|
48
|
+
## The runner and the host bridge
|
|
49
|
+
|
|
50
|
+
`mettaDB()` keeps MeTTa's two query mechanisms distinct: `query(pattern)` does `match &self` over stored atoms and returns binding rows (keys inferred from the pattern, or typed by an explicit `vars` map); `eval(atom)` (and `evalJs`, `evalAsync`, `evalJsAsync`) rewrites with the `=` rules and returns the nondeterministic results.
|
|
51
|
+
|
|
52
|
+
The host bridge runs both directions:
|
|
53
|
+
|
|
54
|
+
- **TypeScript into MeTTa (grounded functions).** `db.fn("name", fn)` registers a plain typed function with arguments auto-unwrapped to JS and the result auto-grounded; `db.fns({ ... })` registers several at once keyed by name; `db.asyncFn` awaits an async function. The raw `db.op`/`db.asyncOp` stay for full atom control (multiple results, custom matching).
|
|
55
|
+
- **MeTTa into TypeScript (backward import).** `db.call.<name>(...)` builds and evaluates `(<name> ...args)` and returns every result unwrapped to JS; use bracket access for hyphenated names (`db.call["is-even"](4)`). `db.import("name")` returns a callable.
|
|
56
|
+
|
|
57
|
+
### Typing the host bridge
|
|
58
|
+
|
|
59
|
+
Pass a schema to `mettaDB` and `call`, `import`, and `fn` become statically typed; with no schema they stay permissive. Both an `interface` and a `type` schema work.
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
interface Api {
|
|
63
|
+
fact: (n: number) => number;
|
|
64
|
+
isEven: (n: number) => boolean;
|
|
65
|
+
}
|
|
66
|
+
const db = mettaDB<Api>();
|
|
67
|
+
db.call.fact(5); // number[]
|
|
68
|
+
const factorial = db.import("fact"); // (n: number) => number | undefined
|
|
69
|
+
db.fn("fact", (n: number) => n + 1); // checked against the schema
|
|
70
|
+
// db.fn("fact", (s: string) => s) // compile error: wrong signature
|
|
39
71
|
```
|
|
40
72
|
|
|
41
|
-
|
|
73
|
+
`ground(x)` is the primitive behind auto-grounding, and `patternVars(atom)` returns the free variables of a pattern (what `query` uses to infer row keys).
|
|
42
74
|
|
|
43
|
-
|
|
44
|
-
- The tagged template `m\`...\`` (and `mAll` for several atoms) runs the real parser, so it expresses every MeTTa form, and `${value}` auto-grounds (the easiest way to drop a TS object in).
|
|
75
|
+
## Typed source queries
|
|
45
76
|
|
|
46
|
-
|
|
77
|
+
`db.q("...")` runs `match &self` from a plain MeTTa source string and types the result rows by the pattern's `$`-variables, extracted at compile time. The keys are known and autocompleted, and a key that is not a variable in the source is a compile error.
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
const rows = db.q("(Likes Ada $thing)"); // Array<{ thing: unknown }>
|
|
81
|
+
rows[0]!.thing; // ok, autocompleted
|
|
82
|
+
// rows[0]!.other // compile error: not a variable in the source
|
|
83
|
+
```
|
|
47
84
|
|
|
48
|
-
|
|
85
|
+
This types the variable *structure*, not the result *values* (those come from runtime rewriting, which the type system cannot evaluate), so values are `unknown`. It works on a plain string, not the `m\`\`` tag: TypeScript widens a tagged template's text to `string`, which discards the literal the type-level parser needs. For a builder-form query with the same auto-inferred keys, use `db.query(pattern)`.
|
|
86
|
+
|
|
87
|
+
## JSON and dict-spaces
|
|
88
|
+
|
|
89
|
+
`db.useJson()` enables the JSON module, then the `jsonEncode`/`jsonDecode`/`dictSpace`/`getKeys`/`getValue` builders bridge JSON and MeTTa spaces. `json-decode` turns a JSON object into a dict-space of `(key value)` pairs, so a fetched payload becomes a queryable space.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
const db = mettaDB().useJson();
|
|
93
|
+
db.evalJs(jsonEncode(42)); // ["42"]
|
|
94
|
+
const doc = jsonDecode('{"name": "Ada", "age": 36}'); // a dict-space
|
|
95
|
+
db.evalFirst(getValue(doc, "name")); // "Ada" (JSON keys decode to strings)
|
|
96
|
+
```
|
|
49
97
|
|
|
50
98
|
## License
|
|
51
99
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Atom,
|
|
1
|
+
import { Atom, ExpressionAtom, SymbolAtom, VariableAtom, MeTTa } from '@metta-ts/hyperon';
|
|
2
2
|
export { Atom, GroundedAtom, ValueAtom, atomToJs } from '@metta-ts/hyperon';
|
|
3
3
|
|
|
4
4
|
/** A typed variable. The phantom `T` is the JS type its binding unwraps to in a query result; it is a
|
|
@@ -6,25 +6,43 @@ export { Atom, GroundedAtom, ValueAtom, atomToJs } from '@metta-ts/hyperon';
|
|
|
6
6
|
type Var<T = unknown> = VariableAtom & {
|
|
7
7
|
readonly __varType?: T;
|
|
8
8
|
};
|
|
9
|
-
/**
|
|
10
|
-
|
|
9
|
+
/** Brand marking a functor/symbol builder minted by {@link names}. A branded builder is a callable
|
|
10
|
+
* object (TS call-signature pattern) whose brand carries its head symbol, so {@link ground} can turn a
|
|
11
|
+
* bare, uncalled builder into that symbol. A real `unique symbol` (runtime value and type-level key)
|
|
12
|
+
* cannot collide with user data. */
|
|
13
|
+
declare const HEAD: unique symbol;
|
|
14
|
+
/** A name minted by {@link names}: call it to apply the functor (`parent(a, b)` -> `(parent a b)`), or
|
|
15
|
+
* use it bare as a term, where it grounds to its symbol (`Ada` -> the symbol `Ada`). */
|
|
16
|
+
type Name = ((...args: Term[]) => ExpressionAtom) & {
|
|
17
|
+
readonly [HEAD]: SymbolAtom;
|
|
18
|
+
};
|
|
19
|
+
/** Anything a builder accepts in term position: an atom (incl. a {@link Var}), a {@link Name}, or a JS
|
|
20
|
+
* value to ground. `Name` is a function, hence covered by `object`, but is listed for intent. */
|
|
21
|
+
type Term = Atom | Name | number | string | boolean | bigint | object | null | undefined;
|
|
11
22
|
/** Extract a {@link Var}'s phantom type (defaults to `unknown`). */
|
|
12
23
|
type VarValue<X> = X extends Var<infer T> ? T : unknown;
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
/** `S` builds a symbol two ways: as a function `S("foo")` or as a property `S.foo`. */
|
|
16
|
-
type SymbolBuilder = ((name: string) => SymbolAtom) & {
|
|
17
|
-
readonly [key: string]: SymbolAtom;
|
|
18
|
-
};
|
|
19
|
-
declare const S: SymbolBuilder;
|
|
20
|
-
/** Coerce a {@link Term} to an atom: atoms and variables pass through; every other JS value is grounded. */
|
|
24
|
+
/** Coerce a {@link Term} to an atom: atoms and variables pass through; a bare builder becomes its head
|
|
25
|
+
* symbol; every other JS value is grounded. */
|
|
21
26
|
declare function ground(x: Term): Atom;
|
|
27
|
+
/** A proxy that mints a {@link Name} per property, memoised so `p.parent` is stable within one scope:
|
|
28
|
+
* `const { parent, Ada, Bob } = names()`. Symbols and functors share this one namespace; a name is a
|
|
29
|
+
* symbol when used bare and a functor when applied. Optionally type the known names:
|
|
30
|
+
* `names<{ parent: unknown; Ada: unknown }>()` restricts the keys. */
|
|
31
|
+
type Names<K extends string = string> = Record<K, Name>;
|
|
32
|
+
declare function names<K extends string = string>(): Names<K>;
|
|
33
|
+
/** A proxy that mints a fresh {@link Var} per property, memoised so `q.x` is the same variable
|
|
34
|
+
* everywhere in one scope: `const { x, y } = vars()`. Type the bindings with a record:
|
|
35
|
+
* `const { n, name } = vars<{ n: number; name: string }>()`. */
|
|
36
|
+
type Vars<T extends Record<string, unknown> = Record<string, unknown>> = {
|
|
37
|
+
readonly [K in keyof T]: Var<T[K]>;
|
|
38
|
+
};
|
|
39
|
+
declare function vars<T extends Record<string, unknown> = Record<string, unknown>>(): Vars<T>;
|
|
40
|
+
/** Collect the distinct variables occurring in a pattern, in first-seen order. Backs auto-inferred
|
|
41
|
+
* query rows: the free variables ARE the columns. */
|
|
42
|
+
declare function patternVars(atom: Atom): Var[];
|
|
22
43
|
/** A raw expression (tuple) from its items, each auto-grounded: `e(x, y, x)` builds `($x $y $x)`. Use it
|
|
23
|
-
* for patterns
|
|
44
|
+
* for patterns not headed by a functor, e.g. repeated-variable patterns or pair structures. */
|
|
24
45
|
declare const e: (...items: Term[]) => ExpressionAtom;
|
|
25
|
-
/** A functor builder: `rel("parent")` returns `(a, b) => (parent a b)`, auto-grounding each argument.
|
|
26
|
-
* Builders compose, so nested patterns like `rel("swap")(rel("Pair")(x, y))` are just function calls. */
|
|
27
|
-
declare function rel(name: string): (...args: Term[]) => ExpressionAtom;
|
|
28
46
|
/** The empty expression `()`, MeTTa's conventional empty/nil list. */
|
|
29
47
|
declare const nil: () => ExpressionAtom;
|
|
30
48
|
/** A Lisp-style cons list: `list([a, b, c])` builds `(:: a (:: b (:: c ())))`. Override the constructor
|
|
@@ -41,23 +59,28 @@ declare const decl: (subject: Term, type: Term) => ExpressionAtom;
|
|
|
41
59
|
/** A function type `(-> A B ... R)`. */
|
|
42
60
|
declare const arrow: (...types: Term[]) => ExpressionAtom;
|
|
43
61
|
/** `(if cond then else)`. Only the taken branch is evaluated. */
|
|
44
|
-
declare const
|
|
62
|
+
declare const If: (cond: Term, then: Term, els: Term) => ExpressionAtom;
|
|
45
63
|
/** `(case scrutinee ((pat body) ...))`, sequential mutually-exclusive pattern matching. */
|
|
46
|
-
declare const
|
|
64
|
+
declare const Case: (scrutinee: Term, cases: ReadonlyArray<readonly [Term, Term]>) => ExpressionAtom;
|
|
47
65
|
/** `(let pattern value body)`: unify `value` against `pattern`, then evaluate `body`. */
|
|
48
|
-
declare const
|
|
66
|
+
declare const Let: (pattern: Term, value: Term, body: Term) => ExpressionAtom;
|
|
49
67
|
/** `(let* ((pat val) ...) body)`: sequential lets. */
|
|
50
|
-
declare const
|
|
68
|
+
declare const LetStar: (bindings: ReadonlyArray<readonly [Term, Term]>, body: Term) => ExpressionAtom;
|
|
51
69
|
/** `(match space pattern template)`. Defaults to `&self`, the program's own space. */
|
|
52
|
-
declare const
|
|
70
|
+
declare const Match: (pattern: Term, template: Term, space?: Term) => ExpressionAtom;
|
|
53
71
|
/** `(superpose (a b ...))`: a nondeterministic choice among the items. */
|
|
54
|
-
declare const
|
|
72
|
+
declare const Superpose: (...items: Term[]) => ExpressionAtom;
|
|
55
73
|
/** `(collapse x)`: gather all nondeterministic results of `x` into a single expression. */
|
|
56
|
-
declare const
|
|
74
|
+
declare const Collapse: (x: Term) => ExpressionAtom;
|
|
57
75
|
/** `(empty)`: no results, which prunes a branch. */
|
|
58
|
-
declare const
|
|
76
|
+
declare const Empty: () => ExpressionAtom;
|
|
59
77
|
/** `(unify a b then else)`: low-level unification with then/else continuations. */
|
|
60
|
-
declare const
|
|
78
|
+
declare const Unify: (a: Term, b: Term, then: Term, els: Term) => ExpressionAtom;
|
|
79
|
+
/** `(sealed (vars...) body)`: alpha-rename `body`'s variables (except `vars`) to fresh names, so a
|
|
80
|
+
* template can be reused without variable capture. */
|
|
81
|
+
declare const Sealed: (vars: ReadonlyArray<Term>, body: Term) => ExpressionAtom;
|
|
82
|
+
/** `(quote x)`: hold `x` as data so the interpreter does not evaluate it. */
|
|
83
|
+
declare const Quote: (x: Term) => ExpressionAtom;
|
|
61
84
|
/** Arithmetic grounded operations. */
|
|
62
85
|
declare const add: (a: Term, b: Term) => ExpressionAtom;
|
|
63
86
|
declare const sub: (a: Term, b: Term) => ExpressionAtom;
|
|
@@ -80,15 +103,13 @@ declare const cdrAtom: (x: Term) => ExpressionAtom;
|
|
|
80
103
|
declare const consAtom: (head: Term, tail: Term) => ExpressionAtom;
|
|
81
104
|
/** `(decons-atom expr)`: split a non-empty expression into `(head tail)`. */
|
|
82
105
|
declare const deconsAtom: (x: Term) => ExpressionAtom;
|
|
83
|
-
/** `(quote x)`: hold `x` as data so the interpreter does not evaluate it. */
|
|
84
|
-
declare const quote: (x: Term) => ExpressionAtom;
|
|
85
106
|
/** Type introspection. `getType` reports an atom's declared/inferred type; `getMetatype` reports its
|
|
86
107
|
* meta-type (`Symbol`/`Variable`/`Expression`/`Grounded`). */
|
|
87
108
|
declare const getType: (x: Term) => ExpressionAtom;
|
|
88
109
|
declare const getMetatype: (x: Term) => ExpressionAtom;
|
|
89
|
-
/** Assertions for eDSL tests. Each returns the unit atom `()` on success and an
|
|
90
|
-
*
|
|
91
|
-
*
|
|
110
|
+
/** Assertions for eDSL tests. Each returns the unit atom `()` on success and an `(Error ...)` atom on
|
|
111
|
+
* failure, matching Hyperon's stdlib. `assertEqual` compares evaluated results; `assertAlphaEqual`
|
|
112
|
+
* compares up to a consistent renaming of variables. */
|
|
92
113
|
declare const assertEqual: (a: Term, b: Term) => ExpressionAtom;
|
|
93
114
|
declare const assertAlphaEqual: (a: Term, b: Term) => ExpressionAtom;
|
|
94
115
|
/** Set operations over the (collapsed) results of their arguments, deduplicating modulo equality.
|
|
@@ -99,21 +120,67 @@ declare const intersection: (a: Term, b: Term) => ExpressionAtom;
|
|
|
99
120
|
declare const subtraction: (a: Term, b: Term) => ExpressionAtom;
|
|
100
121
|
/** `(println! x)`: print `x` (a side effect); returns the unit atom `()`. */
|
|
101
122
|
declare const println: (x: Term) => ExpressionAtom;
|
|
102
|
-
/** `(
|
|
103
|
-
*
|
|
104
|
-
declare const
|
|
123
|
+
/** `(json-encode x)`: encode a MeTTa atom (string, number, expression, dict-space, or a mix) to a JSON
|
|
124
|
+
* string. */
|
|
125
|
+
declare const jsonEncode: (x: Term) => ExpressionAtom;
|
|
126
|
+
/** `(json-decode s)`: decode a JSON string to MeTTa (array to expression, object to a dict-space of
|
|
127
|
+
* `(key value)` pairs, string to string, number to number). */
|
|
128
|
+
declare const jsonDecode: (x: Term) => ExpressionAtom;
|
|
129
|
+
/** `(dict-space ((k v) ...))`: build a grounded Space of `(key value)` pairs from key-value tuples. */
|
|
130
|
+
declare const dictSpace: (pairs: ReadonlyArray<readonly [Term, Term]>) => ExpressionAtom;
|
|
131
|
+
/** `(get-keys space)`: every key in a dict-space, one result per key. */
|
|
132
|
+
declare const getKeys: (x: Term) => ExpressionAtom;
|
|
133
|
+
/** `(get-value space key)`: the value tied to `key` in a dict-space, empty if absent. */
|
|
134
|
+
declare const getValue: (a: Term, b: Term) => ExpressionAtom;
|
|
105
135
|
|
|
106
136
|
/** Parse a MeTTa template into the atoms it contains, with `${...}` holes auto-grounded. */
|
|
107
137
|
declare function mAll(strings: TemplateStringsArray, ...values: Term[]): Atom[];
|
|
108
138
|
/** Parse a MeTTa template into one top-level atom. Throws otherwise; use {@link mAll} for several. */
|
|
109
139
|
declare function m(strings: TemplateStringsArray, ...values: Term[]): Atom;
|
|
140
|
+
/** Parse one atom from a plain source string (no interpolation). Throws unless the source is exactly one
|
|
141
|
+
* atom. Backs the typed source query {@link MettaDB.q}. */
|
|
142
|
+
declare function parseSource(src: string): Atom;
|
|
143
|
+
|
|
144
|
+
/** Characters allowed in a MeTTa variable name after the `$`. */
|
|
145
|
+
type IdentChar = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "_" | "-";
|
|
146
|
+
/** The leading identifier of `S` (characters up to the first non-identifier character). */
|
|
147
|
+
type IdentHead<S extends string, Acc extends string = ""> = S extends `${infer C}${infer R}` ? C extends IdentChar ? IdentHead<R, `${Acc}${C}`> : Acc : Acc;
|
|
148
|
+
/** `S` with its leading identifier removed. */
|
|
149
|
+
type AfterIdent<S extends string> = S extends `${infer C}${infer R}` ? C extends IdentChar ? AfterIdent<R> : S : S;
|
|
150
|
+
/** The union of every `$`-prefixed variable name in the source string `S` (a bare `$` yields nothing). */
|
|
151
|
+
type SourceVars<S extends string> = S extends `${string}$${infer Rest}` ? (IdentHead<Rest> extends "" ? never : IdentHead<Rest>) | SourceVars<AfterIdent<Rest>> : never;
|
|
152
|
+
/** A typed query row: each variable in the source mapped to its (runtime-unwrapped) JS value. */
|
|
153
|
+
type SourceRow<S extends string> = {
|
|
154
|
+
[K in SourceVars<S>]: unknown;
|
|
155
|
+
};
|
|
110
156
|
|
|
111
|
-
/** One typed binding row from
|
|
157
|
+
/** One typed binding row from {@link MettaDB.query} with explicit vars: each requested variable mapped
|
|
158
|
+
* to its JS value. */
|
|
112
159
|
type Row<V extends Record<string, Var>> = {
|
|
113
160
|
[K in keyof V]: VarValue<V[K]>;
|
|
114
161
|
};
|
|
115
|
-
/**
|
|
116
|
-
|
|
162
|
+
/** Any function, used as the permissive default for names outside a schema. */
|
|
163
|
+
type AnyFn = (...args: never[]) => unknown;
|
|
164
|
+
/** A schema mapping MeTTa function names to their TypeScript signatures, for a typed runner:
|
|
165
|
+
* `mettaDB<{ fact: (n: number) => number }>()`. Both an `interface` and a `type` work. */
|
|
166
|
+
type FnSchema = Record<string, AnyFn>;
|
|
167
|
+
/** The argument tuple / return type of a schema entry (like `Parameters`/`ReturnType`, but tolerant of
|
|
168
|
+
* a non-function member, which extracts as `never`). */
|
|
169
|
+
type FnArgs<F> = F extends (...a: infer A) => unknown ? A : never;
|
|
170
|
+
type FnRet<F> = F extends (...a: never[]) => infer R ? R : never;
|
|
171
|
+
/** A MeTTa function imported as a typed TypeScript callable (see {@link MettaDB.import}). Returns the
|
|
172
|
+
* first result unwrapped to JS, or `undefined` when the call produces no result. */
|
|
173
|
+
type ImportedFn<Args extends unknown[], Ret> = (...args: Args) => Ret | undefined;
|
|
174
|
+
/** Proxy surface for calling MeTTa functions by name. A name in the schema `S` is typed by its
|
|
175
|
+
* signature (`db.call.fact(5): number[]`); any other name falls back to `unknown[]`. Bracket access
|
|
176
|
+
* handles hyphenated names: `db.call["is-son"]("Bob", "Tom")`. */
|
|
177
|
+
type CallProxy<S> = {
|
|
178
|
+
[K in keyof S]: (...args: FnArgs<S[K]>) => FnRet<S[K]>[];
|
|
179
|
+
} & Record<string, (...args: Term[]) => unknown[]>;
|
|
180
|
+
/** A typed MeTTa runner. Build it with {@link mettaDB}. The optional schema `S` types the host bridge
|
|
181
|
+
* (`call`, `import`, `fn`); the default is an empty schema, so with no schema those stay permissive
|
|
182
|
+
* (`db.call.<any>(...)` is `unknown[]`, `db.import(name)` a permissive callable) but still work. */
|
|
183
|
+
declare class MettaDB<S = Record<never, never>> {
|
|
117
184
|
/** The underlying hyperon runner, for anything the eDSL does not wrap. */
|
|
118
185
|
readonly metta: MeTTa;
|
|
119
186
|
/** Add atoms (facts, rules, type declarations) to the program space. JS values are auto-grounded. */
|
|
@@ -136,16 +203,49 @@ declare class MettaDB {
|
|
|
136
203
|
evalAsync(atom: Term): Promise<Atom[]>;
|
|
137
204
|
/** Like {@link evalJs}, awaiting async grounded operations. */
|
|
138
205
|
evalJsAsync(atom: Term): Promise<unknown[]>;
|
|
139
|
-
/** `match &self pattern` over stored atoms, returning one
|
|
206
|
+
/** `match &self pattern` over stored atoms, returning one binding row per match. With no `vars`, the
|
|
207
|
+
* row keys are inferred from the pattern's free variables and the values come back as plain JS
|
|
208
|
+
* (typed `unknown`); pass an explicit `vars` map to get statically-typed values. */
|
|
209
|
+
query(pattern: Term): Array<Record<string, unknown>>;
|
|
140
210
|
query<V extends Record<string, Var>>(pattern: Term, vars: V): Array<Row<V>>;
|
|
141
|
-
/**
|
|
211
|
+
/** `match &self` from a plain MeTTa source string, with the result rows typed by the pattern's
|
|
212
|
+
* `$`-variables: `db.q("(Likes Ada $thing)")` returns `Array<{ thing: unknown }>`, keys inferred and
|
|
213
|
+
* autocompleted at compile time. Values are `unknown` (they come from runtime rewriting). For the
|
|
214
|
+
* builder form use {@link query}. */
|
|
215
|
+
q<Src extends string>(src: Src): Array<SourceRow<Src>>;
|
|
216
|
+
/** Register a synchronous TypeScript function as a raw grounded operation (atoms in, atoms out). */
|
|
142
217
|
op(name: string, fn: (args: Atom[]) => Atom[]): this;
|
|
143
|
-
/** Register an async TypeScript function (I/O) as a grounded operation; await it via
|
|
218
|
+
/** Register an async TypeScript function (I/O) as a raw grounded operation; await it via
|
|
219
|
+
* {@link evalAsync}. */
|
|
144
220
|
asyncOp(name: string, fn: (args: Atom[]) => Promise<Atom[]>): this;
|
|
221
|
+
/** Shared body of {@link fn}/{@link fns}: unwrap args to JS, call, ground the result. */
|
|
222
|
+
private registerFn;
|
|
223
|
+
/** Register a plain typed function as a grounded operation, with arguments auto-unwrapped to JS and the
|
|
224
|
+
* single result auto-grounded: `db.fn("balance-of", (a: {balance: number}) => a.balance)`. When the
|
|
225
|
+
* name is in the schema `S`, `fn` is checked against its declared signature. Return an array from `fn`
|
|
226
|
+
* to yield it as one grounded list; use {@link op} for multiple (nondeterministic) results or full
|
|
227
|
+
* atom control. */
|
|
228
|
+
fn<K extends string>(name: K, fn: K extends keyof S ? S[K] : AnyFn): this;
|
|
229
|
+
/** Register several typed functions at once, keyed by name: `db.fns({ inc: n => n+1, ... })`. The JS
|
|
230
|
+
* key becomes the MeTTa token. */
|
|
231
|
+
fns(map: Record<string, AnyFn>): this;
|
|
232
|
+
/** Register a plain async typed function as a grounded operation (args unwrapped, result grounded). */
|
|
233
|
+
asyncFn(name: string, fn: (...args: never[]) => Promise<unknown>): this;
|
|
234
|
+
/** Import a MeTTa function as a typed TypeScript callable. Arguments are auto-grounded, the call is
|
|
235
|
+
* `(name ...args)`, and the first result is unwrapped to JS. A name in the schema `S` is typed from
|
|
236
|
+
* its signature (`db.import("fact")`); a name outside the schema returns a permissive callable. */
|
|
237
|
+
import<K extends string>(name: K): K extends keyof S ? ImportedFn<FnArgs<S[K]>, FnRet<S[K]>> : ImportedFn<unknown[], unknown>;
|
|
238
|
+
/** Proxy for calling MeTTa functions by name from TypeScript. `db.call.fib(5)` evaluates `(fib 5)` and
|
|
239
|
+
* returns each result unwrapped to JS; bracket access handles hyphenated names. */
|
|
240
|
+
get call(): CallProxy<S>;
|
|
241
|
+
/** Enable the JSON module on this runner, registering `json-encode`, `json-decode`, `dict-space`,
|
|
242
|
+
* `get-keys`, and `get-value` (see the builders of the same name). Chainable. */
|
|
243
|
+
useJson(): this;
|
|
145
244
|
/** Run raw MeTTa source, one result group per `!`-query. */
|
|
146
245
|
run(src: string): Atom[][];
|
|
147
246
|
}
|
|
148
|
-
/** Create an ergonomic, typed MeTTa runner.
|
|
149
|
-
|
|
247
|
+
/** Create an ergonomic, typed MeTTa runner. Pass a schema to type the host bridge:
|
|
248
|
+
* `mettaDB<{ fact: (n: number) => number }>()`. */
|
|
249
|
+
declare const mettaDB: <S = Record<never, never>>() => MettaDB<S>;
|
|
150
250
|
|
|
151
|
-
export { MettaDB, type Row,
|
|
251
|
+
export { type CallProxy, Case, Collapse, Empty, type FnSchema, If, type ImportedFn, Let, LetStar, Match, MettaDB, type Name, type Names, Quote, type Row, Sealed, type SourceRow, type SourceVars, Superpose, type Term, Unify, type Var, type VarValue, type Vars, add, and, arrow, assertAlphaEqual, assertEqual, carAtom, cdrAtom, consAtom, decl, deconsAtom, dictSpace, div, e, eq, ge, getKeys, getMetatype, getType, getValue, ground, gt, intersection, jsonDecode, jsonEncode, le, list, lt, m, mAll, mettaDB, mod, mul, names, nil, not, or, parseSource, patternVars, println, rule, sub, subtraction, union, unique, vars };
|
package/dist/index.js
CHANGED
|
@@ -4,23 +4,63 @@ import {
|
|
|
4
4
|
S as hS,
|
|
5
5
|
V,
|
|
6
6
|
E,
|
|
7
|
-
ValueAtom
|
|
7
|
+
ValueAtom,
|
|
8
|
+
VariableAtom,
|
|
9
|
+
ExpressionAtom
|
|
8
10
|
} from "@metta-ts/hyperon";
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
});
|
|
11
|
+
var HEAD = /* @__PURE__ */ Symbol("metta.edsl.head");
|
|
12
|
+
function isName(x) {
|
|
13
|
+
return typeof x === "function" && x[HEAD] !== void 0;
|
|
14
|
+
}
|
|
15
15
|
function ground(x) {
|
|
16
16
|
if (x instanceof Atom) return x;
|
|
17
|
+
if (isName(x)) return x[HEAD];
|
|
17
18
|
return ValueAtom(x);
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
-
function rel(name) {
|
|
20
|
+
function makeName(name) {
|
|
21
21
|
const head = hS(name);
|
|
22
|
-
|
|
22
|
+
const fn = (...args) => E(head, ...args.map(ground));
|
|
23
|
+
return Object.assign(fn, { [HEAD]: head, toString: () => name });
|
|
24
|
+
}
|
|
25
|
+
function names() {
|
|
26
|
+
const cache = /* @__PURE__ */ new Map();
|
|
27
|
+
return new Proxy(/* @__PURE__ */ Object.create(null), {
|
|
28
|
+
get(_t, prop) {
|
|
29
|
+
if (typeof prop !== "string") return void 0;
|
|
30
|
+
let n = cache.get(prop);
|
|
31
|
+
if (n === void 0) {
|
|
32
|
+
n = makeName(prop);
|
|
33
|
+
cache.set(prop, n);
|
|
34
|
+
}
|
|
35
|
+
return n;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function vars() {
|
|
40
|
+
const cache = /* @__PURE__ */ new Map();
|
|
41
|
+
return new Proxy(/* @__PURE__ */ Object.create(null), {
|
|
42
|
+
get(_t, prop) {
|
|
43
|
+
if (typeof prop !== "string") return void 0;
|
|
44
|
+
let x = cache.get(prop);
|
|
45
|
+
if (x === void 0) {
|
|
46
|
+
x = V(prop);
|
|
47
|
+
cache.set(prop, x);
|
|
48
|
+
}
|
|
49
|
+
return x;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
23
52
|
}
|
|
53
|
+
function patternVars(atom) {
|
|
54
|
+
const seen = /* @__PURE__ */ new Map();
|
|
55
|
+
const walk = (a) => {
|
|
56
|
+
if (a instanceof VariableAtom) {
|
|
57
|
+
if (!seen.has(a.name())) seen.set(a.name(), a);
|
|
58
|
+
} else if (a instanceof ExpressionAtom) for (const c of a.children()) walk(c);
|
|
59
|
+
};
|
|
60
|
+
walk(atom);
|
|
61
|
+
return [...seen.values()];
|
|
62
|
+
}
|
|
63
|
+
var e = (...items) => E(...items.map(ground));
|
|
24
64
|
var nil = () => E();
|
|
25
65
|
function list(items, opts) {
|
|
26
66
|
const cons = hS(opts?.cons ?? "::");
|
|
@@ -30,20 +70,23 @@ function list(items, opts) {
|
|
|
30
70
|
}
|
|
31
71
|
|
|
32
72
|
// src/forms.ts
|
|
33
|
-
import { E as E2, S
|
|
34
|
-
var rule = (head, body) => E2(
|
|
35
|
-
var decl = (subject, type) => E2(
|
|
36
|
-
var arrow = (...types) => E2(
|
|
37
|
-
var
|
|
38
|
-
var
|
|
39
|
-
var
|
|
40
|
-
var
|
|
41
|
-
var
|
|
42
|
-
var
|
|
43
|
-
var
|
|
44
|
-
var
|
|
45
|
-
var
|
|
46
|
-
var
|
|
73
|
+
import { E as E2, S } from "@metta-ts/hyperon";
|
|
74
|
+
var rule = (head, body) => E2(S("="), ground(head), ground(body));
|
|
75
|
+
var decl = (subject, type) => E2(S(":"), ground(subject), ground(type));
|
|
76
|
+
var arrow = (...types) => E2(S("->"), ...types.map(ground));
|
|
77
|
+
var If = (cond, then, els) => E2(S("if"), ground(cond), ground(then), ground(els));
|
|
78
|
+
var Case = (scrutinee, cases) => E2(S("case"), ground(scrutinee), E2(...cases.map(([pat, body]) => E2(ground(pat), ground(body)))));
|
|
79
|
+
var Let = (pattern, value, body) => E2(S("let"), ground(pattern), ground(value), ground(body));
|
|
80
|
+
var LetStar = (bindings, body) => E2(S("let*"), E2(...bindings.map(([pat, val]) => E2(ground(pat), ground(val)))), ground(body));
|
|
81
|
+
var Match = (pattern, template, space = S("&self")) => E2(S("match"), ground(space), ground(pattern), ground(template));
|
|
82
|
+
var Superpose = (...items) => E2(S("superpose"), E2(...items.map(ground)));
|
|
83
|
+
var Collapse = (x) => E2(S("collapse"), ground(x));
|
|
84
|
+
var Empty = () => E2(S("empty"));
|
|
85
|
+
var Unify = (a, b, then, els) => E2(S("unify"), ground(a), ground(b), ground(then), ground(els));
|
|
86
|
+
var Sealed = (vars2, body) => E2(S("sealed"), E2(...vars2.map(ground)), ground(body));
|
|
87
|
+
var Quote = (x) => E2(S("quote"), ground(x));
|
|
88
|
+
var op2 = (name) => (a, b) => E2(S(name), ground(a), ground(b));
|
|
89
|
+
var op1 = (name) => (x) => E2(S(name), ground(x));
|
|
47
90
|
var add = op2("+");
|
|
48
91
|
var sub = op2("-");
|
|
49
92
|
var mul = op2("*");
|
|
@@ -54,15 +97,13 @@ var gt = op2(">");
|
|
|
54
97
|
var lt = op2("<");
|
|
55
98
|
var ge = op2(">=");
|
|
56
99
|
var le = op2("<=");
|
|
57
|
-
var op1 = (name) => (x) => E2(S2(name), ground(x));
|
|
58
100
|
var and = op2("and");
|
|
59
101
|
var or = op2("or");
|
|
60
102
|
var not = op1("not");
|
|
61
103
|
var carAtom = op1("car-atom");
|
|
62
104
|
var cdrAtom = op1("cdr-atom");
|
|
63
|
-
var consAtom = (head, tail) => E2(
|
|
105
|
+
var consAtom = (head, tail) => E2(S("cons-atom"), ground(head), ground(tail));
|
|
64
106
|
var deconsAtom = op1("decons-atom");
|
|
65
|
-
var quote = op1("quote");
|
|
66
107
|
var getType = op1("get-type");
|
|
67
108
|
var getMetatype = op1("get-metatype");
|
|
68
109
|
var assertEqual = op2("assertEqual");
|
|
@@ -72,13 +113,17 @@ var union = op2("union");
|
|
|
72
113
|
var intersection = op2("intersection");
|
|
73
114
|
var subtraction = op2("subtraction");
|
|
74
115
|
var println = op1("println!");
|
|
75
|
-
var
|
|
116
|
+
var jsonEncode = op1("json-encode");
|
|
117
|
+
var jsonDecode = op1("json-decode");
|
|
118
|
+
var dictSpace = (pairs) => E2(S("dict-space"), E2(...pairs.map(([k, v]) => E2(ground(k), ground(v)))));
|
|
119
|
+
var getKeys = op1("get-keys");
|
|
120
|
+
var getValue = op2("get-value");
|
|
76
121
|
|
|
77
122
|
// src/template.ts
|
|
78
123
|
import {
|
|
79
124
|
SExprParser,
|
|
80
|
-
SymbolAtom,
|
|
81
|
-
ExpressionAtom,
|
|
125
|
+
SymbolAtom as SymbolAtom2,
|
|
126
|
+
ExpressionAtom as ExpressionAtom2,
|
|
82
127
|
E as E3,
|
|
83
128
|
standardTokenizer
|
|
84
129
|
} from "@metta-ts/hyperon";
|
|
@@ -87,11 +132,11 @@ var SLOT_RE = /^__metta_ts_slot_(\d+)__$/;
|
|
|
87
132
|
var sharedTokenizer;
|
|
88
133
|
var tokenizer = () => sharedTokenizer ??= standardTokenizer();
|
|
89
134
|
function substituteSlots(atom, slots) {
|
|
90
|
-
if (atom instanceof
|
|
135
|
+
if (atom instanceof SymbolAtom2) {
|
|
91
136
|
const match = SLOT_RE.exec(atom.name());
|
|
92
137
|
return match ? slots[Number(match[1])] : atom;
|
|
93
138
|
}
|
|
94
|
-
if (atom instanceof
|
|
139
|
+
if (atom instanceof ExpressionAtom2)
|
|
95
140
|
return E3(...atom.children().map((c) => substituteSlots(c, slots)));
|
|
96
141
|
return atom;
|
|
97
142
|
}
|
|
@@ -109,9 +154,21 @@ function m(strings, ...values) {
|
|
|
109
154
|
);
|
|
110
155
|
return atoms[0];
|
|
111
156
|
}
|
|
157
|
+
function parseSource(src) {
|
|
158
|
+
const atoms = new SExprParser(src).parseAll(tokenizer());
|
|
159
|
+
if (atoms.length !== 1)
|
|
160
|
+
throw new Error(`parseSource: expected exactly one atom, got ${atoms.length}: ${src}`);
|
|
161
|
+
return atoms[0];
|
|
162
|
+
}
|
|
112
163
|
|
|
113
164
|
// src/db.ts
|
|
114
|
-
import {
|
|
165
|
+
import {
|
|
166
|
+
MeTTa,
|
|
167
|
+
E as E4,
|
|
168
|
+
S as S2,
|
|
169
|
+
atomToJs,
|
|
170
|
+
registerJsonModule
|
|
171
|
+
} from "@metta-ts/hyperon";
|
|
115
172
|
var MettaDB = class {
|
|
116
173
|
/** The underlying hyperon runner, for anything the eDSL does not wrap. */
|
|
117
174
|
metta = new MeTTa();
|
|
@@ -158,41 +215,110 @@ var MettaDB = class {
|
|
|
158
215
|
async evalJsAsync(atom) {
|
|
159
216
|
return (await this.evalAsync(atom)).map(atomToJs);
|
|
160
217
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const set = this.metta.space().query(
|
|
218
|
+
query(pattern, vars2) {
|
|
219
|
+
const pat = ground(pattern);
|
|
220
|
+
const set = this.metta.space().query(pat);
|
|
221
|
+
const cols = vars2 ?? Object.fromEntries(patternVars(pat).map((v) => [v.name(), v]));
|
|
164
222
|
return set.frames.map((frame) => {
|
|
165
223
|
const row = {};
|
|
166
|
-
for (const key in
|
|
167
|
-
const bound = frame.resolve(
|
|
224
|
+
for (const key in cols) {
|
|
225
|
+
const bound = frame.resolve(cols[key]);
|
|
168
226
|
row[key] = bound === void 0 ? void 0 : atomToJs(bound);
|
|
169
227
|
}
|
|
170
228
|
return row;
|
|
171
229
|
});
|
|
172
230
|
}
|
|
173
|
-
/**
|
|
231
|
+
/** `match &self` from a plain MeTTa source string, with the result rows typed by the pattern's
|
|
232
|
+
* `$`-variables: `db.q("(Likes Ada $thing)")` returns `Array<{ thing: unknown }>`, keys inferred and
|
|
233
|
+
* autocompleted at compile time. Values are `unknown` (they come from runtime rewriting). For the
|
|
234
|
+
* builder form use {@link query}. */
|
|
235
|
+
q(src) {
|
|
236
|
+
return this.query(parseSource(src));
|
|
237
|
+
}
|
|
238
|
+
/** Register a synchronous TypeScript function as a raw grounded operation (atoms in, atoms out). */
|
|
174
239
|
op(name, fn) {
|
|
175
240
|
this.metta.registerOperation(name, fn);
|
|
176
241
|
return this;
|
|
177
242
|
}
|
|
178
|
-
/** Register an async TypeScript function (I/O) as a grounded operation; await it via
|
|
243
|
+
/** Register an async TypeScript function (I/O) as a raw grounded operation; await it via
|
|
244
|
+
* {@link evalAsync}. */
|
|
179
245
|
asyncOp(name, fn) {
|
|
180
246
|
this.metta.registerAsyncOperation(name, fn);
|
|
181
247
|
return this;
|
|
182
248
|
}
|
|
249
|
+
/** Shared body of {@link fn}/{@link fns}: unwrap args to JS, call, ground the result. */
|
|
250
|
+
registerFn(name, fn) {
|
|
251
|
+
return this.op(name, (args) => [ground(fn(...args.map(atomToJs)))]);
|
|
252
|
+
}
|
|
253
|
+
/** Register a plain typed function as a grounded operation, with arguments auto-unwrapped to JS and the
|
|
254
|
+
* single result auto-grounded: `db.fn("balance-of", (a: {balance: number}) => a.balance)`. When the
|
|
255
|
+
* name is in the schema `S`, `fn` is checked against its declared signature. Return an array from `fn`
|
|
256
|
+
* to yield it as one grounded list; use {@link op} for multiple (nondeterministic) results or full
|
|
257
|
+
* atom control. */
|
|
258
|
+
fn(name, fn) {
|
|
259
|
+
return this.registerFn(name, fn);
|
|
260
|
+
}
|
|
261
|
+
/** Register several typed functions at once, keyed by name: `db.fns({ inc: n => n+1, ... })`. The JS
|
|
262
|
+
* key becomes the MeTTa token. */
|
|
263
|
+
fns(map) {
|
|
264
|
+
for (const [name, fn] of Object.entries(map)) this.registerFn(name, fn);
|
|
265
|
+
return this;
|
|
266
|
+
}
|
|
267
|
+
/** Register a plain async typed function as a grounded operation (args unwrapped, result grounded). */
|
|
268
|
+
asyncFn(name, fn) {
|
|
269
|
+
return this.asyncOp(name, async (args) => [
|
|
270
|
+
ground(await fn(...args.map(atomToJs)))
|
|
271
|
+
]);
|
|
272
|
+
}
|
|
273
|
+
/** Import a MeTTa function as a typed TypeScript callable. Arguments are auto-grounded, the call is
|
|
274
|
+
* `(name ...args)`, and the first result is unwrapped to JS. A name in the schema `S` is typed from
|
|
275
|
+
* its signature (`db.import("fact")`); a name outside the schema returns a permissive callable. */
|
|
276
|
+
import(name) {
|
|
277
|
+
const fn = (...args) => {
|
|
278
|
+
const results = this.evalJs(callExpr(name, args));
|
|
279
|
+
return results.length === 0 ? void 0 : results[0];
|
|
280
|
+
};
|
|
281
|
+
return fn;
|
|
282
|
+
}
|
|
283
|
+
/** Proxy for calling MeTTa functions by name from TypeScript. `db.call.fib(5)` evaluates `(fib 5)` and
|
|
284
|
+
* returns each result unwrapped to JS; bracket access handles hyphenated names. */
|
|
285
|
+
get call() {
|
|
286
|
+
return new Proxy(/* @__PURE__ */ Object.create(null), {
|
|
287
|
+
get: (_t, prop) => typeof prop === "string" ? (...args) => this.evalJs(callExpr(prop, args)) : void 0
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
/** Enable the JSON module on this runner, registering `json-encode`, `json-decode`, `dict-space`,
|
|
291
|
+
* `get-keys`, and `get-value` (see the builders of the same name). Chainable. */
|
|
292
|
+
useJson() {
|
|
293
|
+
registerJsonModule(this.metta);
|
|
294
|
+
return this;
|
|
295
|
+
}
|
|
183
296
|
/** Run raw MeTTa source, one result group per `!`-query. */
|
|
184
297
|
run(src) {
|
|
185
298
|
return this.metta.run(src);
|
|
186
299
|
}
|
|
187
300
|
};
|
|
301
|
+
function callExpr(name, args) {
|
|
302
|
+
return E4(S2(name), ...args.map(ground));
|
|
303
|
+
}
|
|
188
304
|
var mettaDB = () => new MettaDB();
|
|
189
305
|
|
|
190
306
|
// src/index.ts
|
|
191
307
|
import { Atom as Atom3, ValueAtom as ValueAtom2, atomToJs as atomToJs2 } from "@metta-ts/hyperon";
|
|
192
308
|
export {
|
|
193
309
|
Atom3 as Atom,
|
|
310
|
+
Case,
|
|
311
|
+
Collapse,
|
|
312
|
+
Empty,
|
|
313
|
+
If,
|
|
314
|
+
Let,
|
|
315
|
+
LetStar,
|
|
316
|
+
Match,
|
|
194
317
|
MettaDB,
|
|
195
|
-
|
|
318
|
+
Quote,
|
|
319
|
+
Sealed,
|
|
320
|
+
Superpose,
|
|
321
|
+
Unify,
|
|
196
322
|
ValueAtom2 as ValueAtom,
|
|
197
323
|
add,
|
|
198
324
|
and,
|
|
@@ -201,47 +327,43 @@ export {
|
|
|
201
327
|
assertEqual,
|
|
202
328
|
atomToJs2 as atomToJs,
|
|
203
329
|
carAtom,
|
|
204
|
-
caseOf,
|
|
205
330
|
cdrAtom,
|
|
206
|
-
collapse,
|
|
207
331
|
consAtom,
|
|
208
332
|
decl,
|
|
209
333
|
deconsAtom,
|
|
334
|
+
dictSpace,
|
|
210
335
|
div,
|
|
211
336
|
e,
|
|
212
|
-
empty,
|
|
213
337
|
eq,
|
|
214
338
|
ge,
|
|
339
|
+
getKeys,
|
|
215
340
|
getMetatype,
|
|
216
341
|
getType,
|
|
342
|
+
getValue,
|
|
217
343
|
ground,
|
|
218
344
|
gt,
|
|
219
|
-
iff,
|
|
220
345
|
intersection,
|
|
346
|
+
jsonDecode,
|
|
347
|
+
jsonEncode,
|
|
221
348
|
le,
|
|
222
|
-
letStar,
|
|
223
|
-
lett,
|
|
224
349
|
list,
|
|
225
350
|
lt,
|
|
226
351
|
m,
|
|
227
352
|
mAll,
|
|
228
|
-
matchSelf,
|
|
229
353
|
mettaDB,
|
|
230
354
|
mod,
|
|
231
355
|
mul,
|
|
356
|
+
names,
|
|
232
357
|
nil,
|
|
233
358
|
not,
|
|
234
359
|
or,
|
|
360
|
+
parseSource,
|
|
361
|
+
patternVars,
|
|
235
362
|
println,
|
|
236
|
-
quote,
|
|
237
|
-
rel,
|
|
238
363
|
rule,
|
|
239
|
-
sealed,
|
|
240
364
|
sub,
|
|
241
365
|
subtraction,
|
|
242
|
-
superpose,
|
|
243
|
-
unify,
|
|
244
366
|
union,
|
|
245
367
|
unique,
|
|
246
|
-
|
|
368
|
+
vars
|
|
247
369
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metta-ts/edsl",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"author": "MesTTo",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Ergonomic, typed TypeScript eDSL for MeTTa: typed term builders, rewrite rules, a tagged-template surface, and auto-grounding of TypeScript values.",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"sideEffects": false,
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@metta-ts/hyperon": "1.0.
|
|
34
|
+
"@metta-ts/hyperon": "1.0.5"
|
|
35
35
|
},
|
|
36
36
|
"repository": {
|
|
37
37
|
"type": "git",
|