| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import re |
|
|
| |
| SENIOR_PATTERN = re.compile( |
| r"λ°μ¬|ν¬μ€λ₯|ν¬μ€νΈλ₯|μμ|κ΅μ|μ°κ΅¬μ|μ°κ΅¬μ|" |
| r"phd|postdoc|post[- ]doc|researcher|professor|faculty|" |
| r"principal\s*investigator|\bpi\b", |
| re.IGNORECASE, |
| ) |
| JUNIOR_PATTERN = re.compile( |
| r"μμ¬|νλΆ|νμ¬|μ‘Έμ
μμ |" |
| r"master|undergraduate|bachelor|\bms\b|\bbs\b|" |
| r"grad(uate)?\s*student", |
| re.IGNORECASE, |
| ) |
|
|
| STANDARD_CONFLICTS = frozenset([ |
| "method_contradiction", |
| "causation_from_correlation", |
| ]) |
|
|
| STAT_WARNING_KEYWORDS = [ |
| "OLS", "νκ·", "μκ΄", "p-value", "λ΄μμ±", "μμΈκ³Ό", |
| "ν΅κ³", "κ²μ ", "λΆμ°", "νλ³Έ", "Cox", "ANOVA", |
| "regression", "correlation", "endogeneity", |
| ] |
|
|
|
|
| def _is_senior(stage: str) -> bool: |
| return bool(SENIOR_PATTERN.search(stage)) |
|
|
|
|
| def _is_junior(stage: str) -> bool: |
| return bool(JUNIOR_PATTERN.search(stage)) |
|
|
|
|
| def _has_stat_warning(logic_warnings: list) -> bool: |
| text = " ".join(logic_warnings) |
| return any(kw in text for kw in STAT_WARNING_KEYWORDS) |
|
|
|
|
| |
| |
| |
| def select_format( |
| conflict_type: str, |
| stage: str, |
| verdict: str, |
| logic_warnings: list, |
| venue: str = "", |
| specific_concern: str = "", |
| rag_found: bool = False, |
| evidence_gap: str = "", |
| ) -> tuple[str, str]: |
| """ |
| μ
λ ₯ νλΌλ―Έν° β (μΆλ ₯ TYPE, μ ν κ·Όκ±° ν μ€). |
| |
| λ°ν μ: |
| ("journal_fit_review", "μλμ΄ + λͺ©ν νμ μ§ μ§μ ") |
| ("growth_feedback", "PASS νμ ") |
| |
| νμ νΈνμ΄ νμνλ©΄ select_format_simple(...) μ¬μ©. |
| """ |
| if verdict == "PASS": |
| return "growth_feedback", "PASS νμ " |
|
|
| warning_count = len(logic_warnings) |
|
|
| if specific_concern and specific_concern.strip(): |
| return "concern_advisory", "ꡬ체μ μ°λ €μ¬ν μ κΈ°λ¨" |
|
|
| if rag_found and conflict_type and warning_count >= 2: |
| return "visual_report", f"RAG κ·Όκ±° + {conflict_type} + κ²½κ³ {warning_count}κ°" |
|
|
| if (conflict_type == "causation_from_correlation" |
| and _has_stat_warning(logic_warnings)): |
| return "statistical_review", "μΈκ³ΌΒ·μκ΄ νΌλ + ν΅κ³ κ²½κ³ " |
|
|
| if venue and _is_senior(stage): |
| return "journal_fit_review", f"μλμ΄ + λͺ©ν νμ μ§({venue})" |
|
|
| if rag_found and len(evidence_gap) > 10: |
| return "research_discovery", "RAG κ·Όκ±° + λͺ
νν κ·Όκ±° 곡백" |
|
|
| if _is_junior(stage) and ( |
| conflict_type in STANDARD_CONFLICTS or _has_stat_warning(logic_warnings) |
| ): |
| return "methodology_teaching", "μ΄κΈ μ°κ΅¬μ + λ°©λ²λ‘ /ν΅κ³ κ²½κ³ " |
|
|
| if conflict_type == "unsupported_generalization" and _is_senior(stage): |
| return "exploratory", "μλμ΄ + κ³ΌλμΌλ°ν μμ¬" |
|
|
| if _is_junior(stage) or warning_count >= 2: |
| reason = "μ΄κΈ μ°κ΅¬μ" if _is_junior(stage) else f"κ²½κ³ {warning_count}κ°" |
| return "checklist", reason |
|
|
| return "hypothesis_critique", "κΈ°λ³Έ κ²½λ‘ (νΉμ 쑰건 μμ)" |
|
|
|
|
| |
| |
| |
| def select_format_simple(**kwargs) -> str: |
| """μ΄μ λ²μ μ²λΌ strλ§ λ°ν.""" |
| fmt, _ = select_format(**kwargs) |
| return fmt |
|
|
|
|
| def needs_visual( |
| selected_format: str, |
| logic_warnings: list, |
| ) -> bool: |
| """HTML μκ°ν(TYPE_G) λ³ν νμ μ¬λΆ""" |
| if selected_format in ("journal_fit_review", "growth_feedback"): |
| return True |
| if selected_format == "research_discovery" and len(logic_warnings) >= 2: |
| return True |
| return False |
|
|