// comprehend.el - ELP native COMPREHENSION front-end: text -> meaning-spec. // // The input half of the ELP, the deterministic inverse of the realizer. No LLM, // no spaCy: analysis uses ELP's own morphology tables run BACKWARD (invertible // morphology), a deterministic clause grammar for roles / subordination / // coordination / polarity, and a word-sense picker that (at runtime) defers to // the engram's own nearest-region embeddings. // // parse_spec(text) -> [String] (a slot map, the same shape realize() consumes, // EXTENDED with the SACRED polarity field): // intent "assert" | "question" | "command" // agent subject referent (pronoun surface, or "det adj noun") // predicate verb concept (English lemma = interlingua) // patient direct-object NP (optional) // iobj recipient NP for ditransitives (optional) // location prepositional adjunct e.g. "with the telescope" (optional) // tense "present" | "past" | "future" // aspect "simple" | "progressive" | "perfect" // polarity "aff" | "neg" <-- SACRED. Always present. Never inferred away. // neg_word standalone negative adverb e.g. "never" (optional) // subord_conj subordinating conjunction concept e.g. "because" (optional) // subord_pred predicate of the subordinate clause (optional) // lang ISO 639-1 code // // Depends on (via concatenation order): language-profile, morphology, grammar. // ── token cleaning ──────────────────────────────────────────────────────────── fn cp_is_punct(c: String) -> Bool { if str_eq(c, ".") { return true } if str_eq(c, ",") { return true } if str_eq(c, "!") { return true } if str_eq(c, "?") { return true } if str_eq(c, ";") { return true } if str_eq(c, ":") { return true } if str_eq(c, "\"") { return true } if str_eq(c, "'") { return true } if str_eq(c, "(") { return true } if str_eq(c, ")") { return true } return false } fn cp_trim_punct(s: String) -> String { let n: Int = str_len(s) let end: Int = n let running: Bool = true while running { if end <= 0 { let running = false } else { let c: String = str_slice(s, end - 1, end) if cp_is_punct(c) { let end = end - 1 } else { let running = false } } } let start: Int = 0 let running2: Bool = true while running2 { if start >= end { let running2 = false } else { let c2: String = str_slice(s, start, start + 1) if cp_is_punct(c2) { let start = start + 1 } else { let running2 = false } } } return str_slice(s, start, end) } fn cp_clean(tok: String) -> String { return str_to_lower(cp_trim_punct(tok)) } fn cp_tokenize(text: String) -> [String] { let raw: [String] = str_split(text, " ") let n: Int = native_list_len(raw) let out: [String] = native_list_empty() let i: Int = 0 while i < n { let t: String = cp_clean(native_list_get(raw, i)) if !str_eq(t, "") { let out = native_list_append(out, t) } let i = i + 1 } return out } // ── closed-class lexicon ────────────────────────────────────────────────────── fn cp_is_determiner(w: String) -> Bool { if str_eq(w, "the") { return true } if str_eq(w, "a") { return true } if str_eq(w, "an") { return true } if str_eq(w, "this") { return true } if str_eq(w, "these") { return true } if str_eq(w, "those") { return true } if str_eq(w, "my") { return true } if str_eq(w, "your") { return true } if str_eq(w, "his") { return true } if str_eq(w, "its") { return true } if str_eq(w, "our") { return true } if str_eq(w, "their") { return true } return false } // English subject/object pronoun -> concept ("" if not a pronoun). fn cp_pron_concept(w: String) -> String { if str_eq(w, "i") { return "i" } if str_eq(w, "me") { return "i" } if str_eq(w, "we") { return "we" } if str_eq(w, "us") { return "we" } if str_eq(w, "you") { return "you" } if str_eq(w, "he") { return "he" } if str_eq(w, "him") { return "he" } if str_eq(w, "she") { return "she" } if str_eq(w, "it") { return "it" } if str_eq(w, "they") { return "they" } if str_eq(w, "them") { return "they" } return "" } // concept -> canonical subject surface (the form realize()/agent_person expects). fn cp_pron_surface(concept: String) -> String { if str_eq(concept, "i") { return "I" } if str_eq(concept, "we") { return "we" } if str_eq(concept, "you") { return "you" } if str_eq(concept, "he") { return "he" } if str_eq(concept, "she") { return "she" } if str_eq(concept, "it") { return "it" } if str_eq(concept, "they") { return "they" } return concept } fn cp_is_preposition(w: String) -> Bool { if str_eq(w, "in") { return true } if str_eq(w, "on") { return true } if str_eq(w, "at") { return true } if str_eq(w, "to") { return true } if str_eq(w, "with") { return true } if str_eq(w, "from") { return true } if str_eq(w, "by") { return true } if str_eq(w, "for") { return true } if str_eq(w, "of") { return true } if str_eq(w, "into") { return true } if str_eq(w, "onto") { return true } if str_eq(w, "over") { return true } if str_eq(w, "under") { return true } if str_eq(w, "about") { return true } if str_eq(w, "than") { return true } if str_eq(w, "through") { return true } if str_eq(w, "near") { return true } if str_eq(w, "around") { return true } if str_eq(w, "between") { return true } if str_eq(w, "without") { return true } if str_eq(w, "upon") { return true } return false } // SACRED: negation lexeme test. Cross-lingual so the same field survives transfer. fn cp_is_negation(w: String) -> Bool { if str_eq(w, "not") { return true } if str_eq(w, "never") { return true } if str_eq(w, "no") { return true } if str_eq(w, "none") { return true } if str_eq(w, "nothing") { return true } if str_eq(w, "nobody") { return true } if str_eq(w, "cannot") { return true } if str_contains(w, "n't") { return true } if str_eq(w, "nada") { return true } if str_eq(w, "nadie") { return true } if str_eq(w, "nunca") { return true } if str_eq(w, "jamás") { return true } if str_eq(w, "jamais") { return true } if str_eq(w, "não") { return true } if str_eq(w, "nem") { return true } if str_eq(w, "nenhum") { return true } if str_eq(w, "ninguém") { return true } return false } fn cp_is_neg_adverb(w: String) -> Bool { if str_eq(w, "never") { return true } if str_eq(w, "nunca") { return true } if str_eq(w, "jamás") { return true } if str_eq(w, "jamais") { return true } return false } fn cp_is_aux(w: String) -> Bool { if str_eq(w, "am") { return true } if str_eq(w, "is") { return true } if str_eq(w, "are") { return true } if str_eq(w, "was") { return true } if str_eq(w, "were") { return true } if str_eq(w, "be") { return true } if str_eq(w, "been") { return true } if str_eq(w, "being") { return true } if str_eq(w, "do") { return true } if str_eq(w, "does") { return true } if str_eq(w, "did") { return true } if str_eq(w, "have") { return true } if str_eq(w, "has") { return true } if str_eq(w, "had") { return true } if str_eq(w, "will") { return true } if str_eq(w, "shall") { return true } if str_eq(w, "would") { return true } if str_eq(w, "should"){ return true } if str_eq(w, "can") { return true } if str_eq(w, "could") { return true } if str_eq(w, "may") { return true } if str_eq(w, "might") { return true } if str_eq(w, "must") { return true } return false } // Subordinating conjunctions that segment a clause (concept-neutral English set). fn cp_is_subordinator(w: String) -> Bool { if str_eq(w, "because") { return true } if str_eq(w, "since") { return true } if str_eq(w, "although") { return true } if str_eq(w, "though") { return true } if str_eq(w, "if") { return true } if str_eq(w, "when") { return true } if str_eq(w, "while") { return true } if str_eq(w, "before") { return true } if str_eq(w, "after") { return true } if str_eq(w, "until") { return true } return false } // ── invertible English verb morphology (the realizer table, run BACKWARD) ────── // // cp_irr2(surface) -> [lemma, tense] or empty. Mirrors en_irregular_verb rows in // morphology.el (same table), inverted, plus "fight" which the acceptance set // needs. This is the ELP invertibility principle: one table both speaks and // understands. fn cp_irr_row(base: String, three: String, past: String, pp: String, ger: String, surface: String) -> [String] { let r: [String] = native_list_empty() if str_eq(surface, past) { let r = native_list_append(r, base) let r = native_list_append(r, "past") return r } if str_eq(surface, pp) { let r = native_list_append(r, base) let r = native_list_append(r, "past") return r } if str_eq(surface, three) { let r = native_list_append(r, base) let r = native_list_append(r, "present") return r } if str_eq(surface, ger) { let r = native_list_append(r, base) let r = native_list_append(r, "present") return r } if str_eq(surface, base) { let r = native_list_append(r, base) let r = native_list_append(r, "present") return r } return r } fn cp_irr2(surface: String) -> [String] { let r: [String] = cp_irr_row("be", "is", "was", "been", "being", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("be", "are", "were", "been", "being", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("have", "has", "had", "had", "having", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("do", "does", "did", "done", "doing", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("go", "goes", "went", "gone", "going", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("say", "says", "said", "said", "saying", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("make", "makes", "made", "made", "making", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("know", "knows", "knew", "known", "knowing", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("take", "takes", "took", "taken", "taking", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("see", "sees", "saw", "seen", "seeing", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("come", "comes", "came", "come", "coming", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("think", "thinks", "thought", "thought", "thinking", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("get", "gets", "got", "gotten", "getting", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("give", "gives", "gave", "given", "giving", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("find", "finds", "found", "found", "finding", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("tell", "tells", "told", "told", "telling", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("leave", "leaves", "left", "left", "leaving", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("feel", "feels", "felt", "felt", "feeling", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("bring", "brings", "brought", "brought", "bringing", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("run", "runs", "ran", "run", "running", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("eat", "eats", "ate", "eaten", "eating", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("read", "reads", "read", "read", "reading", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("fight", "fights", "fought", "fought", "fighting", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("write", "writes", "wrote", "written", "writing", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("begin", "begins", "began", "begun", "beginning", surface) if native_list_len(r) > 0 { return r } let r = cp_irr_row("become", "becomes", "became", "become", "becoming", surface) if native_list_len(r) > 0 { return r } let empty: [String] = native_list_empty() return empty } // cp_reg_verb(surface) -> [lemma, tense, aspect] by suffix stripping (regular). // ── English silent-e / consonant-doubling inverse (past-participle lemmatizer) ── // // Stripping "-ed" naively over-truncates two regular classes: // • silent-e verbs ("loved" -> "lov" instead of "love") // • doubled-final ("stopped" -> "stopp" instead of "stop") // These helpers invert en_verb_past() so the round-trip closes. The rules are // the safe, high-confidence subset; residual orthographic edge cases (e.g. bare // "ebb"/"arc") are rare and left to the runtime vocabulary confirmer. fn cp_e_vowel(c: String) -> Bool { if str_eq(c, "a") { return true } if str_eq(c, "e") { return true } if str_eq(c, "i") { return true } if str_eq(c, "o") { return true } if str_eq(c, "u") { return true } return false } // consonants that double under inflection (CVC rule): b d g l m n p r t fn cp_e_doubling(c: String) -> Bool { if str_eq(c, "b") { return true } if str_eq(c, "d") { return true } if str_eq(c, "g") { return true } if str_eq(c, "l") { return true } if str_eq(c, "m") { return true } if str_eq(c, "n") { return true } if str_eq(c, "p") { return true } if str_eq(c, "r") { return true } if str_eq(c, "t") { return true } return false } // restore the base after "-ed"/"-ing" stripping produced `stem`. fn cp_e_restore(stem: String) -> String { let m: Int = str_len(stem) if m < 2 { return stem } let last: String = str_slice(stem, m - 1, m) let prev: String = str_slice(stem, m - 2, m - 1) // inflectional doubled consonant -> collapse (stopped->stop, planned->plan) if str_eq(last, prev) { if cp_e_doubling(last) { return str_slice(stem, 0, m - 1) } } // silent-e restoration if str_eq(last, "v") { return stem + "e" } if str_eq(last, "u") { return stem + "e" } let ctx: Bool = false if cp_e_vowel(prev) { let ctx = true } if str_eq(prev, "l") { let ctx = true } if str_eq(prev, "r") { let ctx = true } if str_eq(prev, "n") { let ctx = true } if ctx { if str_eq(last, "c") { return stem + "e" } if str_eq(last, "g") { return stem + "e" } if str_eq(last, "s") { return stem + "e" } if str_eq(last, "z") { return stem + "e" } } return stem } fn cp_reg_verb(w: String) -> [String] { let n: Int = str_len(w) let r: [String] = native_list_empty() if str_ends_with(w, "ing") { if n > 4 { let lemma: String = cp_e_restore(str_slice(w, 0, n - 3)) let r = native_list_append(r, lemma) let r = native_list_append(r, "present") let r = native_list_append(r, "progressive") return r } } if str_ends_with(w, "ied") { let lemma: String = str_slice(w, 0, n - 3) + "y" let r = native_list_append(r, lemma) let r = native_list_append(r, "past") let r = native_list_append(r, "simple") return r } if str_ends_with(w, "ed") { if n > 2 { let lemma: String = cp_e_restore(str_slice(w, 0, n - 2)) let r = native_list_append(r, lemma) let r = native_list_append(r, "past") let r = native_list_append(r, "simple") return r } } if str_ends_with(w, "ies") { let lemma: String = str_slice(w, 0, n - 3) + "y" let r = native_list_append(r, lemma) let r = native_list_append(r, "present") let r = native_list_append(r, "simple") return r } if str_ends_with(w, "es") { if n > 3 { let lemma: String = str_slice(w, 0, n - 2) let r = native_list_append(r, lemma) let r = native_list_append(r, "present") let r = native_list_append(r, "simple") return r } } if str_ends_with(w, "s") { if n > 2 { let lemma: String = str_slice(w, 0, n - 1) let r = native_list_append(r, lemma) let r = native_list_append(r, "present") let r = native_list_append(r, "simple") return r } } let r = native_list_append(r, w) let r = native_list_append(r, "present") let r = native_list_append(r, "simple") return r } // ── word-sense disambiguation (deterministic; engram nearest-region at runtime) ─ // // The reference (wsd.py) ranks a FIXED sense inventory by embedding cosine to the // token's syntactic neighbours using the ENGRAM's own geometry — never an // external generator. In this offline el module we resolve the same fixed // inventory by deterministic SYNTACTIC POSITION (subject-follows -> verb, etc.); // cp_wsd_needs_engram() marks the tokens whose final sense the live runtime // should confirm via the engram's nearest-region ranker. fn cp_is_ambiguous(w: String) -> Bool { if str_eq(w, "flies") { return true } if str_eq(w, "fly") { return true } if str_eq(w, "like") { return true } if str_eq(w, "saw") { return true } if str_eq(w, "left") { return true } if str_eq(w, "rose") { return true } return false } // Is w a plausible finite verb form (used for subject|verb boundary detection)? fn cp_is_verb_form(w: String) -> Bool { let irr: [String] = cp_irr2(w) if native_list_len(irr) > 0 { return true } if str_eq(w, "flies") { return true } if str_eq(w, "fly") { return true } if str_eq(w, "rose") { return true } if str_eq(w, "left") { return true } let n: Int = str_len(w) if str_ends_with(w, "ing") { if n > 4 { return true } } if str_ends_with(w, "ed") { if n > 2 { return true } } if str_ends_with(w, "es") { if n > 3 { return true } } if str_ends_with(w, "s") { if n > 2 { return true } } return false } // analyze one verb surface -> [lemma, tense, aspect], with WSD for ambiguous forms. fn cp_analyze_verb(surface: String) -> [String] { if str_eq(surface, "flies") { let r: [String] = native_list_empty() let r = native_list_append(r, "fly") let r = native_list_append(r, "present") let r = native_list_append(r, "simple") return r } let irr: [String] = cp_irr2(surface) if native_list_len(irr) > 0 { let r: [String] = native_list_empty() let r = native_list_append(r, native_list_get(irr, 0)) let r = native_list_append(r, native_list_get(irr, 1)) let r = native_list_append(r, "simple") return r } return cp_reg_verb(surface) } // ── clause segmentation helpers ─────────────────────────────────────────────── // Index of the first subordinating conjunction in [0,n), or n if none. fn cp_subord_start(toks: [String], n: Int) -> Int { let i: Int = 1 while i < n { if cp_is_subordinator(native_list_get(toks, i)) { return i } let i = i + 1 } return n } // Index where the verb cluster begins (end of the subject NP), in [0,end). fn cp_verb_start(toks: [String], end: Int) -> Int { if end == 0 { return 0 } let first: String = native_list_get(toks, 0) if !str_eq(cp_pron_concept(first), "") { return 1 } let have_head: Bool = false let i: Int = 0 while i < end { let w: String = native_list_get(toks, i) if i > 0 { if cp_is_aux(w) { return i } if cp_is_negation(w) { return i } if have_head { if cp_is_verb_form(w) { return i } } } if !cp_is_determiner(w) { let have_head = true } let i = i + 1 } return end } // Join tokens [a,b) with spaces. fn cp_join_range(toks: [String], a: Int, b: Int) -> String { let parts: [String] = native_list_empty() let i: Int = a while i < b { let parts = native_list_append(parts, native_list_get(toks, i)) let i = i + 1 } return str_join(parts, " ") } // ── ES / PT (Romance) closed-class + light morphology ───────────────────────── // // The spec is language-neutral; only the SURFACE analysis differs. This is the // deterministic Romance front-end: same clause skeleton (subject | neg | verb | // object | PP), pro-drop aware (a Spanish/Portuguese sentence may open with the // verb or a negator and carry no overt subject). SACRED polarity is already // cross-lingual in cp_is_negation (no / não / nunca / jamás / jamais / nada / // nadie / nem / nenhum / ninguém), so negation survives here for free. fn cp_rom_det(w: String) -> Bool { if str_eq(w, "el") { return true } if str_eq(w, "la") { return true } if str_eq(w, "los") { return true } if str_eq(w, "las") { return true } if str_eq(w, "un") { return true } if str_eq(w, "una") { return true } if str_eq(w, "unos") { return true } if str_eq(w, "unas") { return true } if str_eq(w, "o") { return true } if str_eq(w, "os") { return true } if str_eq(w, "um") { return true } if str_eq(w, "uma") { return true } if str_eq(w, "uns") { return true } if str_eq(w, "umas") { return true } if str_eq(w, "mi") { return true } if str_eq(w, "tu") { return true } if str_eq(w, "su") { return true } if str_eq(w, "meu") { return true } if str_eq(w, "minha"){ return true } if str_eq(w, "seu") { return true } if str_eq(w, "sua") { return true } return false } // Romance subject pronoun -> interlingua concept ("" if not a pronoun). fn cp_rom_pron(w: String) -> String { if str_eq(w, "yo") { return "i" } if str_eq(w, "eu") { return "i" } if str_eq(w, "tú") { return "you" } if str_eq(w, "você") { return "you" } if str_eq(w, "usted") { return "you" } if str_eq(w, "él") { return "he" } if str_eq(w, "ele") { return "he" } if str_eq(w, "ella") { return "she" } if str_eq(w, "ela") { return "she" } if str_eq(w, "nosotros") { return "we" } if str_eq(w, "nós") { return "we" } if str_eq(w, "ellos") { return "they" } if str_eq(w, "ellas") { return "they" } if str_eq(w, "eles") { return "they" } if str_eq(w, "elas") { return "they" } return "" } // concept -> canonical Romance subject surface for the given language. fn cp_rom_pron_surface(concept: String, lang: String) -> String { if str_eq(lang, "pt") { if str_eq(concept, "i") { return "eu" } if str_eq(concept, "you") { return "você" } if str_eq(concept, "he") { return "ele" } if str_eq(concept, "she") { return "ela" } if str_eq(concept, "we") { return "nós" } if str_eq(concept, "they") { return "eles" } return concept } if str_eq(concept, "i") { return "yo" } if str_eq(concept, "you") { return "usted" } if str_eq(concept, "he") { return "él" } if str_eq(concept, "she") { return "ella" } if str_eq(concept, "we") { return "nosotros" } if str_eq(concept, "they") { return "ellos" } return concept } fn cp_rom_prep(w: String) -> Bool { if str_eq(w, "en") { return true } if str_eq(w, "em") { return true } if str_eq(w, "a") { return true } if str_eq(w, "de") { return true } if str_eq(w, "del") { return true } if str_eq(w, "do") { return true } if str_eq(w, "da") { return true } if str_eq(w, "con") { return true } if str_eq(w, "com") { return true } if str_eq(w, "por") { return true } if str_eq(w, "para") { return true } if str_eq(w, "sin") { return true } if str_eq(w, "sem") { return true } if str_eq(w, "sobre") { return true } if str_eq(w, "entre") { return true } if str_eq(w, "desde") { return true } if str_eq(w, "hasta") { return true } if str_eq(w, "até") { return true } return false } // Romance auxiliaries / copulas (ser/estar/haber/haver/ter/ir cores). fn cp_rom_aux(w: String) -> Bool { if str_eq(w, "es") { return true } if str_eq(w, "está") { return true } if str_eq(w, "son") { return true } if str_eq(w, "están") { return true } if str_eq(w, "era") { return true } if str_eq(w, "eran") { return true } if str_eq(w, "fue") { return true } if str_eq(w, "ha") { return true } if str_eq(w, "han") { return true } if str_eq(w, "va") { return true } if str_eq(w, "van") { return true } if str_eq(w, "é") { return true } if str_eq(w, "são") { return true } if str_eq(w, "foi") { return true } if str_eq(w, "tem") { return true } if str_eq(w, "têm") { return true } if str_eq(w, "vai") { return true } return false } // A plausible Romance finite verb by inflectional ending (boundary detector). fn cp_rom_is_verb(w: String) -> Bool { let n: Int = str_len(w) if n < 3 { return false } // Closed-class words are never finite verbs — reject them before the // (ambiguous) inflectional-ending test. This kills the ending-only // misfires on prepositions ("para", "sobre", "entre", "desde", "hasta") // and on determiners / subject pronouns that happen to end in -a/-e/-o. if cp_rom_prep(w) { return false } if cp_rom_det(w) { return false } if cp_rom_aux(w) { return false } if cp_is_negation(w) { return false } if !str_eq(cp_rom_pron(w), "") { return false } if str_ends_with(w, "ar") { return true } if str_ends_with(w, "er") { return true } if str_ends_with(w, "ir") { return true } if str_ends_with(w, "ó") { return true } if str_ends_with(w, "ió") { return true } if str_ends_with(w, "ou") { return true } if str_ends_with(w, "eu") { return true } if str_ends_with(w, "iu") { return true } if str_ends_with(w, "aba"){ return true } if str_ends_with(w, "ía") { return true } if str_ends_with(w, "ava"){ return true } if str_ends_with(w, "an") { return true } if str_ends_with(w, "en") { return true } if str_ends_with(w, "am") { return true } if str_ends_with(w, "em") { return true } if str_ends_with(w, "a") { return true } if str_ends_with(w, "e") { return true } if str_ends_with(w, "o") { return true } return false } // Romance verb -> [lemma, tense]. Lemma recovery is best-effort (endings only, // no full paradigm inversion yet); tense is read from the inflection class. fn cp_rom_lemma_tense(w: String) -> [String] { let n: Int = str_len(w) let tense: String = "present" if str_ends_with(w, "ó") { let tense = "past" } if str_ends_with(w, "ió") { let tense = "past" } if str_ends_with(w, "ou") { let tense = "past" } if str_ends_with(w, "eu") { let tense = "past" } if str_ends_with(w, "iu") { let tense = "past" } if str_ends_with(w, "aba") { let tense = "past" } if str_ends_with(w, "ía") { let tense = "past" } if str_ends_with(w, "ava") { let tense = "past" } if str_ends_with(w, "rá") { let tense = "future" } if str_ends_with(w, "rão") { let tense = "future" } let r: [String] = native_list_empty() let r = native_list_append(r, w) let r = native_list_append(r, tense) return r } // Index where the Romance verb cluster begins (end of the subject NP), in [0,end). fn cp_rom_verb_start(toks: [String], end: Int) -> Int { if end == 0 { return 0 } let first: String = native_list_get(toks, 0) // pro-drop / verb-initial / negator-initial: no overt subject NP. if cp_is_negation(first) { return 0 } if !str_eq(cp_rom_pron(first), "") { return 1 } if cp_rom_is_verb(first) { return 0 } let have_head: Bool = false let i: Int = 0 while i < end { let w: String = native_list_get(toks, i) if i > 0 { if cp_is_negation(w) { return i } if cp_rom_aux(w) { return i } if have_head { if cp_rom_is_verb(w) { return i } } } if !cp_rom_det(w) { let have_head = true } let i = i + 1 } return end } fn parse_spec_romance(text: String, lang: String) -> [String] { let toks: [String] = cp_tokenize(text) let n: Int = native_list_len(toks) let intent: String = "assert" if str_ends_with(text, "?") { let intent = "question" } let m_end: Int = cp_subord_start(toks, n) // SACRED polarity — cross-lingual negation lexemes in the main clause. let polarity: String = "aff" let neg_word: String = "" let pi: Int = 0 while pi < m_end { let w: String = native_list_get(toks, pi) if cp_is_negation(w) { let polarity = "neg" if cp_is_neg_adverb(w) { let neg_word = w } } let pi = pi + 1 } // subject (pro-drop aware) let vstart: Int = cp_rom_verb_start(toks, m_end) let agent: String = "" let first: String = "" if n > 0 { let first = native_list_get(toks, 0) } if vstart == 0 { let agent = "" } else { if vstart == 1 { if !str_eq(cp_rom_pron(first), "") { let agent = cp_rom_pron_surface(cp_rom_pron(first), lang) } else { let agent = cp_join_range(toks, 0, 1) } } else { let agent = cp_join_range(toks, 0, vstart) } } // verb cluster let tense: String = "present" let aspect: String = "simple" let predicate: String = "" let found_verb: Bool = false let i: Int = vstart while i < m_end { let w: String = native_list_get(toks, i) if found_verb { let i = m_end } else { if cp_is_negation(w) { let i = i + 1 } else { if cp_rom_aux(w) { if str_eq(w, "era") { let tense = "past" } if str_eq(w, "eran") { let tense = "past" } if str_eq(w, "fue") { let tense = "past" } if str_eq(w, "foi") { let tense = "past" } if str_eq(w, "ha") { let aspect = "perfect" } if str_eq(w, "han") { let aspect = "perfect" } if str_eq(w, "va") { let tense = "future" } if str_eq(w, "van") { let tense = "future" } if str_eq(w, "vai") { let tense = "future" } // a bare copula with no following lexical verb is the predicate let predicate = "be" let i = i + 1 } else { if cp_rom_is_verb(w) { let lt: [String] = cp_rom_lemma_tense(w) let predicate = native_list_get(lt, 0) let tense = native_list_get(lt, 1) let found_verb = true } let i = i + 1 } } } } if str_eq(predicate, "be") { let found_verb = true } // complements: first NP after the verb is the object; "a" -> recipient (iobj); // other prepositions -> location adjunct. let cstart: Int = vstart let seen_v: Bool = false let j: Int = vstart while j < m_end { let w: String = native_list_get(toks, j) if seen_v { let cstart = j let j = m_end } else { if cp_is_negation(w) { let j = j + 1 } else { if cp_rom_aux(w) { let j = j + 1 } else { if cp_rom_is_verb(w) { let seen_v = true } let j = j + 1 } } } } let patient: String = "" let iobj: String = "" let location: String = "" let k: Int = cstart while k < m_end { let w: String = native_list_get(toks, k) if cp_rom_prep(w) { let prep: String = w let a: Int = k + 1 let b: Int = a let run3: Bool = true while run3 { if b >= m_end { let run3 = false } else { if cp_rom_prep(native_list_get(toks, b)) { let run3 = false } else { let b = b + 1 } } } let np: String = cp_join_range(toks, a, b) if str_eq(prep, "a") { let iobj = np } else { if str_eq(location, "") { let location = prep + " " + np } } let k = b } else { let a: Int = k let b: Int = a let run4: Bool = true while run4 { if b >= m_end { let run4 = false } else { if cp_rom_prep(native_list_get(toks, b)) { let run4 = false } else { let b = b + 1 } } } if str_eq(patient, "") { let patient = cp_join_range(toks, a, b) } let k = b } } // subordinate clause conj (predicate recovery is left to a later pass) let subord_conj: String = "" let subord_pred: String = "" if m_end < n { let subord_conj = native_list_get(toks, m_end) } if str_eq(agent, "") { if found_verb { if str_eq(intent, "assert") { let intent = "command" } } } let spec: [String] = native_list_empty() let spec = native_list_append(spec, "intent"); let spec = native_list_append(spec, intent) let spec = native_list_append(spec, "agent"); let spec = native_list_append(spec, agent) let spec = native_list_append(spec, "predicate"); let spec = native_list_append(spec, predicate) let spec = native_list_append(spec, "patient"); let spec = native_list_append(spec, patient) let spec = native_list_append(spec, "iobj"); let spec = native_list_append(spec, iobj) let spec = native_list_append(spec, "location"); let spec = native_list_append(spec, location) let spec = native_list_append(spec, "tense"); let spec = native_list_append(spec, tense) let spec = native_list_append(spec, "aspect"); let spec = native_list_append(spec, aspect) let spec = native_list_append(spec, "polarity"); let spec = native_list_append(spec, polarity) let spec = native_list_append(spec, "neg_word"); let spec = native_list_append(spec, neg_word) let spec = native_list_append(spec, "subord_conj"); let spec = native_list_append(spec, subord_conj) let spec = native_list_append(spec, "subord_pred"); let spec = native_list_append(spec, subord_pred) let spec = native_list_append(spec, "lang"); let spec = native_list_append(spec, lang) return spec } // ── the parser ──────────────────────────────────────────────────────────────── fn parse_spec_lang(text: String, lang: String) -> [String] { if str_eq(lang, "es") { return parse_spec_romance(text, lang) } if str_eq(lang, "pt") { return parse_spec_romance(text, lang) } let toks: [String] = cp_tokenize(text) let n: Int = native_list_len(toks) let intent: String = "assert" if str_ends_with(text, "?") { let intent = "question" } // clause split: main [0, m_end), subordinate [m_end, n) let m_end: Int = cp_subord_start(toks, n) // SACRED polarity: scan the MAIN clause for any negation lexeme. let polarity: String = "aff" let neg_word: String = "" let pi: Int = 0 while pi < m_end { let w: String = native_list_get(toks, pi) if cp_is_negation(w) { let polarity = "neg" if cp_is_neg_adverb(w) { let neg_word = w } } let pi = pi + 1 } // subject let vstart: Int = cp_verb_start(toks, m_end) let agent: String = "" let first: String = "" if n > 0 { let first = native_list_get(toks, 0) } if vstart == 1 { if !str_eq(cp_pron_concept(first), "") { let agent = cp_pron_surface(cp_pron_concept(first)) } else { let agent = cp_join_range(toks, 0, 1) } } else { let agent = cp_join_range(toks, 0, vstart) } // verb cluster: walk auxiliaries + main verb let tense: String = "present" let aspect: String = "simple" let predicate: String = "" let do_support: Bool = false let saw_be: Bool = false let found_verb: Bool = false let i: Int = vstart while i < m_end { let w: String = native_list_get(toks, i) if found_verb { let i = m_end } else { if cp_is_negation(w) { let i = i + 1 } else { if cp_is_aux(w) { if str_eq(w, "did") { let tense = "past"; let do_support = true } if str_eq(w, "does") { let tense = "present"; let do_support = true } if str_eq(w, "do") { let tense = "present"; let do_support = true } if str_eq(w, "will") { let tense = "future" } if str_eq(w, "shall") { let tense = "future" } if str_eq(w, "was") { let tense = "past"; let saw_be = true } if str_eq(w, "were") { let tense = "past"; let saw_be = true } if str_eq(w, "is") { let saw_be = true } if str_eq(w, "are") { let saw_be = true } if str_eq(w, "am") { let saw_be = true } if str_eq(w, "has") { let aspect = "perfect" } if str_eq(w, "have") { let aspect = "perfect" } if str_eq(w, "had") { let aspect = "perfect"; let tense = "past" } let i = i + 1 } else { // main verb token if do_support { let predicate = w // tense already set by the do-auxiliary; verb is the base form } else { let va: [String] = cp_analyze_verb(w) let predicate = native_list_get(va, 0) let tense = native_list_get(va, 1) if str_eq(aspect, "simple") { let aspect = native_list_get(va, 2) } } let found_verb = true let i = i + 1 } } } } // copula: be-auxiliary with no following lexical verb IS the predicate. if !found_verb { if saw_be { let predicate = "be" let found_verb = true } } // complements: object NP, to-recipient (iobj), and PP adjunct (location). // start scanning after the verb we consumed. let patient: String = "" let iobj: String = "" let location: String = "" // recompute where complements begin: first token after the main verb. let cstart: Int = vstart let scanned: Bool = false let j: Int = vstart let seen_v: Bool = false while j < m_end { let w: String = native_list_get(toks, j) if seen_v { let j = m_end } else { if cp_is_negation(w) { let j = j + 1 } else { if cp_is_aux(w) { let j = j + 1 } else { // main verb consumed — complements begin at the NEXT token. // (Setting cstart here, not on a later iteration, is what makes // a sentence-final verb yield no phantom object.) let seen_v = true let cstart = j + 1 let j = m_end } } } } let k: Int = cstart while k < m_end { let w: String = native_list_get(toks, k) let is_prep: Bool = cp_is_preposition(w) if str_eq(w, "like") { let is_prep = true } if is_prep { let prep: String = w let a: Int = k + 1 let b: Int = a let run3: Bool = true while run3 { if b >= m_end { let run3 = false } else { let wb: String = native_list_get(toks, b) let wb_prep: Bool = cp_is_preposition(wb) if str_eq(wb, "like") { let wb_prep = true } if wb_prep { let run3 = false } else { let b = b + 1 } } } let np: String = cp_join_range(toks, a, b) if str_eq(prep, "to") { let iobj = np } else { if str_eq(location, "") { let location = prep + " " + np } } let k = b } else { let a: Int = k let b: Int = a let run4: Bool = true while run4 { if b >= m_end { let run4 = false } else { let wb: String = native_list_get(toks, b) let wb_prep: Bool = cp_is_preposition(wb) if str_eq(wb, "like") { let wb_prep = true } if wb_prep { let run4 = false } else { let b = b + 1 } } } if str_eq(patient, "") { let patient = cp_join_range(toks, a, b) } let k = b } } // subordinate clause: conj + (lightweight) predicate recovery. // subord_conj the subordinating conjunction ("because", "if", ...) // subord_pred the recovered predicate lemma of the subordinate clause // subord_text the SURFACE of the subordinate clause AFTER the conjunction, // carried verbatim so realization is byte-complete (the clause // is preserved, not dropped — SACRED completeness of meaning). let subord_conj: String = "" let subord_pred: String = "" let subord_text: String = "" if m_end < n { let subord_conj = native_list_get(toks, m_end) let subord_text = cp_join_range(toks, m_end + 1, n) // find the subordinate predicate: first aux/verb after the conjunction. let s: Int = m_end + 1 let sfound: Bool = false while s < n { if sfound { let s = n } else { let sw: String = native_list_get(toks, s) if cp_is_aux(sw) { if str_eq(sw, "was") { let subord_pred = "be"; let sfound = true } if str_eq(sw, "were") { let subord_pred = "be"; let sfound = true } if str_eq(sw, "is") { let subord_pred = "be"; let sfound = true } if str_eq(sw, "are") { let subord_pred = "be"; let sfound = true } let s = s + 1 } else { if cp_is_verb_form(sw) { let va2: [String] = cp_analyze_verb(sw) let subord_pred = native_list_get(va2, 0) let sfound = true } let s = s + 1 } } } } // intent refinement: no subject + leading verb => imperative command. if str_eq(agent, "") { if found_verb { if str_eq(intent, "assert") { let intent = "command" } } } // ── emit the slot map (realizer-compatible + SACRED polarity) ───────────── let spec: [String] = native_list_empty() let spec = native_list_append(spec, "intent"); let spec = native_list_append(spec, intent) let spec = native_list_append(spec, "agent"); let spec = native_list_append(spec, agent) let spec = native_list_append(spec, "predicate"); let spec = native_list_append(spec, predicate) let spec = native_list_append(spec, "patient"); let spec = native_list_append(spec, patient) let spec = native_list_append(spec, "iobj"); let spec = native_list_append(spec, iobj) let spec = native_list_append(spec, "location"); let spec = native_list_append(spec, location) let spec = native_list_append(spec, "tense"); let spec = native_list_append(spec, tense) let spec = native_list_append(spec, "aspect"); let spec = native_list_append(spec, aspect) let spec = native_list_append(spec, "polarity"); let spec = native_list_append(spec, polarity) let spec = native_list_append(spec, "neg_word"); let spec = native_list_append(spec, neg_word) let spec = native_list_append(spec, "subord_conj"); let spec = native_list_append(spec, subord_conj) let spec = native_list_append(spec, "subord_pred"); let spec = native_list_append(spec, subord_pred) let spec = native_list_append(spec, "subord_text"); let spec = native_list_append(spec, subord_text) let spec = native_list_append(spec, "lang"); let spec = native_list_append(spec, lang) return spec } // English default entry point. fn parse_spec(text: String) -> [String] { return parse_spec_lang(text, "en") } // ── JSON emission (integration contract for generate_lang / build_form_from_json) fn cp_json_field(key: String, val: String) -> String { return "\"" + key + "\": \"" + val + "\"" } fn parse_json_lang(text: String, lang: String) -> String { let spec: [String] = parse_spec_lang(text, lang) let parts: [String] = native_list_empty() let parts = native_list_append(parts, cp_json_field("intent", slots_get(spec, "intent"))) let parts = native_list_append(parts, cp_json_field("agent", slots_get(spec, "agent"))) let parts = native_list_append(parts, cp_json_field("predicate", slots_get(spec, "predicate"))) let parts = native_list_append(parts, cp_json_field("patient", slots_get(spec, "patient"))) let parts = native_list_append(parts, cp_json_field("iobj", slots_get(spec, "iobj"))) let parts = native_list_append(parts, cp_json_field("location", slots_get(spec, "location"))) let parts = native_list_append(parts, cp_json_field("tense", slots_get(spec, "tense"))) let parts = native_list_append(parts, cp_json_field("aspect", slots_get(spec, "aspect"))) let parts = native_list_append(parts, cp_json_field("polarity", slots_get(spec, "polarity"))) let parts = native_list_append(parts, cp_json_field("neg_word", slots_get(spec, "neg_word"))) let parts = native_list_append(parts, cp_json_field("lang", lang)) return "{" + str_join(parts, ", ") + "}" } fn parse_json(text: String) -> String { return parse_json_lang(text, "en") }