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.