logicaffeine-lexicon 0.9.13

English vocabulary types and compile-time lexicon lookup for logicaffeine
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
//! Lexicon type definitions
//!
//! Core types used by the generated lexicon lookup functions.

/// Article definiteness for noun phrases.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Definiteness {
    /// The referent is uniquely identifiable ("the").
    Definite,
    /// The referent is not uniquely identifiable ("a", "an").
    Indefinite,
    /// The referent is near the speaker ("this", "these").
    Proximal,
    /// The referent is far from the speaker ("that", "those").
    Distal,
}

/// Temporal reference for verb tense.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Time {
    /// Event occurred before speech time.
    Past,
    /// Event overlaps with speech time.
    Present,
    /// Event occurs after speech time.
    Future,
    /// No temporal specification (infinitives, bare stems).
    None,
}

/// Grammatical aspect (viewpoint aspect).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Aspect {
    /// Event viewed as a whole, completed action.
    Simple,
    /// Event viewed as ongoing, in progress.
    Progressive,
    /// Event completed with present relevance.
    Perfect,
}

/// Vendler's Lexical Aspect Classes (Aktionsart)
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash)]
pub enum VerbClass {
    /// +static, +durative, -telic: know, love, exist
    State,
    /// -static, +durative, -telic: run, swim, drive
    #[default]
    Activity,
    /// -static, +durative, +telic: build, draw, write
    Accomplishment,
    /// -static, -durative, +telic: win, find, die
    Achievement,
    /// -static, -durative, -telic: knock, cough, blink
    Semelfactive,
}

impl VerbClass {
    /// Returns true if this is a stative verb class (no change of state).
    ///
    /// States denote properties or relations that hold without change: "know", "love", "exist".
    pub fn is_stative(&self) -> bool {
        matches!(self, VerbClass::State)
    }

    /// Returns true if this verb class denotes events with duration.
    ///
    /// Durative events: States, Activities, and Accomplishments all have temporal extent.
    /// Non-durative: Achievements and Semelfactives are punctual.
    pub fn is_durative(&self) -> bool {
        matches!(
            self,
            VerbClass::State | VerbClass::Activity | VerbClass::Accomplishment
        )
    }

    /// Returns true if this verb class has an inherent endpoint (telic).
    ///
    /// Telic events: Accomplishments and Achievements reach a natural endpoint.
    /// Atelic events: States, Activities, and Semelfactives have no inherent endpoint.
    pub fn is_telic(&self) -> bool {
        matches!(self, VerbClass::Accomplishment | VerbClass::Achievement)
    }
}

/// Semantic sorts for type checking.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Sort {
    /// Top of the hierarchy; any individual.
    Entity,
    /// Concrete, spatially located objects.
    Physical,
    /// Living beings capable of self-motion.
    Animate,
    /// Persons with intentional agency.
    Human,
    /// Non-animal living organisms.
    Plant,
    /// Locations and regions.
    Place,
    /// Temporal intervals and points.
    Time,
    /// Non-physical, conceptual entities.
    Abstract,
    /// Propositional content and data.
    Information,
    /// Occurrences and happenings.
    Event,
    /// Stars, planets, and astronomical bodies.
    Celestial,
    /// Numeric or monetary amounts.
    Value,
    /// Hardware signals, wires, clocks, and buses.
    Signal,
    /// Collections of individuals.
    Group,
}

impl Sort {
    /// Check if this sort can be used where `other` is expected.
    ///
    /// Sort compatibility follows a subsumption hierarchy:
    /// - Human ⊆ Animate ⊆ Physical ⊆ Entity
    /// - Plant ⊆ Animate ⊆ Physical ⊆ Entity
    /// - Everything ⊆ Entity
    ///
    /// For example, a Human noun can fill an Animate slot, but not vice versa.
    pub fn is_compatible_with(self, other: Sort) -> bool {
        if self == other {
            return true;
        }
        match (self, other) {
            (Sort::Human, Sort::Animate) => true,
            (Sort::Plant, Sort::Animate) => true,
            (Sort::Animate, Sort::Physical) => true,
            (Sort::Human, Sort::Physical) => true,
            (Sort::Plant, Sort::Physical) => true,
            (_, Sort::Entity) => true,
            _ => false,
        }
    }
}

