Modeling vocabulary: entities, relations, enums, constants
Vocabulary is the shared language a package speaks: the kinds of things it talks about, the statements it can make, and the fixed values it reuses. Rules, norms, and cases all sit on top of this layer, so getting the vocabulary right is the first modeling step.
Everything on this page works with the public release of law, and no
input files are needed. Each claim carries a status in words
with a letter mark; the full legend is on the
topic index. Every claim here is
available in the public release (S).
The four constructs
Section titled “The four constructs”Four declaration forms carry all vocabulary (S):
entitydeclares a kind of thing, withentity A : Bfor subtyping.relationdeclares a predicate with typed parameters, pluskindandkeyannotations where the model needs them.enumdeclares a closed set of named members.constdeclares a fixed value for reuse.
Visibility is explicit: pub marks what other packages may use,
internal keeps a declaration inside its package (S). The companion
page on local and shared vocabulary explains when to choose each.
entity Parcel;entity Owner;relation owns(owner: Owner, parcel: Parcel);enum ParcelKind { residential, commercial, garden }const registry_name : Text = "Parcel Registry";The parcel example above is a trimmed retelling of the lab fixtures
that accompany this guide: package labparcels.iface contributes the
Parcel and Owner entities, the owns relation, and the
ParcelKind enum with exactly these three members, with no rules and
no sources — vocabulary only. The fixture spells each declaration in
full, adding labels, the institutional kind, and the key; the
lab tour shows the complete text.
What the engine checks
Section titled “What the engine checks”Declarations are not free text. The compiler rejects unknown types, dangling references, and malformed keys with structured diagnostics, and scenario runs exercise the vocabulary against facts (S):
law engine checkreports declaration problems before anything runs.law testruns a package’s declared scenarios over its locked world.- A key conflict at evaluation time keeps both values true and reports
KEY_CONFLICTrather than silently picking one (S).
Which form to reach for
Section titled “Which form to reach for”The four constructs above plus aliases, roles, definitions, and mappings cover every modeling need. Pick by what you are saying, not by how it reads in prose:
| Reach for | When | Not when |
|---|---|---|
type alias | Same type under a shorter local name; the import stays pinned | Two dictionaries describe one idea — an alias cannot join them; import both and write an explicit mapping |
New entity | A new kind of thing with its own identity, such as a parcel or an owner | Members of a closed set — the three parcel kinds are enum members, not entities |
role | A capacity a subject acts in, shared across rules | A one-off rule variable or a parameter position — roles are shared vocabulary, not local shorthand |
relation | A statement with parameters that a case submits or rules derive, with a kind saying which | A fixed reusable value — that is a const, not a relation |
definition | The source states what a term means, as necessary conditions or an exact equivalence | An evaluative standard such as “reasonable”, whose content arrives from case submissions or a named body — that is a relation fed through the judgment channel |
| Mapping | Correspondence between two existing vocabularies — see bridges | Both acts need the same concept — share one dictionary import instead of mapping two copies |
The forms in the table that are not among the four constructs, in one line each:
typealias — a second, local name for an existing type, for example a short name for an imported dictionary type.role— a named capacity attached to an entity type, declared aspub role Servicer for Lender;: the same lender can act as seller and as servicer.definition— a declaration that states what a term means, either as necessary conditions or as an exact equivalence; see Definition.- Mapping — an ordinary package of hand-written rules that relates concepts of two vocabularies; see bridges.
- Judgment channel — an
external judgment relation: a decision input whose value is supplied by a named authority, such as a court, instead of being computed; see Judgment channel and the contracts page.
Reproduction details
Section titled “Reproduction details”Toolchain, hashes, and full transcripts
All commands on the vocabulary pages were run against this toolchain, observed 2026-10-03:
$ law versionlaw 0.1.1semantics: law.core/0.2std for language 0.2: 0.2.0lawql: lawql/1 (queryResult 0.1)binary hash: sha256:cfa7c17232f2dc594e665dbbf2ad3c154675797ef4be07ef7d758c9abfb80a28Where to go next
Section titled “Where to go next”- The companion page on local and shared vocabulary covers visibility and shared dictionaries.
- The companion page on stable identity explains how nodes keep their identity across edits.
- The companion page on contracts covers relation kinds, keys, and predicate templates.
- For a hands-on introduction, see What we talk about.
- For construct-level detail with corpus forms, see the Vocabulary construct reference.
Documentation for Arxo. Writings — blog.arxo.io.
Anonymous visit counts on stats.arxo.io, no cookies.