lexicor 0.2.0
lexicor: ^0.2.0 copied to clipboard
An optimized, strictly typed, offline interface for the Open English WordNet database. Supports lightweight (no definitions) and full (with definitions) modes.
Lexicor #
Lexicor is a strictly typed, highly optimized, offline interface for the Open English WordNet.
Powered by an embedded SQLite database โ no external APIs, no raw text parsing.
โจ Features #
- ๐ Ultra Fast: Microsecond-level lookups (~20ยตs on disk).
WITHOUT ROWIDtables, covering indexes, and LRU result caching. - ๐ Strictly Typed:
Concept,SpeechPart,RelationType,DomainCategoryโ no magic strings or integers anywhere. - ๐ง Morphology Aware: Automatic stem resolution. "ran" โ "run", "better" โ "good".
- ๐ Optional Definitions: Pass
withDefinitions: trueto get WordNet glosses on every concept โ or keep the default lightweight build when you don't need them. - ๐ Rich Relations: Semantic (Concept-to-Concept) and Lexical (Word-to-Word) relations, filterable by type in SQL.
- ๐ฒ Recursive Traversal: Walk hypernym/hyponym chains to arbitrary depth via a single SQLite recursive CTE.
- โก Dual Storage Modes: Disk mode (instant startup) or Memory mode (fastest queries).
๐ฆ Installation #
dependencies:
lexicor: ^0.2.0
๐ Quick Start #
import 'package:lexicor/lexicor.dart';
void main() async {
final lexicor = await Lexicor.init(); // lightweight, no definitions
// final lexicor = await Lexicor.init(withDefinitions: true); // full mode
final result = lexicor.lookup('bank');
print('Found ${result.concepts.length} concepts for "${result.query}"');
for (final concept in result.concepts) {
print('[${concept.part.label}] ${concept.category.label}');
if (concept.definition != null) print(' ${concept.definition}');
final hypernyms = lexicor.related(concept, type: RelationType.hypernym);
for (final rel in hypernyms.items) {
print(' -> is a type of: ${rel.word}');
}
}
lexicor.close();
}
๐ Usage Guide #
Initialization #
// Light mode โ no definitions (~28 MB asset, default)
final lexicor = await Lexicor.init();
// Full mode โ definitions + usage examples (~40 MB asset)
final lexicor = await Lexicor.init(withDefinitions: true);
// Memory mode โ copy DB into RAM for fastest repeated queries
final lexicor = await Lexicor.init(
mode: StorageMode.inMemory,
withDefinitions: true,
);
| Flag | Asset | Concept.definition |
examples() |
Best for |
|---|---|---|---|---|
withDefinitions: false (default) |
dictionary.sqlite ~28 MB |
null |
[] |
Mobile, CLI, embedding |
withDefinitions: true |
dictionary_full.sqlite ~40 MB |
populated | sentences | Dictionaries, NLP |
Definitions #
final lexicor = await Lexicor.init(withDefinitions: true);
final result = lexicor.lookup('bank');
for (final concept in result.concepts) {
print(concept.definition);
// "a financial institution that accepts deposits..."
// "a long ridge or pile..."
}
concept.definition is always null in light mode โ safe to use without
checking the mode:
final def = concept.definition ?? '(no definition)';
Usage Examples #
final lexicor = await Lexicor.init(withDefinitions: true);
final concept = lexicor.lookup('run').primary!;
for (final example in lexicor.examples(concept)) {
print(example); // "she ran to catch the bus"
}
Returns an empty list in light mode.
Synonyms #
final concept = lexicor.lookup('car').primary!;
final syns = lexicor.synonyms(concept);
// ['car', 'auto', 'automobile', 'motorcar']
These are strict synonyms โ words that share the exact same synset. For broader
similarity, use related(concept, type: RelationType.similar).
Recursive Traversal #
Walk a relation chain to arbitrary depth in a single DB call:
final dog = lexicor.lookup('dog').primary!;
final chain = lexicor.traverse(dog, RelationType.hypernym, maxDepth: 5);
for (final word in chain) {
print('${' ' * word.depth}${word.word}');
}
// canine
// carnivore
// placental
// mammal
// ...
traverse uses a SQLite recursive CTE โ the entire hierarchy walk is done in
one round-trip. Only works for relations where RelationType.isRecursive is
true (hypernym, hyponym, partMeronym, etc.).
Relationships #
final rels = lexicor.related(concept);
// SQL-level type filter โ no wasted data transfer
final hypernyms = lexicor.related(concept, type: RelationType.hypernym);
// Or filter the result object
final semantic = rels.semantic; // Concept-to-Concept links
final lexical = rels.lexical; // Word-to-Word links
final antonyms = rels.byType(RelationType.antonym);
Batch Lookup #
final results = lexicor.lookupBatch(['run', 'walk', 'swim', 'run']);
// 'run' is only queried once; the second entry is served from cache.
results['run']?.concepts.length;
Morphology #
// Automatic during lookup:
lexicor.lookup('running').resolvedForms; // ['running', 'run']
// Direct lemmatization:
lexicor.lemmatize('ran', SpeechPart.verb); // 'run'
lexicor.lemmatize('better', SpeechPart.adjective); // 'good'
Flutter Integration #
import 'package:path_provider/path_provider.dart';
import 'package:flutter/services.dart';
import 'package:lexicor/lexicor.dart';
Future<Lexicor> initLexicor({bool withDefinitions = false}) async {
final assetName = withDefinitions ? 'dictionary_full.sqlite' : 'dictionary.sqlite';
final dir = await getApplicationDocumentsDirectory();
final file = File('${dir.path}/$assetName');
if (!file.existsSync()) {
final data = await rootBundle.load('packages/lexicor/assets/$assetName');
await file.writeAsBytes(data.buffer.asUint8List());
}
return Lexicor.init(customPath: file.path, withDefinitions: withDefinitions);
}
๐ Building the Database #
Place your oewn.sqlite (~165 MB source file) at tool/db/oewn.sqlite, then:
# Light build only (~28 MB)
dart run tool/build_database.dart tool/db/oewn.sqlite
# Full build only (~40 MB)
dart run tool/build_database.dart tool/db/oewn.sqlite --full
# Both at once
dart run tool/build_database.dart tool/db/oewn.sqlite --all
# Or via melos
melos run build
melos run build:full
melos run build:all
๐ Database Stats #
| Component | Light | Full | Description |
|---|---|---|---|
| Words | 3.0 MB | 3.0 MB | ~150k unique lemmas |
| Concepts | 1.36 MB | 1.36 MB | ~120k Synsets |
| Senses | 3.4 MB | 3.4 MB | ~210k Word-Concept pairs |
| Semantic Relations | 3.7 MB | 3.7 MB | Hypernyms, Holonyms, Entailments |
| Lexical Relations | 4.0 MB | 4.0 MB | Antonyms, Derivations |
| Indexes | ~11 MB | ~11 MB | COLLATE NOCASE indexes |
| Definitions | โ | ~10 MB | Synset glosses (~120k rows) |
| Examples | โ | ~2 MB | Usage sentences from samples table |
| Total | ~28 MB | ~40 MB |
๐ License #
- Package License: MIT
- Database: Open English WordNet 2025 (v2.3.2), licensed CC BY 4.0.
Commercial use requires attribution to the Open English WordNet project in your app's About / Licenses section.