Files
el/elp/src/vocabulary.el
T
2026-05-02 22:15:25 -05:00

370 lines
23 KiB
EmacsLisp

// vocabulary.el - Vocabulary query interface with inline seed data.
//
// Represents lexical entries with POS, morphological forms, semantic class,
// synonyms, and a language code. Inline data covers English vocabulary needed
// for grammar tests. The long-term backing store is the Neuron Engram (queried
// at runtime via searchKnowledge(query="VOCAB: <word>", category="vocabulary")),
// but inline data is used for bootstrapping.
//
// Language codes follow ISO 639-1. The seed data below is English ("en").
// Vocabulary for other languages is loaded from the Engram at runtime; the
// engine functions `vocab_lookup` and `vocab_synonym` accept a lang_code
// parameter to filter results by language.
//
// POS values: "noun" | "verb" | "adjective" | "adverb" | "determiner" |
// "preposition" | "pronoun" | "conjunction" | "auxiliary"
// LexEntry: a single lexeme
//
// forms meaning:
// noun: [singular, plural]
// verb: [base, 3sg, past, pastpart, gerund]
// pronoun: [nominative, accusative, genitive]
// other: [word]
fn lex_word(entry: [String]) -> String {
return native_list_get(entry, 0)
}
fn lex_pos(entry: [String]) -> String {
return native_list_get(entry, 1)
}
fn lex_form(entry: [String], idx: Int) -> String {
// forms start at index 2
let n: Int = native_list_len(entry)
let real_idx: Int = idx + 2
if real_idx >= n {
return native_list_get(entry, 0)
}
return native_list_get(entry, real_idx)
}
fn lex_class(entry: [String]) -> String {
let n: Int = native_list_len(entry)
let last: Int = n - 1
return native_list_get(entry, last)
}
// Build a vocab entry: [word, pos, form0, form1, ..., semantic_class]
fn make_entry(word: String, pos: String, f0: String, f1: String, f2: String, f3: String, f4: String, cls: String) -> [String] {
let r: [String] = native_list_empty()
let r = native_list_append(r, word)
let r = native_list_append(r, pos)
let r = native_list_append(r, f0)
let r = native_list_append(r, f1)
let r = native_list_append(r, f2)
let r = native_list_append(r, f3)
let r = native_list_append(r, f4)
let r = native_list_append(r, cls)
return r
}
fn make_entry2(word: String, pos: String, f0: String, f1: String, cls: String) -> [String] {
let r: [String] = native_list_empty()
let r = native_list_append(r, word)
let r = native_list_append(r, pos)
let r = native_list_append(r, f0)
let r = native_list_append(r, f1)
let r = native_list_append(r, cls)
return r
}
fn make_entry3(word: String, pos: String, f0: String, f1: String, f2: String, cls: String) -> [String] {
let r: [String] = native_list_empty()
let r = native_list_append(r, word)
let r = native_list_append(r, pos)
let r = native_list_append(r, f0)
let r = native_list_append(r, f1)
let r = native_list_append(r, f2)
let r = native_list_append(r, cls)
return r
}
fn make_entry1(word: String, pos: String, f0: String, cls: String) -> [String] {
let r: [String] = native_list_empty()
let r = native_list_append(r, word)
let r = native_list_append(r, pos)
let r = native_list_append(r, f0)
let r = native_list_append(r, cls)
return r
}
// Seed vocabulary
fn build_vocab() -> [[String]] {
let v: [[String]] = native_list_empty()
// Pronouns [nominative, accusative, genitive]
let v = native_list_append(v, make_entry3("I", "pronoun", "I", "me", "my", "person-first-sg"))
let v = native_list_append(v, make_entry3("you", "pronoun", "you", "you", "your", "person-second"))
let v = native_list_append(v, make_entry3("he", "pronoun", "he", "him", "his", "person-third-sg-m"))
let v = native_list_append(v, make_entry3("she", "pronoun", "she", "her", "her", "person-third-sg-f"))
let v = native_list_append(v, make_entry3("it", "pronoun", "it", "it", "its", "person-third-sg-n"))
let v = native_list_append(v, make_entry3("we", "pronoun", "we", "us", "our", "person-first-pl"))
let v = native_list_append(v, make_entry3("they", "pronoun", "they", "them", "their", "person-third-pl"))
// Determiners [word]
let v = native_list_append(v, make_entry1("a", "determiner", "a", "indefinite"))
let v = native_list_append(v, make_entry1("an", "determiner", "an", "indefinite"))
let v = native_list_append(v, make_entry1("the", "determiner", "the", "definite"))
let v = native_list_append(v, make_entry1("some", "determiner", "some", "indefinite-pl"))
let v = native_list_append(v, make_entry1("this", "determiner", "this", "demonstrative-sg"))
let v = native_list_append(v, make_entry1("that", "determiner", "that", "demonstrative-sg"))
let v = native_list_append(v, make_entry1("these","determiner", "these","demonstrative-pl"))
let v = native_list_append(v, make_entry1("those","determiner", "those","demonstrative-pl"))
// Prepositions [word]
let v = native_list_append(v, make_entry1("in", "preposition", "in", "location"))
let v = native_list_append(v, make_entry1("on", "preposition", "on", "location"))
let v = native_list_append(v, make_entry1("at", "preposition", "at", "location"))
let v = native_list_append(v, make_entry1("to", "preposition", "to", "direction"))
let v = native_list_append(v, make_entry1("for", "preposition", "for", "purpose"))
let v = native_list_append(v, make_entry1("of", "preposition", "of", "relation"))
let v = native_list_append(v, make_entry1("with", "preposition", "with", "accompaniment"))
let v = native_list_append(v, make_entry1("from", "preposition", "from", "source"))
let v = native_list_append(v, make_entry1("by", "preposition", "by", "agent"))
let v = native_list_append(v, make_entry1("into", "preposition", "into", "direction"))
// Auxiliaries [base, 3sg, past, pastpart, gerund]
let v = native_list_append(v, make_entry("is", "auxiliary", "be", "is", "was", "been", "being", "copula"))
let v = native_list_append(v, make_entry("are", "auxiliary", "be", "is", "was", "been", "being", "copula"))
let v = native_list_append(v, make_entry("was", "auxiliary", "be", "is", "was", "been", "being", "copula-past"))
let v = native_list_append(v, make_entry("were", "auxiliary", "be", "is", "were", "been", "being", "copula-past"))
let v = native_list_append(v, make_entry("has", "auxiliary", "have", "has", "had", "had", "having", "perfect"))
let v = native_list_append(v, make_entry("have", "auxiliary", "have", "has", "had", "had", "having", "perfect"))
let v = native_list_append(v, make_entry("had", "auxiliary", "have", "has", "had", "had", "having", "perfect-past"))
let v = native_list_append(v, make_entry("will", "auxiliary", "will", "will", "would", "would", "willing", "future"))
let v = native_list_append(v, make_entry("can", "auxiliary", "can", "can", "could", "could", "canning", "modal"))
let v = native_list_append(v, make_entry("could", "auxiliary", "can", "can", "could", "could", "canning", "modal-past"))
let v = native_list_append(v, make_entry("would", "auxiliary", "will", "will", "would", "would", "willing", "modal-cond"))
let v = native_list_append(v, make_entry("do", "auxiliary", "do", "does", "did", "done", "doing", "do-support"))
let v = native_list_append(v, make_entry("does", "auxiliary", "do", "does", "did", "done", "doing", "do-support"))
let v = native_list_append(v, make_entry("did", "auxiliary", "do", "does", "did", "done", "doing", "do-support-past"))
// Nouns [singular, plural]
let v = native_list_append(v, make_entry2("cat", "noun", "cat", "cats", "animal"))
let v = native_list_append(v, make_entry2("dog", "noun", "dog", "dogs", "animal"))
let v = native_list_append(v, make_entry2("bird", "noun", "bird", "birds", "animal"))
let v = native_list_append(v, make_entry2("fish", "noun", "fish", "fish", "animal"))
let v = native_list_append(v, make_entry2("horse", "noun", "horse", "horses", "animal"))
let v = native_list_append(v, make_entry2("house", "noun", "house", "houses", "building"))
let v = native_list_append(v, make_entry2("book", "noun", "book", "books", "object"))
let v = native_list_append(v, make_entry2("table", "noun", "table", "tables", "furniture"))
let v = native_list_append(v, make_entry2("chair", "noun", "chair", "chairs", "furniture"))
let v = native_list_append(v, make_entry2("door", "noun", "door", "doors", "structure"))
let v = native_list_append(v, make_entry2("window", "noun", "window", "windows", "structure"))
let v = native_list_append(v, make_entry2("city", "noun", "city", "cities", "place"))
let v = native_list_append(v, make_entry2("park", "noun", "park", "parks", "place"))
let v = native_list_append(v, make_entry2("school", "noun", "school", "schools", "place"))
let v = native_list_append(v, make_entry2("store", "noun", "store", "stores", "place"))
let v = native_list_append(v, make_entry2("road", "noun", "road", "roads", "place"))
let v = native_list_append(v, make_entry2("box", "noun", "box", "boxes", "container"))
let v = native_list_append(v, make_entry2("child", "noun", "child", "children", "person"))
let v = native_list_append(v, make_entry2("person", "noun", "person", "people", "person"))
let v = native_list_append(v, make_entry2("man", "noun", "man", "men", "person"))
let v = native_list_append(v, make_entry2("woman", "noun", "woman", "women", "person"))
let v = native_list_append(v, make_entry2("tree", "noun", "tree", "trees", "plant"))
let v = native_list_append(v, make_entry2("flower", "noun", "flower", "flowers", "plant"))
let v = native_list_append(v, make_entry2("water", "noun", "water", "waters", "substance"))
let v = native_list_append(v, make_entry2("food", "noun", "food", "foods", "substance"))
let v = native_list_append(v, make_entry2("time", "noun", "time", "times", "abstract"))
let v = native_list_append(v, make_entry2("day", "noun", "day", "days", "time"))
let v = native_list_append(v, make_entry2("night", "noun", "night", "nights", "time"))
let v = native_list_append(v, make_entry2("home", "noun", "home", "homes", "place"))
// Verbs [base, 3sg, past, pastpart, gerund]
let v = native_list_append(v, make_entry("run", "verb", "run", "runs", "ran", "run", "running", "motion"))
let v = native_list_append(v, make_entry("walk", "verb", "walk", "walks", "walked", "walked", "walking", "motion"))
let v = native_list_append(v, make_entry("go", "verb", "go", "goes", "went", "gone", "going", "motion"))
let v = native_list_append(v, make_entry("come", "verb", "come", "comes", "came", "come", "coming", "motion"))
let v = native_list_append(v, make_entry("see", "verb", "see", "sees", "saw", "seen", "seeing", "perception"))
let v = native_list_append(v, make_entry("hear", "verb", "hear", "hears", "heard", "heard", "hearing", "perception"))
let v = native_list_append(v, make_entry("look", "verb", "look", "looks", "looked", "looked", "looking", "perception"))
let v = native_list_append(v, make_entry("eat", "verb", "eat", "eats", "ate", "eaten", "eating", "action"))
let v = native_list_append(v, make_entry("drink", "verb", "drink", "drinks", "drank", "drunk", "drinking", "action"))
let v = native_list_append(v, make_entry("sleep", "verb", "sleep", "sleeps", "slept", "slept", "sleeping", "state"))
let v = native_list_append(v, make_entry("sit", "verb", "sit", "sits", "sat", "sat", "sitting", "posture"))
let v = native_list_append(v, make_entry("stand", "verb", "stand", "stands", "stood", "stood", "standing", "posture"))
let v = native_list_append(v, make_entry("give", "verb", "give", "gives", "gave", "given", "giving", "transfer"))
let v = native_list_append(v, make_entry("take", "verb", "take", "takes", "took", "taken", "taking", "transfer"))
let v = native_list_append(v, make_entry("make", "verb", "make", "makes", "made", "made", "making", "creation"))
let v = native_list_append(v, make_entry("put", "verb", "put", "puts", "put", "put", "putting", "placement"))
let v = native_list_append(v, make_entry("find", "verb", "find", "finds", "found", "found", "finding", "discovery"))
let v = native_list_append(v, make_entry("know", "verb", "know", "knows", "knew", "known", "knowing", "cognition"))
let v = native_list_append(v, make_entry("think", "verb", "think", "thinks", "thought","thought","thinking", "cognition"))
let v = native_list_append(v, make_entry("say", "verb", "say", "says", "said", "said", "saying", "communication"))
let v = native_list_append(v, make_entry("tell", "verb", "tell", "tells", "told", "told", "telling", "communication"))
let v = native_list_append(v, make_entry("ask", "verb", "ask", "asks", "asked", "asked", "asking", "communication"))
let v = native_list_append(v, make_entry("like", "verb", "like", "likes", "liked", "liked", "liking", "emotion"))
let v = native_list_append(v, make_entry("love", "verb", "love", "loves", "loved", "loved", "loving", "emotion"))
let v = native_list_append(v, make_entry("want", "verb", "want", "wants", "wanted", "wanted", "wanting", "desire"))
let v = native_list_append(v, make_entry("need", "verb", "need", "needs", "needed", "needed", "needing", "desire"))
let v = native_list_append(v, make_entry("have", "verb", "have", "has", "had", "had", "having", "possession"))
let v = native_list_append(v, make_entry("hold", "verb", "hold", "holds", "held", "held", "holding", "possession"))
let v = native_list_append(v, make_entry("open", "verb", "open", "opens", "opened", "opened", "opening", "action"))
let v = native_list_append(v, make_entry("close", "verb", "close", "closes", "closed", "closed", "closing", "action"))
let v = native_list_append(v, make_entry("write", "verb", "write", "writes", "wrote", "written","writing", "action"))
let v = native_list_append(v, make_entry("read", "verb", "read", "reads", "read", "read", "reading", "action"))
let v = native_list_append(v, make_entry("build", "verb", "build", "builds", "built", "built", "building", "creation"))
let v = native_list_append(v, make_entry("live", "verb", "live", "lives", "lived", "lived", "living", "state"))
let v = native_list_append(v, make_entry("work", "verb", "work", "works", "worked", "worked", "working", "activity"))
let v = native_list_append(v, make_entry("play", "verb", "play", "plays", "played", "played", "playing", "activity"))
let v = native_list_append(v, make_entry("help", "verb", "help", "helps", "helped", "helped", "helping", "activity"))
// Adjectives [word]
let v = native_list_append(v, make_entry1("big", "adjective", "big", "size"))
let v = native_list_append(v, make_entry1("small", "adjective", "small", "size"))
let v = native_list_append(v, make_entry1("large", "adjective", "large", "size"))
let v = native_list_append(v, make_entry1("little", "adjective", "little", "size"))
let v = native_list_append(v, make_entry1("old", "adjective", "old", "age"))
let v = native_list_append(v, make_entry1("new", "adjective", "new", "age"))
let v = native_list_append(v, make_entry1("young", "adjective", "young", "age"))
let v = native_list_append(v, make_entry1("good", "adjective", "good", "quality"))
let v = native_list_append(v, make_entry1("bad", "adjective", "bad", "quality"))
let v = native_list_append(v, make_entry1("fast", "adjective", "fast", "speed"))
let v = native_list_append(v, make_entry1("slow", "adjective", "slow", "speed"))
let v = native_list_append(v, make_entry1("hot", "adjective", "hot", "temperature"))
let v = native_list_append(v, make_entry1("cold", "adjective", "cold", "temperature"))
let v = native_list_append(v, make_entry1("happy", "adjective", "happy", "emotion"))
let v = native_list_append(v, make_entry1("sad", "adjective", "sad", "emotion"))
let v = native_list_append(v, make_entry1("red", "adjective", "red", "color"))
let v = native_list_append(v, make_entry1("blue", "adjective", "blue", "color"))
let v = native_list_append(v, make_entry1("green", "adjective", "green", "color"))
let v = native_list_append(v, make_entry1("white", "adjective", "white", "color"))
let v = native_list_append(v, make_entry1("black", "adjective", "black", "color"))
let v = native_list_append(v, make_entry1("long", "adjective", "long", "dimension"))
let v = native_list_append(v, make_entry1("short", "adjective", "short", "dimension"))
let v = native_list_append(v, make_entry1("beautiful","adjective", "beautiful","appearance"))
let v = native_list_append(v, make_entry1("bright", "adjective", "bright", "appearance"))
let v = native_list_append(v, make_entry1("dark", "adjective", "dark", "appearance"))
return v
}
// Vocabulary cache
// The vocab list is built once and reused across queries.
// We use a simple linear scan (adequate for ~100 entries).
fn get_vocab() -> [[String]] {
return build_vocab()
}
// Query functions
//
// All lookup functions accept an optional lang_code parameter. The inline seed
// data is English ("en"). When lang_code is "" the match is language-agnostic
// (useful when the caller has already filtered by language).
//
// The Engram path (not implemented inline) would be:
// searchKnowledge(query="VOCAB: " + word, category="vocabulary", lang=lang_code)
// vocab_lookup(word, lang_code) -> [String]
// Returns the entry whose word (index 0) matches the query word for the given
// language. Pass lang_code="" to match any language.
fn vocab_lookup(word: String, lang_code: String) -> [String] {
let vocab: [[String]] = get_vocab()
let n: Int = native_list_len(vocab)
let i: Int = 0
while i < n {
let entry: [String] = native_list_get(vocab, i)
let w: String = native_list_get(entry, 0)
if str_eq(w, word) {
// The inline seed data is English. If caller requests a specific
// language other than "en", we cannot satisfy it from inline data;
// return empty to signal "not found" (Engram lookup should follow).
if !str_eq(lang_code, "") {
if !str_eq(lang_code, "en") {
let empty: [String] = native_list_empty()
return empty
}
}
return entry
}
let i = i + 1
}
let empty: [String] = native_list_empty()
return empty
}
// vocab_lookup_en(word) -> [String]
// Backward-compatible alias: look up an English word.
fn vocab_lookup_en(word: String) -> [String] {
return vocab_lookup(word, "en")
}
// vocab_synonym(word, register, lang_code) -> String
// Returns a register-appropriate synonym for a word in the given language.
// register: "formal" | "informal" | "neutral"
// Returns the original word if no synonym is found.
fn vocab_synonym(word: String, lang_register: String, lang_code: String) -> String {
// Inline data does not carry synonym information.
// The Engram backing store supplies synonyms via knowledge nodes.
// Return the word unchanged as a safe fallback.
return word
}
// Returns all entries whose pos (index 1) matches.
fn vocab_by_pos(pos: String) -> [[String]] {
let vocab: [[String]] = get_vocab()
let n: Int = native_list_len(vocab)
let result: [[String]] = native_list_empty()
let i: Int = 0
while i < n {
let entry: [String] = native_list_get(vocab, i)
let p: String = native_list_get(entry, 1)
if str_eq(p, pos) {
let result = native_list_append(result, entry)
}
let i = i + 1
}
return result
}
// Returns all entries whose semantic class (last element) matches or starts with cls.
fn vocab_by_class(cls: String) -> [[String]] {
let vocab: [[String]] = get_vocab()
let n: Int = native_list_len(vocab)
let result: [[String]] = native_list_empty()
let i: Int = 0
while i < n {
let entry: [String] = native_list_get(vocab, i)
let m: Int = native_list_len(entry)
let c: String = native_list_get(entry, m - 1)
if str_eq(c, cls) {
let result = native_list_append(result, entry)
}
let i = i + 1
}
return result
}
// Convenience accessors for a retrieved entry
// Is this entry non-empty (i.e., found)?
fn entry_found(entry: [String]) -> Bool {
let n: Int = native_list_len(entry)
if n > 0 {
return true
}
return false
}
fn entry_word(entry: [String]) -> String {
return native_list_get(entry, 0)
}
fn entry_pos(entry: [String]) -> String {
return native_list_get(entry, 1)
}
// Get the Nth morphological form (0-indexed, starts at position 2 in the list).
fn entry_form(entry: [String], n: Int) -> String {
let real: Int = n + 2
let total: Int = native_list_len(entry)
if real >= total {
return native_list_get(entry, 0)
}
return native_list_get(entry, real)
}