#@title 5A. UNIVERSAL CANDIDATE REALIZATION RELIABILITY v4.7 — 42-rule alignment # Complete replacement for Cell 5A v4.7; aligned with Cell 5 v5. # Run immediately after Cell 5 v5 and before Cell 6 v6. # # 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 v5 first." ) EXPECTED_5A_RULE_COUNT = 42 if len(RULES) != EXPECTED_5A_RULE_COUNT: raise RuntimeError( f"Cell 5A expected {EXPECTED_5A_RULE_COUNT} Cell 5 v5 rules, " f"but found {len(RULES)}. Rerun Cell 5 v5 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 _r45_recover_misparsed_finite_predicate(document): """Recover a finite predicate from a known parser ambiguity. Some English past-tense forms are surface-identical to past participles. A parser can therefore analyze a normal clause such as ``The model operated within its established configuration`` as a noun ROOT (model) plus an ``acl`` VBN (operated). This helper accepts that structure only when strong clause evidence is present and passive/reduced-relative evidence is absent. """ if document is None: return False # The helper receives either a spaCy Doc or a sentence Span. Doc exposes # has_annotation directly; Span exposes the parent Doc through .doc. annotation_owner = document if hasattr(document, "has_annotation") else getattr(document, "doc", None) if annotation_owner is None or not annotation_owner.has_annotation("DEP"): return False tokens = list(document) root = next((token for token in tokens if token.dep_ == "ROOT"), None) if root is None or root.pos_ not in {"NOUN", "PROPN", "PRON"}: return False # Require an overt determiner/possessor or sentence-initial nominal subject. has_nominal_anchor = any( child.dep_ in {"det", "poss", "compound", "amod"} for child in root.children ) or root.i == 0 if not has_nominal_anchor: return False candidates = [ child for child in root.children if child.dep_ in {"acl", "relcl"} and child.pos_ == "VERB" and child.tag_ in {"VBD", "VBN"} and child.i > root.i ] for verb in candidates: # Reject passive/reduced-relative evidence such as # ``the model operated by the laboratory``. child_deps = {child.dep_ for child in verb.children} has_passive_evidence = bool( {"auxpass", "aux:pass", "agent", "obl:agent"} & child_deps ) or any( child.lower_ == "by" and child.dep_ in {"prep", "agent"} for child in verb.children ) if has_passive_evidence: continue # A finite-clause interpretation needs material governed by the verb, # such as an object, complement, adverb, or prepositional phrase. has_predicate_complement = any( child.dep_ in { "obj", "dobj", "attr", "oprd", "prep", "obl", "advmod", "advcl", "ccomp", "xcomp", "dative", } for child in verb.children ) if has_predicate_complement: return True return False def _r34_has_finite_predicate(document): """Detect finite predicates by syntax before trusting ambiguous tags. English present-tense verbs with plural subjects are surface-identical to the bare infinitive. spaCy may therefore tag a finite root such as ``Models ... inform ...`` as VB/VerbForm=Inf. A ROOT verb with an explicit subject and no infinitival marker is treated as finite. This is structural, vocabulary-independent, and does not depend on a verb dictionary. """ if document is None: return False if _r45_recover_misparsed_finite_predicate(document): return True tokens = list(document) for token in tokens: if token.tag_ in _FINITE_TAGS: return True try: if "Fin" in token.morph.get("VerbForm"): return True except Exception: pass if token.pos_ in {"VERB", "AUX"} and any( child.dep_ in {"aux", "auxpass", "aux:pass"} and ( child.tag_ in _FINITE_TAGS or "Fin" in child.morph.get("VerbForm") ) for child in token.children ): return True if token.dep_ == "ROOT" and token.pos_ in {"VERB", "AUX"}: subjects = [ child for child in token.children if child.dep_ in {"nsubj", "nsubjpass", "nsubj:pass", "csubj", "expl"} ] infinitive_markers = [ child for child in token.children if child.lower_ == "to" and child.dep_ in {"aux", "mark"} ] # A verbal ROOT governing an explicit subject is a finite clause, # even when the tagger labels the surface-identical plural-present # form as VB/VerbForm=Inf (e.g., models inform, devices trigger). if subjects and not infinitive_markers: return True verb_form = set() try: verb_form = set(token.morph.get("VerbForm")) except Exception: pass if token.tag_ not in {"VBG", "VBN", "VB"} and not ({"Inf", "Ger", "Part"} & verb_form): 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 _r34_has_finite_predicate(following): return False return True def _r34_orphan_participial_fragment(sentence): """Detect vocabulary-independent orphan VBG/VBN modifier fragments. The check does not depend on a list such as spanning/covering/including. It uses dependency labels, verb tags, finite-predicate evidence, and the presence of an explicit relative-clause marker. """ value = str(sentence or "").strip() low = value.lower() document = _r34_parse(value) if document is not None and document.has_annotation("DEP"): if _r45_recover_misparsed_finite_predicate(document): return False root = next((token for token in document if token.dep_ == "ROOT"), None) if root is not None and root.pos_ in {"VERB", "AUX"}: subjects = [ child for child in root.children if child.dep_ in {"nsubj", "nsubjpass", "nsubj:pass", "csubj", "expl"} ] infinitive_markers = [ child for child in root.children if child.lower_ == "to" and child.dep_ in {"aux", "mark"} ] if subjects and not infinitive_markers: return False if _r34_has_finite_predicate(document): return False # A valid finite relative clause has a relative marker followed by a # finite verbal predicate. This accepts unseen verbs such as calibrate, # triangulate, reconcile, or decarbonize. for marker in document: if marker.lower_ not in _RELATIVE_MARKERS: continue following = document[marker.i + 1:] if any(token.tag_ in _FINITE_TAGS or token.pos_ == "AUX" for token in following): return False participles = [ token for token in document if token.tag_ in {"VBG", "VBN"} and token.dep_ in {"ROOT", "acl", "relcl", "advcl", "amod"} ] if participles and not _r34_has_finite_predicate(document): return True # A trained dependency parse was available and did not establish an # orphan fragment. Stop here. Falling through to a suffix-only surface # heuristic would falsely reject valid sentences such as: # Models predicting regional demand inform the allocation process. return False # No dependency parse is available. Keep the fallback deliberately narrow: # reject explicit malformed relative patterns and known duplicate auxiliary # constructions, but do not infer that every -ing/-ed word creates a # fragment. That would reject unseen finite verbs following modifiers. if re.search( r"(?iu)\b(?:that|which|who)\s+[^\W\d_]+(?:ing|ed)\b", value, ): return True if re.search( r"(?iu)\b(?:am|is|are|was|were|has|have|had)\s+" r"(?:am|is|are|was|were|has|have|had)\b", value, ): return True return False def _r34_clause_issues(text): issues = [] for index, sentence in enumerate(_r34_split_sentences(text), start=1): words = re.findall(r"[^\W\d_]+(?:[-’'][^\W\d_]+)*", sentence, flags=re.UNICODE) 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 _r4_dependency_realization_issues(text): """Vocabulary-independent dependency and morphology realization checks.""" issues = [] document = _r34_parse(text) if document is None or not document.has_annotation("DEP"): return issues for sentence_index, sentence in enumerate(document.sents, start=1): root = next((token for token in sentence if token.dep_ == "ROOT"), None) if root is None: issues.append(f"MISSING_ROOT_{sentence_index}") continue # Declarative-looking multiword units should normally contain a finite # predicate unless they are headings, labels, or explicit fragments. token_count = sum(not token.is_punct and not token.is_space for token in sentence) recovered_finite = _r45_recover_misparsed_finite_predicate(sentence) if ( token_count >= 3 and root.pos_ not in {"VERB", "AUX"} and not recovered_finite ): first = next( (token for token in sentence if not token.is_punct and not token.is_space), None, ) if ( first is not None and first.lower_ in _DECLARATIVE_STARTERS and not _r34_has_finite_predicate(sentence) ): issues.append(f"NONVERBAL_DECLARATIVE_ROOT_{sentence_index}") # Reject an explicit relative marker whose clause contains no finite # verb, regardless of the vocabulary used after the marker. for token in sentence: if token.lower_ in _RELATIVE_MARKERS: tail = sentence.doc[token.i + 1:sentence.end] if not _r34_has_finite_predicate(tail): issues.append(f"NONFINITE_RELATIVE_CLAUSE_{sentence_index}") break # Reject duplicated adjacent auxiliaries more generally than the # fixed is-is / been-been surface checks. previous_aux = None for token in sentence: if token.pos_ == "AUX": if previous_aux is not None and previous_aux.lemma_ == token.lemma_: issues.append(f"DUPLICATED_AUXILIARY_SEQUENCE_{sentence_index}") break previous_aux = token elif not token.is_punct: previous_aux = None return issues def _r44_possessive_determiner_issues(text): """Detect high-confidence use of object pronoun *it* where *its* is required. Example rejected: "under it prespecified positive-mean criterion" This is a rejection check, not an automatic correction. The generator is allowed to try another candidate instead of silently changing content. """ issues = [] document = _r34_parse(text) if document is not None and document.has_annotation("DEP"): tokens = list(document) for index, token in enumerate(tokens[:-2]): if token.lower_ != "it" or token.pos_ != "PRON": continue following = tokens[index + 1:index + 5] # Look for one or more adjectival/participial modifiers followed by # a noun. This captures "it prespecified criterion" and analogous # malformed possessive-determiner sequences without hard-coding # the adjective or noun. modifier_count = 0 noun_found = False for item in following: if item.pos_ in {"ADJ"} or item.tag_ in {"VBN", "VBG"}: modifier_count += 1 continue if item.pos_ in {"NOUN", "PROPN"} and modifier_count: noun_found = True break previous = tokens[index - 1] if index > 0 else None if ( noun_found and previous is not None and previous.lower_ in { "under", "within", "according", "based", "from", "in", "on", "through", "with", "by", "after", "before", } ): issues.append("OBJECT_PRONOUN_IN_POSSESSIVE_DETERMINER_SLOT") break # Narrow fallback if dependency annotations are unavailable or ambiguous. # Require a preposition, "it", at least one adjectival-looking modifier, # and a following noun-like token. Common finite continuations are excluded. if re.search( r"(?iu)\b(?:under|within|according\s+to|based\s+on|from|in|on|through|with|by)\s+" r"it\s+(?:[^\W\d_]+(?:[-’'][^\W\d_]+)*\s+){1,3}" r"(?:criterion|criteria|framework|procedure|configuration|method|model|" r"policy|protocol|design|analysis|assessment|evaluation|standard|rule|" r"requirement|approach|context|structure|setting|settings)\b", str(text or ""), ): issues.append("OBJECT_PRONOUN_IN_POSSESSIVE_DETERMINER_SLOT") return list(dict.fromkeys(issues)) def _r44_result_adjunct_punctuation_issues(text): """Detect a missing comma before a supplementary 'thereby + VBG' result.""" issues = [] for sentence in _r34_split_sentences(text): match = re.search(r"(?iu)\bthereby\s+[^\W\d_]+ing\b", sentence) if not match: continue prefix = sentence[:match.start()].rstrip() # Only flag sentence-final/supplementary result adjuncts after a full # clause. A comma or semicolon already supplies the required boundary. if ( len(re.findall(r"[^\W\d_]+", prefix, flags=re.UNICODE)) >= 5 and not prefix.endswith((",", ";", ":")) ): issues.append("MISSING_COMMA_BEFORE_THEREBY_RESULT_ADJUNCT") return issues 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)) issues.extend(_r4_dependency_realization_issues(value)) issues.extend(_r44_possessive_determiner_issues(value)) issues.extend(_r44_result_adjunct_punctuation_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