phase29aj(p0): expose planner outcome facts for strict observability
This commit is contained in:
@ -4,10 +4,10 @@
|
||||
|
||||
use crate::ast::ASTNode;
|
||||
|
||||
use crate::mir::builder::control_flow::plan::facts::try_build_loop_facts;
|
||||
use crate::mir::builder::control_flow::plan::normalize::{canonicalize_loop_facts, CanonicalLoopFacts};
|
||||
use crate::mir::builder::control_flow::plan::normalize::CanonicalLoopFacts;
|
||||
|
||||
use super::candidates::{CandidateSet, PlanCandidate};
|
||||
use super::outcome::build_plan_with_facts;
|
||||
use super::Freeze;
|
||||
use crate::mir::builder::control_flow::plan::{
|
||||
DomainPlan, Pattern2BreakPlan, Pattern2PromotionHint, ScanDirection, ScanWithInitPlan,
|
||||
@ -21,11 +21,7 @@ pub(in crate::mir::builder) fn build_plan(
|
||||
condition: &ASTNode,
|
||||
body: &[ASTNode],
|
||||
) -> Result<Option<DomainPlan>, Freeze> {
|
||||
let Some(facts) = try_build_loop_facts(condition, body)? else {
|
||||
return Ok(None);
|
||||
};
|
||||
let canonical = canonicalize_loop_facts(facts);
|
||||
build_plan_from_facts(canonical)
|
||||
Ok(build_plan_with_facts(condition, body)?.plan)
|
||||
}
|
||||
|
||||
pub(in crate::mir::builder) fn build_plan_from_facts(
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
pub(in crate::mir::builder) mod build;
|
||||
pub(in crate::mir::builder) mod candidates;
|
||||
pub(in crate::mir::builder) mod freeze;
|
||||
pub(in crate::mir::builder) mod outcome;
|
||||
|
||||
pub(in crate::mir::builder) use build::build_plan;
|
||||
pub(in crate::mir::builder) use freeze::Freeze;
|
||||
pub(in crate::mir::builder) use outcome::{build_plan_with_facts, PlanBuildOutcome};
|
||||
|
||||
40
src/mir/builder/control_flow/plan/planner/outcome.rs
Normal file
40
src/mir/builder/control_flow/plan/planner/outcome.rs
Normal file
@ -0,0 +1,40 @@
|
||||
//! Phase 29aj P0: Planner outcome (facts + plan) SSOT
|
||||
|
||||
use crate::ast::ASTNode;
|
||||
use crate::mir::builder::control_flow::plan::facts::try_build_loop_facts;
|
||||
use crate::mir::builder::control_flow::plan::normalize::{
|
||||
canonicalize_loop_facts, CanonicalLoopFacts,
|
||||
};
|
||||
use crate::mir::builder::control_flow::plan::DomainPlan;
|
||||
|
||||
use super::build::build_plan_from_facts;
|
||||
use super::Freeze;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(in crate::mir::builder) struct PlanBuildOutcome {
|
||||
pub facts: Option<CanonicalLoopFacts>,
|
||||
pub plan: Option<DomainPlan>,
|
||||
#[allow(dead_code)]
|
||||
pub chosen_rule: Option<&'static str>,
|
||||
}
|
||||
|
||||
pub(in crate::mir::builder) fn build_plan_with_facts(
|
||||
condition: &ASTNode,
|
||||
body: &[ASTNode],
|
||||
) -> Result<PlanBuildOutcome, Freeze> {
|
||||
let Some(facts) = try_build_loop_facts(condition, body)? else {
|
||||
return Ok(PlanBuildOutcome {
|
||||
facts: None,
|
||||
plan: None,
|
||||
chosen_rule: None,
|
||||
});
|
||||
};
|
||||
let canonical = canonicalize_loop_facts(facts);
|
||||
let plan = build_plan_from_facts(canonical.clone())?;
|
||||
|
||||
Ok(PlanBuildOutcome {
|
||||
facts: Some(canonical),
|
||||
plan,
|
||||
chosen_rule: None,
|
||||
})
|
||||
}
|
||||
@ -7,17 +7,20 @@ use crate::mir::builder::control_flow::joinir::patterns::router::LoopPatternCont
|
||||
use crate::mir::loop_pattern_detection::LoopPatternKind;
|
||||
|
||||
use super::legacy_rules;
|
||||
use crate::mir::builder::control_flow::plan::facts::pattern2_loopbodylocal_facts::{
|
||||
try_extract_pattern2_loopbodylocal_facts, LoopBodyLocalShape,
|
||||
};
|
||||
use crate::mir::builder::control_flow::plan::facts::pattern2_loopbodylocal_facts::LoopBodyLocalShape;
|
||||
use crate::mir::builder::control_flow::plan::planner;
|
||||
use crate::mir::builder::control_flow::plan::{DomainPlan, Pattern2PromotionHint};
|
||||
use crate::mir::builder::control_flow::plan::DomainPlan;
|
||||
|
||||
pub(super) fn try_build_domain_plan(ctx: &LoopPatternContext) -> Result<Option<DomainPlan>, String> {
|
||||
use crate::mir::builder::control_flow::joinir::trace;
|
||||
|
||||
let planner_opt = planner::build_plan(ctx.condition, ctx.body)
|
||||
let outcome = planner::build_plan_with_facts(ctx.condition, ctx.body)
|
||||
.map_err(|freeze| freeze.to_string())?;
|
||||
let planner_opt = outcome.plan.clone();
|
||||
let promotion_facts = outcome
|
||||
.facts
|
||||
.as_ref()
|
||||
.and_then(|facts| facts.facts.pattern2_loopbodylocal.as_ref());
|
||||
|
||||
// NOTE: Names must match the previous PLAN_EXTRACTORS entries exactly.
|
||||
// Order must match exactly.
|
||||
@ -94,36 +97,9 @@ pub(super) fn try_build_domain_plan(ctx: &LoopPatternContext) -> Result<Option<D
|
||||
let promotion_tag = if matches!(entry.kind, RuleKind::Pattern2)
|
||||
&& crate::config::env::joinir_dev::strict_enabled()
|
||||
{
|
||||
let from_plan = match plan_opt.as_ref() {
|
||||
Some(DomainPlan::Pattern2Break(plan)) => {
|
||||
if let Some(Pattern2PromotionHint::LoopBodyLocal(facts)) = &plan.promotion {
|
||||
Some(match facts.shape {
|
||||
LoopBodyLocalShape::TrimSeg { .. } => {
|
||||
"[plan/pattern2/promotion_hint:TrimSeg]"
|
||||
}
|
||||
LoopBodyLocalShape::DigitPos { .. } => {
|
||||
"[plan/pattern2/promotion_hint:DigitPos]"
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
from_plan.or_else(|| {
|
||||
try_extract_pattern2_loopbodylocal_facts(ctx.condition, ctx.body)
|
||||
.ok()
|
||||
.and_then(|facts| {
|
||||
facts.map(|facts| match facts.shape {
|
||||
LoopBodyLocalShape::TrimSeg { .. } => {
|
||||
"[plan/pattern2/promotion_hint:TrimSeg]"
|
||||
}
|
||||
LoopBodyLocalShape::DigitPos { .. } => {
|
||||
"[plan/pattern2/promotion_hint:DigitPos]"
|
||||
}
|
||||
})
|
||||
})
|
||||
promotion_facts.map(|facts| match facts.shape {
|
||||
LoopBodyLocalShape::TrimSeg { .. } => "[plan/pattern2/promotion_hint:TrimSeg]",
|
||||
LoopBodyLocalShape::DigitPos { .. } => "[plan/pattern2/promotion_hint:DigitPos]",
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
||||
Reference in New Issue
Block a user