logicaffeine_lexicon/types.rs
1//! Lexicon type definitions
2//!
3//! Core types used by the generated lexicon lookup functions.
4
5/// Article definiteness for noun phrases.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub enum Definiteness {
8 /// The referent is uniquely identifiable ("the").
9 Definite,
10 /// The referent is not uniquely identifiable ("a", "an").
11 Indefinite,
12 /// The referent is near the speaker ("this", "these").
13 Proximal,
14 /// The referent is far from the speaker ("that", "those").
15 Distal,
16}
17
18/// Temporal reference for verb tense.
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20pub enum Time {
21 /// Event occurred before speech time.
22 Past,
23 /// Event overlaps with speech time.
24 Present,
25 /// Event occurs after speech time.
26 Future,
27 /// No temporal specification (infinitives, bare stems).
28 None,
29}
30
31/// Grammatical aspect (viewpoint aspect).
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
33pub enum Aspect {
34 /// Event viewed as a whole, completed action.
35 Simple,
36 /// Event viewed as ongoing, in progress.
37 Progressive,
38 /// Event completed with present relevance.
39 Perfect,
40}
41
42/// Vendler's Lexical Aspect Classes (Aktionsart)
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash)]
44pub enum VerbClass {
45 /// +static, +durative, -telic: know, love, exist
46 State,
47 /// -static, +durative, -telic: run, swim, drive
48 #[default]
49 Activity,
50 /// -static, +durative, +telic: build, draw, write
51 Accomplishment,
52 /// -static, -durative, +telic: win, find, die
53 Achievement,
54 /// -static, -durative, -telic: knock, cough, blink
55 Semelfactive,
56}
57
58impl VerbClass {
59 /// Returns true if this is a stative verb class (no change of state).
60 ///
61 /// States denote properties or relations that hold without change: "know", "love", "exist".
62 pub fn is_stative(&self) -> bool {
63 matches!(self, VerbClass::State)
64 }
65
66 /// Returns true if this verb class denotes events with duration.
67 ///
68 /// Durative events: States, Activities, and Accomplishments all have temporal extent.
69 /// Non-durative: Achievements and Semelfactives are punctual.
70 pub fn is_durative(&self) -> bool {
71 matches!(
72 self,
73 VerbClass::State | VerbClass::Activity | VerbClass::Accomplishment
74 )
75 }
76
77 /// Returns true if this verb class has an inherent endpoint (telic).
78 ///
79 /// Telic events: Accomplishments and Achievements reach a natural endpoint.
80 /// Atelic events: States, Activities, and Semelfactives have no inherent endpoint.
81 pub fn is_telic(&self) -> bool {
82 matches!(self, VerbClass::Accomplishment | VerbClass::Achievement)
83 }
84}
85
86/// Semantic sorts for type checking.
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
88pub enum Sort {
89 /// Top of the hierarchy; any individual.
90 Entity,
91 /// Concrete, spatially located objects.
92 Physical,
93 /// Living beings capable of self-motion.
94 Animate,
95 /// Persons with intentional agency.
96 Human,
97 /// Non-animal living organisms.
98 Plant,
99 /// Locations and regions.
100 Place,
101 /// Temporal intervals and points.
102 Time,
103 /// Non-physical, conceptual entities.
104 Abstract,
105 /// Propositional content and data.
106 Information,
107 /// Occurrences and happenings.
108 Event,
109 /// Stars, planets, and astronomical bodies.
110 Celestial,
111 /// Numeric or monetary amounts.
112 Value,
113 /// Collections of individuals.
114 Group,
115}
116
117impl Sort {
118 /// Check if this sort can be used where `other` is expected.
119 ///
120 /// Sort compatibility follows a subsumption hierarchy:
121 /// - Human ⊆ Animate ⊆ Physical ⊆ Entity
122 /// - Plant ⊆ Animate ⊆ Physical ⊆ Entity
123 /// - Everything ⊆ Entity
124 ///
125 /// For example, a Human noun can fill an Animate slot, but not vice versa.
126 pub fn is_compatible_with(self, other: Sort) -> bool {
127 if self == other {
128 return true;
129 }
130 match (self, other) {
131 (Sort::Human, Sort::Animate) => true,
132 (Sort::Plant, Sort::Animate) => true,
133 (Sort::Animate, Sort::Physical) => true,
134 (Sort::Human, Sort::Physical) => true,
135 (Sort::Plant, Sort::Physical) => true,
136 (_, Sort::Entity) => true,
137 _ => false,
138 }
139 }
140}
141
142/// Grammatical number for nouns and agreement.
143#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
144pub enum Number {
145 /// Denotes a single individual.
146 Singular,
147 /// Denotes multiple individuals.
148 Plural,
149}
150
151/// Grammatical gender (for pronouns and agreement).
152#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
153pub enum Gender {
154 /// Masculine gender ("he", "him", "his").
155 Male,
156 /// Feminine gender ("she", "her", "hers").
157 Female,
158 /// Neuter gender ("it", "its").
159 Neuter,
160 /// Gender unspecified or indeterminate.
161 Unknown,
162}
163
164/// Grammatical case (for pronouns).
165#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
166pub enum Case {
167 /// Nominative case for subjects ("I", "he", "she").
168 Subject,
169 /// Accusative case for objects ("me", "him", "her").
170 Object,
171 /// Genitive case for possession ("my", "his", "her").
172 Possessive,
173}
174
175/// Lexical polarity for canonical mappings.
176#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
177pub enum Polarity {
178 /// Preserves the meaning (synonym mapping).
179 Positive,
180 /// Inverts the meaning (antonym mapping).
181 Negative,
182}
183
184/// Lexical features that encode grammatical and semantic properties of words.
185///
186/// Features are assigned to lexical entries in the lexicon database and control
187/// how words combine syntactically and what semantic representations they produce.
188/// The feature system follows the tradition of feature-based grammar formalisms
189/// like HPSG and LFG.
190#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
191pub enum Feature {
192 // -------------------------------------------------------------------------
193 // Verb Transitivity Features
194 // -------------------------------------------------------------------------
195
196 /// Verb requires a direct object (NP complement).
197 ///
198 /// Transitive verbs denote binary relations between an agent and a patient/theme.
199 /// In first-order logic, they translate to two-place predicates: `Verb(x, y)`.
200 ///
201 /// Examples: "see", "hit", "love", "build"
202 Transitive,
203
204 /// Verb takes no object (unary predicate).
205 ///
206 /// Intransitive verbs denote properties of a single argument (the subject).
207 /// They translate to one-place predicates: `Verb(x)`.
208 ///
209 /// Examples: "sleep", "arrive", "exist", "die"
210 Intransitive,
211
212 /// Verb takes two objects (direct + indirect).
213 ///
214 /// Ditransitive verbs denote ternary relations, typically involving transfer
215 /// of possession. They translate to three-place predicates: `Verb(x, y, z)`.
216 ///
217 /// Examples: "give", "tell", "show", "send"
218 Ditransitive,
219
220 // -------------------------------------------------------------------------
221 // Control Theory Features
222 // -------------------------------------------------------------------------
223
224 /// The subject of the matrix clause controls the PRO subject of the embedded clause.
225 ///
226 /// In "John promised Mary to leave", John (subject) is understood as the one leaving.
227 /// Formally: promise(j, m, leave(PRO_j)) where PRO is coindexed with the subject.
228 ///
229 /// Examples: "promise", "try", "want", "decide"
230 SubjectControl,
231
232 /// The object of the matrix clause controls the PRO subject of the embedded clause.
233 ///
234 /// In "John persuaded Mary to leave", Mary (object) is understood as the one leaving.
235 /// Formally: persuade(j, m, leave(PRO_m)) where PRO is coindexed with the object.
236 ///
237 /// Examples: "persuade", "force", "convince", "order"
238 ObjectControl,
239
240 /// Raising verb that does not assign a theta-role to its surface subject.
241 ///
242 /// In "John seems to be happy", "John" originates in the embedded clause and
243 /// raises to matrix subject position. No control relation; subject is shared.
244 /// Contrast with control: raising allows expletive subjects ("It seems that...").
245 ///
246 /// Examples: "seem", "appear", "happen", "tend"
247 Raising,
248
249 // -------------------------------------------------------------------------
250 // Semantic Features
251 // -------------------------------------------------------------------------
252
253 /// Creates an opaque (intensional) context blocking substitution of co-referential terms.
254 ///
255 /// In opaque contexts, Leibniz's Law fails: even if a=b, P(a) does not entail P(b).
256 /// "John believes Clark Kent is weak" does not entail "John believes Superman is weak"
257 /// even if Clark Kent = Superman. Requires possible-worlds semantics.
258 ///
259 /// Examples: "believe", "think", "want", "seek"
260 Opaque,
261
262 /// Presupposes the truth of its complement clause.
263 ///
264 /// Factive verbs entail the truth of their embedded proposition regardless of
265 /// the matrix clause's truth value. "John regrets that it rained" presupposes
266 /// that it rained, even under negation: "John doesn't regret that it rained."
267 ///
268 /// Examples: "know", "regret", "realize", "discover"
269 Factive,
270
271 /// Uttering the verb constitutes performing the action it describes.
272 ///
273 /// Performative verbs, when uttered in first person present, do not describe
274 /// an action but perform it. "I promise to come" is itself the act of promising.
275 /// Austin's speech act theory: saying is doing.
276 ///
277 /// Examples: "promise", "declare", "pronounce", "bet"
278 Performative,
279
280 /// Requires a plural or group subject; describes collective action.
281 ///
282 /// Collective predicates cannot distribute over atomic individuals.
283 /// "The students gathered" is true of the group, not of each student individually.
284 /// Contrast with distributive: "gathered" vs "slept".
285 ///
286 /// Examples: "gather", "meet", "disperse", "surround"
287 Collective,
288
289 /// Can be interpreted either collectively or distributively.
290 ///
291 /// Mixed predicates are ambiguous between collective and distributive readings.
292 /// "The students lifted the piano" can mean they lifted it together (collective)
293 /// or each lifted a piano (distributive). Context disambiguates.
294 ///
295 /// Examples: "lift", "carry", "build", "write"
296 Mixed,
297
298 /// Distributes over atomic individuals in a plurality.
299 ///
300 /// Distributive predicates apply to each member of a plural subject individually.
301 /// "The students slept" entails that each student slept. Formally: ∀x(student(x) → slept(x)).
302 ///
303 /// Examples: "sleep", "smile", "breathe", "think"
304 Distributive,
305
306 /// Impersonal verb describing meteorological phenomena; takes expletive subject.
307 ///
308 /// Weather verbs have no semantic subject; "it" in "it rains" is a dummy expletive.
309 /// In formal semantics, they are zero-place predicates or predicates of times/events.
310 ///
311 /// Examples: "rain", "snow", "thunder", "drizzle"
312 Weather,
313
314 /// Intransitive verb whose subject is a theme/patient, not an agent.
315 ///
316 /// Unaccusative verbs have an underlying object that surfaces as subject.
317 /// Evidence: auxiliary selection in Italian/German, participle agreement.
318 /// "The ice melted" - the ice undergoes melting, doesn't cause it.
319 ///
320 /// Examples: "arrive", "fall", "melt", "appear"
321 Unaccusative,
322
323 /// Takes a proposition and evaluates it relative to possible worlds.
324 ///
325 /// Intensional predicates don't just operate on truth values but on intensions
326 /// (functions from worlds to extensions). Required for modal and attitude reports.
327 /// "John believes it might rain" involves multiple world quantification.
328 ///
329 /// Examples: "believe", "know", "hope", "doubt"
330 IntensionalPredicate,
331
332 // -------------------------------------------------------------------------
333 // Noun Features
334 // -------------------------------------------------------------------------
335
336 /// Noun can be counted; takes singular/plural marking and numerals directly.
337 ///
338 /// Count nouns denote atomic, individuated entities. They combine with numerals
339 /// and indefinite articles: "three cats", "a dog". Semantically, they have
340 /// natural atomic minimal parts.
341 ///
342 /// Examples: "cat", "idea", "student", "book"
343 Count,
344
345 /// Noun denotes stuff without natural units; requires measure phrases for counting.
346 ///
347 /// Mass nouns are cumulative and divisive: any part of water is water, and
348 /// water plus water is water. Cannot directly combine with numerals;
349 /// require classifiers: "three glasses of water", not "three waters".
350 ///
351 /// Examples: "water", "rice", "information", "furniture"
352 Mass,
353
354 /// Noun is a proper name denoting a specific individual.
355 ///
356 /// Proper nouns are rigid designators that refer to the same individual in
357 /// all possible worlds. They typically lack articles and don't take plural
358 /// marking. Semantically, they denote individuals directly, not sets.
359 ///
360 /// Examples: "Socrates", "Paris", "Microsoft", "Monday"
361 Proper,
362
363 // -------------------------------------------------------------------------
364 // Gender Features
365 // -------------------------------------------------------------------------
366
367 /// Grammatically masculine; triggers masculine agreement on dependents.
368 ///
369 /// In languages with grammatical gender, masculine nouns control agreement
370 /// on articles, adjectives, and pronouns. In English, primarily affects
371 /// pronoun selection for animate referents.
372 ///
373 /// Examples: "man", "king", "actor", "waiter"
374 Masculine,
375
376 /// Grammatically feminine; triggers feminine agreement on dependents.
377 ///
378 /// Feminine nouns control feminine agreement patterns. In English, primarily
379 /// relevant for pronoun selection with human referents.
380 ///
381 /// Examples: "woman", "queen", "actress", "waitress"
382 Feminine,
383
384 /// Grammatically neuter; triggers neuter agreement on dependents.
385 ///
386 /// Neuter is the default for inanimate objects in English. Used for entities
387 /// where natural gender is absent or unknown. "It" is the neuter pronoun.
388 ///
389 /// Examples: "table", "rock", "system", "idea"
390 Neuter,
391
392 // -------------------------------------------------------------------------
393 // Animacy Features
394 // -------------------------------------------------------------------------
395
396 /// Denotes an entity capable of self-initiated action or sentience.
397 ///
398 /// Animacy is a semantic feature affecting argument realization. Animate
399 /// entities can be agents, experiencers, recipients. Affects pronoun choice
400 /// ("who" vs "what") and relative clause formation.
401 ///
402 /// Examples: "dog", "person", "bird", "robot" (ambiguous)
403 Animate,
404
405 /// Denotes a non-sentient entity incapable of self-initiated action.
406 ///
407 /// Inanimate entities typically serve as themes, patients, or instruments.
408 /// Cannot be agents in the semantic sense. "What" rather than "who".
409 ///
410 /// Examples: "rock", "table", "water", "idea"
411 Inanimate,
412
413 // -------------------------------------------------------------------------
414 // Adjective Features
415 // -------------------------------------------------------------------------
416
417 /// Adjective meaning combines by set intersection with noun meaning.
418 ///
419 /// For intersective adjectives, "A N" denotes things that are both A and N.
420 /// "Red ball" means {x : red(x) ∧ ball(x)}. The adjective has a context-independent
421 /// extension that intersects with the noun's extension.
422 ///
423 /// Examples: "red", "round", "wooden", "French"
424 Intersective,
425
426 /// Adjective meaning cannot be computed by simple intersection.
427 ///
428 /// Non-intersective adjectives require the noun to determine their extension.
429 /// "Fake gun" is not a gun at all, so fake(x) ∧ gun(x) gives wrong results.
430 /// Includes privative ("fake", "former") and modal ("alleged", "potential").
431 ///
432 /// Examples: "fake", "alleged", "former", "potential"
433 NonIntersective,
434
435 /// Adjective picks out a subset of the noun denotation relative to a comparison class.
436 ///
437 /// Subsective adjectives entail the noun: a "skillful surgeon" is a surgeon.
438 /// But "skillful" is relative: skillful for a surgeon, not skillful absolutely.
439 /// "Small elephant" is large for an animal but small for an elephant.
440 ///
441 /// Examples: "skillful", "good", "large", "small"
442 Subsective,
443
444 /// Adjective has a degree argument and supports comparison morphology.
445 ///
446 /// Gradable adjectives place entities on a scale with a contextual standard.
447 /// "Tall" means exceeding some contextual standard of height. Supports
448 /// comparatives ("taller"), superlatives ("tallest"), and degree modification.
449 ///
450 /// Examples: "tall", "expensive", "heavy", "smart"
451 Gradable,
452
453 /// Adjective that modifies the event denoted by the verb, not the noun.
454 ///
455 /// Event-modifying adjectives (when used adverbially) characterize manner or
456 /// other event properties. "Careful surgeon" suggests careful in operating,
457 /// not careful as a person. Related to adverb formation.
458 ///
459 /// Examples: "careful", "slow", "quick", "deliberate"
460 EventModifier,
461}
462
463impl Feature {
464 /// Parses a feature name from a string.
465 ///
466 /// Returns `Some(Feature)` if the string matches a known feature name (case-sensitive),
467 /// or `None` if unrecognized.
468 pub fn from_str(s: &str) -> Option<Feature> {
469 match s {
470 "Transitive" => Some(Feature::Transitive),
471 "Intransitive" => Some(Feature::Intransitive),
472 "Ditransitive" => Some(Feature::Ditransitive),
473 "SubjectControl" => Some(Feature::SubjectControl),
474 "ObjectControl" => Some(Feature::ObjectControl),
475 "Raising" => Some(Feature::Raising),
476 "Opaque" => Some(Feature::Opaque),
477 "Factive" => Some(Feature::Factive),
478 "Performative" => Some(Feature::Performative),
479 "Collective" => Some(Feature::Collective),
480 "Mixed" => Some(Feature::Mixed),
481 "Distributive" => Some(Feature::Distributive),
482 "Weather" => Some(Feature::Weather),
483 "Unaccusative" => Some(Feature::Unaccusative),
484 "IntensionalPredicate" => Some(Feature::IntensionalPredicate),
485 "Count" => Some(Feature::Count),
486 "Mass" => Some(Feature::Mass),
487 "Proper" => Some(Feature::Proper),
488 "Masculine" => Some(Feature::Masculine),
489 "Feminine" => Some(Feature::Feminine),
490 "Neuter" => Some(Feature::Neuter),
491 "Animate" => Some(Feature::Animate),
492 "Inanimate" => Some(Feature::Inanimate),
493 "Intersective" => Some(Feature::Intersective),
494 "NonIntersective" => Some(Feature::NonIntersective),
495 "Subsective" => Some(Feature::Subsective),
496 "Gradable" => Some(Feature::Gradable),
497 "EventModifier" => Some(Feature::EventModifier),
498 _ => None,
499 }
500 }
501}
502
503/// Verb entry returned from irregular verb lookup.
504///
505/// This owned struct is returned when looking up inflected verb forms
506/// (e.g., "ran" → run, "went" → go). Contains the resolved morphological
507/// information needed for semantic processing.
508#[derive(Debug, Clone, PartialEq, Eq)]
509pub struct VerbEntry {
510 /// The dictionary form (infinitive) of the verb.
511 /// Example: "run" for input "ran", "go" for input "went".
512 pub lemma: String,
513
514 /// The temporal reference encoded by the inflection.
515 /// Example: Past for "ran", Present for "runs".
516 pub time: Time,
517
518 /// The grammatical aspect of the inflected form.
519 /// Example: Progressive for "running", Perfect for "run" (in "has run").
520 pub aspect: Aspect,
521
522 /// The Vendler aspectual class (Aktionsart) of the verb.
523 /// Determines compatibility with temporal adverbials and aspect markers.
524 pub class: VerbClass,
525}
526
527/// Static verb metadata from the lexicon database.
528///
529/// This borrowed struct provides zero-copy access to verb information
530/// stored in the generated lexicon. Used for verbs looked up by lemma
531/// rather than inflected form.
532#[derive(Debug, Clone, Copy, PartialEq, Eq)]
533pub struct VerbMetadata {
534 /// The dictionary form (infinitive) of the verb.
535 pub lemma: &'static str,
536
537 /// The Vendler aspectual class determining temporal behavior.
538 pub class: VerbClass,
539
540 /// The default temporal reference (usually [`Time::None`] for infinitives).
541 pub time: Time,
542
543 /// The default grammatical aspect (usually [`Aspect::Simple`]).
544 pub aspect: Aspect,
545
546 /// Lexical features controlling syntax and semantics.
547 /// See [`Feature`] for the full list of possible features.
548 pub features: &'static [Feature],
549}
550
551/// Static noun metadata from the lexicon database.
552///
553/// Provides lexical information for noun lookup including number
554/// and semantic features. Nouns are keyed by their surface form,
555/// with separate entries for singular and plural.
556#[derive(Debug, Clone, Copy, PartialEq, Eq)]
557pub struct NounMetadata {
558 /// The canonical form of the noun (usually singular).
559 pub lemma: &'static str,
560
561 /// The grammatical number of this surface form.
562 /// "cat" → Singular, "cats" → Plural.
563 pub number: Number,
564
565 /// Semantic features including count/mass, animacy, and gender.
566 pub features: &'static [Feature],
567}
568
569/// Static adjective metadata from the lexicon database.
570///
571/// Adjectives carry features that determine their semantic behavior
572/// when combined with nouns (intersective, subsective, etc.) and
573/// whether they support gradability and comparison.
574#[derive(Debug, Clone, Copy, PartialEq, Eq)]
575pub struct AdjectiveMetadata {
576 /// The base form of the adjective (positive degree).
577 pub lemma: &'static str,
578
579 /// Semantic features controlling modification behavior.
580 /// See [`Feature::Intersective`], [`Feature::Subsective`], etc.
581 pub features: &'static [Feature],
582}
583
584/// Canonical mapping for verb synonyms and antonyms.
585///
586/// Maps a verb to its canonical form for semantic normalization.
587/// Antonyms are mapped with negative polarity, synonyms with positive.
588/// Example: "despise" → ("hate", Positive), "love" → ("hate", Negative).
589#[derive(Debug, Clone, Copy, PartialEq, Eq)]
590pub struct CanonicalMapping {
591 /// The canonical verb lemma this word maps to.
592 pub lemma: &'static str,
593
594 /// Whether the mapping preserves (Positive) or inverts (Negative) polarity.
595 pub polarity: Polarity,
596}
597
598/// Morphological rule for derivational morphology.
599///
600/// Defines how suffixes transform words between categories.
601/// Used for productive morphological patterns like "-ness" (adj → noun)
602/// or "-ly" (adj → adv).
603#[derive(Debug, Clone, Copy, PartialEq, Eq)]
604pub struct MorphologicalRule {
605 /// The suffix that triggers this rule (e.g., "-ness", "-ly").
606 pub suffix: &'static str,
607
608 /// The part of speech or category produced (e.g., "noun", "adverb").
609 pub produces: &'static str,
610}