From b3b01def24a576c868c81b878e6060b9dea42d5e Mon Sep 17 00:00:00 2001 From: tomoaki Date: Mon, 29 Dec 2025 10:27:00 +0900 Subject: [PATCH] phase29ai(p13): memoize planner call in single_planner --- docs/development/current/main/10-Now.md | 12 ++++++++- docs/development/current/main/30-Backlog.md | 2 +- .../current/main/phases/phase-29ai/README.md | 4 +++ .../control_flow/plan/single_planner/rules.rs | 25 ++++++++----------- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/docs/development/current/main/10-Now.md b/docs/development/current/main/10-Now.md index 32e2d726..b250be47 100644 --- a/docs/development/current/main/10-Now.md +++ b/docs/development/current/main/10-Now.md @@ -2,7 +2,17 @@ ## Current Focus: Phase 29ai(Plan/Frag single-planner) -Next: `docs/development/current/main/phases/phase-29ai/P13-PLANNER-MEMOIZE-FACTS-IN_SINGLE_PLANNER-INSTRUCTIONS.md` +Next: Phase 29ai P14(TBD: Pattern2 LoopBodyLocal promotion を Plan/Planner へ吸収) + +**2025-12-29: Phase 29ai P13 完了** ✅ +- 目的: single_planner の planner 呼び出しを 1 回に memoize して二重スキャンを解消(仕様不変) +- 実装: `src/mir/builder/control_flow/plan/single_planner/rules.rs` +- 検証: `cargo build --release` / `./tools/smokes/v2/run.sh --profile quick` / `./tools/smokes/v2/profiles/integration/joinir/phase29ae_regression_pack_vm.sh` PASS + +**2025-12-29: Phase 29ai P12 完了** ✅ +- 目的: Pattern2 LoopBodyLocal promotion の facts 抽出を SSOT 化(仕様不変) +- 実装: `src/mir/builder/control_flow/plan/facts/pattern2_loopbodylocal_facts.rs` / `src/mir/builder/control_flow/plan/facts/loop_facts.rs` / `src/mir/builder/control_flow/plan/facts/mod.rs` +- 検証: `cargo build --release` / `./tools/smokes/v2/run.sh --profile quick` / `./tools/smokes/v2/profiles/integration/joinir/phase29ae_regression_pack_vm.sh` PASS **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 971d3c2f..c0b943de 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: `docs/development/current/main/phases/phase-29ai/P13-PLANNER-MEMOIZE-FACTS-IN_SINGLE_PLANNER-INSTRUCTIONS.md` + - Next: Phase 29ai P14(TBD: Pattern2 LoopBodyLocal promotion を Plan/Planner へ吸収) - **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/README.md b/docs/development/current/main/phases/phase-29ai/README.md index 1f776425..b037498c 100644 --- a/docs/development/current/main/phases/phase-29ai/README.md +++ b/docs/development/current/main/phases/phase-29ai/README.md @@ -74,11 +74,15 @@ Goal: pattern 名による分岐を外部APIから消し、Facts(事実)→ - 指示書: `docs/development/current/main/phases/phase-29ai/P12-FACTS-PATTERN2-LOOPBODYLOCAL-PROMOTION-INSTRUCTIONS.md` - ねらい: Pattern2 の “LoopBodyLocal promotion” を Facts として仕様化し、planner/emitter が二重に解析しない形へ寄せる(既定挙動は不変) +- 完了: Pattern2LoopBodyLocal facts 抽出 + LoopFacts 接続(guard解除) + unit tests 追加 +- 検証: `cargo build --release` / `./tools/smokes/v2/run.sh --profile quick` / `./tools/smokes/v2/profiles/integration/joinir/phase29ae_regression_pack_vm.sh` ## P13: Memoize Facts in single_planner(SSOT) - 指示書: `docs/development/current/main/phases/phase-29ai/P13-PLANNER-MEMOIZE-FACTS-IN_SINGLE_PLANNER-INSTRUCTIONS.md` - ねらい: planner 呼び出しを 1 回に収束し、Pattern6/7/2 の planner-first が二重に Facts を走らせないようにする(仕様不変) +- 完了: single_planner 内で planner 結果を memoize し、Pattern6/7/2 は型一致時のみ採用 +- 検証: `cargo build --release` / `./tools/smokes/v2/run.sh --profile quick` / `./tools/smokes/v2/profiles/integration/joinir/phase29ae_regression_pack_vm.sh` ## Verification (SSOT) diff --git a/src/mir/builder/control_flow/plan/single_planner/rules.rs b/src/mir/builder/control_flow/plan/single_planner/rules.rs index 51d58c32..fe4a4bee 100644 --- a/src/mir/builder/control_flow/plan/single_planner/rules.rs +++ b/src/mir/builder/control_flow/plan/single_planner/rules.rs @@ -13,6 +13,9 @@ use crate::mir::builder::control_flow::plan::DomainPlan; pub(super) fn try_build_domain_plan(ctx: &LoopPatternContext) -> Result, String> { use crate::mir::builder::control_flow::joinir::trace; + let planner_opt = planner::build_plan(ctx.condition, ctx.body) + .map_err(|freeze| freeze.to_string())?; + // NOTE: Names must match the previous PLAN_EXTRACTORS entries exactly. // Order must match exactly. let rules: &[RuleEntry] = &[ @@ -66,26 +69,20 @@ pub(super) fn try_build_domain_plan(ctx: &LoopPatternContext) -> Result (extract(ctx)?, true), RuleKind::Pattern6 => { - let from_planner = planner::build_plan(ctx.condition, ctx.body) - .map_err(|freeze| freeze.to_string())?; - match from_planner { - Some(plan) => (Some(plan), false), - None => (legacy_rules::pattern6::extract(ctx)?, true), + match planner_opt.as_ref() { + Some(DomainPlan::ScanWithInit(_)) => (planner_opt.clone(), false), + _ => (legacy_rules::pattern6::extract(ctx)?, true), } } RuleKind::Pattern7 => { - let from_planner = planner::build_plan(ctx.condition, ctx.body) - .map_err(|freeze| freeze.to_string())?; - match from_planner { - Some(plan) => (Some(plan), false), - None => (legacy_rules::pattern7::extract(ctx)?, true), + match planner_opt.as_ref() { + Some(DomainPlan::SplitScan(_)) => (planner_opt.clone(), false), + _ => (legacy_rules::pattern7::extract(ctx)?, true), } } RuleKind::Pattern2 => { - let from_planner = planner::build_plan(ctx.condition, ctx.body) - .map_err(|freeze| freeze.to_string())?; - match from_planner { - Some(DomainPlan::Pattern2Break(_)) => (from_planner, false), + match planner_opt.as_ref() { + Some(DomainPlan::Pattern2Break(_)) => (planner_opt.clone(), false), _ => (legacy_rules::pattern2::extract(ctx)?, true), } }