Skip to main content

ablaut logo

ablaut

A fast, correct German verb conjugator.


crates.io PyPI npm CI license

Try it in the browser


The name is the German term for the vowel gradation in singen, sang, gesungen: Jacob Grimm formalized its seven classes in 1819, and they still describe every strong verb in the language.

Highlights

  • Measured correctness. Every generated form is validated against two machine-readable gold standards: 99.2% agreement with UniMorph deu (194k forms) and 98.0% with the Wiktextract extraction (794k forms, including analytic tenses and the perfect auxiliary). Where the two sources agree with each other, ablaut has zero known errors; every remaining disagreement is ruled on in a published adjudication log with references to standard grammars.
  • Generalizes to unseen verbs. A rule engine with a curated exception lexicon, not a lookup table: novel verbs (googeln, downloaden) conjugate correctly. On verbs outside its lexicon, agreement with UniMorph is 99.55%.
  • Fast and small. No I/O, no runtime data files, no dependencies in the core crate. A complete conjugation table (100+ forms) takes microseconds; the entire engine compiles to a 106 KB WebAssembly binary (about 45 KB gzipped).
  • Permissively licensed. MIT OR Apache-2.0, including the lexicon: no ShareAlike obligations.

Usage

Rust

cargo add ablaut
use ablaut::{AnalyticTense, Mood, Number, Person, Tense, Verb};

let v = Verb::from_infinitive("aufstehen")?;

v.conjugate(Tense::Present, Mood::Indicative, Person::First, Number::Singular);
// "stehe auf"
v.conjugate(Tense::Preterite, Mood::Indicative, Person::Third, Number::Singular);
// "stand auf"
v.analytic(AnalyticTense::Perfect, Mood::Indicative, Person::First, Number::Singular);
// "bin aufgestanden"
v.past_participle();          // "aufgestanden"
v.zu_infinitive();            // "aufzustehen"
v.imperative(Number::Singular); // Some("steh auf"); None for modals

The full paradigm as one struct: ablaut::table::Table::build(&v).

Python

pip install ablaut
import ablaut

c = ablaut.conjugate("aufstehen")
c.present[0]        # "stehe auf"
c.perfect[0]        # "bin aufgestanden"
c.auxiliary         # "sein"
c.zu_infinitive     # "aufzustehen"
c.imperative        # [None, None] for modals

Wheels are abi3 (Python 3.11+); no Rust toolchain needed.

WebAssembly

wasm-pack build --target web -- --features wasm
import init, { conjugate } from "./pkg/ablaut.js";
await init();
const c = conjugate("aufstehen");
c.present[0];       // "stehe auf"
c.zuInfinitive;     // "aufzustehen"

Coverage

All synthetic and analytic forms of standard German:

  • Tenses and moods: Präsens, Präteritum, Perfekt, Plusquamperfekt, Futur I/II, Konjunktiv I and II in all tenses (the würde-form is Futur I Konjunktiv II), processual and statal passive
  • Non-finite and imperative: both participles, zu-infinitive, perfect infinitive, imperatives including the adhortative (stehen wir auf!) and polite (stehen Sie auf!) forms
  • All five inflection classes: weak (the productive default), strong (ablaut, with 2/3sg stem alternation: sprichst, hältst), mixed (dachte), preterite-present (the modals and wissen: ich kann, no imperative), and suppletive (sein, werden, tun)
  • The prefix system: separable (stehe auf, aufgestanden, aufzustehen), inseparable (verstanden), fused compounds that never split (lobsingen: lobsang, lobgesungen), multiword lemmas (Rad fahren: fahre Rad, Rad gefahren), and per-lexeme rulings for dual-behavior prefixes (umarmen vs untertauchen)
  • Orthographic surface rules: e-epenthesis (arbeitest, bewillkommnest), s-coalescence (du lässt), schwa elision (ich sammle), the Latinate -ieren participle (studiert but geschmiert), and per-lexeme perfect auxiliaries (aufstehen: sein)

The exception lexicon (data/verbs.tsv, about 900 human-readable rulings) is compiled into the binary.

How correctness is verified

src/bin/golden.rs diffs every generated form against the gold data (scripts/fetch_unimorph.sh, scripts/fetch_kaikki.sh) and CI fails if accuracy regresses below pinned thresholds. scripts/cross_oracle.py cross-examines the two oracles against each other: they agree on 98.9% of their 195k shared slots, and triaging ablaut's mismatches against that agreement separates genuine bugs from gold-data errors.

The method has found real errors in the gold data itself, documented in docs/adjudications.tsv: UniMorph gives the Konjunktiv II of nennen as nannte (correct: nennte) and marks wisse! as nonexistent; Wiktionary assigns wachen the auxiliary sein and conjugates entgelten weak. One caveat: both oracles derive from Wiktionary, so their agreement is strong but not fully independent evidence.

Design

The architecture is a productive default rule plus a finite table of stored exceptions, which is precisely the dual-mechanism model of inflection (Marcus, Pinker et al., 1995) for which German morphology is the canonical test case. Features follow the UniMorph schema. docs/design.md maps the whole domain in four layers and doubles as the design spec.

License

MIT OR Apache-2.0.

Data provenance: the exception lexicon is independently curated factual data about standard German (principal parts, prefix behavior, auxiliaries), hand-verified row by row. UniMorph (CC BY-SA 3.0) and Wiktextract (CC BY-SA) are used as test oracles only: fetched at development time, never shipped.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ablaut-0.1.3-cp311-abi3-win_amd64.whl (175.0 kB view details)

Uploaded CPython 3.11+Windows x86-64

ablaut-0.1.3-cp311-abi3-manylinux_2_34_x86_64.whl (311.7 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.34+ x86-64

ablaut-0.1.3-cp311-abi3-macosx_11_0_arm64.whl (276.1 kB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

File details

Details for the file ablaut-0.1.3-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: ablaut-0.1.3-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 175.0 kB
  • Tags: CPython 3.11+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ablaut-0.1.3-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 744b218c386a290dc50a8351532d9cdc4c869e9a67de33e0b20038467a3a0035
MD5 29bb66517655233b52d6952426047a7b
BLAKE2b-256 3838b13f31fd70daa016de7cc99badb7fc9912a772f0bda61454a21fa68baf14

See more details on using hashes here.

Provenance

The following attestation bundles were made for ablaut-0.1.3-cp311-abi3-win_amd64.whl:

Publisher: wheels.yml on v4nn4/ablaut

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ablaut-0.1.3-cp311-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for ablaut-0.1.3-cp311-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 ea4807917bbc412ca22d104f9eb887a0e0a1694b4fe606ae53df6e0aed167f2f
MD5 39807682af90f359e9f8e72982b52ebb
BLAKE2b-256 6786ef7dcf6e4c6209644c2704838e0c4deadbb6122e55407ef0a23b54e8fcef

See more details on using hashes here.

Provenance

The following attestation bundles were made for ablaut-0.1.3-cp311-abi3-manylinux_2_34_x86_64.whl:

Publisher: wheels.yml on v4nn4/ablaut

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ablaut-0.1.3-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ablaut-0.1.3-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ba077a253b02cdef4fc41ca7a81247736f02a8be6bf868aba21b53f75f2a4fcd
MD5 ec30064ddc0c175bc71a236dacfa1046
BLAKE2b-256 cd2e9acc2e52df5b837148168a2baf7e58f5fa0e04d06d0521b8bfa6ce8ab4ec

See more details on using hashes here.

Provenance

The following attestation bundles were made for ablaut-0.1.3-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: wheels.yml on v4nn4/ablaut

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page