# math_intent_detector.py - V4.2 (Intent Lockdown) # Rigidly classifies user intent before mathematical planning. import re import logging logger = logging.getLogger(__name__) # Rigid intent categories INTENT_SIMPLE_LINEAR = "SIMPLE_LINEAR_SOLVE" INTENT_WORD_PROBLEM_BASIC = "WORD_PROBLEM_BASIC" INTENT_FUNCTION_ANALYSIS = "FUNCTION_ANALYSIS" INTENT_SYSTEM_EQUATIONS = "SYSTEM_EQUATIONS" INTENT_GENERAL = "GENERAL" # V286.0: New intent categories for 5-unit math coverage INTENT_VECTORS_3D = "VECTORS_3D" INTENT_SOLID_GEOMETRY = "SOLID_GEOMETRY" INTENT_OPTIMIZATION = "OPTIMIZATION" INTENT_PROBABILITY = "PROBABILITY" INTENT_TRIGONOMETRY = "TRIGONOMETRY" INTENT_LOGARITHMS = "LOGARITHMS" INTENT_LIMITS = "LIMITS" def detect_intent(text: str, grade_num: int) -> str: """ Detects the rigid intent category based on keywords and grade boundaries. Focuses on 'Simplifying' intent for lower grades. """ text_lower = text.lower() # 1. Simple Linear Solve (Grade 7 focus) # Check for basic algebra keywords and lack of complex concepts simple_linear_keywords = ["x=", "פתור", "משוואה", "נעלם"] is_simple_algebra = any(kw in text_lower for kw in simple_linear_keywords) # Exclusion markers for simple intent complex_markers = ["נגזרת", "קיצון", "מערכת", "שני נעלמים", "x^2", "x²"] has_complex_content = any(cm in text_lower for cm in complex_markers) if grade_num == 7 and is_simple_algebra and not has_complex_content: print("🎯 [INTENT] Classified as SIMPLE_LINEAR_SOLVE (Grade 7 Lockdown)") return INTENT_SIMPLE_LINEAR # 2. Word Problem Basic word_problem_keywords = ["בעיה", "מילולית", "קנה", "מחיר", "סך הכל"] if any(kw in text_lower for kw in word_problem_keywords): print("🎯 [INTENT] Classified as WORD_PROBLEM_BASIC") return INTENT_WORD_PROBLEM_BASIC # 3. System of Equations if "מערכת" in text_lower or "שני נעלמים" in text_lower: print("🎯 [INTENT] Classified as SYSTEM_EQUATIONS") return INTENT_SYSTEM_EQUATIONS # 4. Function Analysis function_markers = ["נגזרת", "קיצון", "חקירה", "פונקציה", "f(x)"] if any(fm in text_lower for fm in function_markers): print("🎯 [INTENT] Classified as FUNCTION_ANALYSIS") return INTENT_FUNCTION_ANALYSIS # V286.0: 5-unit intent categories # 5. Vectors 3D if any(kw in text_lower for kw in ["וקטור", "וקטורים", "מכפלה סקלרית", "מכפלה וקטורית"]): if any(kw in text_lower for kw in ["מרחב", "מישור", "תלת", "z"]): print("🎯 [INTENT] Classified as VECTORS_3D") return INTENT_VECTORS_3D # 6. Solid Geometry if any(kw in text_lower for kw in ["פירמידה", "מנסרה", "תיבה", "חתך", "אפותם", "פאות"]): print("🎯 [INTENT] Classified as SOLID_GEOMETRY") return INTENT_SOLID_GEOMETRY # 7. Optimization if any(kw in text_lower for kw in ["מקסימום", "מינימום", "מקסימלי", "מינימלי", "ערך מרבי", "ערך מזערי", "שטח גדול ביותר", "נפח מקסימלי"]): print("🎯 [INTENT] Classified as OPTIMIZATION") return INTENT_OPTIMIZATION # 8. Probability if any(kw in text_lower for kw in ["הסתברות", "קומבינטור", "תמורה", "צירוף", "בייס"]): print("🎯 [INTENT] Classified as PROBABILITY") return INTENT_PROBABILITY # 9. Trigonometry if any(kw in text_lower for kw in ["sin", "cos", "tan", "טריגונומטר", "סינוס", "קוסינוס"]): print("🎯 [INTENT] Classified as TRIGONOMETRY") return INTENT_TRIGONOMETRY # 10. Logarithms if any(kw in text_lower for kw in ["לוגריתם", "log", "ln", "מעריכי"]): print("🎯 [INTENT] Classified as LOGARITHMS") return INTENT_LOGARITHMS # 11. Limits if any(kw in text_lower for kw in ["גבול", "lim", "שואף", "לופיטל"]): print("🎯 [INTENT] Classified as LIMITS") return INTENT_LIMITS def _extract_grade_number(text: str) -> int: import re # מחלץ מספר מתוך מחרונה (למשל "ז׳" או "כיתה 7") match = re.search(r'\d+', text) if match: return int(match.group()) # מיפוי ידני למקרים של אותיות mapping = {'ז': 7, 'ח': 8, 'ט': 9, 'י': 10, 'יא': 11, 'יב': 12} for char, num in mapping.items(): if char in text: return num return -1 def get_intent_contract(intent: str, grade_num: int) -> dict: """ Returns the 'Action Contract' for the given intent. This contract is used to constrain the LLM/Solver. """ if intent == INTENT_SIMPLE_LINEAR and grade_num == 7: return { "max_variables": 1, "allowed_operators": ["ADD", "SUB", "MUL", "DIV"], "forbidden_strategies": ["DERIVATIVES", "SYSTEM_OF_EQUATIONS", "COMPLEX_SUBSTITUTION"], "variable_preference": "x", "narrative_tone": "simple_step_by_step" } if intent == INTENT_WORD_PROBLEM_BASIC: return { "max_variables": 2 if grade_num > 8 else 1, "focus": "translation_to_algebra", "forbidden_strategies": ["CALCULUS"] } return {"status": "unconstrained"}