Mova0.6 pre-release⌕
☰
home / docs / repo-docs / Pragmatics: frames — who did what to whom, why, and what came next

Pragmatics: frames — who did what to whom, why, and what came next

This page describes how Mova reads the meaning of a text above the syntax tree. It covers frames (one per event or fact, with roles and links), how to call the reader, the frame bench that measures it, the VerbNet and WordNet rules it uses, the invariants it keeps, and the rules it learns. It also covers the algorithms from the literature that are built in, expressions read by their real meaning, event statistics of books, and the external pragmatics tools kept for tests. There is no bag of words anywhere: a reader matches the roles of frames, never the raw words of whole lines.

At a glance

$ world frames "The fox flattered the crow because she wanted the cheese. The crow opened her beak and the cheese fell."
#0 Event fox flatter patient=crow | cause→#1 next→#2
     roles by vn lure-59.3 «NP V NP»: agent=Agent crow=Patient
#1 Event fox(«she») want patient=cheese
     roles by vn want-32.1-1-1 «NP V NP ADV»: agent=Pivot cheese=Theme
#2 Event crow open patient=beak | next→#3
     roles by vn crane-40.3.2 «NP V NP»: agent=Agent beak=Patient
#3 Event cheese fall
     roles by vn escape-51.1-1 «NP V»: agent=Theme

Each frame knows who did what (agent, patient, recipient, place); keeps links («because» gives a cause, «and» and sentence order give what happened next); resolves pronouns in reading order («she» is the fox); and says where its roles came from (here a VerbNet class and frame). The structure belongs to the skeleton (prag::frames), not to any single reader.

Calling it

// world (parser = the en annotator on cased text + the absurdity-matrix repairs):
let mut ctx = world::frames::Ctx::default();          // one discourse per text (a lesson, a story)
let r = world::frames::read(text, &mut ctx, false)?;   // r.frames, r.asked, r.aliases, r.roots
// any crate with its own parser:
let r = prag::frames::read_with(text, &mut ctx, question, &|sentence| words_of(sentence));

world frames "<text>" prints the frames (FRAMES_TREE=1 adds the trees). Every step of the reader can be switched off for measuring with PRAG_OFF=name,name; the switch names are given below next to each step.

prag depends on en only, so the types and the tree → frames reader live there. The parser world uses adds the absurdity-matrix repairs (world::rerank, world::induce, see Worlds and knowledge), which belong to world; world passes its parser in. Moving the repairs into prag would make prag depend on world — a cycle.

A frame

One predicate of the tree (a verb, or a word with a copula):

fieldmeaning
kindEvent (an action), Fact(Link) (a general statement: is a, is, has, can, does, lives in, made of, used for), Say(Act) (speech or thought, with its speech act from prag::schema::Act), Bare (a phrase without a predicate, e.g. an answer option «A frying-pan»)
agent, patient, recipient, placeentities (Ent)
verbthe lemma with its particle (put down); be for a copula
neg, condnegated; inside an «if» clause
irrealisnot said to have happened: the «to» complement of a wish, plan or attempt («wanted to eat»), and an «if» clause. The implication signatures (prag/data/signatures.tsv, after Karttunen and Nairn et al.) set it top-down with negation: «managed to eat» ate, «failed to eat» did not, «did not fail to eat» ate. PRAG_OFF=factuality, cond-irrealis
tamtense, aspect, voice and modality of the verb group (tam_of): tense, form (Fin, Inf, ToInf, Ger, Part), modal, perfect, progressive, passive, do-support, imperative. PRAG_OFF=tam. The student does not use it yet; the round trip's realizer says the verb group from it
attrsa copula's adjective, «get tiny», manner adverbs, when:day for times
oblsother prepositional roles (with=queen)
quotethe frames a Say frame carries (what was said or thought)
cause, nextlinks to other frames (indices in the same Read)
linkwhere the clause hangs: the frame above, the clause's relation (conj, advcl, xcomp, ccomp, parataxis, acl:relcl …) and its noun when that is not the predicate above. PRAG_OFF=frame-link
unsaidroles filled from elsewhere: an agent shared with the clause above, an imperative's «you», the noun of a relative or infinitive clause. PRAG_OFF=unsaid
mannerthe attrs that are manner adverbs in the text. PRAG_OFF=frame-manner
wordsthe clause's other one-word dependents with relation and tag (then, also, again, discourse words, an expletive «there»), and the words under them flattened onto the clause. PRAG_OFF=frame-words, frame-rest
npsnoun phrases on the clause in no role: time and measure without a preposition («last week»), vocatives, dislocated phrases, a second object, a free wh-word. PRAG_OFF=frame-nps, frame-rest, wh-free
mark, ccthe clause's markers («that», «if», «to») and its conjunction («but», «or»). PRAG_OFF=frame-mark

