考察ノート:Knuthの"Claude's Cycle"問題をLean4で検証する(1):Lean4挑戦の幕開け
【注】本シリーズは(1)~(9)まで続く、最後には証明が完成した、かもしれな。
Knuth先生Opus4.6に驚く
3月3日、スタンフォード大学のクヌース教授(TeXや文芸的プログラミングで著名である)が、Opeus4.6が、クヌース教授がこ数週間取り組んでいた、(数学上の)予想(著書"The Art of Programming"に掲載されているオープンな問題)を解いたという論文が公開された。
ペーパーはこちらである。
https://www-cs-faculty.stanford.edu/~knuth/papers/claude-cycles.pdf
課題に対して、m=3までは自分でも解けていたけども、これを一般化しようとして、行き詰った。友達のFilip氏が、Claudeをつかって、この課題に取り組みだしたのを、クヌース教授は横で見ているという設定。
そして、Claudeが生成したPythonを使って、m=3~101までこの予測が正しいことを示したというのだった。そこからクヌース教授の証明が開始する。
そうこうしているうちに、証明できたそうであるが、しかしこの過程を通じて、クヌース教授の生成AIに対する意見を改めなければならないとまで言わせた。これ(Claudeと人との間のコラボレーション)はcreativeなproblem solvingであるとまでいう。
ChatGPTに聞いてみた。
途中の過程は、省略して最終的には、以下を示したと。
そして、この課題を解いた話の、本質は、
よくわからんな。
ChatGPTにLean4の証明を生成をお願いすると、概略のlean4、sorryが沢山を作ってくれた、完全化ができるというのでやってもらう。
Lean4webではいろいろエラーがでてしまう。
Opus 4.6にお願いした。
添付のknuthの、オープン問題を解いたという記事ついてよく読んで、まずはこの問題定義とOpus4.6がどのように解いたのかを説明した上で、この証明をlean4でたどってほしい。
成果物として、ClaudeCycle.lean, Lemma.leanを生成してくれたが、lake環境をインストールできなかったので、実行はできてない。
Lean 4のインストールがネットワーク制限で不可能なため、ローカルで検証可能なLean 4プロジェクトファイルを作成し、併せてPythonでの構成検証スクリプトも用意します。
Leanの証明は書いてくれたけども、検証とかsorryの展開とかはやってくれない。そうskillが必要で、ここからはClaude Codeにバトンタッチだ。
Lean4-skillsで解いてみる
出来上がったleanファイルをローカルフォルダに入れて、Claude Code から、証明をおこなうようにお願いしてみる。すでにLean4-skillがインストールされているので、leanの証明が実現できるはずである。
readme.txtを読んで、*.leanの証明を完成して。
readme.txtには、ChatGPTの説明を添付する。
Lean 4形式化 (ClaudeCycles.lean) は以下を含みます:
定義: 頂点 Fin m × Fin m × Fin m、方向型 Dir、ファイバーインデックス fiberIndex、バンプ関数 bump、3つのサイクルの方向関数 dir0/dir1/dir2
主要定理の文: cycle0_hamiltonian, cycle1_hamiltonian, cycle2_hamiltonian, 統合定理 claude_decomposition
証明の骨格: Knuthの証明に沿った補題群(cycle0_i_change_condition, checkpoints0_injective, i0_block_complete, block_exit_bumps_i 等)
一般化可能性の定義: Knuthの「Claude-like分解」の概念を ClaudeLike 構造体として形式化
核心的な数学的ステップ(gcd(2,m)=1 による全射性、各i-ブロック内の完全性)は sorry のまま残していますが、補題 Lemmas.lean に証明戦略の詳細な記述を付けています。
テスト (13テスト全通過):
ファイバー進行、方向の置換性、i変化条件、チェックポイント被覆、ブロック連続性、ハミルトン性(m=3〜17)、弧の分割、Knuth論文の具体例との照合、非一般化可能サイクルの検証
Lean 4はこの環境にインストールできなかったため、ローカルで lake build して型検査することをお勧めします。Mathlibの ZMod と Fin の算術補題を使えば、sorry の多くは段階的に埋められるはずです。最初に、lakeのプロジェクト設定をして、Mathrlibを取得、ビルドするとエラーまるけ。
ここから、lean4-skillをつかって、エラーとsorryを対応していゆく、
しかし、エラーが多すぎ、ファイルを書き直すことに、、
そして、sorry付ののleanファイルはコンパイル成功、これからLean4エージェント?をつかって、並行して証明を進める。
2つのエージェントが別のファイルを証明を平行して動かしている。
エージェント1が完了ということで、ClaudeCycle.leanは証明できたのか。それから、Lemma.leanにある残りのsorryをやっつけるために証明を継続。
さすがに時間がかかるし、利用料も100%を突破、追加金額モードに突入。。
確かに、ClaudeCycle.leanのtheoremは、”Goal accomplished"になっている。
Lemma.leanの証明が終わらない。。毒を食らわば皿まで、待ってみよう。。。
なんか、agentが、timeoutを繰り返しているような。。。
追い銭が$7を超えたらやめよう。。
エージェントは終了したが、sorryが残っている。。
証明打ち切り?
sorryは残っているけども、ここで終了。証明完了したtheoryは以下の通り。
一方sorryが残ったのは、
この5つを証明するには、数百行の証明追加が必要。どうせKnuth論文で確認されているから、ここはsorryでいいでしょうというのがOpus4.6の見解。
なぜか、autoprove起動
と、ここまできたところで、pluginのautoproveが起動、、、いやん、数百行の証明やるのか。。
なんか終わらないな。。
以下にあるようなtheoremが証明されていない(ClaudeCycle.lean中)。
これらは、Lemma.leanで証明されるはずである。スケッチとして残っている。
OUTPUT TOKENが設定を超えてしまった模様。追い銭も$9.66になった。ここで打ち切り。
最後に証明の解説を作ってもらった。
# ClaudeCycles.lean 解説
Don Knuth の論文 "Claude's Cycles" (2026年2月28日) を Lean 4 で形式化したものです。
---
## 1. 問題設定
**ケイリー有向グラフ** を考えます。
- **頂点**: $m^3$ 個の三つ組 $(i, j, k)$(各座標は $0 \le i, j, k < m$、つまり `Fin m`)
- **弧(有向辺)**: 各頂点から 3 本の弧が出る
- $(i,j,k) \to (i{+}1, j, k)$ … i 方向のバンプ
- $(i,j,k) \to (i, j{+}1, k)$ … j 方向のバンプ
- $(i,j,k) \to (i, j, k{+}1)$ … k 方向のバンプ
- (加算はすべて $\bmod m$)
**目標**: 奇数 $m \ge 3$ のとき、全 $3m^3$ 本の弧を **3 本のハミルトン閉路** に分解できることを示す。
---
## 2. 基本定義(セクション 1)
```lean
abbrev Vertex (m : ℕ) := Fin m × Fin m × Fin m
inductive Dir where
| bumpi | bumpj | bumpk
```
- `Vertex m` : グラフの頂点($\mathbb{Z}/m\mathbb{Z}$ の三つ組)
- `Dir` : バンプの方向(i, j, k の 3 種類)
### ファイバーインデックス
```lean
def fiberIndex (m : ℕ) [NeZero m] (v : Vertex m) : Fin m :=
v.1 + v.2.1 + v.2.2 -- s = i + j + k (mod m)
```
$s = (i + j + k) \bmod m$ を **ファイバーインデックス** と呼びます。どの方向にバンプしても $s$ は 1 増えるため、軌道は $s = 0, 1, 2, \ldots, m{-}1, 0, 1, \ldots$ と巡回します。
### バンプ関数
```lean
def bump (m : ℕ) [NeZero m] (v : Vertex m) (d : Dir) : Vertex m
```
方向 `d` に応じて対応する座標を $+1 \pmod{m}$ する関数です。
---
## 3. Claude の方向関数(セクション 2)
Knuth の論文の核心は、各頂点で 3 方向のうちどれを選ぶかを定める **方向関数** `dir0`, `dir1`, `dir2` です。
### dir0 の定義
| ファイバー $s$ | 条件 | 選ぶ方向 |
|:-:|:-:|:-:|
| $s = 0$ | $j = m{-}1$ | bumpi |
| $s = 0$ | $j < m{-}1$ | bumpk |
| $s = m{-}1$ | $i > 0$ | bumpj |
| $s = m{-}1$ | $i = 0$ | bumpk |
| $0 < s < m{-}1$ | $i = m{-}1$ | bumpk |
| $0 < s < m{-}1$ | $i < m{-}1$ | bumpj |
`dir1`, `dir2` も同様の場合分けで定義され、3 関数合わせて各頂点で `{bumpi, bumpj, bumpk}` の置換を成します。
### 軌道
```lean
def successor (m : ℕ) [NeZero m] (dirFn : Vertex m → Dir) (v : Vertex m) : Vertex m :=
bump m v (dirFn v)
def orbit (m : ℕ) [NeZero m] (dirFn : Vertex m → Dir) (start : Vertex m) :
(n : ℕ) → Vertex m
| 0 => start
| n + 1 => successor m dirFn (orbit m dirFn start n)
```
`orbit m (dir0 m) start n` は、頂点 `start` から `dir0` に従って $n$ ステップ進んだ先の頂点です。
---
## 4. 証明済みの定理
### fiber_advances
```lean
theorem fiber_advances : fiberIndex m (bump m v d) = fiberIndex m v + 1
```
どの方向にバンプしてもファイバーインデックスが $+1$ されることの証明。Fin の加算の結合律・交換律で直ちに従います。
### directions_are_permutation
```lean
theorem directions_are_permutation (hm : m ≥ 3) (v : Vertex m) :
({dir0 m v, dir1 m v, dir2 m v} : Finset Dir) = {Dir.bumpi, Dir.bumpj, Dir.bumpk}
```
任意の頂点で `dir0`, `dir1`, `dir2` が 3 方向の置換を成すことの証明。6 通りの場合分け($s$ の値 × 座標条件)を `split_ifs` と `fin_cases` で網羅します。
### bump_injective
```lean
theorem bump_injective (d : Dir) :
Function.Injective (fun v : Vertex m => bump m v d)
```
固定方向へのバンプが単射であること。Fin の加算の単射性から従います。
### successor_dir0/1/2_injective / bijective
```lean
theorem successor_dir0_injective (hm : m ≥ 3) :
Function.Injective (successor m (dir0 m))
```
各方向関数による後続関数が有限集合上の単射 → 全射 → 全単射であることの証明。2 頂点の像が一致したとき、同じ方向なら `bump_injective` で即決、異なる方向ならファイバーインデックスの一致から矛盾を導きます。
### mul2_bijective_odd
```lean
theorem mul2_bijective_odd (hm : m % 2 = 1) (hm_pos : 0 < m) :
Function.Bijective (fun x : Fin m => ⟨(2 * x.val) % m, ...⟩)
```
$m$ が奇数のとき、$x \mapsto 2x \pmod{m}$ が全単射であること。$\gcd(2, m) = 1$ の核心的算術補題です。`Nat.Coprime` と `dvd_of_dvd_mul_left` を使って証明しています。
### checkpoints0_injective
```lean
theorem checkpoints0_injective (hm_odd : m % 2 = 1) (hm_ge : m ≥ 3) :
Function.Injective (checkpoint0 m)
```
$i = 0$ ブロックのチェックポイント列が単射であること。$k$ 成分が $2t \pmod{m}$ の形なので、`mul2_bijective_odd` の単射性に帰着します。
### cycle0_i_change_condition
```lean
theorem cycle0_i_change_condition (v : Vertex m) :
dir0 m v = Dir.bumpi ↔ (fiberIndex m v).val = 0 ∧ v.2.1.val = m - 1
```
Cycle 0 で座標 $i$ が変わる(bumpi が選ばれる)のは $s = 0$ かつ $j = m{-}1$ のときに限ること。
### block_exit_bumps_i
```lean
theorem block_exit_bumps_i (hm_ge : m ≥ 3) (i : Fin m) (hi : i.val < m - 1) :
dir0 m exitVertex = Dir.bumpi
```
各 $i$-ブロックの出口で bumpi が選ばれ、次の $i$-ブロックへ遷移すること。
---
## 5. 未証明の定理(sorry)
以下の 5 定理は `sorry` のまま残っています。いずれも軌道の完全性に関する深い組合せ論的議論を要します。
### i0_block_complete(321 行目)
$i = 0$ ブロック内で、チェックポイント $(0, j_0, k_0)$ からの軌道が $m^2$ ステップで全ての $(0, j, k)$ を訪問すること。
**証明の方針**: ファイバー $s = 1, 2, \ldots, m{-}1$ を順に巡り $j$ を掃引、$s = 0$ に戻るたびに $k$ が 2 ずつシフト。$\gcd(2, m) = 1$ より全ての $k$ 値を網羅。
### last_block_complete(366 行目)
$i = m{-}1$ ブロックについて同様の完全性。中間ファイバーでは $i = m{-}1$ なので bumpk が選ばれる点が異なります。
### cycle0_hamiltonian(396 行目)
Cycle 0 全体のハミルトン性。$m$ 個のブロック($i = 0, 1, \ldots, m{-}1$)をつなぎ合わせて $m^3$ 頂点すべてを訪問する閉路を成すこと。
### cycle1_hamiltonian(513 行目)、cycle2_hamiltonian(520 行目)
Cycle 1, Cycle 2 についても同様のハミルトン性。`dir1`, `dir2` の場合分けが異なるだけで、証明構造は Cycle 0 と類似します。
---
## 6. 統合定理(セクション 7)
```lean
theorem claude_decomposition (hm_odd : m % 2 = 1) (hm_ge : m ≥ 3) :
(∃ start₀, ...) ∧ (∃ start₁, ...) ∧ (∃ start₂, ...) ∧
(∀ v, {dir0 m v, dir1 m v, dir2 m v} = {bumpi, bumpj, bumpk})
```
3 つのサイクルがそれぞれハミルトン閉路であり(前半 3 条件)、かつ各頂点で 3 方向の置換を成す(最後の条件)ことを主張します。後者により各弧はちょうど 1 つのサイクルに属し、全 $3m^3$ 弧の分解が完成します。
---
## 7. 補助ファイル
### Lemmas.lean
`ClaudeCycles.lean` を import し、以下を提供します:
- `fiber_advances_detail`: `fiber_advances` の成分明示版
- `two_mul_perm`: $x \mapsto 2x \pmod{m}$ が全単射(`mul2_bijective_odd` の再証明)
- `checkpoint_j_values_surjective`: チェックポイントの $j$ 値が全射
- 方向関数の 6 ケースの詳細な表(コメント)
- $m = 3$ での軌道の具体的な 27 ステップの列挙
---
## 8. ファイル構成
| ファイル | 内容 |
|:--|:--|
| `ClaudeCycles.lean` | 主定義・主定理(約 567 行) |
| `Lemmas.lean` | 補助証明・計算検証(約 167 行) |
| `lakefile.toml` | Lake ビルド設定(Mathlib 依存) |
| `lean-toolchain` | Lean バージョン(v4.29.0-rc2) |
| `readme.txt` | プロジェクト概要 |
---
## 9. ビルド方法
```bash
lake update # Mathlib 取得
lake build # 全ファイルをビルド
```
現在のビルドは sorry 警告 5 件を除き正常完了します(3108 ジョブ)。
とりあえず、成果物をここに供養する。証明は不完全である。



コメント