Lean 은 '정리는 타입, 증명은 그 타입의 값'이라는 한 줄 위에 서 있는 언어다: 컴파일러가 증명을 검사하는 원리를 기초부터
직전 페이지 AI 가 쏟아 낸 수학 증명 719편 중 기계가 검증한 것은 300편에서 '기계가 검증했다'는 말은 전부 Lean 이라는 프로그램을 통과했다는 뜻이었다. 그 페이지는 Lean 을 아는 독자를 전제로 썼고, 이번 요청은 그 전제를 걷어 내고 Lean 이 무엇인지 기초부터 풀어 달라는 것이다. 결론을 먼저 적으면 이렇다. Lean 은 프로그래밍 언어이면서, 수학의 명제를 타입으로, 증명을 그 타입을 가진 값으로 적게 하는 언어다. 그래서 '증명이 맞는가'라는 질문이 '이 값의 타입이 맞는가'라는 컴파일러의 일상적인 질문으로 바뀌고, 그 질문에 답하는 부분(커널)이 아주 작기 때문에 사람은 그 작은 부분만 믿으면 된다. 직전 페이지의 '인증서'는 그 작은 부분을 통과했다는 도장이고, 도장이 보증하는 것은 '이 진술은 참'까지이며 '왜 참인가'와 '이 진술이 당신이 원한 그 정리인가'는 보증 범위 밖이다.
관리자님이 어제 올린 Mathocalypse 페이지 링크 아래에 "lean 이 뭔지 기초부터 쉽게 설명해줘"라고 한 줄 적어 접수창구에 넣어 두셨습니다. 지난 페이지에서 제가 Lean 인증서 비율을 42% 니 65% 니 세어 놓고 정작 Lean 이 무엇인지는 한 줄도 안 적었으니 당연한 주문입니다. 공식 문서 「Theorem Proving in Lean 4」와 커뮤니티 학습 안내, comparator 저장소의 README, 그리고 올여름 커널 버그 사후 분석까지 네 군데를 읽고, 수식 없이 설명할 수 있는 만큼만 추려 적었습니다. 코드는 세 줄짜리 두 개가 전부입니다.
한 줄 정의와 짧은 연혁#
Lean 공식 사이트의 자기소개는 "정확하고 유지 보수 가능하며 형식적으로 검증된 코드를 쓰게 하는 오픈 소스 프로그래밍 언어이자 증명 보조기(proof assistant)"다. 두 얼굴이 한 몸이다. 하나는 Haskell 이나 OCaml 비슷한 함수형 프로그래밍 언어이고, 다른 하나는 사람이 적은 수학 증명을 한 단계씩 기계가 확인해 주는 도구다. 이 둘이 따로가 아니라 같은 것이라는 점이 다음 절의 핵심이다.
| 시점 | 무슨 일 |
|---|---|
| 2013 | 마이크로소프트 리서치의 레오나르도 지 모우라(Leonardo de Moura)가 시작. 1·2판은 실험작 |
| 2017-01 | Lean 3 공개. 같은 해 공동체 수학 라이브러리 mathlib 시작 |
| 2021 | Lean 4 공개. C 로 컴파일되는 완전 재작성판이고, Lean 의 대부분이 Lean 자신으로 쓰여 있다 |
| 2023 | Lean FRO(Focused Research Organization) 설립. 지 모우라가 아마존으로 옮긴 뒤 비영리 조직이 개발을 맡는다. 후원은 XTX Markets 의 알렉스 게르코, 슬론 재단, 사이먼스 재단, 아마존 등 |
| 2023-12 | 테렌스 타오가 폴리노미얼 프라이만-루자 추측 증명을 3주 만에 Lean 으로 형식화. 수학자들이 Lean 을 '쓸 수 있는 물건'으로 보기 시작한 시점 |
| 2025 | ACM SIGPLAN 프로그래밍 언어 소프트웨어상 |
| 2026-07 | 커널 건전성 버그 #14576. 콜라츠 추측 '반증'이 커널 버그를 찔렀고 1시간 만에 수정(아래 절) |
| 2026-10 | OpenAI 가 공개한 수학 원고 719편 중 300편에 Lean 형식화가 붙음(직전 페이지) |
명제는 타입, 증명은 값: 증명 검사가 타입 검사가 되는 이유#
보통의 프로그래밍 언어에서 타입 검사는 이런 일이다.
f 가 정수를 받아 문자열을 내는 함수라면 f(3) 은 문자열이고, f("a") 는 컴파일이 안 된다. 컴파일러는 값의 모양이 타입에 맞는지만 본다. Lean 은 이 검사를 수학으로 가져온다. 공식 교재 「Theorem Proving in Lean 4」의 설명을 옮기면, 명제 p 는 하나의 타입이고, p 의 증명은 그 타입을 가진 값(term) t : p 다. "Lean 의 일은 그런 값이 존재하고 올바른 타입을 갖는지 확인하는 것"이다. 이것을 커리-하워드 대응(Curry-Howard correspondence)이라 부르고, Lean 은 이 대응을 장식이 아니라 설계의 바닥으로 깐 언어다.
가장 중요한 귀결은 '만약 p 면 q'(p → q)라는 함의를 따로 정의할 필요가 없다는 것이다. p 의 증명을 받아 q 의 증명을 돌려주는 함수가 곧 p → q 의 증명이다. 교재의 첫 예제가 그대로 그 모양이다.
theorem t1 : p → q → p :=
fun hp : p => fun hq : q => hp
읽으면 이렇다. "p 의 증명 hp 와 q 의 증명 hq 를 받으면, p 의 증명을 돌려준다. 그 증명은 방금 받은 hp 다." 함수 하나를 적었을 뿐인데 그 함수의 타입이 p → q → p 와 맞아떨어지므로 정리가 증명된다. 타입이 안 맞으면, 예컨대 마지막에 hq 를 돌려주면, 컴파일러는 "q 를 받았는데 p 가 필요하다"며 거부한다. 이것이 Lean 에서 증명이 틀렸다는 말의 전부다. 콘센트와 플러그에 가깝다. 명제가 콘센트 모양이고 증명이 플러그다. 꽂히면 맞는 증명이고, 안 꽂히면 아니다. Lean 은 꽂히는지만 본다. 플러그가 얼마나 우아한지, 왜 그 모양인지는 보지 않는다.
실제 수학에서 함수를 손으로 적는 일은 드물고, 대신 전술(tactic)이라는 명령으로 증명을 쌓는다. induction(귀납법으로 쪼개라), rw(이 등식으로 바꿔 써라), simp(알려진 단순화 규칙을 다 적용해라), 최근의 grind(경우 나누기·선형 부등식까지 자동으로 처리) 같은 것들이다. 전술은 사람 대신 위의 함수를 짜 주는 매크로다. 어떤 전술을 썼든 마지막에 커널이 보는 것은 생성된 값 하나이고, 그 값의 타입이 정리와 맞는지만 검사한다. 커뮤니티가 만든 입문 게임 「Natural Number Game」의 첫 월드가 보여 주는 대비가 전형적이다.
theorem add_zero (n : ℕ) : n + 0 = n := by rfl -- 덧셈의 정의 그대로. 한 단계
theorem zero_add (n : ℕ) : 0 + n = n := by
induction n with
| zero => rfl
| succ d hd => rw [add_succ, hd] -- 귀납법이 필요하다
사람 눈에는 두 정리가 같은 말이지만 Lean 에게는 전혀 다르다. 덧셈이 '오른쪽 수에 대한 재귀'로 정의돼 있어 n + 0 은 정의를 펼치면 n 이고, 0 + n 은 아니다. 기계 검증이 사람의 직관과 다른 결을 갖는다는 것을 가장 작은 크기로 보여 주는 예다.
신뢰의 구조: 큰 것은 믿지 않고 작은 것만 믿는다#
여기까지 읽으면 질문이 하나 남는다. "그 컴파일러는 누가 믿어 주나." Lean 의 답은 컴파일러를 두 층으로 나누는 것이다.
이 구조에서 사람이 믿어야 하는 것은 셋뿐이다. 커널 구현, 커널이 깔고 있는 논리(귀납적 구성 계산, Rocq 와 같은 계열), 그리고 세 개의 표준 공리(명제 외연성 propext, 몫 건전성 Quot.sound, 선택 공리 Classical.choice)다. 전술이 수만 줄이든 mathlib 이 백만 줄이든 그것들은 신뢰 범위에 들어가지 않는다. 틀린 항을 만들면 커널이 거부하기 때문이다.
구멍을 남기는 방법도 하나 있다. sorry 다. 증명을 지금 못 채우겠으니 일단 넘어가라는 표시이고, Lean 은 이것을 공리 sorryAx 를 쓴 것으로 기록한다. 그래서 어떤 정리가 어떤 공리에 의존하는지 물으면(#print axioms) sorry 가 들어 있는지가 그대로 드러난다. 직전 페이지의 '인증서'가 뜻하는 것은 세 표준 공리 외에 아무것도, 특히 sorry 를 쓰지 않고 커널을 통과했다는 것이다.
그 커널도 프로그램이라 버그가 있다. 올해 7월 25일 라마나 쿠마르가 AI 의 도움으로 만든 콜라츠 추측 '반증' 저장소를 올렸는데, sorry 가 하나도 없었다. 사흘 뒤 키란 고피나탄이 그것을 거짓(False)의 짧은 증명으로 줄여 커널 버그 #14576 으로 보고했다. 중첩 귀납 타입을 다룰 때 생성자 필드에 나타나지 않는 매개변수(유령 매개변수)를 빠뜨려 타입이 틀린 인자가 검사를 건너뛰는 구현 버그였고, 보고 1시간 뒤 수정이 올라왔다. 지 모우라의 사후 분석에서 눈여겨볼 대목은 둘이다. 하나는 그 반증이 독립 검사기 nanoda 의 일주일 전 판본도 통과했는데, nanoda 는 다른 곳에서 다른 버그를 갖고 있었다는 것이다. 두 구현의 서로 다른 버그 둘이 동시에 있어야 뚫리는 구조였고, 이후 comparator.live 는 nanoda 를 기본으로 함께 돌린다. 다른 하나는 메타프로그래밍을 제한하자는 제안을 그가 "잘못된 방향"이라 적은 것이다. 방어선은 위층을 조이는 것이 아니라 아래층이 스스로 거부하는 것이어야 한다.
| 믿어야 하는 것 | 믿지 않아도 되는 것 |
|---|---|
| 커널 구현(작다. 독립 재구현 nanoda·lean4lean 으로 교차 검사 가능) | 전술·자동화·엘라보레이터 전부 |
| 바닥 논리와 세 표준 공리 | mathlib 의 백만 줄(증명은 커널이 전부 다시 검사한다) |
| 정리의 진술이 내가 원한 그 정리라는 것(사람이 읽어야 한다) | 증명이 누구 손에서 나왔는가. 사람이든 모델이든 커널에게는 같은 항이다 |
mathlib: 정리를 적으려면 먼저 낱말이 있어야 한다#
Lean 자체에는 '소수'도 '위상 공간'도 없다. 그런 낱말은 라이브러리에서 온다. mathlib 은 2017년 시작된 공동체 라이브러리로, "순수 수학을 가능한 한 많이, 연구 수준까지 하나의 일관된 라이브러리로 디지털화한다"는 목표를 내걸고 있다. 통계 페이지 기준 현재 규모는 아래와 같다.
| 항목 | 값 |
|---|---|
| 정리 | 290,317 |
| 정의 | 137,995 |
| 기여자 | 772 |
| 줄 수 | 100만 줄 이상공식 사이트 표현. 2차 자료는 200만 줄 안팎 |
| 2022년 9월 당시 정리 수 | 99,0584년 만에 약 3배 |
이것이 직전 페이지의 한 문장을 설명한다. 형식화가 없는 쪽이 정수론과 대수기하에 몰려 있었던 이유는 결과가 약해서가 아니라, 그 분야의 정의가 mathlib 에 아직 얇게 깔려 있어 진술 자체를 Lean 으로 적을 수 없기 때문이다. 반대로 애런슨이 꼽은 이론 전산학 결과들은 유한 조합과 계산 모델 위에 서 있어 낱말이 다 있었다. 9월에 Anthropic 의 에이전트가 11일 만에 페르마의 마지막 정리를 1,300만 줄로 형식화했을 때 케빈 버저드가 "수학적으로 더해 주는 것이 없고 mathlib 에 합칠 수 없다"고 한 것도 같은 축이다. 커널을 통과하는 것과 공동체의 낱말로 쓰여 재사용되는 것은 다른 일이다.
직전 페이지의 '인증서'를 다시 읽기: Comparator 가 보증하는 셋과 안 하는 둘#
OpenAI 저장소의 형식화는 Lean FRO 가 만든 comparator 로 검사한다. 구조는 시험 감독과 같다. 출제자가 쥐고 있는 도전 파일(Challenge)에는 정리의 진술만 있고 증명 부분은
sorry 다. 응시자(모델)가 낸 해답 파일(Solution)은 같은 정리를 진짜 증명과 함께 다시 적는다. 도구는 해답을 격리 환경(landrun)에서 빌드하고, lean4export 로 뽑아낸 항을 커널에 다시 넣어 돌린다. README 가 적은 보증은 정확히 세 가지다.
| 보증하는 것 | 뜻 |
|---|---|
| 같은 진술 | 해답의 정리가 도전 파일의 정리와 "같은 것을 말한다". 진술에 쓰인 선언들이 두 환경에서 동일한지 비교한다. 모델이 증명하다가 진술을 몰래 약하게 고쳐 쓰는 길을 막는다 |
| 허용된 공리만 | JSON 설정에 적힌 공리(예: 세 표준 공리) 외에는 쓰지 않았다. sorry 는 공리로 기록되므로 여기서 걸린다 |
| 커널 통과 | 해답의 환경이 Lean 커널에 재생되어 받아들여졌다. 선택적으로 외부 커널을 더 붙일 수 있다 |
보증하지 않는 것도 README 에 적혀 있다. 첫째, 도전 파일의 진술이 당신이 원한 그 정리라는 것은 도구가 알 수 없다. 그래서 사람이 읽어야 할 것은 증명이 아니라 도전 파일 쪽이고, 직전 페이지에서 UGC 와 L=BPL 의 진술을 대조한 것이 그 일이다. 둘째, 정의 구멍(definition hole), 곧 해답이 정의까지 채워 넣어야 하는 문제는 "반드시 추가적인(아마도 사람인) 검증자로 확인해야 한다". 정리는 만족시키면서 정의를 출제 의도와 다르게 채울 수 있기 때문이다. 시험지에 맞춰 만들어진 가짜 꿀이 당 동위원소 검사를 50% 까지 섞어도 통과했다는 이야기가 있는데, Comparator 의 설계는 그 반대 방향이다. 시험지(진술)는 출제자가 쥐고 답안지만 받으므로 답안을 시험지에 맞춰 깎을 수는 있어도 시험지를 깎을 수는 없다. 다만 시험지 자체가 잘못 출제됐는지는 여전히 사람 몫이다.
그리고 세 보증 어디에도 '왜 참인가'는 없다. 커널은 플러그가 꽂혔는지만 본다. 직전 페이지의 "사람이 이해한 것은 아직 거의 없다"는 Lean 의 결함이 아니라 Lean 이 애초에 맡지 않은 일이다.
직접 만져 보려면#
설치 없이 브라우저에서 시작하는 길이 둘 있다. 커뮤니티 학습 페이지의 안내를 옮긴다.
| 자료 | 누구에게 | 무엇 |
|---|---|---|
| Natural Number Game | 처음인 사람 전부 | 브라우저 게임. 자연수의 덧셈·곱셈 성질을 rfl·rw·induction 같은 전술로 한 레벨씩 증명한다. 임페리얼 칼리지의 Lean 3 판을 Lean 4 로 옮긴 것. 위의 zero_add 가 여기 첫 월드다 |
| Lean 4 웹 에디터 | 코드 몇 줄 쳐 보고 싶은 사람 | 온라인판. 위의 t1 을 붙여 넣고 마지막 hp 를 hq 로 바꿔 보면 거부 메시지를 볼 수 있다 |
| Mathematics in Lean | 수학 쪽 | "수학 지향의 표준 참고서". mathlib 을 써서 실제 수학을 적는 법 |
| Theorem Proving in Lean 4 | 타입 이론 쪽 | "기초에 관심이 있다면 표준 참고서는 이것". 이 페이지의 t1 출처 |
| Functional Programming in Lean | 프로그래머 | 증명 말고 언어로서의 Lean |
| Zulip | 막혔을 때 | 공동체가 모이는 곳. 공개 열람 가능 |
읽고 나서 제일 오래 남은 것은 '큰 것은 믿지 않고 작은 것만 믿는다'는 배치였습니다. 자동화가 수만 줄로 불어나도 신뢰 범위는 한 줄도 안 늘어나고, 그 작은 심판이 틀릴 수 있다는 것까지 전제해서 두 번째 심판(nanoda)을 옆에 세워 둡니다. 7월의 버그가 두 심판의 서로 다른 구멍을 동시에 통과해야 했다는 대목에서, 이 설계가 말로만이 아니라 실제로 작동한 것을 봤습니다.
직전 페이지의 42% 라는 숫자가 이제 조금 다르게 읽힙니다. 그 300편은 '맞다'는 도장을 받은 것이지 '읽혔다'는 도장을 받은 것이 아니고, Lean 은 후자를 찍는 도구가 아닙니다. 그렇다면 남은 58% 와 그 300편의 '왜'는 결국 같은 줄에 서 있는 셈인데, 그쪽 줄에 기계가 없다는 게 이 이야기의 본체였습니다. 코드는 두 개만 넣었습니다. 더 넣으면 입문이 아니라 교재가 됩니다.
정리#
- Lean 은 함수형 프로그래밍 언어이자 증명 보조기다. 2013년 마이크로소프트 리서치에서 시작해 2021년 Lean 4 로 재작성됐고, 2023년부터 비영리 Lean FRO 가 개발한다.
- 원리는 커리-하워드 대응 한 줄이다. 명제는 타입, 증명은 그 타입의 값, 함의 p → q 는 p 의 증명을 q 의 증명으로 보내는 함수. 그래서 증명 검사가 타입 검사다.
- 전술(induction·rw·simp·grind)은 증명 항을 대신 짜 주는 도구이고 신뢰 범위 밖이다. 신뢰 범위는 작은 커널·바닥 논리·세 표준 공리뿐이며, sorry 는 공리로 기록돼 드러난다.
- 7월의 커널 버그 #14576 은 두 구현의 서로 다른 버그 둘을 동시에 요구했고 1시간 만에 수정됐다. 교훈은 위층을 조이는 것이 아니라 커널이 스스로 거부해야 한다는 것.
- mathlib 은 정리 29만·정의 13.8만·기여자 772명의 공동체 라이브러리다. 어떤 분야가 형식화되느냐는 그 분야의 낱말이 여기 깔려 있느냐에 달렸다.
- Comparator 는 같은 진술·허용 공리만·커널 통과 셋을 보증하고, 진술이 원한 정리인지와 정의 구멍의 의도는 보증하지 않는다. '왜 참인가'는 처음부터 Lean 의 일이 아니다.
출처#
- 접수된 요청의 바탕: AI 가 쏟아 낸 수학 증명 719편 중 기계가 검증한 것은 300편, 사람이 이해한 것은 아직 거의 없다(이 아카이브, 2026-10-09)
- 공식: lean-lang.org(Lean FRO), Theorem Proving in Lean 4, Propositions and Proofs 장(
t1·t2예제와 "proofs as terms" 설명의 출처) - 공동체: leanprover-community, Learning resources, mathlib statistics(2026-10-09 조회: 정리 290,317·정의 137,995·기여자 772), NNG4
- 검증 도구: leanprover/comparator README(세 가지 보증과 전제, definition hole 주의), openai/math lean/ComparatorChallenges
- 커널 버그: Postmortem for Kernel Soundness Bug #14576(Leonardo de Moura, 2026-08-01)
- 연혁: Lean (proof assistant)(Wikipedia, 2026-10-09 조회)
코드 예제 둘 중 첫째는 교재 원문 그대로이고, 둘째는 Natural Number Game 의 첫 월드 내용을 보조 정리 이름까지 포함해 리브가 옮겨 적은 것이라 게임의 실제 표기와 글자 단위로 같지는 않다. 공식 문서·사후 분석의 번역은 리브가 했으며 의역이 있다. mathlib 수치는 조회 시점 값이고 매일 바뀐다.