santosomar/general-secure-coding-agent-skills/c-cpp-to-lean4-translator

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Translates C/C++ into Lean 4 for interactive theorem proving — deep verification where automated tools fail. Use when Dafny's automation isn't enough, when proving mathematical properties of an algorithm, or when building a machine-checked proof for publication or certification.

Install

npx vskill@latest install santosomar/general-secure-coding-agent-skills/c-cpp-to-lean4-translator

SKILL.md

C/C++ → Lean 4 Translator

Lean is for when you need a proof, not a check. Dafny asks an SMT solver "is this true?"; Lean asks you to construct the proof term. More work, more control, no timeouts.

When Lean over Dafny

SituationWhy Lean
SMT solver times out or returns unknownYou write the proof steps; no solver to time out
Proving mathematical properties (complexity bounds, algebraic laws)Lean has Mathlib; Dafny has arithmetic
The proof itself is the artifact (paper, certification)Lean proofs are inspectable; Dafny's are solver-internal
You need custom proof tacticsLean is a tactic language; Dafny's hints are fixed

The functional lift

Lean is purely functional. The translation path is: imperative C → functional model → proof about the model.

C constructLean model
int32_tInt32 (modular) or Int (unbounded) — same choice as Dafny
Loop with accumulatorFold: xs.foldl f init — or structural recursion
Loop with early exitRecursion with a sum type result: Option α or Except ε α
Mutable local varLet-bind a new name each "mutation": let x₁ := ...; let x₂ := f x₁
Array a[i]a.get i with (h : i < a.size) proof, or a.get? i : Option α
Pointer into array(a : Array α) × (i : Fin a.size) — a dependent pair
structstructure — direct
malloc/pointer to objectJust the object. No heap in the pure fragment.

The state monad escape hatch

If the imperative structure is too tangled to lift functionally, use StateM:

lean
def impStep : StateM (Array Int) Unit := do
let a ← get
if h : 0 < a.size then
set (a.set ⟨0, h⟩ 42)
-- Reason about the result:
theorem impStep_sets_zero (a : Array Int) (h : 0 < a.size) :
(impStep.run a).2.get ⟨0, h⟩ = 42 := by simp [impStep, StateT.run]

But prefer the functional lift — proofs over folds are easier than proofs over monadic runs.

Worked example

C:

c
// Count elements equal to target
size_t count(const int* a, size_t n, int target) {
size_t c = 0;
for (size_t i = 0; i < n; ++i)
if (a[i] == target) ++c;
return c;
}

Lean — functional lift:

lean
def count (a : List Int) (target : Int) : Nat :=
a.foldl (fun c x => if x = target then c + 1 else c) 0
-- Spec via List.countP from Mathlib
theorem count_eq_countP (a : List Int) (target : Int) :
count a target = a.countP (· = target) := by
induction a with
| nil => rfl
| cons x xs ih =>
simp only [count, List.foldl_cons, List.countP_cons]
split <;> simp [ih, count]

Notes:

  • List instead of Array — easier induction. If you need Array for the performance story, prove on List and transport via Array.toList.
  • The theorem connects our count to Mathlib's countP — once connected, all of Mathlib's lemmas about countP apply to us for free.
  • size_t → Nat (unbounded). If we cared about SIZE_MAX, we'd add a separate bound theorem.

Proof patterns you'll need

Goal shapeTactic
Property of a foldinduction xs + unfold the fold one step
Property of recursion on Natinduction n or Nat.rec
Array index in boundsomega / simp_arith — or carry Fin n so it's by-type
Decidable equality case splitsplit after if / by_cases h : P
"Obvious" arithmeticomega, ring, simp_arith
Reuse a library lemmaexact? / apply? — let Lean search Mathlib

Do not

  • Do not translate to Lean when Dafny would verify automatically. Lean proofs are manual labor; only pay for what you need.
  • Do not state the theorem as "equals the C code." State it as "satisfies this mathematical property." The C is an implementation; the theorem is about the spec.
  • Do not fight Lean's termination checker with partial def. partial means "trust me" — you lose proofs-by-induction. Find the structural argument.
  • Do not reinvent Mathlib. List.countP, List.Sorted, Nat.gcd — they exist, with lemma libraries. Connect to them.

Output format

## Functional model
<Lean def — the translated algorithm>
## Theorem
<what property this proves — connected to Mathlib where possible>
## Proof
<tactic script — or `sorry` placeholders with notes on what's left>
## Model fidelity
<where the Lean model diverges from the C: unbounded ints, List vs Array, etc.>

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Refreshed 18 Mar 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/santosomar/general-secure-coding-agent-skills/c-cpp-to-lean4-translator/badge)](https://verified-skill.com/skills/santosomar/general-secure-coding-agent-skills/c-cpp-to-lean4-translator)

Something wrong with this skill or its page? Tell us.