Verb Architecture

This document describes how verbs, tenses, moods, conjugations, and participles are represented in the application. It defines both the linguistic concepts being modeled and the technical implementation used in the database and Rails models.

Key features:

  • Cleanly separates lemma, infinitive, participles, and finite forms
  • Supports compound tenses and gendered participles
  • Links conjugations and infinitives to example sentences
  • Provides single-table lookup for efficient queries
  • Ready to load large datasets (Verbix, Wiktionary, custom corpora)

1. Linguistic Model

1.1 Core linguistic concepts

Concept Description Example (French aller)
Lemma (base verb) The canonical dictionary form of a verb. aller
Infinitive The unconjugated form that names the action. Some languages have multiple infinitive variants (e.g. German Infinitiv I/II). aller, sein, gegangen sein
Participle / Verbal A non-finite verb form used to build compound tenses or adjectives. Participles can vary by gender/number (French, Italian). allé, allée, allés, allées
Mood Expresses the speaker’s attitude (statement, doubt, command…). Indicatif, Subjonctif, Impératif
Tense Places the action in time within a mood. Présent, Passé composé, Imparfait
Person / Number Distinguishes the subject performing the action (1st, 2nd, 3rd; singular/plural). je vais, nous allons
Conjugation A fully inflected finite form (person × mood × tense). vais, allions, j’allais
Compound Tense A multi-word construction: auxiliary (avoir/être) + participle. je suis allé(e)
Surface form The final written version including elisions and contractions. j’ai, j’allais, l’ai vu
Negative form Morphologically negated variant (Turkish, sometimes Romance). Turkish gelmedim = “I didn’t come”

1.2 Supported languages and variations

Language Notes
French Uses être/avoir auxiliaries; participles agree in gender/number. Elisions (j’ai) handled via full_form.
German Has Infinitiv I/II and Partizip I/II; modeled with variant and type_key.
Turkish Negative forms stored via negative flag. No participle gender/number agreement.
English & Romance (ES, IT, PT, RO) Straightforward conjugation grids; optional clitic attachment handled in surface text.
(Future extension) Model supports Slavic aspect, Arabic gendered conjugations, Asian non-finite constructions through later features columns.

2. Data Model Overview

The verb system is decomposed into five primary entities plus two link tables for sentence matching.

2.1 Entities and relationships

verb_lemmas
 ├── has_many infinitives
 ├── has_many verbals
 └── has_many conjugations ── belongs_to tenses
sentences
 ├── has_many sentence_conjugations ── belongs_to conjugations
 └── has_many sentence_infinitives ─── belongs_to infinitives

3. Technical Implementation

3.1 verb_lemmas

Stores one lemma per language.

Column Type Description
language CHAR(2) ISO language code (fr, de, tr, …)
lemma string Dictionary form
common boolean Whether frequently used
regular_overall boolean Global regularity (optional)
english_translation string Optional gloss

Indexes: (language, lemma) unique Associations: has_many :infinitives, :verbals, :conjugations


3.2 tenses

Defines each language’s moods and tenses.

Column Type Example
language CHAR(2) fr
mood string Indicatif
tense_name string Passé composé
common_tense boolean Commonly used tense

Unique (language, mood, tense_name) ensures canonical labels.


3.3 infinitives

Per-lemma infinitive forms, allowing multiple variants.

Column Description
form Text of the infinitive (e.g. aller)
search_form Stripped form for matching
variant default, perfect, etc.
sentences_matched Boolean; has been matched to sentences
language, lemma Cached from parent

3.4 verbals

All participles and gerunds.

Column Description
type_key e.g. present_participle, past_participle, partizip_ii
form Surface form (e.g. allé)
gender, number For agreement forms (m/f, sg/pl)
language, lemma Cached

Examples for aller: allé (m.sg), allée (f.sg), allés (m.pl), allées (f.pl)


3.5 conjugations

Each finite verb form (1–6 persons).