/// Grammatical number for nouns and agreement.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Number {
    /// Denotes a single individual.
    Singular,
    /// Denotes multiple individuals.
    Plural,
}

/// Grammatical gender (for pronouns and agreement).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Gender {
    /// Masculine gender ("he", "him", "his").
    Male,
    /// Feminine gender ("she", "her", "hers").
    Female,
    /// Neuter gender ("it", "its").
    Neuter,
    /// Gender unspecified or indeterminate.
    Unknown,
}

/// Grammatical case (for pronouns).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Case {
    /// Nominative case for subjects ("I", "he", "she").
    Subject,
    /// Accusative case for objects ("me", "him", "her").
    Object,
    /// Genitive case for possession ("my", "his", "her").
    Possessive,
}

/// Lexical polarity for canonical mappings.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Polarity {
    /// Preserves the meaning (synonym mapping).
    Positive,
    /// Inverts the meaning (antonym mapping).
    Negative,
}

/// Lexical features that encode grammatical and semantic properties of words.
///
/// Features are assigned to lexical entries in the lexicon database and control
/// how words combine syntactically and what semantic representations they produce.
/// The feature system follows the tradition of feature-based grammar formalisms
/// like HPSG and LFG.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Feature {
    // -------------------------------------------------------------------------
    // Verb Transitivity Features
    // -------------------------------------------------------------------------

    /// Verb requires a direct object (NP complement).
    ///
    /// Transitive verbs denote binary relations between an agent and a patient/theme.
    /// In first-order logic, they translate to two-place predicates: `Verb(x, y)`.
    ///
    /// Examples: "see", "hit", "love", "build"
    Transitive,

    /// Verb takes no object (unary predicate).
    ///
    /// Intransitive verbs denote properties of a single argument (the subject).
    /// They translate to one-place predicates: `Verb(x)`.
    ///
    /// Examples: "sleep", "arrive", "exist", "die"
    Intransitive,

    /// Verb takes two objects (direct + indirect).
    ///
    /// Ditransitive verbs denote ternary relations, typically involving transfer
    /// of possession. They translate to three-place predicates: `Verb(x, y, z)`.
    ///
    /// Examples: "give", "tell", "show", "send"
    Ditransitive,

    // -------------------------------------------------------------------------
    // Control Theory Features
    // -------------------------------------------------------------------------

    /// The subject of the matrix clause controls the PRO subject of the embedded clause.
    ///
    /// In "John promised Mary to leave", John (subject) is understood as the one leaving.
    /// Formally: promise(j, m, leave(PRO_j)) where PRO is coindexed with the subject.
    ///
    /// Examples: "promise", "try", "want", "decide"
    SubjectControl,

    /// The object of the matrix clause controls the PRO subject of the embedded clause.
    ///
    /// In "John persuaded Mary to leave", Mary (object) is understood as the one leaving.
    /// Formally: persuade(j, m, leave(PRO_m)) where PRO is coindexed with the object.
    ///
    /// Examples: "persuade", "force", "convince", "order"
    ObjectControl,

    /// Raising verb that does not assign a theta-role to its surface subject.
    ///
    /// In "John seems to be happy", "John" originates in the embedded clause and
    /// raises to matrix subject position. No control relation; subject is shared.
    /// Contrast with control: raising allows expletive subjects ("It seems that...").
    ///
    /// Examples: "seem", "appear", "happen", "tend"
    Raising,

    // -------------------------------------------------------------------------
    // Semantic Features
    // -------------------------------------------------------------------------

    /// Creates an opaque (intensional) context blocking substitution of co-referential terms.
    ///
    /// In opaque contexts, Leibniz's Law fails: even if a=b, P(a) does not entail P(b).
    /// "John believes Clark Kent is weak" does not entail "John believes Superman is weak"
    /// even if Clark Kent = Superman. Requires possible-worlds semantics.
    ///
    /// Examples: "believe", "think", "want", "seek"
    Opaque,

    /// Presupposes the truth of its complement clause.
    ///
    /// Factive verbs entail the truth of their embedded proposition regardless of
    /// the matrix clause's truth value. "John regrets that it rained" presupposes
    /// that it rained, even under negation: "John doesn't regret that it rained."
    ///
    /// Examples: "know", "regret", "realize", "discover"
    Factive,

    /// Uttering the verb constitutes performing the action it describes.
    ///
    /// Performative verbs, when uttered in first person present, do not describe
    /// an action but perform it. "I promise to come" is itself the act of promising.
    /// Austin's speech act theory: saying is doing.
    ///
    /// Examples: "promise", "declare", "pronounce", "bet"
    Performative,

    /// Requires a plural or group subject; describes collective action.
    ///
    /// Collective predicates cannot distribute over atomic individuals.
    /// "The students gathered" is true of the group, not of each student individually.
    /// Contrast with distributive: "gathered" vs "slept".
    ///
    /// Examples: "gather", "meet", "disperse", "surround"
    Collective,

    /// Can be interpreted either collectively or distributively.
    ///
    /// Mixed predicates are ambiguous between collective and distributive readings.
    /// "The students lifted the piano" can mean they lifted it together (collective)
    /// or each lifted a piano (distributive). Context disambiguates.
    ///
    /// Examples: "lift", "carry", "build", "write"
    Mixed,

    /// Distributes over atomic individuals in a plurality.
    ///
    /// Distributive predicates apply to each member of a plural subject individually.
    /// "The students slept" entails that each student slept. Formally: ∀x(student(x) → slept(x)).
    ///
    /// Examples: "sleep", "smile", "breathe", "think"
    Distributive,

    /// Impersonal verb describing meteorological phenomena; takes expletive subject.
    ///
    /// Weather verbs have no semantic subject; "it" in "it rains" is a dummy expletive.
    /// In formal semantics, they are zero-place predicates or predicates of times/events.
    ///
    /// Examples: "rain", "snow", "thunder", "drizzle"
    Weather,

    /// Intransitive verb whose subject is a theme/patient, not an agent.
    ///
    /// Unaccusative verbs have an underlying object that surfaces as subject.
    /// Evidence: auxiliary selection in Italian/German, participle agreement.
    /// "The ice melted" - the ice undergoes melting, doesn't cause it.
    ///
    /// Examples: "arrive", "fall", "melt", "appear"
    Unaccusative,

    /// Takes a proposition and evaluates it relative to possible worlds.
    ///
    /// Intensional predicates don't just operate on truth values but on intensions
    /// (functions from worlds to extensions). Required for modal and attitude reports.
    /// "John believes it might rain" involves multiple world quantification.
    ///
    /// Examples: "believe", "know", "hope", "doubt"
    IntensionalPredicate,

    // -------------------------------------------------------------------------
    // Noun Features
    // -------------------------------------------------------------------------

    /// Noun can be counted; takes singular/plural marking and numerals directly.
    ///
    /// Count nouns denote atomic, individuated entities. They combine with numerals
    /// and indefinite articles: "three cats", "a dog". Semantically, they have
    /// natural atomic minimal parts.
    ///
    /// Examples: "cat", "idea", "student", "book"
    Count,

    /// Noun denotes stuff without natural units; requires measure phrases for counting.
    ///
    /// Mass nouns are cumulative and divisive: any part of water is water, and
    /// water plus water is water. Cannot directly combine with numerals;
    /// require classifiers: "three glasses of water", not "three waters".
    ///
    /// Examples: "water", "rice", "information", "furniture"
    Mass,

    /// Noun is a proper name denoting a specific individual.
    ///
    /// Proper nouns are rigid designators that refer to the same individual in
    /// all possible worlds. They typically lack articles and don't take plural
    /// marking. Semantically, they denote individuals directly, not sets.
    ///
    /// Examples: "Socrates", "Paris", "Microsoft", "Monday"
    Proper,

    // -------------------------------------------------------------------------
    // Gender Features
    // -------------------------------------------------------------------------

    /// Grammatically masculine; triggers masculine agreement on dependents.
    ///
    /// In languages with grammatical gender, masculine nouns control agreement
    /// on articles, adjectives, and pronouns. In English, primarily affects
    /// pronoun selection for animate referents.
    ///
    /// Examples: "man", "king", "actor", "waiter"
    Masculine,

    /// Grammatically feminine; triggers feminine agreement on dependents.
    ///
    /// Feminine nouns control feminine agreement patterns. In English, primarily
    /// relevant for pronoun selection with human referents.
    ///
    /// Examples: "woman", "queen", "actress", "waitress"
    Feminine,

    /// Grammatically neuter; triggers neuter agreement on dependents.
    ///
    /// Neuter is the default for inanimate objects in English. Used for entities
    /// where natural gender is absent or unknown. "It" is the neuter pronoun.
    ///
    /// Examples: "table", "rock", "system", "idea"
    Neuter,

    // -------------------------------------------------------------------------
    // Animacy Features
    // -------------------------------------------------------------------------

    /// Denotes an entity capable of self-initiated action or sentience.
    ///
    /// Animacy is a semantic feature affecting argument realization. Animate
    /// entities can be agents, experiencers, recipients. Affects pronoun choice
    /// ("who" vs "what") and relative clause formation.
    ///
    /// Examples: "dog", "person", "bird", "robot" (ambiguous)
    Animate,

    /// Denotes a non-sentient entity incapable of self-initiated action.
    ///
    /// Inanimate entities typically serve as themes, patients, or instruments.
    /// Cannot be agents in the semantic sense. "What" rather than "who".
    ///
    /// Examples: "rock", "table", "water", "idea"
    Inanimate,

    // -------------------------------------------------------------------------
    // Adjective Features
    // -------------------------------------------------------------------------

    /// Adjective meaning combines by set intersection with noun meaning.
    ///
    /// For intersective adjectives, "A N" denotes things that are both A and N.
    /// "Red ball" means {x : red(x) ∧ ball(x)}. The adjective has a context-independent
    /// extension that intersects with the noun's extension.
    ///
    /// Examples: "red", "round", "wooden", "French"
    Intersective,

    /// Adjective meaning cannot be computed by simple intersection.
    ///
    /// Non-intersective adjectives require the noun to determine their extension.
    /// "Fake gun" is not a gun at all, so fake(x) ∧ gun(x) gives wrong results.
    /// Includes privative ("fake", "former") and modal ("alleged", "potential").
    ///
    /// Examples: "fake", "alleged", "former", "potential"
    NonIntersective,

    /// Adjective picks out a subset of the noun denotation relative to a comparison class.
    ///
    /// Subsective adjectives entail the noun: a "skillful surgeon" is a surgeon.
    /// But "skillful" is relative: skillful for a surgeon, not skillful absolutely.
    /// "Small elephant" is large for an animal but small for an elephant.
    ///
    /// Examples: "skillful", "good", "large", "small"
    Subsective,

    /// Adjective has a degree argument and supports comparison morphology.
    ///
    /// Gradable adjectives place entities on a scale with a contextual standard.
    /// "Tall" means exceeding some contextual standard of height. Supports
    /// comparatives ("taller"), superlatives ("tallest"), and degree modification.
    ///
    /// Examples: "tall", "expensive", "heavy", "smart"
    Gradable,

    /// Adjective that modifies the event denoted by the verb, not the noun.
    ///
    /// Event-modifying adjectives (when used adverbially) characterize manner or
    /// other event properties. "Careful surgeon" suggests careful in operating,
    /// not careful as a person. Related to adverb formation.
    ///
    /// Examples: "careful", "slow", "quick", "deliberate"
    EventModifier,
}

