39 releases
| new 0.9.16 | Apr 6, 2026 |
|---|---|
| 0.9.15 | Apr 5, 2026 |
| 0.9.10 | Mar 30, 2026 |
| 0.9.2 | Feb 28, 2026 |
| 0.6.0 | Jan 17, 2026 |
#1518 in Programming languages
Used in 4 crates
(via logicaffeine-language)
83KB
792 lines
logicaffeine-lexicon
Linguistic type definitions and vocabulary management for the Logicaffeine English-to-First-Order-Logic transpiler.
Part of the Logicaffeine project.
Overview
This crate provides:
- Type definitions for linguistic categories (verb classes, semantic sorts, grammatical features)
- Metadata structures for zero-copy lexicon lookups
- Optional runtime lexicon for development iteration (via
dynamic-lexiconfeature)
Quick Start
use logicaffeine_lexicon::{VerbClass, Feature, Sort};
// Check verb aspectual properties (Vendler classification)
let class = VerbClass::Activity;
assert!(!class.is_stative()); // Activities are dynamic
assert!(class.is_durative()); // Activities have duration
assert!(!class.is_telic()); // Activities have no inherent endpoint
// Parse features from strings
let feature = Feature::from_str("Transitive");
assert_eq!(feature, Some(Feature::Transitive));
// Check semantic sort compatibility (subsumption hierarchy)
assert!(Sort::Human.is_compatible_with(Sort::Animate)); // Human ⊆ Animate
assert!(Sort::Human.is_compatible_with(Sort::Entity)); // Everything ⊆ Entity
assert!(!Sort::Animate.is_compatible_with(Sort::Human)); // Not vice versa
Core Types
Grammatical Enumerations
| Type | Variants | Description |
|---|---|---|
Time |
Past, Present, Future, None |
Temporal reference for verb tense |
Aspect |
Simple, Progressive, Perfect |
Viewpoint aspect (grammatical) |
Number |
Singular, Plural |
Grammatical number |
Gender |
Male, Female, Neuter, Unknown |
Grammatical gender |
Case |
Subject, Object, Possessive |
Grammatical case (pronouns) |
Definiteness |
Definite, Indefinite, Proximal, Distal |
Article/demonstrative definiteness |
Polarity |
Positive, Negative |
For synonym/antonym canonical mappings |
VerbClass (Vendler Classification)
Vendler's lexical aspect classes (Aktionsart) determine how verbs interact with temporal adverbials and aspect markers.
| Class | Static | Durative | Telic | Examples |
|---|---|---|---|---|
State |
+ | + | - | know, love, exist |
Activity |
- | + | - | run, swim, drive |
Accomplishment |
- | + | + | build, draw, write |
Achievement |
- | - | + | win, find, die |
Semelfactive |
- | - | - | knock, cough, blink |
use logicaffeine_lexicon::VerbClass;
let class = VerbClass::Accomplishment;
assert!(!class.is_stative()); // Dynamic (involves change)
assert!(class.is_durative()); // Takes time to complete
assert!(class.is_telic()); // Has an inherent endpoint
Sort (Semantic Type Hierarchy)
Sorts provide semantic type checking. A Human can fill an Animate slot, but not vice versa.
Entity
/ \
Physical Abstract
/ \ \
Animate Place Information
/ \
Human Plant Event
(Also: Time, Celestial, Value, Group)
Compatibility follows subsumption:
Human ⊆ Animate ⊆ Physical ⊆ EntityPlant ⊆ Animate ⊆ Physical ⊆ Entity- Everything ⊆
Entity
use logicaffeine_lexicon::Sort;
// Human can be used where Animate is expected
assert!(Sort::Human.is_compatible_with(Sort::Animate));
// But Animate cannot be used where Human is expected
assert!(!Sort::Animate.is_compatible_with(Sort::Human));
Feature (27 Variants)
Lexical features encode grammatical and semantic properties of words.
Transitivity
Transitive— requires direct object: "see", "hit"Intransitive— no object: "sleep", "arrive"Ditransitive— two objects: "give", "tell"
Control Theory
SubjectControl— subject controls embedded PRO: "promise", "try"ObjectControl— object controls embedded PRO: "persuade", "force"Raising— no theta-role to surface subject: "seem", "appear"
Semantic
Opaque— intensional context: "believe", "want"Factive— presupposes complement truth: "know", "regret"Performative— uttering performs the action: "promise", "declare"Collective— requires group subject: "gather", "meet"Mixed— collective or distributive: "lift", "carry"Distributive— applies to each individual: "sleep", "smile"Weather— impersonal, expletive subject: "rain", "snow"Unaccusative— subject is underlying theme: "arrive", "melt"IntensionalPredicate— operates on intensions: "believe", "hope"
Noun
Count— individuated, takes numerals: "cat", "idea"Mass— requires measure phrases: "water", "rice"Proper— rigid designator: "Socrates", "Paris"
Gender
Masculine,Feminine,Neuter
Animacy
Animate— capable of self-initiated actionInanimate— not sentient
Adjective
Intersective— set intersection: "red ball" = red ∧ ballNonIntersective— not intersection: "fake gun" ≠ fake ∧ gunSubsective— relative to comparison class: "skillful surgeon"Gradable— supports degree: "tall", "expensive"EventModifier— modifies events: "careful", "deliberate"
Metadata Structs
These structs provide zero-copy access to lexicon data:
use logicaffeine_lexicon::{VerbMetadata, VerbClass, Feature, Time, Aspect};
// Returned from compile-time generated lookup functions
let verb: VerbMetadata = VerbMetadata {
lemma: "give",
class: VerbClass::Achievement,
time: Time::None,
aspect: Aspect::Simple,
features: &[Feature::Ditransitive],
};
| Struct | Fields |
|---|---|
VerbMetadata |
lemma, class, time, aspect, features |
NounMetadata |
lemma, number, features |
AdjectiveMetadata |
lemma, features |
VerbEntry |
Owned version for irregular verb lookups |
CanonicalMapping |
For synonym/antonym normalization |
MorphologicalRule |
Derivational morphology patterns |
Features
| Feature | Description |
|---|---|
| (default) | Type definitions only, no dependencies beyond logicaffeine-base |
dynamic-lexicon |
Runtime JSON loading, queries, morphology functions |
# Types only (for compile-time codegen)
[dependencies]
logicaffeine-lexicon = "0.6"
# With runtime lexicon (for development)
[dependencies]
logicaffeine-lexicon = { version = "0.6", features = ["dynamic-lexicon"] }
Runtime Lexicon (Optional)
With the dynamic-lexicon feature, you get:
LexiconIndex
use logicaffeine_lexicon::runtime::LexiconIndex;
let lexicon = LexiconIndex::new();
// Query by feature
let transitive = lexicon.verbs_with_feature("Transitive");
let animate = lexicon.nouns_with_feature("Animate");
// Query by category
let proper_nouns = lexicon.proper_nouns();
let common_nouns = lexicon.common_nouns();
let state_verbs = lexicon.verbs_with_class("State");
// Random selection (useful for testing/generation)
let mut rng = rand::thread_rng();
let random_verb = lexicon.random_transitive_verb(&mut rng);
Morphological Functions
use logicaffeine_lexicon::runtime::{NounEntry, VerbEntry, pluralize, present_3s, past_tense, gerund};
use std::collections::HashMap;
// Regular pluralization
let dog = NounEntry {
lemma: "dog".to_string(),
forms: HashMap::new(),
features: vec![],
sort: None,
};
assert_eq!(pluralize(&dog), "dogs");
// Irregular forms (via forms map)
let mouse = NounEntry {
lemma: "mouse".to_string(),
forms: [("plural".to_string(), "mice".to_string())].into(),
features: vec![],
sort: None,
};
assert_eq!(pluralize(&mouse), "mice");
// Verb conjugation
let walk = VerbEntry {
lemma: "walk".to_string(),
class: "Activity".to_string(),
forms: HashMap::new(),
features: vec![],
};
assert_eq!(present_3s(&walk), "walks");
assert_eq!(past_tense(&walk), "walked");
assert_eq!(gerund(&walk), "walking");
Morphological rules applied:
| Function | Rule | Example |
|---|---|---|
pluralize |
sibilant + -es |
box → boxes |
pluralize |
consonant + y → -ies |
city → cities |
present_3s |
sibilant/o + -es |
go → goes |
past_tense |
e + -d |
love → loved |
past_tense |
consonant + y → -ied |
carry → carried |
gerund |
drop e + -ing |
make → making |
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ logicaffeine_language │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ build.rs: generates lexicon.rs from lexicon.json ││
│ │ (compile-time code generation) ││
│ └─────────────────────────────────────────────────────────────┘│
│ │ │
│ ▼ │
│ lexicon.rs (generated) │
│ - lookup_verb("run") → VerbMetadata │
│ - lookup_noun("cat") → NounMetadata │
└─────────────────────────────────────────────────────────────────┘
│
│ uses types from
▼
┌─────────────────────────────────────────────────────────────────┐
│ logicaffeine_lexicon │
│ ┌────────────────────────┐ ┌────────────────────────────────┐ │
│ │ types.rs │ │ runtime.rs (optional) │ │
│ │ - VerbClass │ │ - LexiconIndex │ │
│ │ - Sort │ │ - pluralize(), past_tense() │ │
│ │ - Feature │ │ - JSON deserialization │ │
│ │ - *Metadata structs │ │ (dynamic-lexicon feature) │ │
│ └────────────────────────┘ └────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Compile-time mode (default): logicaffeine_language's build script generates type-safe Rust lookup functions from lexicon.json. This crate provides only the type definitions those functions return.
Runtime mode (dynamic-lexicon): Embeds lexicon.json and parses it at runtime. Useful during development when frequently editing the lexicon, as it avoids full recompilation.
License
Business Source License 1.1 (BUSL-1.1)
- Free for individuals and organizations with <25 employees
- Commercial license required for organizations with 25+ employees offering Logic Services
- Converts to MIT on December 24, 2029
See LICENSE for full terms.
Dependencies
~155–570KB