feat(mir): Loop Canonicalizer Phase 3 - skip_whitespace pattern recognition

## Summary
skip_whitespace パターンを Skeleton→Decision で認識可能に。
dev-only 観測で chosen=Pattern3IfPhi / missing_caps=[] を固定。

## Changes
- src/mir/loop_canonicalizer/mod.rs:
  - try_extract_skip_whitespace_pattern() 追加
    - loop(cond) { ... if check { p = p + 1 } else { break } } パターン認識
    - carrier name, delta, body statements を抽出
  - canonicalize_loop_expr() 拡張(skip_whitespace 対応)
    - Pattern3IfPhi 成功時は RoutingDecision::success 返却
    - Skeleton に HeaderCond, Body, Update ステップ追加
    - CarrierSlot に Counter role 設定
    - ExitContract に has_break=true 設定
  - Phase 3 unit tests 追加
    - test_skip_whitespace_pattern_recognition: 基本パターン
    - test_skip_whitespace_with_body_statements: body 付きパターン
    - test_skip_whitespace_fails_without_else: else なし失敗
    - test_skip_whitespace_fails_with_wrong_delta: 減算パターン失敗
  - Phase 2 obsolete tests 削除
- src/mir/builder/control_flow/joinir/routing.rs:
  - Debug 出力拡張(chosen pattern 表示)

## Tests
- cargo test --release --lib loop_canonicalizer::tests: PASS(11 tests)
- cargo test --release --lib: PASS(1044 tests, 退行なし)
- HAKO_JOINIR_DEBUG=1 test_pattern3_skip_whitespace.hako:
  - chosen=Pattern3IfPhi 
  - missing_caps=[] 

## Validation
-  dev-only 観測(HAKO_JOINIR_DEBUG=1)のときだけログ出力
-  フラグ OFF 時は完全不変
-  skip_whitespace パターンで SUCCESS 固定
-  unit tests で全パターン固定

Phase 137-3 complete
This commit is contained in:
nyash-codex
2025-12-16 05:38:18 +09:00
parent e8d93f107c
commit a0009d474d
7 changed files with 405 additions and 108 deletions

View File

@ -42,7 +42,7 @@ JoinIR の箱構造と責務、ループ/if の lowering パターンを把握
- `docs/development/current/main/design/joinir-design-map.md`
5. Loop Canonicalizer設計 SSOT
- `docs/development/current/main/design/loop-canonicalizer.md`
- 実装Phase 137-1: `src/mir/loop_canonicalizer/mod.rs`
- 実装Phase 137-2: `src/mir/loop_canonicalizer/mod.rs`
6. MIR BuilderContext 分割の入口)
- `src/mir/builder/README.md`
7. Scope/BindingIdshadowing・束縛同一性の段階移行

View File

@ -27,11 +27,11 @@
- Phase 136: MirBuilder の Context 分割を完了し、状態の SSOT を Context に一本化。
- 詳細: `docs/development/current/main/phases/phase-136/README.md`
## 20251216Phase 1371(短報)
## 20251216Phase 1372(短報)
- Loop Canonicalizer の Phase 1型/語彙の SSOTを導入routing/lowering には未介入)。
- Loop Canonicalizer の Phase 2dev-only 観測)まで完了(既定挙動は不変)。
- 設計 SSOT: `docs/development/current/main/design/loop-canonicalizer.md`
- 実装: `src/mir/loop_canonicalizer/mod.rs`
- 実装: `src/mir/loop_canonicalizer/mod.rs`+ 観測: `src/mir/builder/control_flow/joinir/routing.rs`
## 20251214現状サマリ

View File

@ -1,6 +1,6 @@
# Loop Canonicalizer設計 SSOT
Status: Phase 1 done型定義まで)
Status: Phase 2 donedev-only 観測まで)
Scope: ループ形の組み合わせ爆発を抑えるための “前処理” の設計fixture/shape guard/fail-fast と整合)
Related:
- SSOT (契約/不変条件): `docs/development/current/main/joinir-architecture-overview.md`
@ -160,12 +160,12 @@ pub enum CarrierRole {
## 実装の入口(現状)
Phase 1(型定義のみ)の実装はここ:
実装(Phase 12はここ:
- `src/mir/loop_canonicalizer/mod.rs`
注意:
- ここは「型と語彙の SSOT」を置く場所で、routing/lowering にはまだ介入しない
- Phase 2 以降で `canonicalize(loop_ast) -> (LoopSkeleton, RoutingDecision)` を導入し、dev-only で観測から始める。
- Phase 2 で `canonicalize_loop_expr(...) -> Result<(LoopSkeleton, RoutingDecision), String>` を導入し、JoinIR ループ入口で dev-only 観測できるようにした(既定挙動は不変)
- 観測ポイントJoinIR ループ入口): `src/mir/builder/control_flow/joinir/routing.rs``joinir_dev_enabled()` 配下)
## Capability の語彙Fail-Fast reason タグ)
@ -197,7 +197,7 @@ Canonicalizer の判定結果は `RoutingDecision` に集約し、以下に流
```rust
pub struct RoutingDecision {
/// 選択された PatternNone = Fail-Fast
pub chosen: Option<LoopPattern>,
pub chosen: Option<LoopPatternKind>,
/// 不足している Capability のリスト
pub missing_caps: Vec<&'static str>,
@ -206,7 +206,7 @@ pub struct RoutingDecision {
pub notes: Vec<String>,
/// error_tags への追記contract_checks 用)
pub error_tags: Vec<ErrorTag>,
pub error_tags: Vec<String>,
}
```

View File

@ -1,7 +1,7 @@
# Phase 137: Loop Canonicalizer前処理 SSOT
## Status
- 状態: 🔶 進行中Phase 1 完了)
- 状態: 🔶 進行中Phase 2 完了)
## Goal
- ループ形の組み合わせ爆発を抑えるため、`AST → LoopSkeleton → (capability/routing)` の前処理を SSOT 化する。
@ -15,11 +15,17 @@
- `RoutingDecision` / capability tags`CAP_MISSING_*`
- 注意: Phase 1 は「型と語彙」のみ。routing/lowering にはまだ介入しない。
## Phase 2: dev-only 観測の導入
## Phase 2完了: dev-only 観測の導入
- 目標: ループ入口で `LoopSkeleton``RoutingDecision` を生成し、dev-only で観測できるようにする。
- 既定挙動: 不変dev-only の観測から開始
- スイッチ: 新しい env を増やさず、`joinir_dev_enabled()`(既存)配下で有効化する。
- 入口:
- Canonicalize: `src/mir/loop_canonicalizer/mod.rs``canonicalize_loop_expr`
- 観測ポイント: `src/mir/builder/control_flow/joinir/routing.rs``joinir_dev_enabled()` 配下)
- 既定挙動: 不変dev-only 観測のみ)
## Phase 3: Pattern 検出Skeleton→Decision の精密化)
- 目標: `skip_whitespace` を Skeleton から安定に識別し、`RoutingDecision.chosen``missing_caps` を期待通りに固定する。
- 注意: routing/lowering の変更は dev-only の観測結果が固まってから。
## SSOT