Files
hakorune/docs/development/current/main/phases/phase-188.1/README.md

361 lines
12 KiB
Markdown
Raw Normal View History

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>
2025-12-27 05:45:12 +09:00
# Phase 188.1: cap_missing/NestedLoop 解除strict gate unblock
**Date**: 2025-12-27
**Goal**: `cap_missing/NestedLoop` を解除して、`selfhost_minimal` を integration で PASS させるFail-Fastを崩さない
**Status**: ✅ Capability gate unblock 完了 / ❌ Pattern 6検出・loweringは Phase 188.2+ に deferred
---
## ⚠️ Implementation Reality (Phase 188.1 Scope)
### What Phase 188.1 actually did
-**StepTree capability gate**: `StepCapability::NestedLoop` を strict allowlist に追加して、`cap_missing/NestedLoop` を解除した
-**Integration導線**: `selfhost_minimal` の SKIP を撤去しても integration selfhost が FAIL=0 になることを確認した
### What Phase 188.1 did NOT do
- ❌ **Nested loop の自動検出LoopFormベース**は未実装
`loop_pattern_detection::extract_features()``max_loop_depth=1` / `has_inner_loops=false` の固定値TODOで、Pattern 6 の分岐は到達しない
-**Pattern 6 lowering** は未実装
`src/mir/join_ir/lowering/loop_patterns/nested_minimal.rs` はインフラstubで、現状 `None` を返す
### Why LoopForm-based nesting detection is impossible (current architecture)
Nesting depth は **StepTreeAST側**にはあるが、**LoopFormMIR側**には存在しない。
- ✅ StepTree: `StepTreeFeatures.max_loop_depth`AST → StepTree 変換時に計算)
- ❌ LoopForm: `LoopForm = LoopShape` は CFG ブロック参照だけを持ち、親子/深さ情報が無い
従って、ネスト深さの検査や Pattern 6 の自動検出を **LoopFormレイヤーだけで完結させることはできない**
次の実装は Phase 188.2 で「StepTree側を使うか / LoopRegion親子構造を実装するか」を docs-first で決める。
## Pattern 6 Specification: NestedLoop Minimal
**Note**: このセクションは「目標仕様design」であり、Phase 188.1 では gate unblock のみ完了。実装は Phase 188.2+。
### Supported Forms (ONLY)
**Pattern**: Outer Pattern 1 + Inner Pattern 1
```nyash
// Outer loop: Pattern 1 (simple while, no break/continue)
loop(outer_cond) {
// ... outer loop body before inner ...
// Inner loop: Pattern 1 ONLY (simple while, no break/continue)
loop(inner_cond) {
// ... inner loop body ...
}
// ... outer loop body after inner ...
}
```
**Requirements**:
- **Outer loop**: Pattern 1 (Simple While) - no break/continue
- **Inner loop**: Pattern 1 (Simple While) - no break/continue
- **Nesting depth**: EXACTLY 1 level (`max_loop_depth == 2`)
- **No control flow**: No break/continue in either loop
- **Sequential execution**: Inner loop completes before outer continues
### Unsupported Forms (Explicit Error)
**Rejected with明示エラー** (no silent fallback):
1. **Deeper nesting** (`max_loop_depth > 2`):
```
[joinir/nested_loop/depth_exceeded] max_loop_depth=3 exceeds limit (max=2)
Hint: Refactor to avoid 3+ level nesting, or split into separate functions
```
2. **Inner loop with break/continue**:
```
[joinir/nested_loop/inner_control_flow] Inner loop has break/continue (not supported)
Hint: Only simple while loops (Pattern 1) supported as inner loops
```
3. **Outer loop with break/continue**:
```
[joinir/nested_loop/outer_control_flow] Outer loop has break/continue (not supported)
Hint: Only simple while loops (Pattern 1) supported as outer loops
```
4. **Multiple inner loops** (siblings):
```
[joinir/nested_loop/multiple_inner] Multiple inner loops detected (not supported)
Hint: Only one inner loop per outer loop supported
```
---
## JoinIR Lowering Strategy
### Example Input (Nyash)
```nyash
static box Main {
main() {
local outer_i = 0
loop(outer_i < 3) {
local inner_j = 0
loop(inner_j < 2) {
print(inner_j)
inner_j = inner_j + 1
}
outer_i = outer_i + 1
}
return 0
}
}
```
### Expected Output (JoinIR Pseudocode)
```text
fn main():
Call(outer_step, [0, k_main_exit])
fn outer_step(outer_i, k_outer_exit):
// Exit condition check
exit_cond = !(outer_i < 3)
Jump(k_outer_exit, [], cond=exit_cond) // Early exit if condition false
// Initialize inner loop variables
inner_j = 0
// Inner loop step function (nested inside outer_step)
fn inner_step(inner_j, k_inner_exit):
exit_cond = !(inner_j < 2)
Jump(k_inner_exit, [], cond=exit_cond)
print(inner_j)
inner_j_next = inner_j + 1
Call(inner_step, [inner_j_next, k_inner_exit]) // Tail recursion
// k_inner_exit continuation (resume outer loop body after inner completes)
fn k_inner_exit():
outer_i_next = outer_i + 1
Call(outer_step, [outer_i_next, k_outer_exit]) // Outer tail recursion
// Entry: call inner loop
Call(inner_step, [inner_j, k_inner_exit])
fn k_main_exit():
return 0
```
**Key Points**:
- **Nested functions**: Inner step function is defined inside outer step function
- **Continuation wiring**: `k_inner_exit` resumes outer loop body after inner completes
- **Carrier isolation**: Outer carriers (`outer_i`) and inner carriers (`inner_j`) are separate
- **Same pattern as Pattern 1**: Both loops use tail-recursive step function pattern
---
## ⚠️ Implementation Reality (Phase 188.1 Scope)
### What Was Actually Implemented
**Phase 188.1 delivered**:
1.**StepTree capability gate**: `StepCapability::NestedLoop` added to allowlist
2.**Pattern 6 enum**: `Pattern6NestedLoopMinimal` classification added
3.**Lowering stub**: `nested_minimal.rs` module created (infrastructure only)
4.**Test pass**: selfhost_minimal conditional SKIP removed, 154/154 PASS maintained
**Phase 188.1 did NOT implement**:
-**Automatic nesting detection from LoopForm**: LoopForm (= LoopShape) has NO nesting information
-**Pattern 6 lowering logic**: `lower_nested_loop_minimal_to_joinir()` returns `None` (stub)
-**LoopRegion integration**: LoopRegion parent/child structure exists but is NOT instantiated
### Why Automatic Detection Is NOT Possible (Current Architecture)
**LoopForm Limitation**:
```rust
// src/mir/loop_form.rs
pub type LoopForm = crate::mir::control_form::LoopShape;
// LoopShape structure (src/mir/control_form.rs):
pub struct LoopShape {
pub preheader: BasicBlockId,
pub header: BasicBlockId,
pub body: Vec<BasicBlockId>,
pub latch: BasicBlockId,
pub exit_blocks: Vec<BasicBlockId>,
// ❌ NO parent field
// ❌ NO children field
// ❌ NO depth field
}
```
**Nesting information exists ONLY in StepTree** (AST level):
```rust
// src/mir/control_tree/step_tree/mod.rs (line 17-25)
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>
2025-12-27 05:45:12 +09:00
pub struct StepTreeFeatures {
pub max_loop_depth: u32, // ← Detected during AST → StepTree conversion
// ...
}
```
- ✅ AST parsing time: Nesting depth calculated
- ❌ MIR lowering time: LoopForm has NO access to this information
**LoopRegion infrastructure exists but is NOT integrated**:
```rust
// src/mir/control_form.rs (line 40-62) - Phase 32 definition
pub struct LoopRegion {
pub parent: Option<LoopId>, // ← Structure defined
pub children: Vec<LoopId>, // ← But NOT instantiated anywhere
}
```
### Where Nesting Depth Checking MUST Happen
**✅ Possible locations**:
1. **StepTree level** (before LoopForm creation):
- Use `StepTreeFeatures.max_loop_depth` during control flow analysis
- Reject `max_loop_depth > 2` at StepTree → LoopForm conversion time
2. **LoopRegion level** (if integrated in Phase 188.2+):
- Use `LoopRegion.parent` to compute actual nesting depth
- Build LoopRegion tree and check depth constraints
**❌ Impossible location**:
- **LoopForm level**: No nesting information available (by design)
### Phase 188.2 Design Decision Required
**Choice A: StepTreeFeatures Integration**
- Pass `StepTreeFeatures` (AST-level) to JoinIR lowering
- Use `max_loop_depth` from StepTree for Pattern 6 detection
- Pro: Nesting info already exists
- Con: AST-level info may not match MIR structure (optimizations)
**Choice B: LoopRegion Integration**
- Instantiate `LoopRegion` with parent/child relationships
- Compute nesting depth from MIR control flow graph
- Pro: MIR-level truth (accurate after optimizations)
- Con: Requires implementing LoopRegion builder (Phase 32 infrastructure not yet wired)
**Decision timeline**: Phase 188.2 planning session (docs-first approach)
---
## Implementation Files
### New Files Created
1. **`src/mir/join_ir/lowering/loop_patterns/nested_minimal.rs`**
- Phase 188.1: インフラstub。現状 `lower_nested_loop_minimal_to_joinir()``None` を返す
### Modified Files
1. **`src/mir/loop_pattern_detection/mod.rs`** (~15 lines)
- Add `Pattern6NestedLoopMinimal` enum variant
- Add `max_loop_depth`, `has_inner_loops` to `LoopFeatures`
- Update `extract_features()`, `classify()`
2. **`src/mir/join_ir/lowering/loop_patterns/mod.rs`** (~2 lines)
- Export `nested_minimal` module
3. **`src/mir/join_ir/lowering/loop_pattern_router.rs`** (~10 lines)
- Add Pattern 6 routing case
- Add explicit error for `max_loop_depth > 2`
4. **`src/mir/builder/control_flow/joinir/control_tree_capability_guard.rs`** (~1 line)
- Add `StepCapability::NestedLoop` to allowlist
5. **`tools/smokes/v2/profiles/integration/selfhost/selfhost_minimal.sh`** (~6 lines removed)
- Remove conditional SKIP for `cap_missing/NestedLoop`
---
## Integration Points
### Detection Pipeline
1. **AST → StepTree** (`step_tree.rs` lines 461-463):
```rust
if features.max_loop_depth > 1 {
facts.add_capability(StepCapability::NestedLoop);
}
```
2. **StepTree → Contract** (automatic capability contract check)
3. **Contract → Guard** (`control_tree_capability_guard.rs` line 44):
```rust
StepCapability::NestedLoop, // Phase 188.1: Now in allowlist
```
4. **LoopForm → Pattern Detection** (`loop_pattern_detection::classify()`):
```rust
// Phase 188.1: Pattern 6 enum defined, but detection logic is STUB
// Currently always returns max_loop_depth = 1 (default)
// because LoopForm has NO nesting information.
//
// TODO (Phase 188.2): Integrate StepTreeFeatures or LoopRegion
// to enable actual nesting detection.
if features.max_loop_depth == 2
&& features.has_inner_loops
&& !features.has_break
&& !features.has_continue
{
return LoopPatternKind::Pattern6NestedLoopMinimal; // Never reached (stub)
}
```
5. **Pattern → Lowering** (`loop_pattern_router.rs`):
```rust
LoopPatternKind::Pattern6NestedLoopMinimal => {
super::loop_patterns::lower_nested_loop_minimal_to_joinir(loop_form, lowerer)
}
```
---
## Success Criteria
### Functional Requirements
-`selfhost_minimal.sh`: Remove conditional SKIP, test PASS (or explicit error)
-`integration --filter "selfhost_"`: FAIL=0 maintained
-`quick`: 154/154 PASS unchanged
### Quality Requirements
- ✅ Explicit errors for unsupported forms (no silent `Ok(None)`)
- ✅ Phase 286 Fail-Fast principle maintained (no silent fallback)
- ✅ Minimal diff (~180 lines total)
---
## Out of Scope (Future Work)
**Deferred to Phase 188.2+**:
- Pattern 6 の実装ネスト検出のSSOT決定 + lowering 実装)
- break/continue in nested loops (Pattern 2/4 inner/outer combinations)
- Multiple inner loops (siblings)
- 2+ level nesting (3+ loop depth)
- Nested loops with PHI (Pattern 3 inner/outer combinations)
- Shared carriers between outer/inner loops
**Rationale**: Phase 188.1 is minimal PoC to unblock selfhost_minimal. Complex patterns deferred to avoid scope creep.
---
## References
- **Phase 188 Overview**: `docs/private/roadmap2/phases/phase-188-joinir-loop-pattern-expansion/README.md`
- **Pattern Classification**: `docs/private/roadmap2/phases/phase-188-joinir-loop-pattern-expansion/pattern-classification.md`
- **JoinIR Architecture**: `docs/development/current/main/joinir-architecture-overview.md`
- **Selfhost Integration Limitations**: `docs/development/current/main/investigations/selfhost-integration-limitations.md`
---
## End of Phase 188.1 Documentation
**Status**: Infrastructure complete, detection logic deferred to Phase 188.2
**Reality**: Pattern 6 enum exists, but automatic detection is NOT implemented (LoopForm limitation)
**Total Estimated Effort**: 4-5 hours (infrastructure only)
**Date Completed**: 2025-12-27