fix: subtype resolver + comprehensive matching program test

Fix 4 remaining defects found by adversarial testing:
1. MT03 N:1 → subtype corrected to N:1 (key suffix -M/-T heuristic)
2. MT32 混合 → subtype added (項目チェック programs with WS-PREV-KEY)
3. MT33 混合异键 → WS-ALT-KEY detection → 混合(异键)
4. MT18/MT19 → subtype M:N (correct: static cannot distinguish M:N→M vs M:N→N)

Also expand subtype resolver scope: now also processes 項目チェック
classified programs with matching-like characteristics (WS-PREV-KEY),
not just マッチング.

New test: test_matching_programs.py — 10 parametrized tests covering
all 4 dimensions (category, subtype, branches, files) for every
matching program. Known limitation documented: MT18 vs MT19
requires runtime data for M:N→M vs M:N→N distinction.

Regression: 755 passed (10 new, 0 failures).
This commit is contained in:
NB-076
2026-06-21 13:40:58 +08:00
parent 6b3f526b80
commit a5939e6722
2 changed files with 103 additions and 5 deletions
+23 -5
View File
@@ -429,8 +429,8 @@ def _resolve_matching_subtype(
更新后的 result,增加 "subtype" 字段。
"""
category = result.get("category", "")
if "マッチング" not in category and "キーブレイク" not in category:
return result # 非匹配程序不做子类型区分
if "マッチング" not in category and "キーブレイク" not in category and "項目チェック" not in category:
return result # 非匹配/校验程序不做子类型区分
src_upper = cobol_source.upper()
import re
@@ -445,12 +445,17 @@ def _resolve_matching_subtype(
result["subtype"] = "M:N→MxN"
return result
# 2. 混合匹配 (WS-PREV-KEY 存在)
# 2. 混合匹配 (WS-PREV-KEY 存在) — 也覆盖 項目チェック 分类
if 'WS-PREV-KEY' in src_upper:
result["subtype"] = "混合"
return result
# 3. 检查键变量命名模式
# 3. WS-ALT-KEY → 混合(异键)
if 'WS-ALT-KEY' in src_upper or 'ALTERNATE' in src_upper.upper():
result["subtype"] = "混合(异键)"
return result
# 4. 检查键变量命名模式
key_vars = set(re.findall(r'WS-[\w-]*KEY[A-Z0-9-]*', src_upper))
# 不对称键名 → 1:N 或 N:1 (WS-MAST-KEY + WS-TRAN-KEY)
@@ -460,7 +465,20 @@ def _resolve_matching_subtype(
result["subtype"] = "1:N"
return result
# ── 第 2 层: 静态规则+LLM 辅助 ──
# 5. 命名模式启发式: WS-KEY-M/WS-KEY-T → Master/Transaction → N:1
# WS-KEY-A/WS-KEY-B → 对称命名 → 1:1
# WS-KEY-M/WS-KEY-N → M:N 多文件
key_suffixes = [k.split('-')[-1] if '-' in k else '' for k in key_vars]
if 'M' in key_suffixes and 'T' in key_suffixes:
# WS-KEY-M + WS-KEY-T → Master/Transaction → N:1
result["subtype"] = "N:1"
return result
if 'M' in key_suffixes and 'N' in key_suffixes:
# WS-KEY-M + WS-KEY-N → M:N 多文件(无法区分 M:N→M 还是 M:N→N)
result["subtype"] = "M:N"
return result
# ── 第 2 层: LLM 辅助 ──
# 多个键变量 + 多文件 → 可能是 M:N→M 或 M:N→N,需要 LLM 分辨
needs_llm = (
len(key_vars) >= 3 or