PythonToMeTTa - trueagi-io/metta-wam GitHub Wiki
Python to Relational MeTTa
✅ Overview
This project presents a method for converting compact or AI-generated Python code ("vibe-coded") into relational, symbolic, and declarative programs using MeTTa — a Datalog-inspired logic language that uses S-expressions and logic variables like $x1, $x2, etc. Unlike traditional code, MeTTa logic is inherently composable, multidirectional, and symbolically expressive. Each step is written as a relation, not a function — enabling symbolic reasoning, bidirectional execution, and flexible queryability. *
🔄 Why Translate Python to MeTTa?
- Every term is a symmetric relation
- Inputs, outputs, or intermediates can be queried
- Control flow is replaced by logic composition
- Supports partial evaluation, symbolic inversion, and search MeTTa lets you build programs incrementally — one clause at a time — without refactoring earlier logic.
🧩 Example Translation: ARC Function
Original Python (compressed)
def solve_496994bd(I):
x = crop(I, ORIGIN, astuple(halve(height(I)), width(I)))
return vconcat(x, hmirror(x))
Verbose Python (for clarity)
def solve_496994bd(I):
x1 = width(I)
x2 = height(I)
x3 = halve(x2)
x4 = astuple(x3, x1)
x5 = crop(I, ORIGIN, x4)
x6 = hmirror(x5)
return vconcat(x5, x6)
MeTTa (Relational Logic)
(= (solve_496994bd $I $Out)
(and
(height $I $H)
(halve $H $H2)
(width $I $W)
(astuple $H2 $W $Dims)
(= $ORIGIN (0 0))
(crop $I $ORIGIN $Dims $X)
(hmirror $X $X_Mirror)
(vconcat $X $X_Mirror $Out)))
📦 Source Dataset: ARC-DSL Primitives
We began with a dataset of 400 Python programs, each solving a unique puzzle from the Abstraction and Reasoning Corpus (ARC). These programs were built atop ~160 core primitives forming a Python domain-specific language (DSL), known as ARC-DSL, authored by Michael Hodel. By translating these into the substrat, we hade a logic layer that describes what each transformation means — not just how to compute it.
;; def height(piece): ...
;; if piece == (): return 0
(= (height $Grid 0) (== $Grid ()))
;; elif is_tuple(piece): return len(piece)
(= (height $Grid $H)
(and (is-tuple? $Grid)
(length $Grid $H)))
;; else: return lowermost(piece) - uppermost(piece) + 1
(= (height $Grid $H)
(and (not (is-tuple? $Grid))
(uppermost $Grid $U)
(lowermost $Grid $L)
(- $L $U $H1)
(+ $H1 1 $H)))
;; def width(piece): ... ;; if piece == (): return 0 (= (width $Grid 0) (== $Grid ()))
;; elif is_tuple(piece): return len(piece[0]) (= (width $Grid $W) (and (is-tuple? $Grid) (nth 0 $Grid $Row) (length $Row $W)))
;; else: return rightmost(piece) - leftmost(piece) + 1 (= (width $Grid $W) (and (not (is-tuple? $Grid)) (leftmost $Grid $L) (rightmost $Grid $R) (- $R $L $W1) (+ $W1 1 $W)))
;; def halve(n): ... ;; return n // 2 (= (halve $N $Half) (and (is-int? $N) (// $N 2 $Half)))
;; def halve((a, b)): ... ;; return (a // 2, b // 2) (= (halve (tuple $A $B) (tuple $HA $HB)) (and (// $A 2 $HA) (// $B 2 $HB)))
;; def astuple(a, b): ... ;; return (a, b) (= (astuple $A $B (tuple $A $B)))
;; def crop(grid, start, dims): ... ;; return crop_rows(grid, start_row, num_rows, start_col, num_cols) (= (crop $Grid (tuple $R0 $C0) (tuple $NR $NC) $Cropped) (crop-rows $Grid $R0 $NR $C0 $NC $Cropped))
;; def crop_rows(grid, row0, nrows, col0, ncols): ... ;; return [slice_row(grid[r], col0, ncols) for r in range(row0, row0 + nrows)] (= (crop-rows $Grid $R0 $NR $C0 $NC $Rows) (map-range $R0 (+ $R0 $NR -1) (lambda $RIndex (nth $RIndex $Grid $Row) (slice-row $Row $C0 $NC $Slice) $Slice) $Rows))
;; def slice_row(row, col0, ncols): ... ;; return [row[i] for i in range(col0, col0 + ncols)] (= (slice-row $Row $C0 $NC $Slice) (range $C0 (+ $C0 $NC -1) $Indices) (map $Indices (lambda $I (nth $I $Row)) $Slice))
;; def hmirror(piece): ... ;; if is_tuple(piece): return piece[::-1] (= (hmirror $Piece $Mirrored) (and (is-tuple? $Piece) (reverse $Piece $Mirrored)))
;; else: reflect each pixel across vertical axis (= (hmirror $Piece $Mirrored) (and (ulcorner $Piece (tuple $ULx _)) (lrcorner $Piece (tuple $LRx _)) (+ $ULx $LRx $D) ;; if values: (if (has-values? $Piece) (map $Piece (lambda (tuple $V (tuple $X $Y)) (tuple $V (tuple (- $D $X) $Y))) $Mirrored) ;; else: (map $Piece (lambda (tuple $X $Y) (tuple (- $D $X) $Y)) $Mirrored))))
;; def vconcat(a, b): ... ;; return a + b (= (vconcat $A $B $Out) (append $A $B $Out))
;; def is_tuple(x): ... ;; return isinstance(x, tuple) and all(isinstance(e, list) for e in x) (= (is-tuple? $X) (and (is-list? $X) (not (== $X ())) (every $X is-list?)))
;; def has_values(piece): ... ;; return any(isinstance(p, tuple) for p in piece) (= (has-values? $Set) (exists $Set (lambda $X (match $X (tuple _ _)))))
;; def ulcorner(piece): ... ;; return (leftmost(piece), uppermost(piece)) (= (ulcorner $Set (tuple $X $Y)) (leftmost $Set $X) (uppermost $Set $Y))
;; def lrcorner(piece): ... ;; return (rightmost(piece), lowermost(piece)) (= (lrcorner $Set (tuple $X $Y)) (rightmost $Set $X) (lowermost $Set $Y))
➡️ See the full list of translated primitives in arc_primitives.metta
*
### 🚀 Why MORK Matters
Despite MeTTa (via MeTTaLog/Prolog) already outperforming Python in logic-heavy domains, MORK — the MeTTa Optimized Reduction Kernel — brings native execution plus parallelization.