diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index 0b7a1c6b..73af35b3 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -18,8 +18,8 @@ Scope: Repo root の旧リンク互換。現行の入口は `docs/development/cu **CorePlan migration 道筋 SSOT** `docs/development/current/main/design/coreplan-migration-roadmap-ssot.md` が移行タスクの Done 判定の入口。 -**Next implementation (CorePlan composition scaffold)** -`docs/development/current/main/phases/phase-29ao/P0-COREPLAN-COMPOSER-SCAFFOLD-INSTRUCTIONS.md` +**Next implementation (CorePlan composition, P2 planned)** +`docs/development/current/main/phases/phase-29ao/README.md` **Next implementation (Phase 29ao P1)** `docs/development/current/main/phases/phase-29ao/P1-COREPLAN-COMPOSER-API-BRIDGE-INSTRUCTIONS.md` diff --git a/docs/development/current/main/10-Now.md b/docs/development/current/main/10-Now.md index 1b50fbca..bc86f7b7 100644 --- a/docs/development/current/main/10-Now.md +++ b/docs/development/current/main/10-Now.md @@ -2,7 +2,7 @@ ## Current Focus: Phase 29ao(CorePlan composition) -Next: Phase 29ao P1(Composer API決定 + bridge 実装) +Next: Phase 29ao P2(CoreLoop skeleton → CorePlan) 運用ルール: integration filter で phase143_* は回さない(JoinIR 回帰は phase29ae pack のみ) 運用ルール: phase286_pattern9_* は legacy pack (SKIP) を使う 移行道筋 SSOT: `docs/development/current/main/design/coreplan-migration-roadmap-ssot.md` @@ -12,6 +12,11 @@ Next: Phase 29ao P1(Composer API決定 + bridge 実装) - 変更: `src/mir/builder/control_flow/plan/composer/mod.rs` / `src/mir/builder/control_flow/plan/mod.rs` / `docs/development/current/main/phases/phase-29ao/README.md` - 検証: `cargo build --release` / `./tools/smokes/v2/run.sh --profile quick` / `./tools/smokes/v2/profiles/integration/joinir/phase29ae_regression_pack_vm.sh` +**2025-12-30: Phase 29ao P1 完了** ✅ +- 目的: composer bridge で `CanonicalLoopFacts` から `DomainPlan` を組み立てる入口を追加(未接続) +- 変更: `src/mir/builder/control_flow/plan/composer/mod.rs` / `docs/development/current/main/phases/phase-29ao/README.md` / `docs/development/current/main/10-Now.md` / `docs/development/current/main/30-Backlog.md` / `CURRENT_TASK.md` +- 検証: `cargo build --release` / `./tools/smokes/v2/run.sh --profile quick` / `./tools/smokes/v2/profiles/integration/joinir/phase29ae_regression_pack_vm.sh` + **2025-12-29: Phase 29an P15 完了** ✅ - 目的: P0–P14 の成果を closeout 形式でまとめ、次フェーズ(Phase 29ao)入口を固定 - 変更: `docs/development/current/main/phases/phase-29an/README.md` / `docs/development/current/main/10-Now.md` / `docs/development/current/main/30-Backlog.md` / `CURRENT_TASK.md` diff --git a/docs/development/current/main/30-Backlog.md b/docs/development/current/main/30-Backlog.md index 55489059..a1c3b951 100644 --- a/docs/development/current/main/30-Backlog.md +++ b/docs/development/current/main/30-Backlog.md @@ -15,7 +15,7 @@ Related: - **Phase 29ao(active): CorePlan composition from Skeleton/Feature** - 入口: `docs/development/current/main/phases/phase-29ao/README.md` - - 状況: P0 ✅ 完了 / Next: P1(Composer API決定 + bridge 実装) + - 状況: P0/P1 ✅ 完了 / Next: P2 - **Phase 29af(✅ COMPLETE): Boundary hygiene / regression entrypoint / carrier layout SSOT** - 入口: `docs/development/current/main/phases/phase-29af/README.md` diff --git a/docs/development/current/main/phases/phase-29ao/README.md b/docs/development/current/main/phases/phase-29ao/README.md index 3a9fc80f..9ca673a1 100644 --- a/docs/development/current/main/phases/phase-29ao/README.md +++ b/docs/development/current/main/phases/phase-29ao/README.md @@ -21,7 +21,7 @@ Gate(SSOT): - 指示書: `docs/development/current/main/phases/phase-29ao/P0-COREPLAN-COMPOSER-SCAFFOLD-INSTRUCTIONS.md` - ねらい: `CanonicalLoopFacts`(projection済み)→ `CorePlan` 合成の入口を 1 箇所に作り、以後の実装を “合成だけ” に寄せる -## P1: Composer API決定 + bridge(未接続・仕様不変) +## P1: Composer API決定 + bridge(未接続・仕様不変)✅ - 指示書: `docs/development/current/main/phases/phase-29ao/P1-COREPLAN-COMPOSER-API-BRIDGE-INSTRUCTIONS.md` - ねらい: diff --git a/src/mir/builder/control_flow/plan/composer/mod.rs b/src/mir/builder/control_flow/plan/composer/mod.rs index cf0033c1..343bfc00 100644 --- a/src/mir/builder/control_flow/plan/composer/mod.rs +++ b/src/mir/builder/control_flow/plan/composer/mod.rs @@ -1,10 +1,29 @@ //! Phase 29ao P0: CorePlan composer scaffold (CanonicalLoopFacts -> CorePlan) -use super::CorePlan; +use super::{CorePlan, DomainPlan, Pattern1SimpleWhilePlan}; use crate::mir::builder::control_flow::plan::facts::skeleton_facts::SkeletonKind; use crate::mir::builder::control_flow::plan::normalize::CanonicalLoopFacts; use crate::mir::builder::control_flow::plan::planner::Freeze; +#[allow(dead_code)] +pub(in crate::mir::builder) fn try_compose_domain_plan_from_canonical_facts( + facts: &CanonicalLoopFacts, +) -> Result, Freeze> { + if !matches!(facts.skeleton_kind, SkeletonKind::Loop) { + return Ok(None); + } + let Some(pattern1) = &facts.facts.pattern1_simplewhile else { + return Ok(None); + }; + Ok(Some(DomainPlan::Pattern1SimpleWhile( + Pattern1SimpleWhilePlan { + loop_var: pattern1.loop_var.clone(), + condition: pattern1.condition.clone(), + loop_increment: pattern1.loop_increment.clone(), + }, + ))) +} + #[allow(dead_code)] pub(in crate::mir::builder) fn try_compose_core_plan_from_canonical_facts( facts: &CanonicalLoopFacts, @@ -18,9 +37,13 @@ pub(in crate::mir::builder) fn try_compose_core_plan_from_canonical_facts( #[cfg(test)] mod tests { - use super::try_compose_core_plan_from_canonical_facts; + use super::{ + try_compose_core_plan_from_canonical_facts, try_compose_domain_plan_from_canonical_facts, + }; + use crate::ast::{ASTNode, BinaryOperator, LiteralValue, Span}; use crate::mir::builder::control_flow::plan::facts::feature_facts::LoopFeatureFacts; use crate::mir::builder::control_flow::plan::facts::loop_facts::LoopFacts; + use crate::mir::builder::control_flow::plan::facts::pattern1_simplewhile_facts::Pattern1SimpleWhileFacts; use crate::mir::builder::control_flow::plan::facts::scan_shapes::{ ConditionShape, StepShape, }; @@ -28,6 +51,21 @@ mod tests { SkeletonFacts, SkeletonKind, }; use crate::mir::builder::control_flow::plan::normalize::canonicalize_loop_facts; + use crate::mir::builder::control_flow::plan::DomainPlan; + + fn v(name: &str) -> ASTNode { + ASTNode::Variable { + name: name.to_string(), + span: Span::unknown(), + } + } + + fn lit_int(value: i64) -> ASTNode { + ASTNode::Literal { + value: LiteralValue::Integer(value), + span: Span::unknown(), + } + } #[test] fn composer_scaffold_returns_none() { @@ -54,4 +92,74 @@ mod tests { try_compose_core_plan_from_canonical_facts(&canonical).expect("Ok"); assert!(composed.is_none()); } + + #[test] + fn composer_bridge_builds_pattern1_domain_plan() { + let pattern1 = Pattern1SimpleWhileFacts { + loop_var: "i".to_string(), + condition: ASTNode::BinaryOp { + operator: BinaryOperator::Less, + left: Box::new(v("i")), + right: Box::new(lit_int(3)), + span: Span::unknown(), + }, + loop_increment: ASTNode::BinaryOp { + operator: BinaryOperator::Add, + left: Box::new(v("i")), + right: Box::new(lit_int(1)), + span: Span::unknown(), + }, + }; + let facts = LoopFacts { + condition_shape: ConditionShape::Unknown, + step_shape: StepShape::Unknown, + skeleton: SkeletonFacts { + kind: SkeletonKind::Loop, + }, + features: LoopFeatureFacts::default(), + scan_with_init: None, + split_scan: None, + pattern1_simplewhile: Some(pattern1), + pattern3_ifphi: None, + pattern4_continue: None, + pattern5_infinite_early_exit: None, + pattern8_bool_predicate_scan: None, + pattern9_accum_const_loop: None, + pattern2_break: None, + pattern2_loopbodylocal: None, + }; + let canonical = canonicalize_loop_facts(facts); + let plan = + try_compose_domain_plan_from_canonical_facts(&canonical).expect("Ok"); + assert!(matches!( + plan, + Some(DomainPlan::Pattern1SimpleWhile(_)) + )); + } + + #[test] + fn composer_bridge_returns_none_without_pattern1() { + let facts = LoopFacts { + condition_shape: ConditionShape::Unknown, + step_shape: StepShape::Unknown, + skeleton: SkeletonFacts { + kind: SkeletonKind::Loop, + }, + features: LoopFeatureFacts::default(), + scan_with_init: None, + split_scan: None, + pattern1_simplewhile: None, + pattern3_ifphi: None, + pattern4_continue: None, + pattern5_infinite_early_exit: None, + pattern8_bool_predicate_scan: None, + pattern9_accum_const_loop: None, + pattern2_break: None, + pattern2_loopbodylocal: None, + }; + let canonical = canonicalize_loop_facts(facts); + let plan = + try_compose_domain_plan_from_canonical_facts(&canonical).expect("Ok"); + assert!(plan.is_none()); + } }