arabelatso/c-cpp-to-lean4-translator
Translate C or C++ programs into equivalent Lean4 code, preserving program semantics and ensuring the generated code is well-typed, executable, and can run successfully. Use when the user asks to convert C/C++ code to Lean4, port C/C++ programs to Lean4, translate imperative code to functional Lean4, or create Lean4 versions of C/C++ algorithms.
npx skills add https://github.com/ArabelaTso/Skills-4-SE --skill c-cpp-to-lean4-translator
Transform C or C++ programs into equivalent Lean4 code that preserves the original semantics while leveraging Lean4's functional programming paradigm, strong type system, and proof capabilities.
Understand the C/C++ program structure and semantics:
Plan the Lean4 equivalent before writing code:
Int for signed integersNat for unsigned integers and array indicesFloat for floating-point numbersArray for dynamic arraysList for linked listsstructure types for structs/classesIO monadIO.Ref or ST monadFollow these translation principles:
Pattern: Pure function
// C/C++
int add(int a, int b) {
return a + b;
}
-- Lean4
def add (a b : Int) : Int :=
a + b
Pattern: Function with side effects
// C/C++
void printSum(int a, int b) {
printf("%d\n", a + b);
}
-- Lean4
def printSum (a b : Int) : IO Unit :=
IO.println (a + b)
Pattern: If-else
// C/C++
int max(int a, int b) {
if (a > b) return a;
else return b;
}
-- Lean4
def max (a b : Int) : Int :=
if a > b then a else b
Pattern: For loop → Tail recursion
// C/C++
int sum(int n) {
int result = 0;
for (int i = 0; i < n; i++) {
result += i;
}
return result;
}
-- Lean4
def sum (n : Nat) : Nat :=
let rec loop (i acc : Nat) : Nat :=
if i >= n then acc
else loop (i + 1) (acc + i)
loop 0 0
Pattern: While loop → Recursion
// C/C++
int factorial(int n) {
int result = 1;
while (n > 1) {
result *= n;
n--;
}
return result;
}
-- Lean4
def factorial (n : Nat) : Nat :=
let rec loop (n acc : Nat) : Nat :=
if n <= 1 then acc
else loop (n - 1) (acc * n)
loop n 1
Pattern: Struct
// C/C++
struct Point {
int x;
int y;
};
-- Lean4
structure Point where
x : Int
y : Int
deriving Repr
Pattern: Array
// C/C++
int arr[5] = {1, 2, 3, 4, 5};
-- Lean4
def arr : Array Int := #[1, 2, 3, 4, 5]
Key principle: Lean4 doesn't have raw pointers. Translate based on usage:
IO.Ref or return new values// C/C++ - Output parameter
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
-- Lean4 - Return tuple
def swap (a b : Int) : Int × Int :=
(b, a)
Lean4's type system is strict. Address common type issues:
Nat for non-negative values (array indices, counts)Int for potentially negative valuesn.toNat, n.toIntarr.get?, arr[i]?arr[i]! with runtime checkn / m (rounds down)Int.div: Type for clarityEnsure the translated code works correctly:
lake build
#eval add 2 3 -- Should output 5
#eval factorial 5 -- Should output 120
Improve the translated code:
List.foldl, Array.foldl /-- Calculate the sum of first n natural numbers -/
def sum (n : Nat) : Nat :=
n * (n + 1) / 2
Array over List for random access@[inline] for small functionsFor detailed patterns, see translation_patterns.md.
| C/C++ | Lean4 |
|-------|-------|
| int x | def x : Int |
| unsigned int x | def x : Nat |
| float x | def x : Float |
| bool x | def x : Bool |
| char* str | def str : String |
| int arr[] | def arr : Array Int |
| struct S | structure S where |
| for (...) | let rec loop ... |
| while (...) | let rec loop ... |
| if (...) {...} | if ... then ... else ... |
| switch (...) | match ... with |
| return x | x (last expression) |
| void f() | def f : IO Unit |
| printf(...) | IO.println ... |
C/C++ Input:
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
Lean4 Output:
def gcd (a b : Nat) : Nat :=
if b = 0 then a
else gcd b (a % b)
C/C++ Input:
int findMax(int arr[], int size) {
int max = arr[0];
for (int i = 1; i < size; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
Lean4 Output:
def findMax (arr : Array Int) : Option Int :=
if arr.isEmpty then
none
else
some (arr.foldl max arr[0]!)
C/C++ Input:
struct Rectangle {
int width;
int height;
int area() {
return width * height;
}
int perimeter() {
return 2 * (width + height);
}
};
Lean4 Output:
structure Rectangle where
width : Nat
height : Nat
deriving Repr
def Rectangle.area (r : Rectangle) : Nat :=
r.width * r.height
def Rectangle.perimeter (r : Rectangle) : Nat :=
2 * (r.width + r.height)
C/C++ Input:
#include <stdio.h>
int main() {
int n;
printf("Enter a number: ");
scanf("%d", &n);
printf("Factorial: %d\n", factorial(n));
return 0;
}
Lean4 Output:
def factorial (n : Nat) : Nat :=
if n <= 1 then 1
else n * factorial (n - 1)
def main : IO Unit := do
IO.print "Enter a number: "
let input ← IO.getStdIn >>= (·.getLine)
match input.trim.toNat? with
| some n =>
IO.println s!"Factorial: {factorial n}"
| none =>
IO.println "Invalid input"
Option or Except for error casesTake arabelatso/c-cpp-to-lean4-translator from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.