"""Explicit answer aspects; these select evidence, never supply facts.""" import re from tools.answers.context_policy import normalized FACET_PATTERNS = { "assignment": r"\b(?:zadani\w*|ciel\w*)\b", "plans": r"\b(?:planovan\w*|dalsi\w*\s+uloh\w*|uloh\w*)\b", "problems": r"\b(?:problem\w*|tazkost\w*|prekazk\w*|chyb\w*)\b", "methods": r"\b(?:metod\w*|technolog\w*|nastroj\w*|pouziv\w*|pouzil\w*)\b", "experiments": r"\b(?:experiment\w*|merani\w*|testovani\w*|vyhodnocov\w*)\b", "progress": r"\b(?:priebezn\w*\s+)?stav\w*\b", "results": r"\b(?:vysledk\w*|dosiahn\w*)\b", } FACET_LABELS = { "assignment": "Zadanie a ciele", "plans": "Plánované úlohy", "problems": "Riešené problémy", "methods": "Metódy a technológie", "experiments": "Experimenty a vyhodnotenie", "progress": "Priebežný stav", "results": "Zaznamenané výsledky", } def requested_facets(question: str) -> list[str]: text = normalized(re.sub(r'[„“"«][^„“”"»]+[“”"»]', " ", question)) matches = [ (m.start(), key) for key, pattern in FACET_PATTERNS.items() if (m := re.search(pattern, text)) ] return [key for _, key in sorted(matches)] def content_question(question: str) -> bool: text = normalized(question) return bool( requested_facets(question) or re.search( r"\b(?:comu|o com|obsah\w*|opis\w*|popis\w*|zamer\w*|zhrn\w*|implement\w*)\b", text ) ) def facet_mode(question: str) -> bool: facets = requested_facets(question) return any( facet in facets for facet in ["plans", "progress", "problems", "methods", "experiments", "results"] ) def actual_methods_requested(question: str) -> bool: return bool( re.search( r"\b(?:skutocne|pouziva\w*|pouzil\w*|vyuzival\w*|implementoval\w*)\b|" r"\b(?:pouzit\w*|aplikovan\w*|vyuzit\w*)\s+(?:metod\w*|technolog\w*|nastroj\w*)\b", normalized(question), ) ) def unresolved_followup(question: str) -> bool: return bool( re.fullmatch( r"(?:(?:daj|uved|ukaz|vypis|porovnaj|chcem|prosim)\s+)?" r"(?:obe|oba|obidv\w*|vsetky|prvy|druhy)(?:\s+(?:prace|projekty))?[.!?]?", normalized(question), ) ) def output_year_requested(question: str) -> bool: # A supplied year scopes the evidence; it does not itself ask for a year claim. text = normalized(question) without_filters = re.sub(r"\b(?:v|z|pre|na)\s+rok(?:u)?\s+\d+\b", " ", text) return bool(re.search(r"\brok\w*\b", without_filters)) def graph_needs_text(question: str) -> bool: text = normalized(re.sub(r'[„“"«][^„“”"»]+[“”"»]', " ", question)) # Explicit graph properties stay on their existing path. if re.search(r"\b(?:tag\w*|klucov\w*|kategor\w*|tem\w*|nazov\w*|autor\w*)\b", text): return False return bool( set(requested_facets(question)) & {"assignment", "plans", "problems", "methods", "experiments", "progress", "results"} ) def planned_experiments(question: str) -> bool: text = normalized(question) if re.search( r"\b(?:vykonal\w*|vykonan\w*|uskutocnil\w*|uskutocnen\w*|realizoval\w*|realizovan\w*|otestoval\w*|vyhodnotil\w*)\b", text, ): return False return bool( re.search( r"\b(?:plan\w*|pripravit|navrhnut)|" r"\b(?:mal|mali|mala|ma|maju)\s+(?:priprav\w*|navrhn\w*|otest\w*|vyhodnot\w*)", text, ) )