#@title 5A. CANDIDATE REALIZATION RELIABILITY PATCH v3.4 # Complete replacement for Cell 5A v3.3. # Run immediately after Cell 5 v4.1 and before Cell 6 v5. # # Purpose: # - reject malformed candidates at both generation stages; # - preserve valid relative clauses, appositives, lists, and terminology; # - remain rerun-safe after Generator is rebuilt by Cell 5; # - add no transformation families and change no semantic policy; # - expose precise rejection evidence to Cell 7, Cell 7B, and Cell 9. import re from collections import Counter # ===================================================================== # 0. PREREQUISITE AND VERSION CHECKS # ===================================================================== _REQUIRED_5A = [ "RULES", "rule", "Candidate", "Generator", "clean", "K", "lower_initial", "surface_key", "nlp", ] _missing_5a = [name for name in _REQUIRED_5A if name not in globals()] if _missing_5a: raise RuntimeError( "Cell 5A cannot run. Missing: " + ", ".join(_missing_5a) + ". Run the complete Cell 5 v4.1 first." ) EXPECTED_5A_RULE_COUNT = 30 if len(RULES) != EXPECTED_5A_RULE_COUNT: raise RuntimeError( f"Cell 5A expected {EXPECTED_5A_RULE_COUNT} Cell 5 v4.1 rules, " f"but found {len(RULES)}. Rerun Cell 5 v4.1 first." ) # ===================================================================== # 1. HIGH-CONFIDENCE REALIZATION CHECKS # ===================================================================== _SUBJECT_PRONOUNS = {"i", "we", "he", "she", "they", "who"} _OBJECT_PRONOUNS = {"me", "us", "him", "her", "them", "whom"} _FINITE_TAGS = {"VBD", "VBP", "VBZ", "MD"} _DECLARATIVE_STARTERS = { "i", "we", "you", "he", "she", "it", "they", "this", "that", "these", "those", "the", "a", "an", } _RELATIVE_MARKERS = {"that", "which", "who", "whose", "where"} def _r34_split_sentences(text): """Return bounded sentence units without modifying source content.""" value = clean(text) try: document = nlp()(value) units = [sent.text.strip() for sent in document.sents if sent.text.strip()] if units: return units except Exception: pass return [ part.strip() for part in re.split(r"(?<=[.!?])\s+", value) if part.strip() ] def _r34_parse(text): try: document = nlp()(str(text or "")) return document if len(document) else None except Exception: return None def _r34_has_finite_predicate(document): if document is None: return False for token in document: if token.tag_ in _FINITE_TAGS: return True if token.pos_ in {"VERB", "AUX"} and any( child.dep_ in {"aux", "auxpass"} and child.tag_ in _FINITE_TAGS for child in token.children ): return True return False def _r34_relative_clause_is_finite(document): """Validate finite predicates after explicit relative markers.""" if document is None: return True for token in document: if token.lower_ not in _RELATIVE_MARKERS: continue following = document[token.i + 1:] if not following: return False if not any( item.tag_ in _FINITE_TAGS or item.pos_ == "AUX" for item in following ): return False return True def _r34_orphan_participial_fragment(sentence): """ Detect noun/preposition fragments such as: 'Protocol to small cybersecurity learners spanning ...' while allowing a valid finite relative clause: 'learners that span ...' """ low = sentence.lower().strip() if re.search(r"\b(?:that|which|who)\s+(?:span|spans|cover|covers|include|includes|contain|contains|involve|involves)\b", low): return False document = _r34_parse(sentence) if document is not None and document.has_annotation("DEP"): root = next((token for token in document if token.dep_ == "ROOT"), None) if root is not None: if root.pos_ in {"VERB", "AUX"} and _r34_has_finite_predicate(document): return False participles = [ token for token in document if token.text.lower() in { "spanning", "covering", "including", "containing", "involving" } ] if participles and not _r34_has_finite_predicate(document): return True return bool(re.match( r"(?is)^(?:[A-Z][\w-]*|The|A|An)\b.+\s+" r"(?:spanning|covering|including|containing|involving)\s+.+$", sentence, )) and not bool(re.search( r"\b(?:is|are|was|were|has|have|had|do|does|did|can|could|may|might|" r"must|should|will|would|span|spans|cover|covers|include|includes|" r"contain|contains|involve|involves)\b", low, )) def _r34_clause_issues(text): issues = [] for index, sentence in enumerate(_r34_split_sentences(text), start=1): words = re.findall(r"[A-Za-z]+(?:[-'][A-Za-z]+)*", sentence) if not words: issues.append(f"EMPTY_SENTENCE_{index}") continue first = words[0].lower() document = _r34_parse(sentence) if first in _DECLARATIVE_STARTERS and not _r34_has_finite_predicate(document): issues.append(f"NONFINITE_DECLARATIVE_FRAGMENT_{index}") if document is not None: root = next((token for token in document if token.dep_ == "ROOT"), None) if ( first in _DECLARATIVE_STARTERS and root is not None and root.pos_ not in {"VERB", "AUX"} and not _r34_has_finite_predicate(document) ): issues.append(f"NOMINAL_ROOT_FRAGMENT_{index}") if not _r34_relative_clause_is_finite(document): issues.append(f"NONFINITE_RELATIVE_CLAUSE_{index}") else: if re.match( r"(?is)^(?:I|We|You|He|She|It|They|The|A|An|This|That|These|Those)\s+" r"(?:[A-Z][\w-]*\s+){1,8}" r"(?:Framework|System|Model|Protocol|Method|Procedure|Process|Team|Study)\b", sentence, ): issues.append(f"LIKELY_NOMINAL_FRAGMENT_{index}") if _r34_orphan_participial_fragment(sentence): issues.append(f"ORPHAN_PARTICIPIAL_FRAGMENT_{index}") return issues def _r34_balanced_delimiters(text): pairs = {"(": ")", "[": "]", "{": "}"} stack = [] for char in str(text or ""): if char in pairs: stack.append(pairs[char]) elif char in pairs.values(): if not stack or stack.pop() != char: return False return not stack def realization_issues(text): """Return only high-confidence grammatical/realization defects.""" value = clean(text) low = value.lower() issues = [] if not value: return ["EMPTY_OUTPUT"] if not _r34_balanced_delimiters(value): issues.append("UNBALANCED_DELIMITERS") if re.search( r"\b(?:for|to|with|by|from|of|about)\s+(?:i|we|he|she|they|who)\b", low, ): issues.append("SUBJECT_PRONOUN_AFTER_PREPOSITION") if re.match( r"^(?:me|us|him|her|them|whom)\s+" r"(?:am|is|are|was|were|must|should|can|could|may|might|will|would)\b", low, ): issues.append("OBJECT_PRONOUN_AS_SUBJECT") if re.match( r"^(?:inspect|distinguish|evaluate|examine|analyze|compare|apply|use|" r"test|measure|determine|identify|review|assess|implement|investigate)" r"\b.+\s+is\s+the\s+(?:next|first|second|third|final|primary|main)\s+" r"(?:step|task|action|objective|goal)\b", low, ): issues.append("BARE_ACTION_AS_NOMINAL_SUBJECT") if re.search(r"\b(?:is|are|was|were)\s+(?:is|are|was|were)\b", low): issues.append("DUPLICATED_COPULA") if re.search(r"\b(?:has|have|had)\s+been\s+been\b", low): issues.append("DUPLICATED_AUXILIARY") if re.search(r"\b(?:a|an)\s+(?:are|were|have|do)\b", low): issues.append("DETERMINER_BEFORE_FINITE_VERB") if re.search( r"\b(?:of|for|with|by|from|to|in|on|under|within|across)\s+" r"(?:The|A|An)\s+\w+", value, ): issues.append("INTERNAL_CAPITALIZED_DETERMINER") if re.search(r"\s+[,.!?;:]", value): issues.append("SPACE_BEFORE_PUNCTUATION") if re.search(r"[.!?]{2,}", value): issues.append("DUPLICATED_TERMINAL_PUNCTUATION") if len(re.findall(r"\b\w+\b", value)) < 3: issues.append("TOO_SHORT") issues.extend(_r34_clause_issues(value)) return list(dict.fromkeys(issues)) # ===================================================================== # 2. RELIABLE SAME-NAME RULE OVERRIDES # ===================================================================== @rule( "copular_action_frame", {"Balanced", "Structural"}, {"COPULAR_ACTION_FRAME"}, .96, ) def tr_copular_action_reliable(analysis, profile, user_terms): match = re.match( r"(?is)^The\s+(?Pnext|first|second|third|final|primary|main)\s+" r"(?P