# explanation_math_firewall.py - V4.2 (Behavioral Firewall) # Prevents semantic leaks of forbidden mathematical concepts. import re import logging logger = logging.getLogger(__name__) # Concepts that are often "shadow paths" or over-qualified for lower grades FORBIDDEN_CONCEPTS = [ r"נגזרת", r"נגזור", r"גזירה", r"קיצון", r"מקסימום", r"מינימום", r"אינטגרל", r"אינטגרציה", r"הפרש", r"מערכת", r"נעלמים", r"שני נעלמים", r"פיתגורס", r"שורשים", r"מכנה משותף" # Add more as needed ] # Symbols that indicate over-qualified math FORBIDDEN_SYMBOLS = [ r"'", r"\\'", r"integral", r"\\int", r"\\Sigma", r"\\Delta" ] def scan_explanation(text: str, proof_graph) -> tuple[bool, str]: """ Scans explanation text for concepts NOT present in the ProofGraph. Returns (is_safe, violation_reason). """ if not text: return True, "" # 1. Check for Hebrew forbidden concepts for pattern in FORBIDDEN_CONCEPTS: if re.search(pattern, text): # Check if this concept is "allowed" because it's in the ProofGraph # (e.g., if we actually used a Derivative, it's fine to say 'נגזרת') is_in_proof = False if proof_graph: for step in proof_graph.steps: if step.operator_used and pattern in step.logic_description: is_in_proof = True break if not is_in_proof: logger.warning(f"🛡️ [FIREWALL] Semantic violation detected: '{pattern}'") return False, f"Concept '{pattern}' found in text but not in ProofGraph." # 2. Check for forbidden mathematical symbols for symbol in FORBIDDEN_SYMBOLS: if symbol in text: # Similar logic: check if the symbol appears in math_content of proof_graph is_in_proof = False if proof_graph: for step in proof_graph.steps: if symbol in str(step.math_content): is_in_proof = True break if not is_in_proof: logger.warning(f"🛡️ [FIREWALL] Symbol violation detected: '{symbol}'") return False, f"Symbol '{symbol}' found in text but not in ProofGraph." return True, ""