feat(joinir): Phase 188.3 - Pattern6 (NestedLoopMinimal) 選択ロジック実装

## Phase 188.3 進捗: Phase 2 完了 (6/13 tasks)

### 実装完了 

**Phase 1: Fixture作成**
- apps/tests/phase1883_nested_minimal.hako 追加
  - Add/Compare のみ(乗算なし)
  - 期待 exit code: 9 (3×3 nested loops)
- 既存 lowering で fallback 動作確認

**Phase 2: 選択ロジック (SSOT)**
- LoopPatternContext に step_tree_max_loop_depth フィールド追加
- choose_pattern_kind() に Pattern6 選択ロジック実装:
  1. Cheap check (has_inner_loop)
  2. StepTree 構築 (max_loop_depth 取得)
  3. AST validation (is_pattern6_lowerable)
- pattern6_nested_minimal.rs モジュール作成 (stub)
- LOOP_PATTERNS に Pattern6 entry 追加
- **検証**: Pattern6 が正しく選択される 

### 設計原則 (確認済み)

1. **Fail-Fast**: Pattern6 選択後は Ok(None) で逃げない
2. **outer 変数 write-back 検出 → validation false** (Phase 188.4+)
3. **最小実装**: inner local だけ、Pattern1 モデル二重化
4. **cfg! 依存なし**: production で動作

### 検証結果

```
[choose_pattern_kind] has_inner_loop=true
[choose_pattern_kind] max_loop_depth=2
[choose_pattern_kind] is_pattern6_lowerable=true
 Pattern6 SELECTED!
```

Stub からの期待エラー:
```
[ERROR]  [Pattern6] Nested loop lowering not yet implemented
```

### 次: Phase 3 (Lowering 実装 - 推定4時間)

残りタスク:
- Phase 3-1: AST 抽出ヘルパー
- Phase 3-2: Validation ヘルパー
- Phase 3-3: Continuation 生成 (outer_step, inner_step, k_inner_exit)
- Phase 3-4: fixture が exit=9 を返すことを検証

### 変更ファイル

**新規**:
- apps/tests/phase1883_nested_minimal.hako
- src/mir/builder/control_flow/joinir/patterns/pattern6_nested_minimal.rs
- docs/development/current/main/phases/phase-188.{1,2,3}/README.md

**変更**:
- src/mir/builder/control_flow/joinir/routing.rs (Pattern6 選択)
- src/mir/builder/control_flow/joinir/patterns/router.rs (Context 拡張)
- src/mir/builder/control_flow/joinir/patterns/mod.rs (module 宣言)

🎯 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-27 05:45:12 +09:00
parent 229553f7a4
commit a2c5fd90fe
32 changed files with 1780 additions and 42 deletions

View File

@ -0,0 +1,104 @@
# Phase 188.3: Nested loop lowering (1-level) — make Pattern 6 real
**Date**: TBD
**Status**: Planning (docs-first)
**Prereq**: Phase 188.2 Option A is complete (StepTree depth SSOT + strict Fail-Fast)
---
## Goal
`max_loop_depth == 2`1-level nested loop**JoinIR lowering で実際に通す**
- 既知の事実: `LoopForm (=LoopShape)` にはネスト情報が無いので、**LoopFormベースの Pattern6 検出/ルーティングでは実装できない**
- 実装は **StepTreeAST側**を SSOT として扱うPhase 188.2 Option A を継続)
---
## Scope (minimal)
対応するのは “NestedLoop Minimal” の 1形だけに限定する。
- depth: `max_loop_depth == 2` のみ
- inner loop: Pattern1相当break/continue 無し)
- outer loop: Pattern1相当break/continue 無し)を優先
- それ以外:
- strict mode: 明示エラーPhase 188.2 の depth check とは別タグで良い)
- non-strict mode: 既存の fallback 経路に任せる(ただし silent fallback を増やさない)
---
## SSOT (what to rely on)
- nesting depth SSOT: `StepTreeFeatures.max_loop_depth`
- depth > 2: strict mode で `control_tree/nested_loop/depth_exceeded`Phase 188.2
---
## Scope & Variable Model (SSOT)
Nyash の変数スコープ方針に合わせて、nested loop lowering でも以下を SSOT として固定する。
### Visibility (read)
- inner loop から outer の binding は参照できるlexical scope: “1つ上は見える”
- ただし JoinIR lowering では「見える」を **明示的な引数/継続で表現**する(暗黙キャプチャを増やさない)
### Mutation (write-back)
Phase 188.3 では段階的に進める:
- **P188.3 (minimal)**: outer 変数の **read-only capture** を許すinner から outer を読む)
- **P188.4+ (generalize)**: outer 変数の **write-back** を対応するinner で outer に代入した値を `k_inner_exit(...)` で戻す)
この分離により、PHI/exit binding の複雑さを Phase 188.3 に持ち込まずに済む。
---
## Lowering sketch (how it should look)
Nested loop は JoinIR の「tail recursion + continuation」を再帰的に合成して表現する。
- outer: `outer_step(state..., k_outer_exit)`
- inner: `inner_step(state..., k_inner_exit)`
- inner が終わったら `k_inner_exit(...)` で outer の“残り”へ戻る
この `k_inner_exit` がスコープ境界として働くので、将来の write-back もここに集約できる。
---
## Deliverables
1. **Fixture + integration smokeexit code SSOT**
- 1-level nested loop を最小で再現する `.hako` を追加
- integration で実行し、exit code で判定stdout比較はしない
2. **StepTree-based lowering implementation**
- StepTree を辿って、inner loop を outer loop の中で正しく lowering できるようにする
- 入口は “StepTree→JoinIR” のどこかLoopFormベースの router は使わない)
3. **Docs update**
- Phase 188.1 の “Pattern6 specification” が design であることは維持
- Phase 188.3 で “実装済み/未実装の境界” を明確に書く
---
## Acceptance Criteria
- `./tools/smokes/v2/run.sh --profile quick` が常にグリーン維持
- integration selfhost が FAIL=0 を維持
- 追加した nested loop fixture が PASSJoinIR lowering が使われたことをログ/タグで確認可能)
---
## Next (schedule)
- **Phase 188.3**: depth=2 の最小形を “確実に通す” + PoC fixture を smoke 固定
- **Phase 188.4+**: write-backouter carrier reconnectionと “再帰 lowering の一般化depthを増やしても壊れない” を docs-first で設計してから実装
---
## Out of Scope
- nested loop + break/continue の一般対応
- LoopRegion を使った MIR-level nesting SSOTOption B