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}