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 /// Hardware signals, wires, clocks, and buses.
114 Signal,
115 /// Collections of individuals.
116 Group,
117}
118
119impl Sort {
120 /// Check if this sort can be used where `other` is expected.
121 ///
122 /// Sort compatibility follows a subsumption hierarchy:
123 /// - Human ⊆ Animate ⊆ Physical ⊆ Entity
124 /// - Plant ⊆ Animate ⊆ Physical ⊆ Entity
125 /// - Everything ⊆ Entity
126 ///
127 /// For example, a Human noun can fill an Animate slot, but not vice versa.
128 pub fn is_compatible_with(self, other: Sort) -> bool {
129 if self == other {
130 return true;
131 }
132 match (self, other) {
133 (Sort::Human, Sort::Animate) => true,
134 (Sort::Plant, Sort::Animate) => true,
135 (Sort::Animate, Sort::Physical) => true,
136 (Sort::Human, Sort::Physical) => true,
137 (Sort::Plant, Sort::Physical) => true,
138 (_, Sort::Entity) => true,
139 _ => false,
140 }
141 }
142
143 /// Whether this sort denotes an OCCASION — an occurrence or happening whose
144 /// head noun behaves as a soft type. For occasion sorts, "the \[modifier\]
145 /// \[head\]" lets the modifier do the referring (the same event can be a
146 /// "trip", a "vacation", or a "holiday"), so two such definite descriptions
147 /// corefer when their modifier matches and their head sorts agree.
148 ///
149 /// Concrete physical objects (box, ball) are NOT occasions: "the red box"
150 /// and "the red ball" are distinct things even though both are `Physical`,
151 /// so they must never corefer through a shared modifier.
152 pub fn is_occasion(self) -> bool {
153 matches!(self, Sort::Event)
154 }
155}
156
157/// Grammatical number for nouns and agreement.
158#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
159pub enum Number {
160 /// Denotes a single individual.
161 Singular,
162 /// Denotes multiple individuals.
163 Plural,
164}
165
166/// Grammatical gender (for pronouns and agreement).
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
168pub enum Gender {
169 /// Masculine gender ("he", "him", "his").
170 Male,
171 /// Feminine gender ("she", "her", "hers").
172 Female,
173 /// Neuter gender ("it", "its").
174 Neuter,
175 /// Gender unspecified or indeterminate.
176 Unknown,
177}
178
179/// Grammatical case (for pronouns).
180#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
181pub enum Case {
182 /// Nominative case for subjects ("I", "he", "she").
183 Subject,
184 /// Accusative case for objects ("me", "him", "her").
185 Object,
186 /// Genitive case for possession ("my", "his", "her").
187 Possessive,
188}
189
190/// Lexical polarity for canonical mappings.
191#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
192pub enum Polarity {
193 /// Preserves the meaning (synonym mapping).
194 Positive,
195 /// Inverts the meaning (antonym mapping).
196 Negative,
197}
198
199/// Lexical features that encode grammatical and semantic properties of words.
200///
201/// Features are assigned to lexical entries in the lexicon database and control
202/// how words combine syntactically and what semantic representations they produce.
203/// The feature system follows the tradition of feature-based grammar formalisms
204/// like HPSG and LFG.
205#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
206pub enum Feature {
207 // -------------------------------------------------------------------------
208 // Verb Transitivity Features
209 // -------------------------------------------------------------------------
210
211 /// Verb requires a direct object (NP complement).
212 ///
213 /// Transitive verbs denote binary relations between an agent and a patient/theme.
214 /// In first-order logic, they translate to two-place predicates: `Verb(x, y)`.
215 ///
216 /// Examples: "see", "hit", "love", "build"
217 Transitive,
218
219 /// Verb takes no object (unary predicate).
220 ///
221 /// Intransitive verbs denote properties of a single argument (the subject).
222 /// They translate to one-place predicates: `Verb(x)`.
223 ///
224 /// Examples: "sleep", "arrive", "exist", "die"
225 Intransitive,
226
227 /// Verb takes two objects (direct + indirect).
228 ///
229 /// Ditransitive verbs denote ternary relations, typically involving transfer
230 /// of possession. They translate to three-place predicates: `Verb(x, y, z)`.
231 ///
232 /// Examples: "give", "tell", "show", "send"
233 Ditransitive,
234
235 // -------------------------------------------------------------------------
236 // Control Theory Features
237 // -------------------------------------------------------------------------
238
239 /// The subject of the matrix clause controls the PRO subject of the embedded clause.
240 ///
241 /// In "John promised Mary to leave", John (subject) is understood as the one leaving.
242 /// Formally: promise(j, m, leave(PRO_j)) where PRO is coindexed with the subject.
243 ///
244 /// Examples: "promise", "try", "want", "decide"
245 SubjectControl,
246
247 /// The object of the matrix clause controls the PRO subject of the embedded clause.
248 ///
249 /// In "John persuaded Mary to leave", Mary (object) is understood as the one leaving.
250 /// Formally: persuade(j, m, leave(PRO_m)) where PRO is coindexed with the object.
251 ///
252 /// Examples: "persuade", "force", "convince", "order"
253 ObjectControl,
254
255 /// Raising verb that does not assign a theta-role to its surface subject.
256 ///
257 /// In "John seems to be happy", "John" originates in the embedded clause and
258 /// raises to matrix subject position. No control relation; subject is shared.
259 /// Contrast with control: raising allows expletive subjects ("It seems that...").
260 ///
261 /// Examples: "seem", "appear", "happen", "tend"
262 Raising,
263
264 // -------------------------------------------------------------------------
265 // Semantic Features
266 // -------------------------------------------------------------------------
267
268 /// Creates an opaque (intensional) context blocking substitution of co-referential terms.
269 ///
270 /// In opaque contexts, Leibniz's Law fails: even if a=b, P(a) does not entail P(b).
271 /// "John believes Clark Kent is weak" does not entail "John believes Superman is weak"
272 /// even if Clark Kent = Superman. Requires possible-worlds semantics.
273 ///
274 /// Examples: "believe", "think", "want", "seek"
275 Opaque,
276
277 /// Presupposes the truth of its complement clause.
278 ///
279 /// Factive verbs entail the truth of their embedded proposition regardless of
280 /// the matrix clause's truth value. "John regrets that it rained" presupposes
281 /// that it rained, even under negation: "John doesn't regret that it rained."
282 ///
283 /// Examples: "know", "regret", "realize", "discover"
284 Factive,
285
286 /// Uttering the verb constitutes performing the action it describes.
287 ///
288 /// Performative verbs, when uttered in first person present, do not describe
289 /// an action but perform it. "I promise to come" is itself the act of promising.
290 /// Austin's speech act theory: saying is doing.
291 ///
292 /// Examples: "promise", "declare", "pronounce", "bet"
293 Performative,
294
295 /// Requires a plural or group subject; describes collective action.
296 ///
297 /// Collective predicates cannot distribute over atomic individuals.
298 /// "The students gathered" is true of the group, not of each student individually.
299 /// Contrast with distributive: "gathered" vs "slept".
300 ///
301 /// Examples: "gather", "meet", "disperse", "surround"
302 Collective,
303
304 /// Can be interpreted either collectively or distributively.
305 ///
306 /// Mixed predicates are ambiguous between collective and distributive readings.
307 /// "The students lifted the piano" can mean they lifted it together (collective)
308 /// or each lifted a piano (distributive). Context disambiguates.
309 ///
310 /// Examples: "lift", "carry", "build", "write"
311 Mixed,
312
313 /// Distributes over atomic individuals in a plurality.
314 ///
315 /// Distributive predicates apply to each member of a plural subject individually.
316 /// "The students slept" entails that each student slept. Formally: ∀x(student(x) → slept(x)).
317 ///
318 /// Examples: "sleep", "smile", "breathe", "think"
319 Distributive,
320
321 /// Impersonal verb describing meteorological phenomena; takes expletive subject.
322 ///
323 /// Weather verbs have no semantic subject; "it" in "it rains" is a dummy expletive.
324 /// In formal semantics, they are zero-place predicates or predicates of times/events.
325 ///
326 /// Examples: "rain", "snow", "thunder", "drizzle"
327 Weather,
328
329 /// Intransitive verb whose subject is a theme/patient, not an agent.
330 ///
331 /// Unaccusative verbs have an underlying object that surfaces as subject.
332 /// Evidence: auxiliary selection in Italian/German, participle agreement.
333 /// "The ice melted" - the ice undergoes melting, doesn't cause it.
334 ///
335 /// Examples: "arrive", "fall", "melt", "appear"
336 Unaccusative,
337
338 /// Takes a proposition and evaluates it relative to possible worlds.
339 ///
340 /// Intensional predicates don't just operate on truth values but on intensions
341 /// (functions from worlds to extensions). Required for modal and attitude reports.
342 /// "John believes it might rain" involves multiple world quantification.
343 ///
344 /// Examples: "believe", "know", "hope", "doubt"
345 IntensionalPredicate,
346
347 /// Causative change-of-state verb that licenses a RESULTATIVE secondary
348 /// predicate: the object's resulting state is brought about by the event.
349 /// "paint the door RED" (the door becomes red), "hammer the metal FLAT".
350 /// Verbs without this feature take a post-object AP as a DEPICTIVE instead
351 /// ("eat the meat RAW" — the meat is raw during, not caused by, the eating).
352 ///
353 /// Examples: "paint", "dye", "break", "flatten", "freeze"
354 Resultative,
355
356 /// Perception verb (see, hear, watch, …) taking a small-clause complement
357 /// "NP bare-VP" that denotes the PERCEIVED EVENT (§3.2): "Mary heard the bell
358 /// RING" → Hear(mary, ⟨Ring(bell)⟩).
359 ///
360 /// Examples: "see", "hear", "watch", "feel", "notice", "observe"
361 Perception,
362
363 /// Addressee-oriented attitude verb that, in an "if you V …" antecedent, marks a
364 /// BISCUIT / relevance conditional (§4.2): the consequent is asserted and the
365 /// if-clause restricts relevance, not truth ("If you WANT tea, the kettle is hot").
366 ///
367 /// Examples: "want", "need", "wonder", "care", "desire", "wish", "like"
368 Relevance,
369
370 // -------------------------------------------------------------------------
371 // Noun Features
372 // -------------------------------------------------------------------------
373
374 /// Noun can be counted; takes singular/plural marking and numerals directly.
375 ///
376 /// Count nouns denote atomic, individuated entities. They combine with numerals
377 /// and indefinite articles: "three cats", "a dog". Semantically, they have
378 /// natural atomic minimal parts.
379 ///
380 /// Examples: "cat", "idea", "student", "book"
381 Count,
382
383 /// Noun denotes stuff without natural units; requires measure phrases for counting.
384 ///
385 /// Mass nouns are cumulative and divisive: any part of water is water, and
386 /// water plus water is water. Cannot directly combine with numerals;
387 /// require classifiers: "three glasses of water", not "three waters".
388 ///
389 /// Examples: "water", "rice", "information", "furniture"
390 Mass,
391
392 /// Noun is a proper name denoting a specific individual.
393 ///
394 /// Proper nouns are rigid designators that refer to the same individual in
395 /// all possible worlds. They typically lack articles and don't take plural
396 /// marking. Semantically, they denote individuals directly, not sets.
397 ///
398 /// Examples: "Socrates", "Paris", "Microsoft", "Monday"
399 Proper,
400
401 // -------------------------------------------------------------------------
402 // Gender Features
403 // -------------------------------------------------------------------------
404
405 /// Grammatically masculine; triggers masculine agreement on dependents.
406 ///
407 /// In languages with grammatical gender, masculine nouns control agreement
408 /// on articles, adjectives, and pronouns. In English, primarily affects
409 /// pronoun selection for animate referents.
410 ///
411 /// Examples: "man", "king", "actor", "waiter"
412 Masculine,
413
414 /// Grammatically feminine; triggers feminine agreement on dependents.
415 ///
416 /// Feminine nouns control feminine agreement patterns. In English, primarily
417 /// relevant for pronoun selection with human referents.
418 ///
419 /// Examples: "woman", "queen", "actress", "waitress"
420 Feminine,
421
422 /// Grammatically neuter; triggers neuter agreement on dependents.
423 ///
424 /// Neuter is the default for inanimate objects in English. Used for entities
425 /// where natural gender is absent or unknown. "It" is the neuter pronoun.
426 ///
427 /// Examples: "table", "rock", "system", "idea"
428 Neuter,
429
430 // -------------------------------------------------------------------------
431 // Animacy Features
432 // -------------------------------------------------------------------------
433
434 /// Denotes an entity capable of self-initiated action or sentience.
435 ///
436 /// Animacy is a semantic feature affecting argument realization. Animate
437 /// entities can be agents, experiencers, recipients. Affects pronoun choice
438 /// ("who" vs "what") and relative clause formation.
439 ///
440 /// Examples: "dog", "person", "bird", "robot" (ambiguous)
441 Animate,
442
443 /// Denotes a non-sentient entity incapable of self-initiated action.
444 ///
445 /// Inanimate entities typically serve as themes, patients, or instruments.
446 /// Cannot be agents in the semantic sense. "What" rather than "who".
447 ///
448 /// Examples: "rock", "table", "water", "idea"
449 Inanimate,
450
451 // -------------------------------------------------------------------------
452 // Adjective Features
453 // -------------------------------------------------------------------------
454
455 /// Adjective meaning combines by set intersection with noun meaning.
456 ///
457 /// For intersective adjectives, "A N" denotes things that are both A and N.
458 /// "Red ball" means {x : red(x) ∧ ball(x)}. The adjective has a context-independent
459 /// extension that intersects with the noun's extension.
460 ///
461 /// Examples: "red", "round", "wooden", "French"
462 Intersective,
463
464 /// Adjective meaning cannot be computed by simple intersection.
465 ///
466 /// Non-intersective adjectives require the noun to determine their extension.
467 /// "Fake gun" is not a gun at all, so fake(x) ∧ gun(x) gives wrong results.
468 /// Includes privative ("fake", "former") and modal ("alleged", "potential").
469 ///
470 /// Examples: "fake", "alleged", "former", "potential"
471 NonIntersective,
472
473 /// Adjective picks out a subset of the noun denotation relative to a comparison class.
474 ///
475 /// Subsective adjectives entail the noun: a "skillful surgeon" is a surgeon.
476 /// But "skillful" is relative: skillful for a surgeon, not skillful absolutely.
477 /// "Small elephant" is large for an animal but small for an elephant.
478 ///
479 /// Examples: "skillful", "good", "large", "small"
480 Subsective,
481
482 /// Adjective has a degree argument and supports comparison morphology.
483 ///
484 /// Gradable adjectives place entities on a scale with a contextual standard.
485 /// "Tall" means exceeding some contextual standard of height. Supports
486 /// comparatives ("taller"), superlatives ("tallest"), and degree modification.
487 ///
488 /// Examples: "tall", "expensive", "heavy", "smart"
489 Gradable,
490
491 /// Adjective that modifies the event denoted by the verb, not the noun.
492 ///
493 /// Event-modifying adjectives (when used adverbially) characterize manner or
494 /// other event properties. "Careful surgeon" suggests careful in operating,
495 /// not careful as a person. Related to adverb formation.
496 ///
497 /// Examples: "careful", "slow", "quick", "deliberate"
498 EventModifier,
499
500 /// Denominal, non-predicating adjective denoting a relation to a base noun.
501 ///
502 /// Relational (pertainymic) adjectives — "dental" ← tooth, "coastal" ← coast,
503 /// "nuclear" ← nucleus — are NOT intersective: "a dental procedure" is not
504 /// {dental things} ∩ {procedures}; the adjective relates the procedure to
505 /// teeth. They are predicates of KINDS (McNally & Boleda 2004), modeled as
506 /// `Noun(x) ∧ Rel(x, ^Base)` (kind-level, default) or
507 /// `Noun(x) ∧ ∃y(Base(y) ∧ Rel(x, y))` (instance-level override).
508 ///
509 /// Examples: "dental", "coastal", "nuclear", "marine", "postal", "solar"
510 Relational,
511
512 /// Gradable adjective with borderline cases and sorites behavior (§8.5): the
513 /// threshold has a PENUMBRA (a vague region θ_low < d < θ_high), not a sharp
514 /// cutoff. Implies a degree-standard reading plus a borderline marker.
515 ///
516 /// Examples: "bald", "tall", "heavy", "rich", "old", "big"
517 Vague,
518
519 /// Negative-pole (decreasing) gradable adjective: the comparative denotes a
520 /// SMALLER value on the canonical measured scale, so an arithmetic comparative
521 /// subtracts rather than adds ("narrower" → less wingspan, "lighter" → less
522 /// weight). The unmarked positive pole ("wide", "long", "heavy") increases.
523 ///
524 /// Examples: "narrow", "short", "small", "light", "cheap", "slow", "young"
525 Decreasing,
526}
527
528impl Feature {
529 /// Parses a feature name from a string.
530 ///
531 /// Returns `Some(Feature)` if the string matches a known feature name (case-sensitive),
532 /// or `None` if unrecognized.
533 pub fn from_str(s: &str) -> Option<Feature> {
534 match s {
535 "Transitive" => Some(Feature::Transitive),
536 "Intransitive" => Some(Feature::Intransitive),
537 "Ditransitive" => Some(Feature::Ditransitive),
538 "SubjectControl" => Some(Feature::SubjectControl),
539 "ObjectControl" => Some(Feature::ObjectControl),
540 "Raising" => Some(Feature::Raising),
541 "Opaque" => Some(Feature::Opaque),
542 "Factive" => Some(Feature::Factive),
543 "Performative" => Some(Feature::Performative),
544 "Collective" => Some(Feature::Collective),
545 "Mixed" => Some(Feature::Mixed),
546 "Distributive" => Some(Feature::Distributive),
547 "Weather" => Some(Feature::Weather),
548 "Unaccusative" => Some(Feature::Unaccusative),
549 "IntensionalPredicate" => Some(Feature::IntensionalPredicate),
550 "Resultative" => Some(Feature::Resultative),
551 "Perception" => Some(Feature::Perception),
552 "Relevance" => Some(Feature::Relevance),
553 "Count" => Some(Feature::Count),
554 "Mass" => Some(Feature::Mass),
555 "Proper" => Some(Feature::Proper),
556 "Masculine" => Some(Feature::Masculine),
557 "Feminine" => Some(Feature::Feminine),
558 "Neuter" => Some(Feature::Neuter),
559 "Animate" => Some(Feature::Animate),
560 "Inanimate" => Some(Feature::Inanimate),
561 "Intersective" => Some(Feature::Intersective),
562 "NonIntersective" => Some(Feature::NonIntersective),
563 "Subsective" => Some(Feature::Subsective),
564 "Gradable" => Some(Feature::Gradable),
565 "EventModifier" => Some(Feature::EventModifier),
566 "Relational" => Some(Feature::Relational),
567 "Vague" => Some(Feature::Vague),
568 "Decreasing" => Some(Feature::Decreasing),
569 _ => None,
570 }
571 }
572}
573
574/// Verb entry returned from irregular verb lookup.
575///
576/// This owned struct is returned when looking up inflected verb forms
577/// (e.g., "ran" → run, "went" → go). Contains the resolved morphological
578/// information needed for semantic processing.
579#[derive(Debug, Clone, PartialEq, Eq)]
580pub struct VerbEntry {
581 /// The dictionary form (infinitive) of the verb.
582 /// Example: "run" for input "ran", "go" for input "went".
583 pub lemma: String,
584
585 /// The temporal reference encoded by the inflection.
586 /// Example: Past for "ran", Present for "runs".
587 pub time: Time,
588
589 /// The grammatical aspect of the inflected form.
590 /// Example: Progressive for "running", Perfect for "run" (in "has run").
591 pub aspect: Aspect,
592
593 /// The Vendler aspectual class (Aktionsart) of the verb.
594 /// Determines compatibility with temporal adverbials and aspect markers.
595 pub class: VerbClass,
596}
597
598/// Static verb metadata from the lexicon database.
599///
600/// This borrowed struct provides zero-copy access to verb information
601/// stored in the generated lexicon. Used for verbs looked up by lemma
602/// rather than inflected form.
603#[derive(Debug, Clone, Copy, PartialEq, Eq)]
604pub struct VerbMetadata {
605 /// The dictionary form (infinitive) of the verb.
606 pub lemma: &'static str,
607
608 /// The Vendler aspectual class determining temporal behavior.
609 pub class: VerbClass,
610
611 /// The default temporal reference (usually [`Time::None`] for infinitives).
612 pub time: Time,
613
614 /// The default grammatical aspect (usually [`Aspect::Simple`]).
615 pub aspect: Aspect,
616
617 /// Lexical features controlling syntax and semantics.
618 /// See [`Feature`] for the full list of possible features.
619 pub features: &'static [Feature],
620}
621
622/// Static noun metadata from the lexicon database.
623///
624/// Provides lexical information for noun lookup including number
625/// and semantic features. Nouns are keyed by their surface form,
626/// with separate entries for singular and plural.
627#[derive(Debug, Clone, Copy, PartialEq, Eq)]
628pub struct NounMetadata {
629 /// The canonical form of the noun (usually singular).
630 pub lemma: &'static str,
631
632 /// The grammatical number of this surface form.
633 /// "cat" → Singular, "cats" → Plural.
634 pub number: Number,
635
636 /// Semantic features including count/mass, animacy, and gender.
637 pub features: &'static [Feature],
638}
639
640/// Static adjective metadata from the lexicon database.
641///
642/// Adjectives carry features that determine their semantic behavior
643/// when combined with nouns (intersective, subsective, etc.) and
644/// whether they support gradability and comparison.
645#[derive(Debug, Clone, Copy, PartialEq, Eq)]
646pub struct AdjectiveMetadata {
647 /// The base form of the adjective (positive degree).
648 pub lemma: &'static str,
649
650 /// Semantic features controlling modification behavior.
651 /// See [`Feature::Intersective`], [`Feature::Subsective`], etc.
652 pub features: &'static [Feature],
653}
654
655/// Canonical mapping for verb synonyms and antonyms.
656///
657/// Maps a verb to its canonical form for semantic normalization.
658/// Antonyms are mapped with negative polarity, synonyms with positive.
659/// Example: "despise" → ("hate", Positive), "love" → ("hate", Negative).
660#[derive(Debug, Clone, Copy, PartialEq, Eq)]
661pub struct CanonicalMapping {
662 /// The canonical verb lemma this word maps to.
663 pub lemma: &'static str,
664
665 /// Whether the mapping preserves (Positive) or inverts (Negative) polarity.
666 pub polarity: Polarity,
667}
668
669/// Morphological rule for derivational morphology.
670///
671/// Defines how suffixes transform words between categories.
672/// Used for productive morphological patterns like "-ness" (adj → noun)
673/// or "-ly" (adj → adv).
674#[derive(Debug, Clone, Copy, PartialEq, Eq)]
675pub struct MorphologicalRule {
676 /// The suffix that triggers this rule (e.g., "-ness", "-ly").
677 pub suffix: &'static str,
678
679 /// The part of speech or category produced (e.g., "noun", "adverb").
680 pub produces: &'static str,
681}