python-to-lean4-translator — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited python-to-lean4-translator (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Translate Python programs into equivalent, executable Lean4 code while preserving program semantics and ensuring type safety.
This skill provides systematic guidance for translating Python code to Lean4, handling type inference, function translations, data structures, control flow, and ensuring well-typed, executable output.
Python Input → Analyze Structure → Map Types → Translate Constructs → Verify → Output Lean4
├─ Identify types and signatures
├─ Map Python constructs to Lean4 equivalents
├─ Handle type conversions
├─ Ensure totality and termination
└─ Validate executabilityLean4 is strongly typed. Every translation must:
Option for nullable values, Except for error handlingThe translated code must maintain the same computational behavior, preserve function input-output relationships, keep the same algorithmic complexity, and handle edge cases equivalently.
Generated Lean4 code must compile without errors, be executable (use #eval to verify), terminate (prove termination for recursive functions), and follow Lean4 syntax and conventions.
| Python Type | Lean4 Type | Notes |
|---|---|---|
int | Int or Nat | Use Nat for non-negative integers |
float | Float | Lean4's floating point type |
bool | Bool | Direct mapping |
str | String | Direct mapping |
None | Option α | Use none for None, some x for values |
list | List α | Homogeneous lists |
tuple | Product types α × β or custom structure | |
dict | Std.HashMap or List (α × β) | Requires import |
set | Std.HashSet or List α | Requires import |
For detailed type system information, see references/type_mappings.md.
Simple function:
def add(a: int, b: int) -> int:
return a + bLean4:
def add (a : Int) (b : Int) : Int :=
a + bRecursive function:
def factorial(n: int) -> int:
if n <= 1:
return 1
else:
return n * factorial(n - 1)Lean4:
def factorial (n : Nat) : Nat :=
if n ≤ 1 then
1
else
n * factorial (n - 1)If-else:
if condition:
result = value1
else:
result = value2Lean4:
let result := if condition then value1 else value2For loops (list iteration):
total = 0
for x in items:
total += xLean4 (using fold):
let total := items.foldl (· + ·) 0List comprehension:
squares = [x * x for x in range(10)]Lean4:
let squares := (List.range 10).map (fun x => x * x)Filter:
evens = [x for x in numbers if x % 2 == 0]Lean4:
let evens := numbers.filter (fun x => x % 2 == 0)Python class:
class Rectangle:
def __init__(self, width: int, height: int):
self.width = width
self.height = height
def area(self) -> int:
return self.width * self.heightLean4:
structure Rectangle where
width : Int
height : Int
def Rectangle.area (r : Rectangle) : Int :=
r.width * r.heightAnalyze usage to infer types, use sum types for multiple possible types, use Option for nullable values, and document type assumptions.
Use immutable bindings with let, thread state through function parameters, or use monadic state (StateM) if needed.
Convert Python exceptions to Except or Option:
def divide(a: int, b: int) -> float:
if b == 0:
raise ValueError("Division by zero")
return a / bLean4:
def divide (a b : Int) : Except String Float :=
if b = 0 then
Except.error "Division by zero"
else
Except.ok (a.toFloat / b.toFloat)Use structural recursion when possible, add termination_by clause for complex recursion:
def fibonacci (n : Nat) : Nat :=
match n with
| 0 => 0
| 1 => 1
| n + 2 => fibonacci n + fibonacci (n + 1)
termination_by nUse IO monad for I/O operations:
def greet(name: str):
print(f"Hello, {name}!")Lean4:
def greet (name : String) : IO Unit :=
IO.println s!"Hello, {name}!"Identify all functions, classes, and global variables. Infer types from usage and annotations. Identify dependencies and imports. Note any dynamic behavior or side effects.
Map Python types to Lean4 types. Identify where Option, Except, or sum types are needed. Plan structure definitions for classes. Determine function signatures.
Start with data structures (classes → structures). Translate pure functions first. Handle control flow (convert loops to recursion). Translate functions with side effects using IO. Add necessary imports.
Add explicit type annotations. Resolve type mismatches. Handle implicit conversions. Add termination proofs for recursive functions.
Check syntax with Lean4 compiler. Test with #eval for simple cases. Verify output matches Python behavior. Document any semantic differences.
Common imports for translated code:
import Std.Data.HashMap
import Std.Data.HashSet
import Init.Data.List.Basic
import Init.Data.Option.BasicPython:
def is_prime(n: int) -> bool:
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def primes_up_to(limit: int) -> list[int]:
return [n for n in range(2, limit + 1) if is_prime(n)]Lean4:
def isPrime (n : Nat) : Bool :=
if n < 2 then
false
else
let rec checkDivisors (i : Nat) : Bool :=
if i * i > n then
true
else if n % i = 0 then
false
else
checkDivisors (i + 1)
checkDivisors 2
def primesUpTo (limit : Nat) : List Nat :=
(List.range (limit + 1)).drop 2 |>.filter isPrime
-- Test
#eval primesUpTo 20 -- [2, 3, 5, 7, 11, 13, 17, 19]#eval to test each function as you translateOption or Except instead of exceptionsBefore finalizing translation:
#eval produces expected results for test casesOption or Except appropriatelyIOFor complex translations, refer to:
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.