Vocabulary
In one sentence: the vocabulary is everything a package declares before
the first rule: individual types (entity), assertion signatures
(relation), closed lists (enum), named values (const), and visibility
(pub). The author always takes the vocabulary first: without a declared
name any literal is a check rejection, and there is nothing to write a
rule about.
The language specification treats the vocabulary as the package header: entities, relations, enumerations, constants, and visibility are declared before the first rule, and every literal is checked against them. The judgment channel (relations answered by an organ, not by facts) lives on the judgment-channel page.
1. When to use and when not to
Section titled “1. When to use and when not to”| Instead | Selection rule |
|---|---|
relation vs an entity field | An entity { field: Type; } body holds only internal immutable fields. Everything that changes over time, is contested, or is established by a case is a relation. Criterion: the value arrives as a fact — therefore relation |
kind empirical vs kind institutional | An observable case fact (measurement, event) is empirical; a status or qualification established by law is institutional; rule-head-inferred is derived. kind is metadata, it does not change truth, but its lies are expensive: another’s kind confuses the analysis reader |
enum vs an open relation | A closed list (classes, ranks) is an enum: members are incomparable with another enumeration (TYPE_ERROR at runtime, LDC-E2122 at check), there is no order. An open set is a relation with a parameter |
const Name = entity_ref(…) vs a bare name | An individual gets a name only through const: a bare name in term position must resolve to a declaration, otherwise LDC-E1330. registered_in(c, Astana) without const Astana is a rejection, not “a new individual” |
key(c) vs a second rule | A key is an integrity restriction: two tuples with one key projection give issue KEY_CONFLICT, the evaluator picks nothing and deletes nothing. The “latest/correct” of the two is not by key but by rule priority or a decision table |
2. Minimal example
Section titled “2. Minimal example”Package research.vocabulary.company_registry: entities, a named individual via
const, a rate ceiling via const Decimal, an enumeration of classes,
relations with keys, and three strict reader rules:
entity Company { label ru-KZ official "Компания"; }entity Region { label ru-KZ official "Регион"; }const CAPITAL: Region = entity_ref("urn:case:research:vocabulary:capital") { label ru-KZ official "столичный регион";};pub const MAX_RATE: Decimal = 25 percent;enum LicenceClass { first; second; third; }relation registered_in(c: Company, r: Region) kind institutional { key(c); }relation licence_class(c: Company, k: LicenceClass) kind institutional { key(c); }relation rate_applied(c: Company, r: Decimal) kind empirical { key(c); }rule CapitalCompany strict { for c: Company; when registered_in(c, CAPITAL); then capital_company(c);}rule FirstClass strict { for c: Company; for k: LicenceClass; when licence_class(c, k) and k == first; then first_class(c);}Case facts: registered_in(alpha, capital) with origin case_input.
Query: evaluate truth(capital_company(alpha)). The CAPITAL constant is
dereferenced before evaluation, so the fact about
entity_ref("urn:case:research:vocabulary:capital") and the rule about
CAPITAL concern one individual.
Actual engine answer:
law test research.vocabulary.company_registry: мир research.vocabulary.company_registry ok [research.vocabulary.company_registry#authored] tests/01-capital-company.lawtest / urn:query:research-vocabulary-01 ok [research.vocabulary.company_registry#authored] tests/02-first-class.lawtest / urn:query:research-vocabulary-02итого: 2 проверено, 2 прошли, 0 не прошли, 0 не исполнены; код 0law engine check — check OK, no warnings. Sensitivity:
licence_class(alpha, second) gives first_class(alpha) = Not established, not refuted
(the second test): a different enumeration member — the rule
stays silent. An enumeration member is written bare (second) — it is the
same node as LicenceClass.second.
Second package research.vocabulary.subtype_key: a subtype entity Branch : Company
and a key. A branch fits the Company slot: the BranchRegion rule
reads registered_in(b, r) through the supertype. Two regions of one branch
give Established plus issue KEY_CONFLICT
(expect issue(KEY_CONFLICT)); one region — Established without issues,
law test — 2/2. Sensitivity: removing
the second fact removes both the conflict and the second support.
3. Example by domain
Section titled “3. Example by domain”- Standards: package
scrum.guide(Scrum Guide) —pub enum DeveloperAccountabilitywith a label and members (see the corpus forms):pub enumexports the type and every member. - Law (sanctions): package
us.ofac.fifty_percent(OFAC 50% rule, US sanctions) — subtypesentity BlockedPerson : Partyandentity Entity : Party: party roles as subtypes, not flags. - Historical law: package
eng.corpus.statutes_of_apparel_1574(Statutes of Apparel 1574, England) — a series ofconst …: Rank = entity_ref(…)with labels: nine of the corpus’s ten constants are named individuals, not numbers. - Finance: package
us.fnma.selling_income(FNMA income rules, US) — relations withkey(src)and a comment on the honestKEY_CONFLICTinstead of a silent pick: a model of documenting a key.
4. How the engine answers
Section titled “4. How the engine answers”Table — actual runs of this section’s teaching packages:
| Facts | Question | Answer | Why |
|---|---|---|---|
registered_in(alpha, capital) | capital_company(alpha) | Established | CAPITAL dereferenced to the same entity_ref |
licence_class(alpha, second) | first_class(alpha) | Not established, not refuted | different enumeration member |
| two regions of one branch | branch_region | Established + KEY_CONFLICT | key violated, facts not deleted |
| one branch region | branch_region | Established, issues empty | counterfactual: the key alone declares the conflict |
branch_office, branch registered_in | branch_region | Established | branch is a company subtype |
- Entity identity is the “nominal type, StableId” pair: one row in
Companyand inRegionare different values; no implicit conversions. - An enumeration member is a value, and it is its identity: the guard
k == firstcompares StableIds; dotted, bare, and qualified spellings are one constant reference. - A constant through a constant unfolds recursively, in one pre-pass over the program and the case.
- On the rate value:
20 percentagainst the25 percentceiling — in the case language; the threshold is written as the guardr <= MAX_RATE, there are no const-percents in the corpus. On this section’s teaching packages a numeric vocabulary guard is not fixed by a run (incompany-registrytheWithinCaprule exists, but there is no test withrate_applied) — the claim of its firing is marked here as “not checked”.
Additionally, further checked behaviours of the earlier edition (not fixed by a run in these teaching packages):
| Facts | Question | Answer | Why |
|---|---|---|---|
registered_in(alpha, north) | capital_company(alpha) | Not established, not refuted | a different individual; the rule stays silent, it does not refuse |
rate_applied(alpha, 20 percent) | within_cap(alpha) | Established | rate within MAX_RATE |
rate_applied(beta, 30 percent) | within_cap(beta) | Not established, not refuted | above the ceiling — the rule stays silent |
licence_class(alpha, first) | first_class(alpha) | Established | an enumeration member as a value |
licence_class(alpha, first) | reliable(alpha) | Not established, not refuted + REQUIRES_JUDGMENT | the judge did not answer: good_standing is a judgment channel (the channel itself lives on the judgment-channel page) |
risk_level(alpha, high) | audit_flag(alpha) | Established | the dotted spelling RiskLevel.high is the same member |
registered_in(alpha, capital) and (alpha, north) | capital_company(alpha) | Established + KEY_CONFLICT | an observation expecting KEY_CONFLICT |
5. Common mistakes
Section titled “5. Common mistakes”- An individual name without declaration —
LDC-E1330(pitfalls, item 1). - A field in a constant’s label block —
LDC-E0201(pitfalls, item 2). - A hard-keyword name (
LDC-E0203) and arity off-declaration (LDC-E2103) (pitfalls, item 3). - A constant type not matching the initializer —
LDC-E2111; prose-style percentage and money types are not resolved by the compiler (pitfalls, item 4). - A subtype the wrong way round —
LDC-E2104(pitfalls, item 5). - Members of different enumerations in one guard —
LDC-E2122(pitfalls, item 6). - A constant through itself — silent
check,CYCLIC_CONSTANTat runtime (pitfalls, item 7).
6. References
Section titled “6. References”- Neighbour pages: strict rules, facts and evidence.
- The first-vocabulary tutorial lives in the tutorials catalogue.
- The judgment channel (
external judgment relation,REQUIRES_JUDGMENT) lives on the judgment-channel page; the syntax is in section 7 below. - The pitfalls page lists the diagnostics (
LDC-E1330,LDC-E0201,LDC-E0203,LDC-E2103,LDC-E2111,LDC-E2104,LDC-E2122) with wrong forms and fixes.
7. Grammar excerpts
Section titled “7. Grammar excerpts”Show syntax reference
Declaration visibility (who sees the symbol):
top_declaration = { annotation }, [ visibility ], declaration ;visibility = "pub" | "internal" ;Entity and subtype (the entity_decl production):
entity_decl = "entity", identifier, [ ":", type_ref ], [ "{", { field_decl | label_item | metadata_item }, "}" ], [ ";" ] ;Enumeration (the enum_decl, enum_variant productions; separators —
the = "string" form out of slice 0.1 — LDC-E0206):
enum_decl = "enum", identifier, "{", { label_item }, enum_variant, { enum_variant | label_item }, "}" ;(* Errata E-0082: разделитель вариантов необязателен и допускает запятую. Перепись корпуса: 193 варианта записаны через `;`, 98 через `,`; обе реализации принимают и смешанную запись, и вовсе бессоюзную. Форма `= string_literal` остаётся ЗАРЕЗЕРВИРОВАННОЙ (вне среза 0.1, LDC-E0206). *)enum_variant = identifier, [ "=", string_literal ], [ ";" | "," ] ;Constant (the const_decl production; after the expression the body
admits only a label):
const_decl = "const", identifier, ":", type_ref, "=", expression, ( ";" | "{", { label_item }, "}", [ ";" ] ) ;Relation and key (the relation_decl, relation_item, relation_kind
productions):
relation_decl = "relation", identifier, "(", parameter_list, ")", [ "kind", relation_kind ], ( ";" | "{", { relation_item }, "}" ) ;relation_item = "key", "(", identifier, { ",", identifier }, ")", ";" | label_item | metadata_item ;relation_kind = "empirical" | "institutional" | "evaluative" | "derived" | "normative_auxiliary" | "external" ;Symbol parameters (the parameter_list, parameter productions):
parameter_list = [ parameter, { ",", parameter }, [ "," ] ] ;parameter = identifier, ":", type_ref, [ "{", { label_item }, "}" ] ;Judgment channel: block content (the external_judgment_item production;
semantics and behaviour live on the judgment-channel page):
external_judgment_item = "authority", identifier, ";" | "request_schema", type_ref, ";" | label_item ;Documentation for Arxo. Writings — blog.arxo.io.
Anonymous visit counts on stats.arxo.io, no cookies.