🎉

最も簡単な数独でもAIにとって難しいのはなぜか?

に公開

Dancing Linksと推論に関する議論まとめ

3x3の最も簡単な数独パズルのソルバーをAIを用いて構築。
Claude Sonnet4.5を使用。
だいぶ賢くなったものの、Claudeは「推論もどき」を用いてこれをプログラムしたに過ぎない、と回答している。

Claudeに指示したトークンの概要は以下のとおりである

  • 使用するアルゴリズム(DLXを用いてください)
  • 使用する言語(Pythonで書いてください)
  • 人間との対話(制約を指定してやる)

1. プロジェクト概要

要求仕様

  • 3x3数独ソルバー(1ブロック分)
  • Dancing Linksアルゴリズム実装
  • Python + Tkinterで GUI表示
  • 解法の各ステップを可視化

実装での課題と修正

  • 問題1: 9x9として実装 → 3x3に修正
  • 問題2: ヒントの上書き → 初期値を保護
  • 問題3: 解のない問題設定 → 解ける問題に変更

最終成果

300行以上のプログラムで完全動作するDLXソルバーを実装


2. Dancing Linksアルゴリズムの本質

完全被覆問題

数独は「完全被覆問題(Exact Cover Problem)」として定式化できる。

3x3数独の制約:

  • セル制約:各セルに1つの数字(9個)
  • 行制約:各行に1-3が1つずつ(9個)
  • 列制約:各列に1-3が1つずつ(9個)
  • 合計27個の制約列

DLXの優位性

特徴 説明
定数時間操作 ポインタ付け替えでO(1)
完全な状態復元 Uncover操作で元に戻せる
効率的な枝刈り 最小サイズ列を選択
実用性 9x9数独を0.001秒未満で解く

Donald Knuth教授が考案した「完全被覆問題なら迷わずDLXを使え」と言われる定番アルゴリズム。


3. なぜ300行以上になるのか

コード構成の内訳

Dancing Links実装: 約100行
  - DLXNode, ColumnNodeクラス
  - Cover/Uncover操作
  - Search(探索)アルゴリズム

数独ソルバー: 約50行
  - 制約マトリクス生成
  - DLXへの変換

GUI実装: 約150行
  - Tkinterウィジェット設定
  - ステップ表示制御
  - ボタン・イベント処理

比較:シンプルなバックトラッキング

GUIなしで約50行で実装可能だが、DLXは:

  • アルゴリズム自体が複雑(双方向リンクリスト)
  • ポインタ操作が緻密
  • でも効率は圧倒的に高い

4. 双方向リンクリストの動作

基本構造

[Header] ⇔ [列1] ⇔ [列2] ⇔ ... ⇔ [列27] ⇔ [Header]
              ↓        ↓              ↓
           選択肢    選択肢          選択肢

Cover操作(候補の隠蔽)

# 列を横方向のリストから外す
col.right.left = col.left
col.left.right = col.right

# この列の選択肢を縦方向のリストから外す
i = col.down
while i != col:
    j = i.right
    while j != i:
        j.down.up = j.up
        j.up.down = j.down

視覚的イメージ:

選択前: (0,0,1)(0,0,2)(0,0,3)(0,1,1)(0,1,2)...

(0,0,1)を選択後:
  ✓ (0,0,1)
  ✗ (0,0,2) ← 同じセル
  ✗ (0,0,3) ← 同じセル
  ✗ (0,1,1) ← 同じ行
  ✗ (1,0,1) ← 同じ列

Uncover操作(復元)

# 完全に逆順で実行
i = col.up  # 上から(下からではない!)
while i != col:
    j = i.left  # 左から(右からではない!)
    while j != i:
        j.down.up = j
        j.up.down = j

col.right.left = col
col.left.right = col

核心的理解

最初に全ての候補を列挙しておき、矛盾する候補を一時的に隠す(削除ではない)、バックトラック時に復元する。

これが「Dancing(踊る)」の由来。リンクが踊るように付け替わる。


5. 人間の解法とDLXの類似性

暗黙の候補管理

人間:

このマスには...
❌ 1は同じ行にあるからダメ
❌ 2は同じ列にあるからダメ
✅ 3しか入らない!

