Metadata-Version: 2.4
Name: PyMeTTa
Version: 0.9.0
Summary: MeTTa in Python, on a SWI-Prolog engine
License-Expression: MIT
Project-URL: Homepage, https://github.com/MesTTo/MeTTa
Project-URL: Repository, https://github.com/MesTTo/MeTTa
Project-URL: Issues, https://github.com/MesTTo/MeTTa/issues
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Prolog
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Science/Research
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: annotated-types>=0.7
Requires-Dist: docstring-parser>=0.17
Provides-Extra: engine
Requires-Dist: janus-swi>=1.5.2; extra == "engine"
Provides-Extra: arrays
Requires-Dist: metta-arrays; extra == "arrays"
Requires-Dist: metta-faiss; extra == "arrays"
Requires-Dist: metta-numpy; extra == "arrays"
Provides-Extra: arrow
Requires-Dist: metta-nanoarrow; extra == "arrow"
Requires-Dist: metta-pyarrow; extra == "arrow"
Provides-Extra: das
Requires-Dist: metta-websocket; extra == "das"
Provides-Extra: otel
Requires-Dist: metta-otel; extra == "otel"
Provides-Extra: graphql
Requires-Dist: metta-graphql; extra == "graphql"
Provides-Extra: dataframes
Requires-Dist: metta-tables; extra == "dataframes"
Requires-Dist: metta-pandas; extra == "dataframes"
Requires-Dist: metta-polars; extra == "dataframes"
Provides-Extra: sql
Requires-Dist: metta-tables; extra == "sql"
Requires-Dist: metta-duckdb; extra == "sql"
Requires-Dist: metta-sqlite; extra == "sql"
Provides-Extra: models
Requires-Dist: metta-pydantic; extra == "models"
Provides-Extra: live
Requires-Dist: metta-live; extra == "live"
Provides-Extra: remote
Requires-Dist: metta-remote; extra == "remote"
Provides-Extra: test
Requires-Dist: pymetta[arrays,arrow,das,dataframes,graphql,live,models,otel,remote,sql]; extra == "test"
Requires-Dist: metta-benchmarking; extra == "test"
Requires-Dist: metta-otel[test]; extra == "test"
Requires-Dist: hypothesis>=6.165; extra == "test"
Requires-Dist: griffelib<3,>=2.3; extra == "test"
Requires-Dist: networkx<4,>=3.6; extra == "test"
Requires-Dist: openapi-spec-validator>=0.9; extra == "test"
Requires-Dist: pytest>=8.4.2; extra == "test"
Requires-Dist: pytest-benchmark>=5.2; extra == "test"
Requires-Dist: pytest-randomly>=5; extra == "test"
Requires-Dist: pytest-timeout>=2.4; extra == "test"
Requires-Dist: pytest-xdist<4,>=3.8; extra == "test"
Provides-Extra: checks
Requires-Dist: pymetta[test]; extra == "checks"
Requires-Dist: bandit>=1.9; extra == "checks"
Requires-Dist: codespell>=2.4; extra == "checks"
Requires-Dist: coverage[toml]>=7.15; extra == "checks"
Requires-Dist: deptry>=0.25; extra == "checks"
Requires-Dist: import-linter>=2.13; extra == "checks"
Requires-Dist: interrogate>=1.7; extra == "checks"
Requires-Dist: mypy>=1.18; extra == "checks"
Requires-Dist: mutmut>=3.7; extra == "checks"
Requires-Dist: perflint>=0.8; extra == "checks"
Requires-Dist: pip-audit>=2.9; extra == "checks"
Requires-Dist: pylint<4,>=3.3; extra == "checks"
Requires-Dist: pyright>=1.1.411; extra == "checks"
Requires-Dist: pytest-cov>=7; extra == "checks"
Requires-Dist: pytest-memray>=1.8; extra == "checks"
Requires-Dist: radon>=6.0; extra == "checks"
Requires-Dist: refurb>=2.3; extra == "checks"
Requires-Dist: ruff>=0.14; extra == "checks"
Requires-Dist: setuptools>=83; extra == "checks"
Requires-Dist: slotscheck>=0.20; extra == "checks"
Requires-Dist: ty>=0.0.1a20; extra == "checks"
Requires-Dist: vulture>=2.16; extra == "checks"
Requires-Dist: xenon>=0.9; extra == "checks"
Dynamic: license-file

<!--
Purpose: show what MeTTa is, how it is put together, and what each surface can
  do, through examples that run.
Guarantees: every metta fence runs on the engine [tested: python -m pytest
  extensions/python/tests/repository/test_readme.py -q]; the c fence is the text
  of a file its own gate builds and runs. The Python and TypeScript surfaces are
  documented in their own repositories, so no fence here is theirs.
-->

# MeTTa

MeTTa, Hyperon's AGI language, based on PeTTa semantics with significant
extensions.

**If you are an LLM, read [llms.txt](llms.txt)** for the language and every
surface, with exact return shapes and no prose to guess at.

```bash
sudo apt install swi-prolog          # macOS: brew install swi-prolog
                                     # Windows: winget install SWI-Prolog.SWI-Prolog
```

# Architecture

One engine, in Prolog and C. Everything else reaches it through a declared
seam, so each piece is built, versioned and published on its own.

