370 lines
23 KiB
EmacsLisp
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)
|
|
}
|