Skip to main content

ablaut

A fast, correct German verb conjugator.

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.2-cp311-abi3-win_amd64.whl (174.7 kB view details)

Uploaded CPython 3.11+Windows x86-64

ablaut-0.1.2-cp311-abi3-manylinux_2_34_x86_64.whl (311.4 kB view details)

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

ablaut-0.1.2-cp311-abi3-macosx_11_0_arm64.whl (275.8 kB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: ablaut-0.1.2-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 174.7 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.2-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 799071f8e57290e3d9d5ce704b95865cb0ed69c1e9f9966bbfa8f6ef475084a8
MD5 6f80687fced1479ce8e29805e94d15b6
BLAKE2b-256 62516ca66d24f0a2c891793f1b2277256a475ce60e374dae0b7f36715ecc70a5

See more details on using hashes here.

Provenance

The following attestation bundles were made for ablaut-0.1.2-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.2-cp311-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for ablaut-0.1.2-cp311-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 5ef64f740f06a12363a054ae1115ab15a181024a59312c7537be3ffe34ddc038
MD5 c805a9a4bbc4a32a2acd20e476ec8a54
BLAKE2b-256 1c68ac25c05f2b72b6113e5887a7b82aa1d6601f79909ab0cc4f2257e25ac6e7

See more details on using hashes here.

Provenance

The following attestation bundles were made for ablaut-0.1.2-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.2-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ablaut-0.1.2-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 10a7268bd060f5e4f7d5412f464c286f54a8ad9ae235fec9048ad032425515fb
MD5 3761c9d854763444272766b217da3326
BLAKE2b-256 a36656c74176b16d303c5dc4c3c8935dac93a1a586682d8a13eb54958461d224

See more details on using hashes here.

Provenance

The following attestation bundles were made for ablaut-0.1.2-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