A sentence whose root is no predicate (a heading, a title, a list item, «Yes.») gets one Bare frame, after the predicates' frames and before the nouns' events: the root's entity as the patient (or with its preposition the place or an oblique); a root that is no entity is its first words entry with relation root. PRAG_OFF=frame-fragment.

An entity (Ent) keeps its head lemma, number, name bit, adjectives and coordinated heads, and what this mention says: poss («his nose»), mods («a cup of tea»), appos, words, conj, det, case, cc, rel_word («who»). With ent-rest it keeps every other dependent too. The discourse (Ctx) keeps only the entity. PRAG_OFF=ent-poss, ent-mods, ent-conj, ent-det, ent-case, rel-word, ent-rest.

The fields from link down and the entity's fields from poss on keep what the tree says beside the roles, so that the frames can be said back (the round trip, tools/roundtrip, see The English layer). The student, show and the frame bench do not read them.

Anchors (Ctx::anchors, one per frame of the last sentence): the predicate's token, the token of the frame it hangs on with the relation, and the head token of each role said in the clause. Nothing in the reader reads them; tools/translate reads its meta-world's tree through them. PRAG_OFF=anchors.

Entities are head lemmas (the Cheshire Cat = the Cat = cat; Ent::same). Pronouns are resolved by Ctx in word order (a pronoun sees only what came before it): agreement in number; he/she → a person or an animate being of the right gender, never a thing already called «it»; it → never a person; numbers and times are never antecedents; salience by the best role of each sentence (subject > object > other), halved per sentence, with a bonus for the pronoun's own role; a plain object pronoun is never its own clause's subject; a dummy «it» (it depends, it is unkind to …) stays unresolved. With PRAG_VN=gender-table a common noun the closed lists say nothing of takes animacy and he/she gender from the coreference noun lexicon counted from Mova's own parses (coref), and «it» never takes a noun the lexicon calls animate; it is opt-in because the school did not gain (2026-11-04). Inside quotes «I» is the speaker of the Say frame and «you» its addressee. PRAG_COREF picks the resolver: 3 this one (default); 1/2/4 the coref crate's sieve alone or first; 0 salience alone.

Links: «because / since / as», a purpose «to …» and «by V-ing» → cause; «so / therefore» → the clause before is the cause; «so … that» → the result's cause; «and / then / after / before / when / until» and consecutive sentences → next, kept only between actions and speech (never from or to a state, a general fact or a condition); a ccomp of say/think/know/fear and quoted speech → quote of the Say frame. Only a verb of saying or knowing carries a quote.

Roles, more: an imperative's agent is you; object control (make X grow, tell X to go) gives the infinitive the object as agent; gerund subjects are the activity; phrasal verbs come from the expression base (adverb particles anywhere, prepositions only standing alone); the speaker after a quote («"…" cries the Badger»); the person told or asked is the recipient; the act by the quote's ?/!; no place for persons, animals, times and measures.