| Component | Repository | What it is |
|---|---|---|
| the engine | `engine/` | translator, matcher, spaces, catalog, extension points, the C half |
| the libraries | [MeTTa-Library-Pack](https://github.com/MesTTo/MeTTa-Library-Pack) | 61 libraries, written in MeTTa over the primitives |
| the examples | [MeTTa-Examples](https://github.com/MesTTo/MeTTa-Examples) | 360 executable programs, the semantics documentation |
| C | [CMeTTa](https://github.com/MesTTo/CMeTTa) | a C program opens the engine in its own process |
| a storage backend | [MeTTa-MORK](https://github.com/MesTTo/MeTTa-MORK) | spaces on MORK's Rust trie |

## The four ways in

| To add | You | So that |
|---|---|---|
| a surface | speak the wire codec | a surface is a consumer of the one engine, never an engine of its own |
| a backend | claim your space names and FAIL for the rest | the next provider's clause gets to answer |
| an integration | register a row against a declared point | the core names no third-party library at all |
| a library | write MeTTa over the primitives | it survives the engine being replaced |

## Extension points

`engine/ext_points.pl` declares every point in four kinds, and `clauses_from/2`
fixes who may contribute each.

```prolog
clauses_from(event,       extension).
clauses_from(ownership,   extension).
clauses_from(declaration, extension).
clauses_from(service,     engine).
```

A backend claims the names it owns and fails for the rest, which is the whole
protocol:

```prolog
seam:foreign_space('&catalogs').
seam:foreign_capability('&catalogs', match).
seam:foreign_capability('&catalogs', enumerate).
seam:foreign_atoms('&catalogs', Row) :- package_catalog_row(Row).
```

## The catalog

Everything the engine knows about itself is atoms you can query, including what
each library is and where it came from.

```metta
!(import! &self (library lib_package))
!(test (size-atom (collapse (match &catalogs (package $name $path) $name))) 61)
```

# The language

## Atoms

Four kinds, and that is the whole representation.

```metta
!(test (get-metatype Tom) Symbol)                   ; a name that denotes itself
!(test (get-metatype $x) Variable)                  ; stands for anything
!(test (get-metatype 42) Grounded)                  ; a number, a string, a host object
!(test (get-metatype (Parent Tom Bob)) Expression)  ; atoms in order
```

Terms read and print as themselves.

```metta
!(test (repr 42) "42")
!(test (repr "42") "\"42\"")
!(test (repr (A (B C))) "(A (B C))")
!(test (repr (A (, B , C ,))) "(A (, B , C ,))")
!(test (repr 2025_12_12) "2025_12_12")
!(test (repr ()) "()")
```

## Spaces and matching

A space is where a program lives, and `match` reads it.

```metta
(= (matchtrickery)
   (let* (($t1 (add-atom &self (foo a)))
          ($t2 (add-atom &self (foo b))))
         (match &self (foo $1) (bar $1))))

!(test (collapse (matchtrickery))
       ((bar a) (bar b)))
```

A pattern's head can be a constant, so the head is just another position.

```metta
(= (h (justdata haha $B) $C)
   (+ $B $C))

!(test (h (justdata haha 30) 40) 70)
```

## Equations

An equation is an atom, so partial application and composition fall out of the
same rule.

```metta
(= (mp) (+))

!(test (mp 1 1) 2)

(= (.. $f1 $f2 $arg) ($f1 ($f2 $arg)))

(= (plus1times2) (.. (* 2) (+ 1)))

!(test (plus1times2 1) 4)
```

## Many answers

Nondeterminism is the default, and `empty` is the answer with no answers.

```metta
(= (y) (empty))

!(test (collapse (y))
       ())
```

`once` commits to the first.

```metta
(foo 1)
(foo 2)

(= (match-single $space $pat $ret)
   (once (match $space $pat $ret)))

!(let $x (match-single &self (foo $1) $1) (add-atom &self (bar $x)))

!(test (collapse (match &self (bar $1) (bar $1)))
       ((bar 1)))
```

## Control flow

`if` takes a boolean and two branches.

```metta
!(test (if True 42) 42)
```

`case` dispatches on shape.

```metta
(= (casetest $x)
   (case $x ((4 42)
             ($otherpattern 44)
             ($otherother $45))))

!(test (casetest 5) 44)
```

`chain` sequences.

```metta
!(test (chain (+ 2 4) $n (* 3 $n))
       18)

!(test (chain (+ 1 3) $n (chain (* 2 $n) $m (+ $n $m)))
       12)
```

A cut commits to what has been found.

```metta
(foo 1)
(foo 2)

(= (match-single $space $pat $ret)
   (let* (($x (match $space $pat $ret))
          ($temp (cut)))
         $x))

!(let $x (match-single &self (foo $1) $1) (add-atom &self (bar $x)))

!(test (collapse (match &self (bar $1) (bar $1)))
       ((bar 1)))
```

Recursion under an explicit branch budget.

```metta
(= (fib $N)
   (if (< $N 2)
       $N
       (+ (fib (- $N 1))
          (fib (- $N 2)))))

!(test (with-pragma! ((max-stack-depth 100000000)) (fib 30)) 832040)
```

## Data

Multiset operations over atoms.

```metta
!(test (unique-atom (a b c d d)) (a b c d))
!(test (union-atom (a b b c) (b c c d)) (a b b c b c c d))
!(test (intersection-atom (a b c c) (b c c c d)) (b c c))
!(test (subtraction-atom (a b b c) (b c c d)) (a b))
!(test (intersection-atom (a b c c) (b c d)) (b c))
!(test (intersection-atom (a a a) (a)) (a))
!(test (subtraction-atom (a a a) (a)) (a a))
!(test (intersection-atom (a b) ()) ())
```

## Sequence variables

A pattern child that stands for a run of atoms. Upstream PeTTa has no such
pattern, so this is the one part of the language below that a stock kernel will
not parse, and the sixteen libraries listed under [the library pack](#the-library-pack)
are written with it.

```metta
!(test (collapse (let ((:seg $pre) SEP (:seg $post)) (a b SEP c SEP d)
                      (pair $pre $post)))
       ((pair (a b) (c SEP d)) (pair (a b SEP c) (d))))

!(test (let (row (:seg $r)) (row) $r) ())
!(test (let (row (:seg $r)) (row a b c) $r) (a b c))

!(test (get-metatype (let (row (:seg $r)) (row a b) $r)) Expression)
!(test (size-atom (let (row (:seg $r)) (row a b) $r)) 2)
!(test (car-atom (let (row (:seg $r)) (row a b) $r)) a)

!(test (let (f (:seg $x) g (:seg $x)) (f a b g a b) $x) (a b))
!(test (collapse (let (f (:seg $x) g (:seg $x)) (f a b g c) $x)) ())
!(test (let (f (:seg $x) g (:seg $x)) (f 1 g 1.0) took) took)

!(test (collapse (let (f ... g ...) (f a g b c) done)) (done))

!(test (let (f (g ...) b) (f (g 1 2) b) nested) nested)
!(test (collapse (let (A ... D) (A b c E) never)) ())

!(add-atom &self (edge a b))
!(add-atom &self (edge b c d))
!(add-atom &self (tag b hot))
!(test (collapse (match &self (edge a ... $last) $last)) (b))
!(test (collapse (match &self (, (edge ... $mid) (tag $mid $heat)) ($mid $heat)))
       ((b hot)))
```

## Numbers

```metta
!(test (exp-math 0) 1.0)
!(test (exp-math 1.0) 2.718281828459045)
!(test (< (abs-math (- (exp-math 2.0) (* 2.718281828459045 2.718281828459045))) 1.0e-12) true)
!(test (< (abs-math (- (log-math 2.718281828459045 (exp-math 3.0)) 3.0)) 1.0e-12) true)

(= (in-range $lo $hi $x) (and (<= $lo $x) (<= $x $hi)))
!(test (in-range 1 6 (random-int 1 6)) true)
!(test (in-range 0.0 1.0 (random-float 0.0 1.0)) true)
!(test (in-range 5 5 (random-int 5 5)) true)
```

## Python as a notation

```metta
!(test (repr (py-call (str true))) "True")
!(test (repr (py-call (str false))) "False")
!(test (py-call (sorted (true false))) (false true))
!(test (py-call (len (true false true))) 3)
!(test (py-call (isinstance true (py-call (type false)))) true)
!(test (py-call (bool 1)) true)
!(test (py-call (bool 0)) false)
!(test (py-call (.bit_length true)) 1)
!(test (repr (py-call (.upper abc))) "ABC")
```

## Types

Optional, and parametric.

```metta
(: apply (-> (-> $tx $ty) $tx $ty))
(= (apply $f $x) ($f $x))
!(apply not False) ; True
!(get-type (apply not False))
!(test (let (get-type apply) (-> (-> Bool Bool) Bool $result) $result)
       Bool)
```

## Errors and refusals

A refusal names what went wrong rather than failing silently.

```metta
!(test (throw (my-ball 1)) (Error (throw (my-ball 1)) (my-ball 1)))
!(test (throw "text") (Error (throw "text") "text"))

!(test (if-error (throw oops) caught fine) caught)
!(test (if-error 42 caught fine) fine)
!(test (return-on-error (throw oops) carried-on) (Error (throw oops) oops))
!(test (return-on-error 42 carried-on) carried-on)

!(test (throw (Error (inner 1) because)) (Error (inner 1) because))
!(test (throw (throw first)) (Error (throw first) first))

(= (half $n) (if (== (% $n 2) 0) (/ $n 2) (throw (odd $n))))
!(test (half 10) 5)
!(test (half 7) (Error (throw (odd 7)) (odd 7)))
!(test (if-error (half 7) refused (half 7)) refused)

!(test (trace! "the answer" 42) 42)
!(test (+ 1 (trace! "adding one to" 41)) 42)
!(test (trace! (half 10) (half 10)) 5)

!(test (trace! (checking (odd 7)) ok) ok)
```

## Testing

Every example checks itself, using the same forms you would.

```metta
!(import! &self (library lib_he))

(= (add 1 2) 3)

!(test (id 5) 5)

!(test (=alpha (Father $X) (Father $Y)) True)

!(test (=alpha (Father $X) (Son $X)) False)

!(test (if-equal 1 1 "Equal" "Not Equal") "Equal")
```

## Seeing your program

```metta
!(import! &self (library lib_string))

!(test (> (current-time) 1700000000.0) True)

!(test (<= (current-time) (current-time)) True)

!(test (format-time "abc") abc)
!(test (== (format-time "abc") "abc") False)
!(test (string-length (format-time "a literal")) 9)
!(test (string-length (format-time "")) 0)
!(test (string-length (format-time "%%")) 1)

!(test (string-length (format-time "%Y")) 4)
!(test (string-length (format-time "%Y-%m-%d")) 10)
!(test (string-length (format-time "%H:%M:%S")) 8)

!(test (collapse (argv 999)) ())
!(test (collapse (argv -1)) ())

!(test (== (argv 0) (argv 0)) True)

(= (argument-or $index $default)
   (let $found (collapse (argv $index))
        (if (== $found ()) $default (car-atom $found))))
!(test (argument-or 999 no-such-argument) no-such-argument)
!(test (== (argument-or 0 no-such-argument) no-such-argument) False)
```

## Events and standing queries

```metta
!(test (match &metta (vocabulary delivery $a $b $c) ($a $b $c))
       (at-most-once at-least-once per-write-exactly))
!(test (match &metta (vocabulary event-order $a $b) ($a $b))
       (ordered unordered))
!(test (match &metta (kind events $ctx $delivery $order) $delivery)
       (one-of delivery))

!(test (if-error (catch (add-atom &metta (events &feed eventually)))
                 refused admitted)
       refused)

!(add-atom &native-events (reading 1))
!(test (collapse (match &metta (events &native-events $d $o) declared)) ())

!(test (match &metta (vocabulary agenda-policy $a $b $c $d $e) ($a $b $c $d $e))
       (declaration recency specificity priority user))
!(test (match &metta (policy reaction-order $knob $default) ($knob $default))
       (agenda declaration))
!(test (match &metta (kind agenda $ctx $policy $fn) $policy)
       (one-of agenda-policy))

!(test (match &metta (kind on $ctx $pattern $op $priority) $priority)
       (optional integer))
```

## Concurrency

```metta
!(add-atom &Point (: Point (-> Number Number Point)))
!(add-atom &Point (= (Point-x (Point $x $y)) $x))
!(add-atom &Point (= (Point-y (Point $x $y)) $y))

!(add-atom &Point
  (= (Point-norm (Point $x $y)) (sqrt-math (+ (* $x $x) (* $y $y)))))

!(add-atom &Point
  (= (Point-add (Point $x1 $y1) (Point $x2 $y2)) (Point (+ $x1 $x2) (+ $y1 $y2))))

!(add-atom &Point
  (= (Point-quadrant $p)
     (case $p (((Point 0 0) origin) ((Point 0 $y) axis) ((Point $x $y) plane)))))

!(add-atom &self (from &Point))

!(test (Point-norm (Point 3 4)) 5.0)
!(test (Point-add (Point 1 2) (Point 3 4)) (Point 4 6))
!(test (Point-quadrant (Point 0 0)) origin)
!(test (Point-quadrant (Point 0 4)) axis)
!(test (Point-quadrant (Point 3 4)) plane)
!(test (== (Point-add (Point 1 2) (Point 3 4)) (Point 4 6)) True)
```

## Worlds and state

```metta
!(bind! state (new-state rest))
!(test (get-state state) rest)

!(test (change-state! state active) true)
!(test (get-state state) active)

!(test (get-type (new-state 5)) (StateMonad Number))
!(test (get-type (new-state "hi")) (StateMonad String))

!(test (let $cell (new-state 1)
            (let $_ (change-state! $cell 2) (get-state $cell)))
       2)
```

## Performance

Memoisation is a library, not a keyword.

```metta
!(import! &self (library lib_memo))

!(memoize sq)
(= (sq $x) (* $x $x))

!(test (sq 9) 81)
!(test (sq 9) 81)
!(test (sq 9) 81)
```

## Spaces backed by anything

A space of your own, inheriting what it does not answer.

```metta
!(add-atom &family-parent (edge a b))
!(add-atom &family-parent (parent-only kept))
!(add-atom &family-parent (layer parent))
!(new-space &family-child (inherits &family-parent))
!(add-atom &family-child (edge b c))
!(add-atom &family-child (child-only local))
!(add-atom &family-child (layer child))

!(test (collapse (match &family-child
                         (, (edge $x $y) (edge $y $z))
                         ($x $z)))
       ((a c)))

!(test (collapse (match &family-child (layer $x) $x)) (child parent))
!(test (space-atom-count &family-child) 3)

!(test (collapse (match &family-parent (parent-only $x) $x)) (kept))
!(test (collapse (match &family-child (parent-only $x) $x)) (kept))
!(test (collapse (match &family-parent (child-only $x) $x)) ())
```

Rows in a CSV file, queried as atoms.

```metta
!(import! &self (library lib_csv))
!(import! &self (library lib_file))

!(bind! &csv-path (temp-path! "metta-csv-example"))
!(write-file! &csv-path "id,amount\n001,12.50\n002,9\n002,9\n")
!(bind! &sales (csv-space &csv-path))

!(test (collapse (match &sales (row $id $amount) ($id $amount)))
       (("id" "amount") ("001" "12.50") ("002" "9") ("002" "9")))
!(test (match &sales (row "001" $amount) (parse-number $amount)) 12.5)

!(write-file! &csv-path "003,42\n")
!(test (collapse (match &sales (row $id $amount) ($id $amount)))
       (("003" "42")))
!(delete-file! &csv-path)
```

## A reasoner

```metta
(= (myf $M)
   (and (and (member a $M)
             (member b $M))
        (== (size-atom $M) 2)))

!(test (if (once (myf $M)) $M)
       (a b))
```

## Weighted answers

```metta
!(import! &self (library lib_pln))

(= (STV A) (stv 0.5 0.9))
(= (STV B) (stv 0.25 0.9))
(= (STV C) (stv 0.25 0.9))
(= (STV D) (stv 0.5 0.9))

(= (kb)
   ((Sentence ((Inheritance A B) (stv 0.25 0.9)) (1))
    (Sentence ((Inheritance A C) (stv 0.25 0.9)) (2))
    (Sentence ((Inheritance B D) (stv 0.5 0.9)) (3))
    (Sentence ((Inheritance C D) (stv 0.5 0.9)) (4))
   ))

!(test (with-pragma! ((max-stack-depth 100000000))
                     (PLN.Query (kb) (Inheritance A D)))
       ((stv 0.5 0.9473684210526316) (1 2 3 4)))
```

## Search

```metta
!(add-atom &self (= (fib $N)
                    (if (< $N 2)
                        $N
                        (+ (fib (- $N 1))
                           (fib (- $N 2))))))

!(test (with-pragma! ((max-stack-depth 100000000)) (fib 30)) 832040)
```

## Extending the engine

A translator rule changes what a form compiles to.

```metta
(= (runtime42 $arg)
   (cons 42 $arg))

(= (compileeval42 $arg)
   (cons 42 $arg))

(= (compile42 $arg)
   (noeval (cons 42 $arg)))

!(add-translator-rule! compileeval42)
!(add-translator-rule! compile42)

!(test (runtime42 (43)) (42 43))
!(test (compileeval42 (43)) (42 43))
!(test (compile42 (43)) (42 43))
```

Prolog underneath, when you want it.

```metta
!(test (progn (translatePredicate (is $x 2))
              (translatePredicate (+ $x 40 $z)) $z)
       42)
```

MeTTa's own evaluator, written in MeTTa.

```metta
(: myinterpreter (-> Atom %Undefined%))
(= (myinterpreter $code)
   (let $temp (println! ("Runtime-interpreting code" $code))
        (eval $code)))

(= (w) 42)
(= (v) 43)

!(test (myinterpreter (if (== 1 1) (w) (v))) 42)
!(test (myinterpreter (if (== 1 2) (w) (v))) 43)
```

`git-import!` fetches and builds a library from source; see
[the example](examples/ch20-extending-the-engine/20-04-modules-and-the-catalog/06-git_import.metta).

# The library pack

Sixty-one libraries sit under `lib/`. None is loaded until a program names it,
and every example below is run by the gate on a fresh space, so a line that
stops being true fails the build instead of going stale on the page.

Sixteen of them are written in a language upstream PeTTa does not accept. They
use the sequence variables above, `(:seg $rest)` and its anonymous `...`, in
their own definitions and signatures: `lib_sets` types union as
`(-> (:seg Expression) Expression)` so it takes any number of sets, and
`lib_strategy` types `seq` the same way. What they mean is PeTTa's; what they
are written in is a superset of it, so these sixteen need this kernel:

> `lib_builtin_types`, `lib_combinatorics`, `lib_database`, `lib_datastructures`, `lib_encoding`, `lib_functional`, `lib_graph`, `lib_package`, `lib_pairs`, `lib_parsing`, `lib_random`, `lib_sets`, `lib_statistics`, `lib_strategy`, `lib_tabling`, `lib_uuid`.

The other forty-four import and run on either. `lib_gitimport` is the
sixty-first and has no MeTTa half at all: it is the Prolog backing
`lib_package` calls to fetch a repository, reached through a package
requirement rather than through `import!`.

One example each is what this page is for. Every head a library exports, with
its own `(@doc ...)` text, is in `website/reference/metta-libraries.md`,
generated from the live atoms by `extensions/python/tools/libdoc.py`; `help!`
and `get-doc` answer the same atoms at the prompt.

### `lib_builtin_types`

Declare the type surface of MeTTa's shipped builtins, its type-kind markers included, for engine reflection and optional live typed dispatch. Needs sequence variables.

```metta
!(import! &self (library lib_builtin_types))
!(test (format-args "{} and {}" ("only")) "only and ")
```

### `lib_cli`

Declare typed command-line parsing, help and exact argument access.

```metta
!(import! &self (library lib_cli))
!(test (cli-types) (boolean integer float atom string metta))
```

### `lib_combinatorics`

Finite choices and exact counts as MeTTa answer streams. Needs sequence variables.

```metta
!(import! &self (library lib_combinatorics))
!(test (choose2l (a b c)) ((a b) (a c) (b c)))
```

### `lib_compression`

Declare compression and archive operations from native typed exports.

```metta
!(import! &self (library lib_compression))
!(test (compression-formats) (gzip zlib))
```

### `lib_conformance`

Prove a foreign space provider before its users find out, for the tier that had no way to do it.

```metta
!(import! &self (library lib_conformance))
!(test (get-type check-space-provider) (-> Atom Expression))
```

### `lib_constraints`

Expose SWI's clpq and clpb as MeTTa operations.

```metta
!(import! &self (library lib_constraints))
!(test (clpq (= (+ $x 1) 3)) True)
```

### `lib_crypto`

Expose the native crypto declarations, types and help to MeTTa.

```metta
!(import! &self (library lib_crypto))
!(test (crypto-hash sha256 "") "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
```

### `lib_csv`

Lossless CSV text, streamed rows, live views and mutable snapshots.

```metta
!(import! &self (library lib_csv))
!(test (csv-parse "001,\"a,b\"\r\n002,9\r\n") (("001" "a,b") ("002" "9")))
```

### `lib_database`

Declare independent persistent stores from the native typed exports. Needs sequence variables.

```metta
!(import! &self (library lib_database))
!(test (get-type database-open!) (-> %Undefined% Symbol %Undefined%))
```

### `lib_datastructures`

Immutable maps, priority queues, functional queues and finger trees. Needs sequence variables.

```metta
!(import! &self (library lib_datastructures))
!(test (map-size (map-from-pairs ((a 1) (b 2)))) 2)
```

### `lib_datetime`

Supply clocks, calendar records, parsing and explicit-zone arithmetic.

```metta
!(import! &self (library lib_datetime))
!(test (day-of-week 1766188800) Saturday)
```

### `lib_derived`

The derived forms the engine keeps FUSED into its compiler, written out as translator rules, so a program that wants the smaller instruction set can have it and pay the difference knowingly.
fused, written out as translator rules so a program can have the smaller
instruction set and pay the difference knowingly. `add-translator-rule!`
registers for every space and the rest of the session, so a program that only
wanted it briefly gives it back.

```metta
!(import! &self (library lib_derived))
!(test (once (superpose (1 2 3))) 1)
!(remove-translator-rule! once)
```

### `lib_dict`

A space used as a dictionary; the dict story, and it is the space.

```metta
!(import! &self (library lib_dict))
!(test (dict-size (dict-put (new-space) a 1)) 1)
```

### `lib_doc`

Preserve the old lib_doc import path after its vocabulary moved into the engine.

```metta
!(import! &self (library lib_doc))
!(test (get-metatype (get-doc get-doc)) Expression)
```

### `lib_encoding`

Compose UTF8/base64 host codecs with inspectable MeTTa hex recipes. Needs sequence variables.

```metta
!(import! &self (library lib_encoding))
!(test (utf8-encode "hi") (104 105))
```

### `lib_file`

Files, directories, paths, links, traversal, scopes and streams.

```metta
!(import! &self (library lib_file))
!(test (path-join "one" "two") "one/two")
```

### `lib_functional`

Compose collection transformations and held control forms in MeTTa. Needs sequence variables.

```metta
!(import! &self (library lib_functional))
!(test (zip (1 2 3) (a b c)) ((1 a) (2 b) (3 c)))
```

### `lib_graph`

Derive directed graphs from canonical relation and set expressions. Needs sequence variables.

```metta
!(import! &self (library lib_graph))
!(test (graph-topological-order ((a (b)) (b ()))) (a b))
```

### `lib_he`

The hyperon-experimental compatibility surface.

```metta
!(import! &self (library lib_he))
!(test (unify (f a) (f $x) $x none) a)
```

### `lib_http`

Declare the HTTP surface generated from its native typed exports.

```metta
!(import! &self (library lib_http))
!(test (http-methods) (delete get head post put patch options))
```

### `lib_import`

Load Prolog support and expose source imports as queryable data.

```metta
!(import! &self (library lib_import))
!(test (get-metatype use-module!) Grounded)
```

### `lib_json`

JSON documents whose objects are queryable spaces.

```metta
!(import! &self (library lib_json))
!(test (json-decode "[1,2,3]") (1 2 3))
```

### `lib_logging`

Structured host messages, topic controls and explicit handlers.

```metta
!(import! &self (library lib_logging))
!(test (log-levels) (debug informational warning error))
```

### `lib_markup`

XML and HTML as expressions, with a selector language over them.

```metta
!(import! &self (library lib_markup))
!(test (markup-text (markup-parse-xml "<p>hi</p>")) "hi")
```

### `lib_math`

Compose exact number operations over the shared numeric providers.

```metta
!(import! &self (library lib_math))
!(test (math-gcd (12 18)) 6)
```

### `lib_measure`

Weighted-superposition operations for normalization, ranking, sampling, aggregation, and expectation.

```metta
!(import! &self (library lib_measure))
!(test (get-metatype measure) Symbol)
```

### `lib_memo`

Expose the resident automatic and explicit memoization controls.

```metta
!(import! &self (library lib_memo))
!(test (get-metatype memo) Symbol)
```

### `lib_mm2`

Five operators as a notation over `&mork`, the on-demand half of a seat whose provider is `extensions/mork`.

```metta
!(import! &self (library lib_mm2))
!(test (get-type ＋) (-> Atom %Undefined%))
```

### `lib_nars`

Provide NARS truth functions, inference rules, and bounded derivation.

```metta
!(import! &self (library lib_nars))
!(test (get-metatype nars) Symbol)
```

### `lib_observe`

Make execution observations queryable with match and get-atoms.

```metta
!(import! &self (library lib_observe))
!(test (get-type observe-source) (-> SpaceType String String SpaceType))
```

### `lib_package`

Document the default package interpreter and its explicit setup door. Needs sequence variables.

```metta
!(import! &self (library lib_package))
!(test (size-atom (collapse (match &catalogs (package $n $p) $n))) 61)
```

### `lib_pairs`

Read ordinary (Key Value) pairs as a relation through collection operations. Needs sequence variables.

```metta
!(import! &self (library lib_pairs))
!(test (pairs-lookup ((a 1) (b 2)) b) 2)
```

### `lib_parsing`

Prepare grammar data as ordinary nondeterministic MeTTa functions. Needs sequence variables.

```metta
!(import! &self (library lib_parsing))
!(test (grammar-parse (lit "ab") "ab") "ab")
```

### `lib_patrick`

lib_patrick's four idioms: composition and iteration.

```metta
!(import! &self (library lib_patrick))
!(test (get-type compose) (-> Atom _ _))
```

### `lib_pln`

Probabilistic logic network truth functions, confidence and weight.

```metta
!(import! &self (library lib_pln))
!(test (Truth_w2c 1) 0.5)
```

### `lib_pln2`

An isolated, assumption-explicit truth-value library for Beta and moment formulas that are independently checked rather than inherited from legacy lib_pln policy.

```metta
!(import! &self (library lib_pln2))
!(test (get-metatype pln2) Symbol)
```

### `lib_process`

Run a program with an argument vector, capture what it wrote, and start, watch, signal and wait for one that outlives the call.

```metta
!(import! &self (library lib_process))
!(test (process-run! "echo" ("hi")) (process-result 0 "hi\n" ""))
```

### `lib_random`

Construct inspectable sample programs and select distinct occurrences. Needs sequence variables.

```metta
!(import! &self (library lib_random))
!(test (random-shuffle! ()) ())
```

### `lib_redis`

Shared spaces over Redis, SWI's own library(redis) underneath, plugged into the engine's foreign-space seam.

```metta
!(import! &self (library lib_redis))
!(test (get-metatype redis-open!) Symbol)
```

### `lib_reflect`

Inspect the engine's surface and manipulate literal terms as data.

```metta
!(import! &self (library lib_reflect))
!(test (atom-variables (f $x $y)) ($x $y))
```

### `lib_regex`

Declare compiled PCRE2 matching, capture scans and substitutions.

```metta
!(import! &self (library lib_regex))
!(test (re-match "(?i)^needle" "Needle in a haystack") True)
```

### `lib_roman`

Tracing helpers and higher-order list operations, `map-flat` among them.

```metta
!(import! &self (library lib_roman))
!(test (get-metatype roman) Symbol)
```

### `lib_sets`

Derive set operations over canonical expressions from core collections. Needs sequence variables.

```metta
!(import! &self (library lib_sets))
!(test (set-of (3 1 2 1)) (1 2 3))
```

### `lib_socket`

Typed generated socket operations over File's owned stream handles.

```metta
!(import! &self (library lib_socket))
!(test (socket-wait! () infinite) ())
```

### `lib_soft`

Score written terms using symbol similarity and structural recursion.

```metta
!(import! &self (library lib_soft))
!(test (sym-sim a a) 1.0)
```

### `lib_spaces`

Migrate, copy, drain and count atoms between spaces.

```metta
!(import! &self (library lib_spaces))
!(test (match-count (new-space) ($x)) 0)
```

### `lib_statistics`

Derive sample summaries and finite probability laws in MeTTa. Needs sequence variables.

```metta
!(import! &self (library lib_statistics))
!(test (stats-mean (1 2 3)) 2)
```

### `lib_strategy`

Compose literal term rewrites through ordinary MeTTa functions. Needs sequence variables.

```metta
!(import! &self (library lib_strategy))
!(test (get-type seq) (-> Atom (:seg Atom) %Undefined%))
```

### `lib_string`

Compose String recipes over the shared text and metric providers.

```metta
!(import! &self (library lib_string))
!(test (string-length "a🦊é") 3)
```

### `lib_system`

The environment, the working directory and what the host says about itself, as data a program can read and write.

```metta
!(import! &self (library lib_system))
!(test (collapse (env-get "NO_SUCH_VARIABLE_HERE")) ())
```

### `lib_tabling`

The runtime control plane for tabling MeTTa functions. Needs sequence variables.

```metta
!(import! &self (library lib_tabling))
!(test (get-type tabled) (-> Atom Bool))
```

### `lib_testing`

Import finite generators for properties expressed with core assertions.

```metta
!(import! &self (library lib_testing))
!(test (== 1 1) True)
```

### `lib_thread`

Publish parallel data operations, M:N engine futures, timers, channels, pools, Linda waits and locks over SWI-Prolog primitives.

```metta
!(import! &self (library lib_thread))
!(test (get-type spawn) (-> Atom %Undefined%))
```

### `lib_torch`

PyTorch from plain MeTTa through py-call: tensors, algebra, reductions, activations, the exits back to MeTTa data and autograd, with no Python-side setup needed beyond torch being importable.

```metta
!(import! &self (library lib_torch))
!(test (get-type torch-tensor) (-[det,writesState]-> %Undefined% %Undefined%))
```

### `lib_unicode`

The Unicode character database and the standard text transformations over it.

```metta
!(import! &self (library lib_unicode))
!(test (unicode-normalize nfkc "ﬃ") "ffi")
```

### `lib_uri`

Declare URI operations from their native typed exports.

```metta
!(import! &self (library lib_uri))
!(test (uri-parts "") (("path" "")))
```

### `lib_uuid`

Compose UUID names, namespaces and byte fields as MeTTa equations. Needs sequence variables.

```metta
!(import! &self (library lib_uuid))
!(test (uuid-version (uuid-random!)) 4)
```

### `lib_vector`

Compose numeric construction from MeTTa streams and shared kernels.

```metta
!(import! &self (library lib_vector))
!(test (dot (1.0 2.0) (3.0 4.0)) 11.0)
```

### `lib_yaml`

YAML documents as MeTTa values, in the shape lib_json already uses.

```metta
!(import! &self (library lib_yaml))
!(test (yaml-decode "- 1\n- 2\n") (1 2))
```

### `lib_zar`

Prolog interop: predicate-style `consult` and `use_module` wrappers.

```metta
!(import! &self (library lib_zar))
!(test (get-type consult_file) (-> %Undefined% %Undefined%))
```

# CMeTTa

A C program opens the engine in its own process, builds terms and asks.
[Repository](https://github.com/MesTTo/CMeTTa) ·
[llms.txt](extensions/cmetta/llms.txt)

| Feature | Doors |
|---|---|
| Runtime | `mt_open`, `mt_close`, `mt_verbose`, `mt_thread_attach`, `mt_thread_detach` |
| Constructors | `mt_sym`, `mt_var`, `mt_text`, `mt_num`, `mt_real`, `mt_bool`, `mt_unit`, `mt_bigint`, `mt_rational`, `mt_spaceref`, `mt_exprv` |
| References | `mt_keep`, `mt_drop` |
| Inspection | `mt_kind_of`, `mt_name`, `mt_int`, `mt_float`, `mt_truth`, `mt_len`, `mt_at`, `mt_eq`, `mt_hash` |
| Unification | `mt_unify`, `mt_unifyv`, `mt_bindings_*`, `mt_substitute` |
| Spaces | `mt_self`, `mt_catalog`, `mt_space_open`, add/del/match/eval/atoms/count/wipe |
| Answers | `mt_run`, `mt_load`, `mt_do`, `mt_next`, `mt_row_next`, `mt_bound` |
| Text | `mt_parse`, `mt_show`, `mt_write_dup`, `mt_free` |
| Errors | `mt_error`, `mt_errmsg`, `mt_remedy`, `mt_ground`, `mt_ok`, `mt_clear` |
| Defining | `mt_def` for a C function, `mt_lower` for equations from C tokens |

```c
#define MT_SHORTHAND
#include <cmetta.h>
#include <stdio.h>

/* --- the two doors, side by side ------------------------------------ *
 *
 * mt_def publishes a C function. The engine CALLS it, and because nothing can
 * be seen of what it does, it must declare an effect class.
 *
 * mt_lower installs an EQUATION. It is MeTTa, so the engine reads it,
 * type-checks it, specialises it, matches on it, and a call crosses into no
 * host at all.
 *
 * The preprocessor is what makes the second one possible in C. Python lowers
 * by reading a function's __code__ and Node by reading its toString(); C has
 * neither at run time, but `#` is access to the program's own source at the
 * one moment C offers it.
 */

static mt_status op_triple(mt_call *call, void *user)
{ int64_t v;
  (void)user;
  mt_clear();
  v = mt_int(mt_arg(call, 0));
  if ( !mt_ok() ) return mt_fail(call, "triple wants a Number");
  return mt_answer(call, N(v * 3));
}

/* --- one body, two languages ---------------------------------------- *
 *
 * The operators are parameters, so the same body expands to C in one mode and
 * to MeTTa tokens in the other. The function exists once and is callable from
 * both, which is what the other seats' twins buy, bought the way C buys it.
 */
#define POLY(ADD, MUL, x)  ADD(MUL(3, x), 1)
#define C_ADD(a, b)        ((a) + (b))
#define C_MUL(a, b)        ((a) * (b))
#define M_ADD(a, b)        (+ a b)
#define M_MUL(a, b)        (* a b)

static int64_t poly(int64_t x) { return POLY(C_ADD, C_MUL, x); }

int main(void)
{ metta *m = mt_open(NULL);
  if ( !m ) return fprintf(stderr, "boot: %s\n", mt_errmsg()), 1;

  /* Called: the engine crosses into C, and had to be told the effect class. */
  mt_def(m, (mt_op){ .name = "triple", .arity = 1,
                     .effect = MT_PURE, .fn = op_triple });
  printf("called   (triple 7) = %lld\n",
         (long long)mt_one_int(mt_run(m, "!(triple 7)")));

  /* Lowered: the body is C tokens the compiler saw, installed as MeTTa. No
     quoting, no escaped newlines, and unbalanced parentheses are a compile
     error rather than a runtime one. */
  mt_lower(m, (twice $x), (* 2 $x));
  mt_lower(m, (fib $n), (if (< $n 2) $n
                            (+ (fib (- $n 1)) (fib (- $n 2)))));
  printf("lowered  (twice 21) = %lld\n",
         (long long)mt_one_int(mt_run(m, "!(twice 21)")));
  printf("lowered  (fib 20)   = %lld\n",
         (long long)mt_one_int(mt_run(m, "!(fib 20)")));

  /* One body, both languages. */
  mt_lower(m, (poly $x), POLY(M_ADD, M_MUL, $x));
  printf("in MeTTa (poly 5)   = %lld\n",
         (long long)mt_one_int(mt_run(m, "!(poly 5)")));
  printf("in C     poly(5)    = %lld\n", (long long)poly(5));

  /* And the difference that matters: a lowered equation is an ATOM in the
     space, so the engine can be asked about it. A published C function is
     opaque and there is nothing to ask. */
  mt_each (a, mt_match(mt_self(m), E("=", E("poly", V("x")), V("body"))))
      printf("the engine can see: %s\n", mt_show(a));

  mt_each (a, mt_match(mt_self(m), E("=", E("triple", V("x")), V("body"))))
      printf("...but not this:    %s\n", mt_show(a));
  printf("(nothing printed above, because a called function has no equation)\n");

  mt_close(m);
  return 0;
}
```

# Documentation

| Read | For |
|---|---|
| [llms.txt](llms.txt) | the language and every surface, exact return shapes, gate-checked names |
| [examples/](examples/) | 360 programs in 22 chapters, every one run by the gate |
| [EXTENDING.md](EXTENDING.md) | writing an integration |
| [CONTRIBUTING.md](CONTRIBUTING.md) | working on this repository |
| [SECURITY.md](SECURITY.md) | reporting a vulnerability |

## Citing

```bibtex
@software{petta,
  author = {Hammer, Patrick},
  title  = {PeTTa},
  url    = {https://github.com/patham9/PeTTa},
  note   = {The MeTTa implementation whose semantics this engine follows}
}

@software{metta_kernel,
  author  = {MesTTo},
  title   = {MeTTa Kernel},
  url     = {https://github.com/MesTTo/MeTTa},
  version = {0.8.0}
}
```

## Licence

Apache-2.0. See [LICENSE](LICENSE).