impl Feature {
    /// Parses a feature name from a string.
    ///
    /// Returns `Some(Feature)` if the string matches a known feature name (case-sensitive),
    /// or `None` if unrecognized.
    pub fn from_str(s: &str) -> Option<Feature> {
        match s {
            "Transitive" => Some(Feature::Transitive),
            "Intransitive" => Some(Feature::Intransitive),
            "Ditransitive" => Some(Feature::Ditransitive),
            "SubjectControl" => Some(Feature::SubjectControl),
            "ObjectControl" => Some(Feature::ObjectControl),
            "Raising" => Some(Feature::Raising),
            "Opaque" => Some(Feature::Opaque),
            "Factive" => Some(Feature::Factive),
            "Performative" => Some(Feature::Performative),
            "Collective" => Some(Feature::Collective),
            "Mixed" => Some(Feature::Mixed),
            "Distributive" => Some(Feature::Distributive),
            "Weather" => Some(Feature::Weather),
            "Unaccusative" => Some(Feature::Unaccusative),
            "IntensionalPredicate" => Some(Feature::IntensionalPredicate),
            "Count" => Some(Feature::Count),
            "Mass" => Some(Feature::Mass),
            "Proper" => Some(Feature::Proper),
            "Masculine" => Some(Feature::Masculine),
            "Feminine" => Some(Feature::Feminine),
            "Neuter" => Some(Feature::Neuter),
            "Animate" => Some(Feature::Animate),
            "Inanimate" => Some(Feature::Inanimate),
            "Intersective" => Some(Feature::Intersective),
            "NonIntersective" => Some(Feature::NonIntersective),
            "Subsective" => Some(Feature::Subsective),
            "Gradable" => Some(Feature::Gradable),
            "EventModifier" => Some(Feature::EventModifier),
            _ => None,
        }
    }
}