Questions (question = true): the first wh-word gives Asked { frame, what } with Ask::Cause (why), Ask::Next (what happened next), Ask::Role(slot) (who → agent, what → patient, what … do → verb, where → place, how → attr, which N → N's role), Ask::Frame (yes/no, when). Do-support and modal questions are put in statement order before parsing («What did the cook throw?» → «the cook threw what?»), because the tagger misreads them. «what happens when X» → Ask::Next on X.

Deterministic: word order and ordered maps; the same text and ctx give the same frames.

The linguists' rules: VerbNet and WordNet

The roles come first from open lexicons written by linguists (prag::vn); the tree heuristics above are the fallback. Only permissive data builds the reader: VerbNet 3.4 (VerbNet 3.0 License, © University of Colorado), Princeton WordNet 3.1 (WordNet 3.0 License, © Princeton University) — both free including commercial use with the notice — and our own lessons. PropBank (CC BY-SA) and NomBank / NOMLEX (research-only) are tests and measurement only: converted outside the repo, never compiled in, never read by the reader or the rule learner.

Compiled tables (deterministic converters in prag::vnconv; each header records the source version and a checksum):

tablebuilt bycontent
prag/data/verbnet.tsvprag lexicon convert <verbnet3.4> <propbank frames> <nombank.1.0> <out> [<test dir>]classes with subclasses, members, frames (a syntactic pattern → roles, selectional restrictions, semantic predicates). The same command writes PropBank's and NomBank's tables to the test dir (prag-lexicon)
prag/data/nominals.tsvprag lexicon nominals <wordnet 3.1 dict> <out>nouns that name a verb's event: a noun whose first sense lies in an event file (act, event, process, state, communication, cognition, feeling, phenomenon, possession) → the verb of the first such sense with a derivational link («arrival» → arrive, «destruction» → destroy), unless the verb is made from the noun («memory» → memorize); transitivity from WordNet's verb frames
prag/data/vnfreq.tsvworld frames vnfreqfor verbs with several classes, how often each class alone matched best in our courses' clauses

The frame bench

world frames bench [dev|held] [baseline] [worst N] [errors <role>] [prons] [agents] is the yardstick of the reader. Its lines come from the lessons of six courses (books, world, biology, everyday, history, reflection), split into dev and held-out; their frames were written once by the teacher (world frames bench-make) and live in prag-bench (lines.tsv, gold.tsv, notes.tsv, calls.jsonl). The scorer (prag::fbench) parses the gold and the reader's own show with one parser, aligns frames (verb head or two roles) and gives P/R/F1 per role — agent, verb, patient, recipient, place, speaker (Say + act + speaker), says, cause, next, coref (pronouns in roles) — and a micro overall. The negative control is baseline (first noun agent, first verb, next noun patient). Decisions are made on dev; the held-out lines are run rarely and never read by any learner.

Invariants over the corpus

prag::invariants lists rows the reader should never give. Each check has a unit test with a negative control (a correct frame is not flagged). A corpus-wide run writes one TSV per check (sentence id, text, row, detail) and counts.tsv for review; that run is not part of this repository.

checkflags
copula-no-whoa copula frame with no subject
time-in-wherea word of time as the place (frames::time_word)
vn-spreadone verb in one syntactic frame given more than one VerbNet class
unsaid-owna role marked «not said here» while the clause has its own dependent for it
who-is-whatthe agent and the patient are the same entity (reflexives and bare pronouns aside)

Reader steps that keep these rows out, each switchable with PRAG_OFF:

A place VerbNet calls a Goal outside the classes of putting, sending and motion, or a Result, is marked by Frame::goal («sorted the garbage into paper»); the site shows it under «other». The reader keeps it in place, because the student's weights lean on place matches (PRAG_VN=goal-obl makes it an oblique).

Rules the reader learns itself

prag::rules (world frames rules learn | control | cv | show | apply-check) learns transformations applied after the reader, error-driven from the gold (after Brill 1995, as world induce learns tree repairs; see Training Mova). The sources are the bench's dev lines and the teacher's verdicts (log.tsv: OK, WRONG with the correction, MISSING). Every rule is a sentence: «For a frame: if the predicate word is tagged VBN, it has no object in the tree and comes after the word above it, then it has no agent.»

Most learned rules are deletions, and deleting next links and Say frames hurts the student's «what next» answers, so the checker accepts few. One rule is accepted: a motion verb with no object in the tree has no patient.

Clients

Algorithms from the literature

These algorithms are built into prag and world as deterministic, explained Rust: integer or exact-fraction arithmetic, fixed order, and a trace that says why. Card links point to the paper cards in ../papers/.

algorithmsourcewhere in codestatus
Implication signatures (managed / failed to)Karttunen; Nairn et al. 2006prag/data/signatures.tsv, frame irrealisbuilt in
Social obligations (greeting, thanks, apology, goodbye, politeness question)Bunt et al. 2017, 2020 (ISO 24617-2)world/src/talk.rsbuilt in; the full dimension × function scheme is not
Politeness strategies: 20 detectors with integer weightsDanescu-Niculescu-Mizil et al. 2013 (strategy list as facts; data CC BY-NC-SA); Brown & Levinson 1987world/src/talk.rsbuilt in: a blunt request is done, and the fired strategies are noted
Indirect requests: «Can you X?» is a request only when the speaker wants it and the hearer is capable, willing and obligatedSarathy et al. 2020, Roque et al. 2020, after Brown 1980world/src/talk.rsbuilt in; otherwise the direct reading (an answer about ability)
Scalar implicature on Horn scales (blocked by a stronger item, negation, cancellation)Tatu & Moldovan 2012; Krause 2024prag/src/infer.rs, prag inferbuilt in
Presupposition triggers (again, still, also, too, stop, continue, know, realize, regret, forget …), licensed by the same predicate in the previous 50 tokens or marked newCianflone et al. 2018prag/src/infer.rsbuilt in
Gricean maxims: Quality (a question → the speaker does not know; an exclamation → strong feeling), Manner (coordinated events are ordered, not with stative verbs)Tatu & Moldovan 2012prag/src/infer.rs maximsbuilt in
Sarcasm by incongruity: polarity lexicon, explicit and implicit incongruity, pragmatic cues; the incongruent pair is the explanationJoshi 2017, Riloff et al. 2013prag/src/irony.rs, prag inferbuilt in; meets the absurdity matrix's humor trigger in world/src/domains.rs
Rational Speech Acts: L0 ∝ [[u]]·P, S1 ∝ L0^α·2^(−αC), L1 ∝ S1·P in exact fractionsMonroe & Potts 2015; Frank & Goodman; Anderson 2021prag/src/rsa.rs, prag rsa scalar|reference|explainbuilt in for small closed sets (scalar and reference games); negative control: an always-true utterance returns the prior
Questions under discussion: a stack; assertions attach to the deepest congruent open question; implicit questions accommodated from given lemmas only; answer leakage rejectedRoberts 2012, Riester et al. 2021, QUDevalworld/src/qud.rs, world qud "<text>"built in
Error-driven transformation rulesBrill 1995prag::rulesbuilt in (above)

Each built-in piece has tests with negative controls. Known parser slips affect them: «The fox ate again» (ate tagged as a noun), «knows that the door is open» (the clause read as xcomp).

Expressions by their real meaning

The pragmatics lens reads idioms, proverbs, phrasal verbs and verb phrases, slang and register-marked words by their real meaning, not literally. Its knowledge is the expression base expressions.tsv, built from the English Wiktionary dump by tools/wikt-idioms: kinded multiword entries (idioms, proverbs, phrases, verb phrases, phrasal verbs), other multiword entries, and single words with register or regional labels, each label with the gloss of the sense it marks. It is CC BY-SA and stays out of the free release.

Example: «Grandpa kicked the bucket, the poor old geezer.» → kicked the bucket = to die (euphemistic, humorous); geezer (informal, derogatory) → domains hidden-meaning, humor, slang.

The lens feeds «what was meant» and the domain switch. As features of the act classifier it gave no clear gain, so it is not used there.

Domain modules. world domains "<text>" [--genre tale] switches domains on with reasons; world domains-eval <set.jsonl> measures them on contrast sets with literal controls. The evidence: register labels on the main sense (regional varieties as variety:<country>), idioms and proverbs of two or more content words, the formal register measured on corpora (global::register_z("legal"): log-odds of public-domain legal and official books against tales, children's and other books, after Monroe et al. 2008; world register-stats; lexicons global/data/register-{legal,tale,children}.tsv), a register clash (formal language about everyday things → mock-formal humor), and absurdity that survives the genre's domain layer (a talking fox is humor in the real world, literal in a tale; see Worlds and knowledge).

Limits: humor is the weakest domain — jokes rest on world knowledge and context, and word statistics catch only mock-formal clashes and absurdity. Modern slang («lowkey», «no cap») is mostly a secondary Wiktionary sense of common words; it needs time-sliced corpus statistics, not the dictionary.

Event statistics of books

world events <out-dir> <book.txt>... [--threads N] (world/src/events.rs) parses every sentence of a book and counts events: agent, verb, patient, recipient (nouns only; pronouns are skipped). «The fox said to the crow» → fox say →crow; «the cheese fell» → cheese fall. The matrix's repairs are applied to the trees.

Outputs hold counts and ids only — no text, no trees:

filecontent
books/<book>.jsona summary: main actors, interactions (crow ~ fox), top events
books/<book>.events.tsvthe search index: sentence id <book>:<n> → event (ids stable within one version of the sentence split, events::SPLIT)
events.tsvcorpus-wide events with counts and number of books
cells.tsvobserved verb × noun × role (SUBJ/OBJ/TO) counts: the empirical side of the absurdity matrix

Uses: what the corpus is about, a search index («where does a fox speak to a crow»), candidate cells for the matrix, and systematic errors (world absurd-events, see Worlds and knowledge); world events-show <book.txt> <n>... prints the sentences behind ids. For public-domain books the summaries and the index are public; for restricted books they stay internal, and answers are short summaries in our own words, never quotes. The two kinds are always run into separate output folders and never merged.

External pragmatics tools

Open pragmatics software and models serve as task definitions, test sets and comparison points. None of them is wired into Mova, whose pragmatics stays rule-based and transparent.

categoryexamplesuse
RST and PDTB discourse parsing, discourse relations and markersDMRST, DPLP, isanlp_rst, GumDrop, discopy, DISRPT shared tasksdiscourse relations over our trees, as a comparison
coherencecoherence-rst, GCDCtests
dialogue and speech actsSILICONE models, MIDAS, DialogTag, SwDAthe speech act of Say frames, as a comparison
politenessConvoKit, politeness, Intel polite-guardrequests and imperatives against talk.rs
irony, sarcasm, metaphorTweetEval irony model, sarcasm detectors, MelBERTcomparison with irony.rs; the tweet-trained models over-fire on plain sentences
implicature, presupposition, RSAImpPres, NOPE, CREPE, pragmeval, pypragmodstest sets for infer.rs and rsa.rs
certainty, hedging, stancecertainty-estimator, hedge detectorstests

Licences: GPL, NC and repositories without a licence file (all rights reserved) are for tests and measurement only. MIT, Apache and BSD are candidates for building, after a check of the data they were trained on. See Data and model licences.

Limits

This page in Markdown → https://md.mova.elamur.ai/free/en/docs/repo-docs/pragmatics/