Column Description
verb_lemma_id, tense_id Foreign keys
person_seq 1–6 (language-agnostic order)
person_label je, tu, il, nous, …
form Bare conjugated form (ai)
full_form Final surface string (j'ai)
search_form Stripped form for matching (j ai)
regular Boolean; per-form irregularity
negative Boolean (for Turkish, optional)
sentences_matched Boolean; has been matched to sentences
language, lemma, mood, tense_name Cached for fast queries

Indexes:

  • (verb_lemma_id, tense_id, person_seq) unique
  • (language, lemma) for lemma lookups
  • (language, sentences_matched) for batch processing
  • (search_form) for matching

3.6 Sentence linking tables

Table Purpose
sentence_conjugations Links sentences to specific conjugations
sentence_infinitives Links sentences to infinitives

sentence_conjugations caches: language, lemma, mood, tense_name, person_seq, person_label, conj_form

sentence_infinitives caches: language, lemma

These enable fast queries without joins. See sentence_matching.md for details on the matching system.


4. Model Layer (Rails)

4.1 Core verb models

class VerbLemma < ApplicationRecord
  has_many :infinitives, :verbals, :conjugations
  validates :language, presence: true, length: {is: 2}
  validates :lemma, presence: true
end

class Tense < ApplicationRecord
  has_many :conjugations
  validates :language, presence: true, length: {is: 2}
  validates :mood, :tense_name, presence: true
end

class Infinitive < ApplicationRecord
  belongs_to :verb_lemma
  has_many :sentence_infinitives
  has_many :sentences, through: :sentence_infinitives
  before_validation :cache_parent_fields
  before_save :set_search_form  # Strips special chars for matching
end

class Verbal < ApplicationRecord
  belongs_to :verb_lemma
  validates :type_key, :form, presence: true
  validates :gender, inclusion: {in: %w[m f n], allow_nil: true}
  validates :number, inclusion: {in: %w[sg pl], allow_nil: true}
  before_validation :cache_parent_fields
end

class Conjugation < ApplicationRecord
  belongs_to :verb_lemma
  belongs_to :tense
  has_many :sentence_conjugations
  has_many :sentences, through: :sentence_conjugations
  validates :person_seq, inclusion: {in: 1..6}
  validates :full_form, presence: true
  before_validation :cache_parent_fields
  before_save :set_search_form  # Strips special chars for matching
end

4.2 Sentence linking

class Sentence < ApplicationRecord
  has_many :sentence_conjugations
  has_many :sentence_infinitives
  has_many :conjugations, through: :sentence_conjugations
  has_many :infinitives, through: :sentence_infinitives
end

class SentenceConjugation < ApplicationRecord
  belongs_to :sentence
  belongs_to :conjugation
  before_validation :cache_fields  # Caches denormalized lookup fields
end

class SentenceInfinitive < ApplicationRecord
  belongs_to :sentence
  belongs_to :infinitive
  before_validation :cache_fields  # Caches denormalized lookup fields
end

5. Example: French aller

Mood Tense Person form full_form
Indicatif Présent je vais je vais
Indicatif Imparfait je allais j’allais
Indicatif Passé composé je suis je suis allé(e) (via participle)
Subjonctif Présent je aille j’aille

Participles (verbals):

type_key gender number form
past_participle m sg allé
past_participle f sg allée
past_participle m pl allés
past_participle f pl allées

6. Query patterns

# All conjugations for a verb
Conjugation.for_lemma('fr', 'aller').order(:mood, :tense_name, :person_seq)

# All participles for a verb
Verbal.where(language: 'fr', lemma: 'aller', type_key: 'past_participle')

# Find sentences using a verb in a specific tense
SentenceConjugation.where(language: 'fr', lemma: 'aller', mood: 'Indicatif', tense_name: 'Présent')

# Find all conjugations in a sentence
sentence.conjugations  # via has_many :through

# Find all sentences containing a conjugation
conjugation.sentences  # via has_many :through

7. Performance

Cached fields (language, lemma, mood, tense_name) on conjugations enable single-table queries without joins. The search_form field pre-strips special characters for efficient text matching.


8. Future Extensions

Feature Where to add
Aspect pairs (Slavic) verb_lemmas.aspect_class, partner_verb_id
Politeness / formality conjugations.features JSONB
Gendered conjugations (Arabic/Hindi) conjugations.features or additional slot table
Non-inflecting languages allow person_seq = NULL
Audio & phonetic data separate pronunciations table

9. Sentence Matching

The system automatically links verb conjugations and infinitives to example sentences using PostgreSQL full-text search. The matching system:

  • Uses GIN indexes for fast, language-specific matching
  • Processes conjugations and infinitives to find containing sentences
  • Tracks processing status with sentences_matched flags
  • Supports batch processing via rake tasks and async background jobs
  • Only processes sentences ≤80 characters for performance

See sentence_matching.md for complete documentation of the matching system, including:

  • Detailed matching algorithm
  • Background jobs and rake tasks
  • Query patterns and performance characteristics

10. Summary

This architecture cleanly separates lemmas, infinitives, participles, and finite forms while supporting compound tenses, gendered participles, and efficient sentence linking. Denormalized fields enable fast queries without joins, and the system is ready to load large datasets from Verbix, Wiktionary, or custom corpora.


This site uses Just the Docs, a documentation theme for Jekyll.