diff --git a/docs/development/current/main/10-Now.md b/docs/development/current/main/10-Now.md index 5246b00e..c7408bd3 100644 --- a/docs/development/current/main/10-Now.md +++ b/docs/development/current/main/10-Now.md @@ -2,7 +2,7 @@ ## Current Focus: Phase 29ai(Plan/Frag single-planner) -Next: Phase 29ai P12(Pattern2 LoopBodyLocal promotion の Facts 仕様化) +Next: `docs/development/current/main/phases/phase-29ai/P12-FACTS-PATTERN2-LOOPBODYLOCAL-PROMOTION-INSTRUCTIONS.md` **2025-12-29: Phase 29ai P11 完了** ✅ - 目的: Pattern2 break subset を Facts→Planner に吸収し、single_planner で planner-first を開始(仕様不変) diff --git a/docs/development/current/main/30-Backlog.md b/docs/development/current/main/30-Backlog.md index 29f2e0e8..cc03cbf1 100644 --- a/docs/development/current/main/30-Backlog.md +++ b/docs/development/current/main/30-Backlog.md @@ -19,7 +19,7 @@ Related: - **Phase 29ai(candidate): Plan/Frag single-planner(Facts SSOT)** - 入口: `docs/development/current/main/phases/phase-29ai/README.md` - - Next: P12(Pattern2 LoopBodyLocal promotion の Facts 仕様化) + - Next: `docs/development/current/main/phases/phase-29ai/P12-FACTS-PATTERN2-LOOPBODYLOCAL-PROMOTION-INSTRUCTIONS.md` - **Phase 29ae P1(✅ COMPLETE): JoinIR Regression Pack (SSOT固定)** - 入口: `docs/development/current/main/phases/phase-29ae/README.md` diff --git a/docs/development/current/main/phases/phase-29ai/P12-FACTS-PATTERN2-LOOPBODYLOCAL-PROMOTION-INSTRUCTIONS.md b/docs/development/current/main/phases/phase-29ai/P12-FACTS-PATTERN2-LOOPBODYLOCAL-PROMOTION-INSTRUCTIONS.md new file mode 100644 index 00000000..82c9f814 --- /dev/null +++ b/docs/development/current/main/phases/phase-29ai/P12-FACTS-PATTERN2-LOOPBODYLOCAL-PROMOTION-INSTRUCTIONS.md @@ -0,0 +1,97 @@ +# Phase 29ai P12: Facts SSOT(Pattern2 LoopBodyLocal promotion) + +Date: 2025-12-29 +Status: Ready for execution +Scope: Pattern2 の LoopBodyLocal promotion(A-3 Trim / A-4 DigitPos)を Facts として仕様化(仕様不変) +Goal: “promotion が必要な形” を Facts で 1 箇所に固定し、JoinIR/pattern 側に解析が散らないようにする + +## Background + +Pattern2 には break 条件が loop-body で生成した一時値(LoopBodyLocal)に依存する形があり、ここが promotion(host binding / derived slot / trim 形状など) +の主要露出点になっている。既存実装は JoinIR 側の箱群(Pattern2 promotion)で成立しているが、長期的には Facts→Plan→Emit の 1 本導線へ寄せたい。 + +P12 では “解析(何が LoopBodyLocal で、どの形か)” を Facts として SSOT 化し、Planner/Emitter が再解析・分岐増殖しない形にする。 + +## Non-goals(この P12 ではやらない) + +- 実際の promotion ロジックの差し替え(既定挙動の変更) +- derived slot emitter / merge 側の契約変更 +- Pattern2 の全形対応(real-world まで一気に拡張しない) +- 新しい env var / debug トグル追加 +- by-name 分岐の追加(禁止) + +## Target Fixtures(SSOT) + +この 2 本を “promotion が必要な代表” として SSOT にする(既存のまま): + +- `apps/tests/phase29ab_pattern2_loopbodylocal_min.hako`(A-4 DigitPos) +- `apps/tests/phase29ab_pattern2_loopbodylocal_seg_min.hako`(A-3 Trim / seg) + +## Deliverables + +1. Facts 型と抽出入口(SSOT): + - `Pattern2LoopBodyLocalFacts`(例: `variant=TrimSeg|DigitPos` + 関連 var 名 + 依存グラフの最小) + - 抽出: `try_extract_pattern2_loopbodylocal_facts(condition, body) -> Result, Freeze>` +2. Facts→Planner/Plan への橋渡しのための “最低限の情報” を明文化(どの情報が必須か)。 +3. unit tests(AST を組んで `Ok(Some)` / `Ok(None)` の境界を固定)。 +4. 追跡 docs(phase-29ai README / Now / Backlog)更新。 + +## Proposed Data Model(最小) + +`Pattern2LoopBodyLocalFacts` は “promotion の判断に必要な最小セット” だけ持つ(推測は禁止。取れなければ `Ok(None)`)。 + +例: + +- 共通: + - `loop_var: String` + - `loopbodylocal_var: String`(例: `seg` / `digit_pos`) + - `break_uses_loopbodylocal: bool`(必ず true で Some を返す) + - `shape: LoopBodyLocalShape`(下の enum) +- `LoopBodyLocalShape`(P12は2つだけ) + - `TrimSeg { s_var, i_var }`(`seg = s.substring(i, i+1)` + `if seg == " " || seg == "\\t" { break }`) + - `DigitPos { digits_var, ch_var }`(`digit_pos = digits.indexOf(ch)` + `if digit_pos < 0 { break }`) + +## Implementation Steps(Critical Order) + +### Step 1: Facts module を追加 + +- 新規: `src/mir/builder/control_flow/plan/facts/pattern2_loopbodylocal_facts.rs` +- 更新: `src/mir/builder/control_flow/plan/facts/mod.rs`(module 登録) + +### Step 2: LoopFacts に “補助 facts” を接続(ただし既定挙動不変) + +- 更新: `src/mir/builder/control_flow/plan/facts/loop_facts.rs` + - `pattern2_loopbodylocal: Option` を追加(または `pattern2_break` 内へ nest) + - `try_build_loop_facts()` で `try_extract_pattern2_loopbodylocal_facts(condition, body)` を呼ぶ + +方針: +- 抽出が曖昧なら `Ok(None)`(Freeze は出さない)。 +- `pattern2_break` が `None` のときは `pattern2_loopbodylocal` も `None` にする(矛盾を作らない)。 + +### Step 3: unit tests で境界固定 + +- `src/mir/builder/control_flow/plan/facts/pattern2_loopbodylocal_facts.rs` に `#[cfg(test)]` を追加 +- 2 fixture 相当の AST を直接組んで `Ok(Some(shape=...))` を固定 +- “似てるけど違う” 形(例: `seg = substring(i,i+2)` / break で seg を使ってない)を `Ok(None)` に固定 + +### Step 4: docs / tracking 更新 + +- `docs/development/current/main/phases/phase-29ai/README.md` +- `docs/development/current/main/10-Now.md` +- `docs/development/current/main/30-Backlog.md` + +書くこと(最小): +- P12 の scope(Facts のみ、仕様不変) +- P13 候補(例: Facts→Planner で “promotion-required” を Plan に載せる) + +## Verification (SSOT) + +- `cargo build --release` +- `./tools/smokes/v2/run.sh --profile quick` +- `./tools/smokes/v2/profiles/integration/joinir/phase29ae_regression_pack_vm.sh` + +## Notes(Fail-Fast / Freeze) + +P12 は実行経路で Freeze を増やさない(曖昧なら `Ok(None)`)。Fail-Fast/Freeze を導入するのは、P13 以降で +“planner-first で確実に採用される範囲” が固まってからにする。 + diff --git a/docs/development/current/main/phases/phase-29ai/README.md b/docs/development/current/main/phases/phase-29ai/README.md index 976f1e6c..4e52446d 100644 --- a/docs/development/current/main/phases/phase-29ai/README.md +++ b/docs/development/current/main/phases/phase-29ai/README.md @@ -70,6 +70,11 @@ Goal: pattern 名による分岐を外部APIから消し、Facts(事実)→ - 完了: Pattern2BreakFacts/Planner 候補/Pattern2 planner-first を接続、subset fixture + smoke 追加 - 検証: `cargo build --release` / `./tools/smokes/v2/run.sh --profile quick` / `./tools/smokes/v2/profiles/integration/joinir/phase29ae_regression_pack_vm.sh` / `./tools/smokes/v2/run.sh --profile integration --filter "phase29ai_pattern2_break_plan_subset_ok_min"` +## P12: Facts SSOT(Pattern2 LoopBodyLocal promotion) + +- 指示書: `docs/development/current/main/phases/phase-29ai/P12-FACTS-PATTERN2-LOOPBODYLOCAL-PROMOTION-INSTRUCTIONS.md` +- ねらい: Pattern2 の “LoopBodyLocal promotion” を Facts として仕様化し、planner/emitter が二重に解析しない形へ寄せる(既定挙動は不変) + ## Verification (SSOT) - `cargo build --release`