Phase 33 NORM canon test: enforce normalized dev route for P1/P2/JP mini

This commit is contained in:
nyash-codex
2025-12-11 20:54:33 +09:00
parent 59a985b7fa
commit af6f95cd4b
170 changed files with 4423 additions and 1897 deletions

View File

@ -79,7 +79,12 @@ pub enum ConditionPattern {
pub fn analyze_condition_pattern(cond: &ASTNode) -> ConditionPattern {
match cond {
// Comparison operators: ==, !=, <, >, <=, >=
ASTNode::BinaryOp { operator, left, right, .. } => {
ASTNode::BinaryOp {
operator,
left,
right,
..
} => {
// Check if operator is a comparison
let is_comparison = matches!(
operator,
@ -225,12 +230,12 @@ pub struct NormalizedCondition {
/// ```
fn flip_compare_op(op: CompareOp) -> CompareOp {
match op {
CompareOp::Lt => CompareOp::Gt, // < → >
CompareOp::Gt => CompareOp::Lt, // > → <
CompareOp::Le => CompareOp::Ge, // <= → >=
CompareOp::Ge => CompareOp::Le, // >= → <=
CompareOp::Eq => CompareOp::Eq, // == → == (不変)
CompareOp::Ne => CompareOp::Ne, // != → != (不変)
CompareOp::Lt => CompareOp::Gt, // < → >
CompareOp::Gt => CompareOp::Lt, // > → <
CompareOp::Le => CompareOp::Ge, // <= → >=
CompareOp::Ge => CompareOp::Le, // >= → <=
CompareOp::Eq => CompareOp::Eq, // == → == (不変)
CompareOp::Ne => CompareOp::Ne, // != → != (不変)
}
}
@ -278,12 +283,24 @@ fn binary_op_to_compare_op(op: &BinaryOperator) -> Option<CompareOp> {
/// ```
pub fn normalize_comparison(cond: &ASTNode) -> Option<NormalizedCondition> {
match cond {
ASTNode::BinaryOp { operator, left, right, .. } => {
ASTNode::BinaryOp {
operator,
left,
right,
..
} => {
// Comparison operator のみ受理
let compare_op = binary_op_to_compare_op(operator)?;
// Case 1: var CmpOp literal (e.g., i > 0)
if let (ASTNode::Variable { name: left_var, .. }, ASTNode::Literal { value: LiteralValue::Integer(right_val), .. }) = (left.as_ref(), right.as_ref()) {
if let (
ASTNode::Variable { name: left_var, .. },
ASTNode::Literal {
value: LiteralValue::Integer(right_val),
..
},
) = (left.as_ref(), right.as_ref())
{
return Some(NormalizedCondition {
left_var: left_var.clone(),
op: compare_op,
@ -292,7 +309,16 @@ pub fn normalize_comparison(cond: &ASTNode) -> Option<NormalizedCondition> {
}
// Case 2: literal CmpOp var (e.g., 0 < i) → 左右反転
if let (ASTNode::Literal { value: LiteralValue::Integer(left_val), .. }, ASTNode::Variable { name: right_var, .. }) = (left.as_ref(), right.as_ref()) {
if let (
ASTNode::Literal {
value: LiteralValue::Integer(left_val),
..
},
ASTNode::Variable {
name: right_var, ..
},
) = (left.as_ref(), right.as_ref())
{
return Some(NormalizedCondition {
left_var: right_var.clone(),
op: flip_compare_op(compare_op), // 演算子を反転
@ -301,7 +327,13 @@ pub fn normalize_comparison(cond: &ASTNode) -> Option<NormalizedCondition> {
}
// Case 3: var CmpOp var (e.g., i > j)
if let (ASTNode::Variable { name: left_var, .. }, ASTNode::Variable { name: right_var, .. }) = (left.as_ref(), right.as_ref()) {
if let (
ASTNode::Variable { name: left_var, .. },
ASTNode::Variable {
name: right_var, ..
},
) = (left.as_ref(), right.as_ref())
{
return Some(NormalizedCondition {
left_var: left_var.clone(),
op: compare_op,
@ -351,7 +383,10 @@ mod tests {
fn test_simple_comparison_greater() {
// i > 0
let cond = binop(BinaryOperator::Greater, var("i"), int_lit(0));
assert_eq!(analyze_condition_pattern(&cond), ConditionPattern::SimpleComparison);
assert_eq!(
analyze_condition_pattern(&cond),
ConditionPattern::SimpleComparison
);
assert!(is_simple_comparison(&cond));
}
@ -359,7 +394,10 @@ mod tests {
fn test_simple_comparison_less() {
// i < 10
let cond = binop(BinaryOperator::Less, var("i"), int_lit(10));
assert_eq!(analyze_condition_pattern(&cond), ConditionPattern::SimpleComparison);
assert_eq!(
analyze_condition_pattern(&cond),
ConditionPattern::SimpleComparison
);
assert!(is_simple_comparison(&cond));
}
@ -367,7 +405,10 @@ mod tests {
fn test_simple_comparison_equal() {
// i == 5
let cond = binop(BinaryOperator::Equal, var("i"), int_lit(5));
assert_eq!(analyze_condition_pattern(&cond), ConditionPattern::SimpleComparison);
assert_eq!(
analyze_condition_pattern(&cond),
ConditionPattern::SimpleComparison
);
assert!(is_simple_comparison(&cond));
}
@ -375,7 +416,10 @@ mod tests {
fn test_simple_comparison_not_equal() {
// i != 0
let cond = binop(BinaryOperator::NotEqual, var("i"), int_lit(0));
assert_eq!(analyze_condition_pattern(&cond), ConditionPattern::SimpleComparison);
assert_eq!(
analyze_condition_pattern(&cond),
ConditionPattern::SimpleComparison
);
assert!(is_simple_comparison(&cond));
}
@ -384,7 +428,10 @@ mod tests {
// Phase 242-EX-A: i % 2 == 1 (BinaryOp in LHS) is now SimpleComparison
let lhs = binop(BinaryOperator::Modulo, var("i"), int_lit(2));
let cond = binop(BinaryOperator::Equal, lhs, int_lit(1));
assert_eq!(analyze_condition_pattern(&cond), ConditionPattern::SimpleComparison);
assert_eq!(
analyze_condition_pattern(&cond),
ConditionPattern::SimpleComparison
);
assert!(is_simple_comparison(&cond));
}
@ -393,7 +440,10 @@ mod tests {
// Phase 242-EX-A: i == a + b (BinaryOp in RHS) is now SimpleComparison
let rhs = binop(BinaryOperator::Add, var("a"), var("b"));
let cond = binop(BinaryOperator::Equal, var("i"), rhs);
assert_eq!(analyze_condition_pattern(&cond), ConditionPattern::SimpleComparison);
assert_eq!(
analyze_condition_pattern(&cond),
ConditionPattern::SimpleComparison
);
assert!(is_simple_comparison(&cond));
}
@ -402,7 +452,10 @@ mod tests {
// Pattern3/4 で使う典型的なフィルタ条件: i % 2 == 1
let lhs = binop(BinaryOperator::Modulo, var("i"), int_lit(2));
let cond = binop(BinaryOperator::Equal, lhs, int_lit(1));
assert_eq!(analyze_condition_pattern(&cond), ConditionPattern::SimpleComparison);
assert_eq!(
analyze_condition_pattern(&cond),
ConditionPattern::SimpleComparison
);
assert!(is_simple_comparison(&cond));
}
@ -535,7 +588,10 @@ mod tests {
fn test_analyze_pattern_literal_cmp_var() {
// Phase 222: 0 < i → SimpleComparison
let cond = binop(BinaryOperator::Less, int_lit(0), var("i"));
assert_eq!(analyze_condition_pattern(&cond), ConditionPattern::SimpleComparison);
assert_eq!(
analyze_condition_pattern(&cond),
ConditionPattern::SimpleComparison
);
assert!(is_simple_comparison(&cond));
}
@ -543,7 +599,10 @@ mod tests {
fn test_analyze_pattern_var_cmp_var() {
// Phase 222: i > j → SimpleComparison
let cond = binop(BinaryOperator::Greater, var("i"), var("j"));
assert_eq!(analyze_condition_pattern(&cond), ConditionPattern::SimpleComparison);
assert_eq!(
analyze_condition_pattern(&cond),
ConditionPattern::SimpleComparison
);
assert!(is_simple_comparison(&cond));
}
}