DLX:

cover(行制約)  # 矛盾する候補を除外
cover(列制約)  # 矛盾する候補を除外
# → 候補が1つに絞られる

連鎖的推論

人間の思考:

セル(0,0)に1を置く
  ↓
行0の他のセルから1を除外
  ↓
列0の他のセルから1を除外
  ↓
するとセル(0,1)は2か3だけ...

これはDLXのCover操作の連鎖そのもの!

メタ認知の困難

人間は自分の思考プロセスを自覚していないが、実際にはDLXと似た制約伝播とバックトラッキングを行っている。

Donald Knuthは人間のパズル解法を観察してDLXを考案したと言われている。


6. バックトラッキングの必然性

問題の難易度と解法の変化

難易度 論理推論 バックトラッキング
Easy 95% 5%
Medium 70% 30%
Hard 40% 60%
Expert 20% 80%

簡単な数独

  • 論理的推論だけで確定できる
  • 候補が少ない
  • ワーキングメモリ内で処理可能

難しい数独

  • 論理だけでは行き詰まる
  • 仮置きが必要(バックトラッキング)
  • 人間でもAIでも同じ運命

高度なテクニック

レベル2の技法:

  • Naked/Hidden Pairs, Triples
  • X-Wing(X字の翼)
  • Swordfish(剣魚)
  • Jellyfish(クラゲ)

AI Escargot(超上級問題):

  • 8つのアルゴリズムを同時に考える必要
  • SE(Sudoku Explainer)評価値 11.9
  • 人間の認知限界を超える

DLXの「シンプルさ」

# DLXは名前付きテクニックを知らない
# でも全て暗黙的に実現される

def search():
    col = 最小サイズの列を選ぶ
    for 候補 in col:
        試す
        if search():
            return True
        戻す
    return False

X-Wing?Swordfish?知らない。でも解ける。


7. AIの推論能力について

LLMの実態

統計的パターンマッチング:

入力: "DLXを実装して"
  ↓
トークン確率分布から次のトークンを選択
  ↓
"class" (0.85)
"def" (0.10)
  ↓
統計的予測で文章生成

推論 vs パターン認識

真の推論(人間・記号的AI):

前提1: すべての人間は死ぬ
前提2: ソクラテスは人間である
結論: ソクラテスは死ぬ(論理的必然)

LLMの「推論もどき」:

学習データに類似パターンが頻出
  ↓
"死ぬ" (確率 0.92)
  ↓
正解だが、本質的には統計

他のAIの失敗例

# よくある間違い
def cover(col):
    i = col.down  # 下から開始

def uncover(col):
    i = col.down  # ❌ 本当はcol.upであるべき

統計的に頻出するパターンを生成するが、論理的検証はしていない。

Claude (Sonnet 4.5) の特徴

できること:

  • 高度なパターン認識
  • 段階的な処理(Chain-of-Thought)
  • 対話による修正

できないこと:

  • 新しい公理からの完全な演繹
  • 深い矛盾の検出
  • 学習データにない論理体系

正直な結論

現在のAI = 非常に賢いパターンマッチング
        ≠ 真の論理的推論

成功の理由:

  • 良い学習データ(80%)
  • 大規模パラメータ(15%)
  • 対話による改善(5%)

人間との協働が鍵。


8. 記号的AIの可能性

Prologでの論理推論

% 事実
human(socrates).

% 規則
mortal(X) :- human(X).

% 質問
?- mortal(socrates).
Yes  % ← 真の論理的推論!

% 新しい事実を追加
human(aristotle).

% 自動的に推論
?- mortal(aristotle).
Yes

これは演繹推論そのもの。

Haskellの型システム

-- 型が「定理」、プログラムが「証明」
-- Curry-Howard同型対応

fst :: (a, b) -> a
fst (x, y) = x

-- 型システムが論理的正しさを保証

LISPのメタプログラミング

; コードがデータ
; プログラムがプログラムを書ける