/// Verb entry returned from irregular verb lookup.
///
/// This owned struct is returned when looking up inflected verb forms
/// (e.g., "ran" → run, "went" → go). Contains the resolved morphological
/// information needed for semantic processing.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VerbEntry {
    /// The dictionary form (infinitive) of the verb.
    /// Example: "run" for input "ran", "go" for input "went".
    pub lemma: String,

    /// The temporal reference encoded by the inflection.
    /// Example: Past for "ran", Present for "runs".
    pub time: Time,

    /// The grammatical aspect of the inflected form.
    /// Example: Progressive for "running", Perfect for "run" (in "has run").
    pub aspect: Aspect,

    /// The Vendler aspectual class (Aktionsart) of the verb.
    /// Determines compatibility with temporal adverbials and aspect markers.
    pub class: VerbClass,
}

/// Static verb metadata from the lexicon database.
///
/// This borrowed struct provides zero-copy access to verb information
/// stored in the generated lexicon. Used for verbs looked up by lemma
/// rather than inflected form.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct VerbMetadata {
    /// The dictionary form (infinitive) of the verb.
    pub lemma: &'static str,

    /// The Vendler aspectual class determining temporal behavior.
    pub class: VerbClass,

    /// The default temporal reference (usually [`Time::None`] for infinitives).
    pub time: Time,

    /// The default grammatical aspect (usually [`Aspect::Simple`]).
    pub aspect: Aspect,

    /// Lexical features controlling syntax and semantics.
    /// See [`Feature`] for the full list of possible features.
    pub features: &'static [Feature],
}