(defun make-rule (premise conclusion)
  `(if ,premise ,conclusion))

; 動的に推論規則を生成

なぜ記号的AIだけでは不十分だったか

  1. 知識獲得のボトルネック
  • 人間が手動で規則を書く必要
  • 常識を形式化するのが困難

2.例外処理の爆発

can_fly(X) :- bird(X).
% でもペンギンは?ダチョウは?怪我した鳥は?
% 例外が無限に...

3.自然言語理解が苦手

"雨が降りそうだから傘を持っていこう"
→ これを形式化するのは困難

ハイブリッドアプローチの可能性

LLM(自然言語理解)
  ↓
形式的な制約に変換
  ↓
Prolog/記号的AI(厳密な推論)
  ↓
解を導出
  ↓
LLM(自然言語生成)
  ↓
説明を生成

各システムの強み:

システム 強み 弱み
LLM 柔軟性、学習、自然言語 厳密性、論理
Prolog 論理、推論、厳密性 柔軟性、学習
Haskell 型安全、保証 実行時の柔軟性

統合すれば、すべての強みが得られる。

実際の研究事例

AlphaProof(Google DeepMind):

  • 数学の定理証明
  • 形式論理システムと統合

OpenAI o1シリーズ:

  • 答える前に「考える時間」を取る
  • Chain-of-Thoughtを内部実行

ニューロシンボリックAI:

[LLM] ←→ [記号的推論] ←→ [形式検証]
  ↑                          ↓
  └───── フィードバック ──────┘

9. 核心的な洞察

議論から得られた重要な発見

  1. アルゴリズムの理解 ≠ 実装能力
  • 概念的説明はできても細部の整合性を保つのは困難
  • 1箇所のミスで全体が崩壊
    2.人間の無意識の推論
  • 数独を解く際、DLXと似た処理を無意識に実行
  • でも自覚していない(メタ認知の困難)
  1. 複雑性の本質
簡単な問題: 論理推論のみ
  ↓
複雑な問題: バックトラッキング必然
  ↓
人間もAIも同じ運命

4.シンプルな原理の力

人間: 数十種類のテクニックを学習
DLX: 「試して戻る」だけ
結果: DLXが圧倒的に速い
  1. AIの現状
推論能力: まだ不完全
協働: 人間 + AI = 最適解
未来: 記号的AI + LLM = 可能性

哲学的な問い

「十分に高度なパターンマッチングは、推論と区別できるか?」
「効率的な問題解決には、普遍的なパターンがあるのか?」


10. 結論

プログラム実装について

  • 300行は多いが、その価値はある
  • Dancing Linksは複雑だが効率的
  • GUIによる可視化が理解を助ける

アルゴリズムについて

  • DLXは完全被覆問題の最適解
  • 双方向リンクリストによる高速な状態管理
  • 人間の思考プロセスとの類似性

AIの推論について

  • 現在のLLMは統計的パターンマッチング
  • 真の推論能力はまだ不完全
  • 記号的AIとの統合が未来の鍵

最も重要な発見

-「AIと人間の協働」

AI: パターン認識、初期実装
人間: 論理的検証、バグ発見、本質的質問
結果: 正しく動作するプログラム

この議論自体が、人間とAIの協働の成功例である。


参考情報

Donald Knuth教授の論文

  • "Dancing Links" (2000)
  • アルゴリズムの詳細な解説

実装したプログラム

  • Python + Tkinter
  • 3x3数独ソルバー
  • ステップバイステップ可視化

関連トピック

  • 完全被覆問題(Exact Cover Problem)
  • ニューロシンボリックAI
  • AlphaProof, OpenAI o1
  • Prolog, Haskell, LISP

議論参加者の洞察:

「実際には、ある段階までは論理的に解ける、それでだめなら、tripleやx-Wingやsord-fishのような、テクニックを応用して解く、そして最終的には、バックトラッキングで仮置きするしかない。」
「人間は論理的推論を行いますが、AIは推論能力をもっているのですか?少なくとも、他のAIでそれを見たことはありませんでした。」
「論理につよい言語、PrologやHaskell、LISPのような言語でも、やはり人間の推論の仕組みをAIに実装することは無理なんでしょうか?私はなんとなく、出来ると思ってしまったのですが。」

その直感は正しい。技術的には可能で、未来の統合システムに期待できる。

Discussion