/// Static noun metadata from the lexicon database.
///
/// Provides lexical information for noun lookup including number
/// and semantic features. Nouns are keyed by their surface form,
/// with separate entries for singular and plural.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct NounMetadata {
    /// The canonical form of the noun (usually singular).
    pub lemma: &'static str,

    /// The grammatical number of this surface form.
    /// "cat" → Singular, "cats" → Plural.
    pub number: Number,

    /// Semantic features including count/mass, animacy, and gender.
    pub features: &'static [Feature],
}

/// Static adjective metadata from the lexicon database.
///
/// Adjectives carry features that determine their semantic behavior
/// when combined with nouns (intersective, subsective, etc.) and
/// whether they support gradability and comparison.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct AdjectiveMetadata {
    /// The base form of the adjective (positive degree).
    pub lemma: &'static str,

    /// Semantic features controlling modification behavior.
    /// See [`Feature::Intersective`], [`Feature::Subsective`], etc.
    pub features: &'static [Feature],
}

/// Canonical mapping for verb synonyms and antonyms.
///
/// Maps a verb to its canonical form for semantic normalization.
/// Antonyms are mapped with negative polarity, synonyms with positive.
/// Example: "despise" → ("hate", Positive), "love" → ("hate", Negative).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct CanonicalMapping {
    /// The canonical verb lemma this word maps to.
    pub lemma: &'static str,

    /// Whether the mapping preserves (Positive) or inverts (Negative) polarity.
    pub polarity: Polarity,
}

/// Morphological rule for derivational morphology.
///
/// Defines how suffixes transform words between categories.
/// Used for productive morphological patterns like "-ness" (adj → noun)
/// or "-ly" (adj → adv).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MorphologicalRule {
    /// The suffix that triggers this rule (e.g., "-ness", "-ly").
    pub suffix: &'static str,

    /// The part of speech or category produced (e.g., "noun", "adverb").
    pub produces: &'static str,
}