# Litex Manual
Created and maintained by Jiachen Shen.
Read and run examples in the [online Manual](https://litexlang.com/doc/Manual).
The maintained [Markdown source](https://github.com/litexlang/golitex/blob/main/docs/Manual.md)
is the single home for the language guide and detailed reference.
> **Litex is an experimental hobby project still in beta. Expect rough edges.**
## Mathematics as source code
**Write math, get formalized code: because the math already is.**
Litex makes mathematical objects, definitions and facts part of the formal
source itself. In the [example below](#the-core-reading-model), `x + 1 = 3`
is both the mathematical claim and the statement submitted for checking.
Authors provide the ideas, conditions and meaningful proof steps. For ordinary
fact statements, the executor checks conditions, searches for local grounds,
records the result and makes accepted facts available to later steps. Its
knowledge storage and lookup follow mathematical structure, scope and
conditions of use.
This division of work is meant to reduce the extra rules and operations an
author must learn. Supporting familiar writing requires work in the executor;
Litex is still exploring how far it can go. This manual gives the precise
syntax, supported checks and boundaries. Supported Lean compilation is a
further use of the source and its verification evidence.
## How to use this manual
Read the opening guide to understand what a statement makes available. Use the
dictionaries when choosing a mathematical operation, checking its domain, or
finding the next explicit proof step. Each entry connects meaning, conditions,
execution or verification, reusable facts, examples, and its nearest boundary.
The reciprocal thread shows why those pieces belong together: `1 / x` needs
nonzeroness, its callable definition records that domain, and a later product
identity may need the defining equation as an explicit bridge.
| Part | Read it to | Start here |
|---|---|---|
| Core idea | Understand the division of work between author and executor | [Mathematics as source code](#math-is-code) |
| Design principles | Understand the mathematical object model and checking contracts | [Principles](#design-principles), [core model](#the-core-reading-model) |
| System pipeline | Follow source input through the complete system and identify each owner's job | [Pipeline and component map](#system-pipeline) |
| Project organization | Select dependencies/exports and understand names and load order | [Projects](#project-organization) |
| Syntax and proof/output | Write facts, check WD and read verification results | [Syntax](#syntax-reference), [facts](#factual-statements), [WD](#well-defined-objects), [proof/output](#proof-process) |
| Basic proof writing | Turn a mathematical sentence into the right declaration, goal, proof block and witness | [Basic decisions](#basic-decisions-before-writing-a-proof) |
| Dictionaries and practice | Look up native contracts and choose a mathematical proof formulation | [S](#statement-dictionary), [O](#object-dictionary), [F/C](#builtin-atomic-fact-dictionary-and-relationships), [pitfalls](#pitfalls-and-missing-proof-steps), [recipes](#recommended-mathematical-formulations) |
| Advanced interfaces | Read deeper function, struct and template contracts | [Interface details](#advanced-interface-details) |
| Native rules and inference | Find extra guarded laws, calculation limits and inference triggers | [Verification rules](#builtin-verification-rules), [inference](#builtin-inference) |
| Execution and extraction | Run algorithms/eval and inspect Python/C extraction boundaries | [Executable path](#execution-and-extraction) |
| Compatibility and evidence | Interpret removed forms, assumptions and verification records | [Compatibility](#removed-and-renamed-public-forms), [coverage](#verification-and-coverage), [appendix](#appendix) |
| Design context and references | Understand design influences, mathematical sources and related work | [References](#design-context-and-references) |
The native inventory has **51 public statement forms, 93 active object leaves,
20 builtin atomic families with their negative forms, and two native certificate
predicates**, plus the 32 reserved native theorem interfaces. Stable S/O/F/C
identifiers survive the merge. This inventories the public native language,
not every imported theorem or every individual kernel rewrite.
The language guide and detailed reference share this manual, with stable S/O/F/C entry identifiers. Expected rejections and migration examples carry skip markers and are excluded from positive runnable examples. Trust and axiom examples demonstrate ordinary-mode assumptions, not strict proofs; strict-mode rejection is described separately. Runnable code blocks are intended to be self-contained.
### The core reading model
A Litex file is read from top to bottom. A successful statement may introduce
a name, define vocabulary, verify a fact, or add information that later
statements can reuse.
```litex
have x R = 2
x + 1 = 3
x^2 = 4
```
The first line introduces a real object `x` and records `x = 2`. The next two
lines state facts. Litex checks them from the current context and stores the
accepted facts for later use.
Keep three language categories separate:
| Category | Meaning | Examples |
|---|---|---|
| **Object** | A mathematical value or expression | `x`, `R`, `C`, `i`, `{1, 2}`, `x + 1`, `fn(t R) R` |
| **Fact** | A proposition about objects | `x = 2`, `x $in R`, `$prime(n)` |
| **Statement** | An action that checks or changes the context | `have`, a bare fact, `prop`, `claim`, `thm` |
For a factual statement, the user-facing outcomes are:
| Result | Meaning | Next action |
|---|---|---|
| Success | Litex found a verification route and merged the statement. | Inspect `proof_method` when provenance matters. |
| Failed (soft miss) | The statement did not succeed (search miss, well-definedness, …); the temporary env is discarded. | Add a smaller equality, membership, domain fact, or lemma; or fix the WD obligation. |
| SessionError | Hard failure; the session must stop. | Fix the invariant / bug / unrecoverable condition before continuing. |
Batch JSON presents Success as statement `"statement_result": "accepted"`,
Failed as `"statement_result": "rejected"` inside `statement_results` (not a
lifted top-level `verify_error`), and SessionError as
`"session_terminated": true` plus structured `termination`. See [cli.md](cli.md).
AI-generated explanations and Litex drafts are untrusted until the displayed
formal code has been checked.
A common mistake is to read a soft miss as false:
```text
have x R
x = 0
```
The second line normally fails search (`why_failed.phase: search_proof`). That
is not a proof that `x != 0`. The context only says that `x` is real.
### Reading path
Read [design principles](#design-principles), the [system pipeline](#system-pipeline),
and [project organization](#project-organization) for the system-level picture.
Then use [syntax](#syntax-reference), [fact grammar](#factual-statements),
[WD](#well-defined-objects) and [proof/output](#proof-process) for authoring.
The S/O/F/C dictionaries and P/R entries provide the detailed lookup route.
The final technical chapters continue with [advanced interfaces](#advanced-interface-details),
[native rules](#builtin-verification-rules) and [inference](#builtin-inference),
then [execution/extraction](#execution-and-extraction). Each deep note links
back to its dictionary entry; domains, facts and scope have the same meaning
in both views.
The [Learner Cheatsheet](Litex_Learner_Cheatsheet.md) supplies compact learning
developments; [examples](../examples/README.md) supply longer runnable files.
The [Blueprint](Litex_Blueprint.md) and
[Lean–Litex comparisons](Representative_Lean_Litex_Example_Comparisons.md)
cover rationale and comparisons. Installation and command flags belong in
the [CLI reference](cli.md).
### Supported syntax and recommended source style
This manual describes what Litex accepts. For new proofs and ordinary teaching
examples, prefer `release thm name(args)` for calls without selection,
multiline `forall`, and English/ASCII keywords and operators. Bare `by thm`,
inline universals, and the documented Unicode aliases remain supported.
Keep `by thm name(args) => fact` when selecting an atomic consequence; its
context effect differs from an all-conclusions release. See the
[learner recommendation table](Litex_Learner_Cheatsheet.md#supported-syntax-and-recommended-writing)
for examples and reasons. These source-style preferences do not impose parser
restrictions.
## Design principles
### Pure-set object model
Litex uses one universe of mathematical objects and chooses a pure-set
foundation: every well-defined Litex object satisfies `$is_set`. Thus a
numeral, a function value, a user-defined set, a function space, and each of
`N`, `Z`, `Q`, `R`, and `C` are all objects. They keep different mathematical
interfaces, but they are not different runtime carrier types.
Membership is a fact between two objects. For example, `1`, `N`, and `R` are
objects; `1 $in N` and `1 $in R` are separate facts about the same `1`.
Likewise, `forall x R` introduces an object `x` together with the fact
`x $in R`; it does not retype `x` as a host-language real number. A function
space `fn(x R) R` and a function belonging to it are also objects, while the
function-space membership records the callable contract.
This is Litex's explicit choice within the pure/impure distinction described
in Tao's *Analysis I*: the book remains agnostic about whether primitive
objects are themselves sets, while Litex adopts the pure interpretation. The
choice is foundational rather than notational. Surface concepts still retain
their ordinary roles: a number is used arithmetically, a function is applied,
and a set is inspected through membership. Set equality is extensional:
`by extension` proves equality from the two membership directions. In the pure
model this is the common object equality principle, not a separate equality
for a host-language `Set` type.
The object universe is not an internal universal set. `Object` is the
meta-level carrier used to implement the language, not an object that can be
written on either side of `$in`. Litex also does not provide unrestricted
comprehension. A set builder has the bounded form `{x S: facts}` over an
already available `S`; replacement and other partial constructors have their
own well-definedness obligations. These restrictions are what separate
"every object is set-coded" from the inconsistent claim that every predicate
defines a set of all objects.
### Meaning, evidence and context
Objects, facts and statements have the roles shown in the
[core reading model](#the-core-reading-model). Before truth verification,
well-definedness checks that the objects and predicate applications are
meaningful under their domains. A successful statement can then make facts
available in its scope; later statements consume those facts through checked
routes. [Inference](#builtin-inference) accounts for the routine consequences
published after acceptance.
These are mathematical and checking contracts. Naming, operator precedence,
delimiters and Unicode spellings are [syntax rules](#syntax-reference).
The [trust boundary](#trust-boundary) states what a successful check assumes.
## System pipeline
This chapter follows one current source input from launch to visible results.
Project mounting supplies its definitions and names; the source runner handles
tokenization and statement order; each statement handler checks its own
mathematical obligations and commits accepted information. The [proof
process](#proof-process) zooms into verification inside this larger flow.
### From input to results
```mermaid
flowchart TD
A["CLI or REPL entry"] --> B["Load configured imports and exports"]
B --> C["Read the current source input"]
C --> D["Tokenize the whole input into top-level blocks"]
D --> E["Parse the next complete block and resolve names"]
E --> F["Dispatch the statement in a temporary execution scope"]
F --> G["Check WD and the statement-specific obligations"]
G --> H["Record accepted definitions, facts and inference effects"]
H --> I["Commit a successful statement"]
I --> J{"More blocks?"}
J -->|yes| E
J -->|no| K["Return results: JSON or REPL feedback"]
F -->|soft failure| L["Discard current effects and restore parse bindings"]
L --> J
E -->|parse error| M["Stop and report the error"]
F -->|execution error| M
D -->|tokenizer error| M
M --> K
```
The tokenize step runs over the complete current input before any of its
statements execute. After that, parsing and execution alternate **one complete
top-level block at a time**. A theorem, claim or sketch includes its entire
nested proof in that block; parsing does not execute an unfinished proof.
Successful earlier blocks remain available when a later block soft-fails.
WD and truth verification are distinct obligations. A fact assertion verifies
its fact before storing it. A definition checks its construction contract;
a proof directive runs its scoped proof route; `eval` checks its computation
and result equality. Ordinary-mode `trust` checks WD while explicitly assuming
truth, and strict mode rejects the user-assumption forms. The diagram groups
these handler-specific checks without claiming they all use one verifier.
**Source:** [source runner](../src/run/run_litex_code.rs),
[statement transaction and dispatch](../src/execute/exec_stmt.rs),
[fact verify → store/infer](../src/execute/execute_fact_stmt/exec_fact_stmt.rs).
### What each part owns
| Part | Responsibility | Input → result | Implementation |
|---|---|---|---|
| Launch and run | Select file/project/source/REPL, strict policy and output language; route to the appropriate runner | Command arguments → selected run | [launch](../src/launch_command.rs), [run](../src/run/README.md) |
| Project loading | Read `litex.config`, run imports and selected exports in order, and record completed file environments | Manifest and files → mounted project context | [run_module](../src/run_module/README.md) |
| Module and name management | Track module/file owners and resolve qualified names against loaded exports | Alias/export/name → its owner-qualified identity | [module_manager](../src/module_manager/README.md) |
| Tokenization | Recognize tokens, comments, aliases, indentation and complete source blocks | Source text → token blocks or tokenizer error | [tokenize](../src/tokenize/mod.rs) |
| Parsing and AST | Build the Stmt/Obj/Fact shapes, attach binder identities and resolve source names | One complete block → structured statement or parse error | [parser entry](../src/parse/parse.rs), [AST](../src/ast/mod.rs) |
| Runtime and execution environments | Own active context, name visibility and scoped statement execution; commit successful effects | Existing context + statement → success, soft failure or hard error | [Runtime](../src/runtime/mod.rs), [ExecEnv](../src/exec_env/mod.rs), [exec_stmt](../src/execute/exec_stmt.rs) |
| Well-definedness | Check child objects, declaration/signature visibility, carriers and partial-operation guards | Object/fact + context → domain evidence or WD failure | [object WD](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/mod.rs), [atomic WD](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_well_defined.rs) |
| Fact verification and proof handlers | Reuse known facts and permitted calculation/rules/definitions/universals; check explicit proof routes | Goal + available evidence → typed verification result | [fact checking](../src/execute/execute_fact_stmt/README.md), [proof statements](../src/execute/execute_by_stmt/mod.rs) |
| Instantiation | Substitute actual arguments into domains, bodies and facts while retaining binding identity and checking the caller's obligations | Parameterized interface + arguments → instantiated interface | [instantiate](../src/instantiate/mod.rs) |
| Exact mathematical calculation | Provide bounded exact numeric/algebraic calculation to the checking and evaluation paths | Supported expressions → exact values/normal forms or a declined calculation | [rational_expression](../src/rational_expression/mod.rs) |
| Storage and inference | Index accepted seeds, assign/cite facts and publish supported routine consequences in the current scope | Accepted fact → stored fact and inference effects | [store_fact_and_infer](../src/store_fact_and_infer/README.md) |
| Display and result projection | Render statements and project existing result/evidence trees into localized output; projection adds no proof | Structured statement/result → readable representation and JSON | [display_and_ir](../src/display_and_ir/README.md), [json_output](../src/json_output/README.md) |
| Import knowledge-base cache | Reuse a completed dependency's saved knowledge where policy permits; strict imports replay source | Dependency record → cached context or cold execution | [knowledge_base](../src/knowledge_base/README.md), [strict cache policy](../src/run_module/import_kb.rs) |
| Optional executable extraction | Select marked source, verify that virtual program, then lower the supported executable subset to Python or C | Selected checked program → executable-code artifact | [extract_executable_code](../src/extract_executable_code/README.md) |
Instantiation, exact calculation, storage and name resolution are shared
services used at the appropriate points, rather than unconditional extra
passes over every statement. A cold project import re-enters the same source and
statement checking path for the dependency's files. An eligible cache hit
restores completed dependency knowledge; strict imports take the source path. Imported file environments
keep their owners; they are not flattened into one ambient fact collection.
The current active Rust modules are listed in [src/lib.rs](../src/lib.rs).
### One statement leaves evidence for the next
```litex
have n N
0 <= n
n + 0 = n
```
The parser introduces the name for the declaration. Execution checks that
`N` is a usable nonempty carrier, stores `n $in N`, and inference publishes
the nonnegative bound. The second line reads that known consequence. The third
line checks the addition's object domains and proves the equality through the
ordinary equality route. Each successful statement commits before the next
block is parsed. [F01](#f01-membership-and-nonmembership) owns the membership
contract and [S04](#s04-arbitrary-members) owns arbitrary-member introduction.
**Expected soft failure — the third statement misses `search_proof`; the
fourth still succeeds:**
```litex
have n N
0 <= n
n = 0
n + 0 = n
```
The aggregate run reports failure because one statement failed; there is no
session error, and the successful statements remain recorded. The failed
equality is not a proof of `n != 0`. A failed declaration likewise restores
its speculative parse bindings, so it cannot occupy a name for the next
block. Global identifier counters are not rolled back or reused.
### Project loading, proof checking and executable output
Read [project organization](#project-organization) next for which sources are
selected and how their names are made available. Read [proof process](#proof-process)
for which evidence can justify a goal. Finally, [execution and extraction](#execution-and-extraction)
explains how checked algorithms become computations or target programs.
Those chapters describe connected parts of this pipeline, with separate
responsibilities and checked boundaries.
## Project organization
### Modules and manifests (preview)
> **Project modules:** there is no `submodule` and no `[hierarchy]`.
> A maintained package is a single module. `[export]` lists only `.lit` files;
> `[import]` and `[import std]` share one alias namespace within each manifest.
>
> - Tables / parse / `::` elaborate:
> [`src/module_manager/README.md`](../src/module_manager/README.md)
> - How `-r` / `-f` / `-e` / REPL mount and run:
> [`src/run/README.md`](../src/run/README.md)
> - Fixtures:
> [`examples/module_manager/`](../examples/module_manager/)
A maintained project directory has one `litex.config`.
```ini
[import]
Algebra = "../Algebra"
[import std]
basics # Alternatively: basics = basics (choose one spelling, not both)
[export]
chap1 = "./chapter01.lit"
chap2 = "./chapter02.lit"
chap3 = "./chapter03.lit"
```
Under the Litex CLI:
| Command | Config | Behavior |
|---------|--------|----------|
| `-r
` | required at `` | all imports, then all exports |
| `-f ` | optional at `parent(file)` | listed → prefix through file; unlisted → full mount then file; missing → isolated |
| `-e` / bare REPL | optional at cwd | full mount (or empty), then eval / REPL |
Mount soft Failed becomes session `FailToImport`. Soft Failed on a `-f`
**target** itself stays a normal file failure.
Important rules:
1. `[export]` is ordered and each entry names one `.lit` file. Exporting a
child directory or nested config node is not allowed.
2. `[export]` is an explicit selection list, not a complete directory
inventory. Unlisted files and folders are sidecars: discovery does not
parse, execute, or expose them in the module namespace. Every declared
export path must exist and point to a `.lit` file.
3. `[import] Alias = path` mounts another module directory.
`[import std]` accepts either a bare name `N` (meaning `N = N`) or
`Alias = StdName`; both mount `/` under `Alias`.
After resolution `[import]` and `[import std]` are the same kind of
import. Import aliases from both sections must be unique within that
`litex.config`; separate packages may reuse an alias for their own paths.
An export name may reuse an import spelling: `a::b` is always a
current export, `a::b::c` is an import path, and `a:::b` is explicit
single-export sugar for `a::::b`.
4. Canonical names follow the mount alias and export name, for example
`Algebra::chap1::name` or `basics:::name` when `basics` has one export.
Struct carriers accept these same paths: `&local::Pair`,
`&Lib::facts::Tagged` and, for an import with exactly one export,
`&Lib:::Tagged`. The full definition owner is retained for field types,
function returns and nested struct fields. Missing paths, wrong arguments
and tuples outside the chosen carrier are rejected. See the runnable
[qualified struct fixture](../examples/module_manager/qualified_struct_views/README.md).
Cross-module references always use canonical qualified names. Module aliases
and symbols are separate, so a local symbol may also be named `A`; field
selection such as `obj.b` remains in the field namespace. An export is
unavailable while it is still loading, so an earlier file cannot cite a later
export.
An import alias is resolved using the importing package's manifest, then the
normalized directory path selects the global module ID. For example, two
packages may each declare `Common = "./dep"` and refer to different dependency
directories. Same-path imports under different aliases share one module.
The loader assigns distinct global display labels when local aliases repeat;
these labels do not change source name resolution. See the runnable
[cross-file identity fixture](../examples/module_manager/cross_file_identity/README.md).
Project dependencies come from `litex.config` (`[import]` / `[import std]`),
not from source-level `import` statements. Every `.lit` file rejects `import`;
reproducible dependencies belong in the manifest. The interactive REPL runs
Litex source blocks only; it does not add a separate terminal `import`
command surface.
```ini
[hierarchy]
module
```
```ini
[hierarchy]
submodule
```
```ini
[export]
Part2 = "./Part2"
```
```ini
[import]
basics = "../OtherBasics"
[import std]
basics = basics
```
These manifests are invalid under the current module design: `[hierarchy]` and
`submodule` are removed, `[export]` cannot name a folder, and import aliases
must be unique across `[import]` and `[import std]`.
Project execution, persistent sessions and output are
CLI contracts rather than language syntax. See the [CLI reference](cli.md) for
installation, project-running examples, and the current command set.
## Syntax Reference
### Binder syntax
| Meaning | Form | Canonical section |
|---|---|---|
| Object in a set | `x S` | [Bare facts and `have`](#bare-facts-and-have) |
| Set parameter | `S set` | [Bare facts and `have`](#bare-facts-and-have) |
| Nonempty set parameter | `S nonempty_set` | [Bare facts and `have`](#bare-facts-and-have) |
| Finite set parameter | `S finite_set` | [Bare facts and `have`](#bare-facts-and-have) |
| Multiple names in one domain | `x, y R` | [Universal facts](#universal-facts) |
| Domain condition | `x R: x != 0` | [Domain obligations](#domain-obligations) |
| Parameterized definition | `template:` | [Templates](#templates) |
| Shared universal assumptions | Explicit typed parameters and an indented premise block; `setting` is unsupported | [Shared assumptions](#shared-assumptions-and-inline-universals) |
| Struct parameter | `struct Group:` | [Struct objects](#struct-objects-and-definition-owned-field-access) |
### Syntax lookup
| What is being written | Canonical index |
|---|---|
| Object/expression | [Complete O index](#object-dictionary) |
| Atomic relation or predicate | [Complete F index](#builtin-atomic-fact-dictionary-and-relationships) |
| Compound or quantified fact | [Fact-shape summary](#fact-shape-summary) |
| Definition or proof action | [Complete S index](#statement-dictionary) |
| Reserved builtin theorem | [Native theorem index](#reserved-builtin-theorem-interfaces) |
| Removed legacy spelling | [Compatibility table](#removed-and-renamed-public-forms) |
### Names, numbers, and arithmetic
Names refer to builtin objects, earlier definitions, local binders, or
module-qualified definitions. Arithmetic uses ordinary precedence:
parentheses, calls, and indexing bind tightly, then powers, prefix `-`,
multiplication and division, then addition and subtraction. Powers associate
to the right.
The parser therefore reads `-t^2` as `-(t^2)`, not `(-t)^2`. That compatibility
rule does not make the bare spelling canonical authoring: it still leaves a
reader to recall the precedence choice. Write `-(t^2)` (equivalently
`-1 * (t^2)`) for the opposite of a square, and write `(-t)^2` for the square
of the negative value. Parenthesize a negative exponent too: `t^(-1)`, not
`t^-1`. This explicit-parentheses rule applies to generated and agent-authored
Litex as well as handwritten source.
prefix `-a` is the unary arithmetic operator `neg(a)` (AST
`Neg`), not the same tree as the binary difference `0 - a`. Closed numeric
evaluation treats both. Do not rely on `-a` and `0 - a` being identical AST.
User-defined names may begin with a letter or one underscore and may then use
letters, numbers, and underscores. The prefix `__` (two underscores) is
reserved for generated symbols, including names in Lean output, and is rejected
during tokenization. Names beginning with one underscore remain ordinary user
space, as do prefixes such as `h_` and `fn_`. Comments and quoted strings are
not symbol tokens and may contain the reserved spelling.
Builtin object spellings are also reserved at declaration sites: literals
`i`, `e`, `pi`, standard sets such as `N`, `R`, `C`, and object constructor/function
names such as `sin`, `sqrt`, `fn`, `sum` and `cart` cannot be user definitions,
parameters, fields, indices or witnesses. Their uses are parsed as builtins
before identifier lookup. Use a fresh name such as `t`, `epsilon` or `pi_value`;
a rejected declaration does not leave its attempted names bound.
### Compact numeric-set suffixes
The suffix must be adjacent to its base. These compact forms are canonical;
the verifier prints the same spelling.
The signs are strict: `+` means greater than zero, `-` means less than zero,
and `*` means nonzero. `N*` is not a standard spelling; use `N+` for nonzero
naturals.
### Operator and delimiter notes
- Arithmetic binding from tighter to looser is: calls/indexing, right-associative
`^`, prefix `-`, multiplicative operators, then binary `+` and `-`. Thus the
parser reads `-t^2` as `-(t^2)`, while `-t * u` groups as `(-t) * u`.
- At the prefix-`-`/power boundary, always state the intended tree explicitly:
`-(t^2)` or `-1 * (t^2)` negates the power, `(-t)^2` powers the negative
base, and `t^(-1)` uses a negative exponent. Do not author `-t^2` or `t^-1`.
- Function and coordinate application use `()`. Bracket indexing is removed; see [compatibility](#removed-and-renamed-public-forms).
- `{a, b}` is a displayed set; `{x S: facts}` is a set comprehension.
- `st { ... }` delimits an existential body. Its entries are atomic facts or
their supported boolean combinations (`and` / chain / `or`); name a quantified
condition with `prop` before using it there. Restricting the body this way
keeps exist index keys easy to design for known-fact search. The same
restriction applies to set builders.
- `#` outside an inline aside starts a line comment. Quotes in that comment
need not be balanced. A trailing comment preserves a block header's colon.
Indentation defines block structure.
- Inline aside `"..."` (ASCII quotes, single line) is stripped at tokenize time
and is not part of the AST. Unclosed `"..."` is a parse error.
- Block comment: a line that is exactly `"""` after trim opens or closes a
multi-line comment. Only ASCII `"""` counts; `"`, `""`, or `""""` alone do
not. Unclosed `"""..."""` is a parse error. Distinct from `#` and from
inline `"..."`.
- Line continuation (preview): a line whose code region ends
with `\\` joins the next physical line into the same logical line. Optional
trailing whitespace and a following `# ...` comment after `\\` are allowed
and dropped with the marker (so the continued line is not commented out).
Leading spaces on the continued line are ordinary whitespace. Mid-line `\\`
is not continuation and is unrelated to the template prefix `\`. A trailing
`\\` with no following line is a parse error.
- Bracket sequence literals, the matrix carrier, and apostrophe matrix operators are removed; use functions with explicit index sets.
### Unicode mathematical input aliases (preview)
Litex accepts the following Unicode mathematical input. Simple aliases are
canonicalized during tokenization; infix set forms are lowered by the parser to
the existing set-object and fact nodes. Stored facts, diagnostics, and verifier
semantics continue to use canonical ASCII Litex syntax.
For new proofs and ordinary documentation examples, prefer the English/ASCII
column below. Unicode remains supported input; use it deliberately when the
example teaches notation aliases or the author requests that style.
| Unicode input | Canonical Litex syntax |
|---|---|
| `∀`, `∃`, `∃!` | `forall`, `exist`, `exist!` |
| `≤`, `≥`, `≠` | `<=`, `>=`, `!=` |
| `→`, `↔` | `=>`, `<=>` |
| `∧`, `∨`, `¬` | `and`, `or`, `not` |
| `∈` | `$in` |
| `∉` | `not ... $in ...` |
| `⊆`, `⊇` | `$subset`, `$superset` |
| `⊂`, `⊊`, `⊋` | `$proper_subset`, `$proper_subset`, `$proper_superset` |
| `A ∪ B`, `A ∩ B` | `union(A, B)`, `intersect(A, B)` |
| `A × B` | `cart(A, B)` |
| `ℕ`, `ℤ`, `ℚ`, `ℝ`, `ℂ` | `N`, `Z`, `Q`, `R`, `C` |
| `ℕ+`, `ℤ+`, `ℚ+`, `ℝ+` | `N+`, `Z+`, `Q+`, `R+` |
| `ℤ-`, `ℚ-`, `ℝ-` | `Z-`, `Q-`, `R-` |
| `ℤ*`, `ℚ*`, `ℝ*`, `ℂ*` | `Z*`, `Q*`, `R*`, `C*` |
| `π`, `∅` | `pi`, `{}` |
For example, this is the same universal fact as its ASCII spelling:
```litex
∀ x ℝ:
x ≠ 0
→:
x ∈ ℂ
x ≤ x ∧ x ≥ x
```
Aliases are recognized only as complete tokens and are not rewritten inside
quoted module paths. `⊂` deliberately means strict/proper subset, the same as
`⊊`; non-strict subset remains `⊆`. Unicode compact numeric sets mirror the
existing ASCII keyword family exactly, so `ℕ*` remains unsupported just as
`N*` is unsupported.
`∃!` has exactly the existing unique-existence semantics of `exist!`. In
particular, `witness ∃! ...` must prove both that the supplied witness satisfies
the body and that any two witnesses satisfying the body are equal.
The infix precedence from lower to higher is `∪`, `∩`, `×`, then the existing
arithmetic object operators. Union and intersection associate to the left. A
direct product chain is flattened, so `A × B × C` becomes `cart(A, B, C)`;
parentheses can request nesting. `×` never means numeric multiplication:
`2 × 3` is parsed as `cart(2, 3)` and is rejected because the factors are not
sets. Write `2 * 3` for arithmetic multiplication. The word forms remain
constructor calls such as `union(A, B)`; this preview does not add `A union B`.
### Absolute-value bars (preview)
Prefer `|expr|` in ordinary mathematical examples and showcases. Use
`abs(expr)` when explaining the function spelling or canonical output.
`|expr|` is another input spelling of the existing real `abs(expr)` object.
The enclosed expression is grouped as a whole; ordinary operators and
postfixes apply outside it. `abs(...)` remains supported, and stored facts and
diagnostics keep the canonical `abs(...)` spelling.
```litex
|-3| = abs(-3) = 3
|1 - 4|^2 = 9
forall x, y R:
|x + y| <= |x| + |y|
```
Bars can nest: `||x||` means `abs(abs(x))`. Both delimiters are required,
and empty bars are rejected. Multiplication stays explicit (`2 * |x|`). The
domain remains real: `|i|` and `|{1, 2}|` are rejected, with complex modulus
still written `C_abs(i)` and finite cardinality `finite_set_size({1, 2})`.
These bars do not introduce a norm. See the maintained
[absolute-value bars tracer](../examples/test_objs/absolute_value_bars.lit).
---
## Factual Statements
A **fact** is a proposition Litex can try to verify. A top-level accepted fact
is stored in the current context; a fact nested inside a quantifier or proof
block follows that form's scope.
### Atomic facts
An atomic fact applies a builtin relation or a declared predicate to objects.
The [F dictionary](#builtin-atomic-fact-dictionary-and-relationships) owns their meanings, domains,
negative forms and relationships. An expression alone, such as `2 + 3`, is not
a fact; write `2 + 3 = 5` or use [eval](#s51-exact-evaluation).
### Conjunctions, chains, and disjunctions
Use `and` for a conjunction on one line, adjacent binary relations for a
chain, and `or` for alternatives.
```litex
1 < 2 and 2 < 3
1 <= 2 = 2 < 3
1 < 2 or 1 >= 2
```
For an equality chain, Litex checks each adjacent equality and then stores
the non-adjacent equalities by transitivity. For example, this chain stores
`y = 3`, which the next statement can use:
```litex
have x R = 2
have y R = x + 1
y = x + 1 = 3
y^2 = 9
```
The definition step and calculation step are explicit. Automatic definition
expansion does not enable rewrite in its residual goal. A failed chain does
not commit its endpoint equality.
The fact grammar has a deliberate canonical hierarchy rather than arbitrary
recursive nesting. A conjunction is a flat list of atomic facts. A disjunction
is the outer layer, and each of its branches is one atomic fact, one relation
chain, or one flat conjunction. In ordinary operator terms, `and` binds more
tightly than `or`. That parser precedence is also why the verifier can treat
`or` branches as a small fixed set of shapes when matching known and goal
disjunctions.
For example:
```text
$p(a) and $q(a) or $t(a)
```
has two `or` branches: `($p(a) and $q(a))` and `$t(a)`. It is not read as
`$p(a) and ($q(a) or $t(a))`. Allowing an `or` branch to be a completed
conjunction preserves this fixed hierarchy; it does not make `and` or `or`
arbitrarily nestable.
Verification of an `or` proves that at least one branch holds; it does not add
an arbitrary branch as a known fact.
A verified conjunction or relation chain can introduce a disjunction even
when its other branches are compound. Litex checks the selected branch and
retains that proof; it does not assume that the compound branch is true.
```text
have x R
x = 0 or x != 0
x = 0
```
The disjunction is true, but the last line still soft-fails.
### Existential facts
`exist` states existence, `exist!` states unique existence, and `not exist`
states non-existence. Witness variables are local to the fact.
An existential used as a complete fact must consume its whole line, including
inside `forall` conclusions and `prop` definitions. A suffix such as
`exist y R st {y = x} and 0 = 1` is a parse error; it is never discarded.
Put additional conditions inside `st { ... }`, or write a separate fact on
the next line. The enclosing `witness exist ... from ...` form still consumes
its own `from` clause after the existential.
```litex
witness exist x R st {x^2 = 4} from 2:
2^2 = 4
witness exist! x R st {x = 0} from 0
by contra:
? not exist x R st {x != x}
obtain x from exist x R st {x != x}
impossible x != x
```
Knowing an existential does not put its bound name in the outer context:
```text
exist x R st {x = 1}
x = 1
```
The second line is an `error` because the existential `x` is out of scope. Use
`obtain` to introduce a fresh witness name.
Existential bodies may contain atomic facts, conjunctions, chains, and
disjunctions. They do not contain anonymous `forall` facts. Put the quantified
condition in a named `prop` and reference it atomically. Braces delimit the
body:
```litex
prop universally_self_equal(x R):
forall y R:
x = x
forall:
exist x R st {$universally_self_equal(x)}
=>:
exist x R st {$universally_self_equal(x)}
```
### Universal facts
`forall` introduces arbitrary parameters, optional assumptions, and
conclusions. With no assumptions, write conclusions directly rather than an
empty `=>:` block. A parameterless `forall:` is allowed: it binds no names and
just packages the body facts (useful as a bare `? forall:` theorem goal).
```litex
forall x R:
0 <= x^2
forall x R:
x = 2
=>:
x + 1 = 3
forall:
1 + 1 = 2
```
A universal over the literal empty display can be checked by finite enumeration:
```litex
by enumerate finite_set:
? forall x {}:
x != x
x != x
```
This enumeration uses the literal `{}`. It does not discharge
the corresponding goal over `range(3, 3)`, even after proving that range equal
to `{}`. The following is a known soft failure:
```text
forall index range(3, 3):
index != index
```
The conclusion of a `forall` cannot itself be another `forall`. Put every
quantified parameter in the same header. The nested spelling below is a parse
`error`:
```text
forall x R:
x > 0
=>:
forall y R:
y > 0
=>:
x + y > 0
```
Write the flat fact instead:
```litex
forall x, y R:
x > 0
y > 0
=>:
x + y > 0
```
A universal fact may still be an explicit premise before `=>:`. That premise
is an assumed fact in the outer scope, not a universal conclusion. A
`not forall` fact is likewise not allowed as a direct universal conclusion;
name that quantified proposition before using it there.
An assumption is local; it does not become a global fact:
```text
forall x R:
x = 2
=>:
x + 1 = 3
x = 2
```
The last line is an `error` because the bound `x` no longer exists.
#### Shared assumptions and inline universals
The current parser rejects `setting` and does not expand `forall [Name]`
bundles. Write the parameters and assumptions directly in each universal:
```litex
forall X nonempty_set, x, y X, z X:
x = y
=>:
z = z
```
A premise-free universal may use `forall x R => x = x`. The current parser
also supports a one-line premise and conclusion separated by the outer arrow:
```litex
forall x R: x > 0 => x != 0
```
Prefer an indented block in newly authored proofs, so the premises and
conclusions are easy to inspect and extend:
```litex
forall x R:
x > 0
=>:
x != 0
```
Existential and set-builder property bodies do not admit a nested `forall`;
name the quantified condition with `prop` and use its atomic `$P(...)` fact.
### Universal equivalence and negated universals
`forall ... <=>:` stores both directions of an equivalence. The left side is
introduced after `=>:` even when it has no shared assumptions.
Well-definedness is checked separately for the two generated universal
directions. Each check receives the shared assumptions and its own antecedent,
but it cannot borrow a side condition from the opposite side. Put any side
condition needed to make both directions meaningful before `=>:` as a shared
assumption.
```litex
forall x, y R:
=>:
x = y
<=>:
y = x
```
`not forall` negates a universal claim. its domain and
conclusions are restricted to quantifier-free shapes (atomic / `and` / chain /
`or`) — the same shapes allowed inside an `exist … st {…}` body. Prove and store
both reduce to the De Morgan counterexample exist
`exist binders st { dom…, not(then)… }` (the `not forall` fact itself is still
recorded in `facts_by_id`; search reuses `known_exist`). Nested `exist` or
`forall` inside `not forall` is a parse error; name such content as a `prop`
instead.
**Checked example.**
```litex
by contra:
? not forall x R:
x > 0
impossible 0 > 0
```
Do not replace `not forall` with an unsupported prefix on a block:
```text
not:
forall x R:
x > 0
```
This is a parse `error`; write `not forall ...` on one header.
### Fact-shape summary
| Shape | Syntax |
|---|---|
| Atomic | `a = b`, `a $in A`, `$P(a)` |
| Flat conjunction | `atomic and atomic` |
| Chain | `a <= b = c < d` |
| Outer disjunction | `(atomic, chain, or flat-conjunction branch) or branch` |
| Existence | `exist params st {facts}` |
| Unique existence | `exist! params st {facts}` |
| Non-existence | `not exist params st {facts}` |
| Universal implication | `forall params: assumptions =>: conclusions` |
| Universal equivalence | `forall params: =>: left <=>: right` |
| Inline universal | `forall params: assumption => conclusion` |
| Negated universal | `not forall params: facts` |
| Inline negated universal | `not forall params: assumption => conclusion` |
---
## Well-Defined Objects
Before Litex tries to prove a fact, it checks that every object in that fact is
meaningful in the current context. A well-definedness failure is an `error`,
not a soft-miss theorem label.
### Domain obligations
Ordinary `prop` and `abstract_prop` facts must refer to a declaration visible
at the point where their well-definedness is checked, with exactly the declared
number of arguments. Qualified predicate names use the declaration in that
module and file. A declaration later in a claim's proof body cannot make an
earlier undefined goal well-defined. This also applies to negated predicate
facts and to facts used as quantified assumptions.
Function definitions are checked under the parameter types and domain facts
written in their signature.
```litex
have fn reciprocal(x R: x != 0) R = 1 / x
have fn root(x R: 0 <= x) R = sqrt(x)
reciprocal(2) = 1 / 2
sqrt(4) = 2
root(4) = 2
```
The same expressions fail when their obligations are absent:
```text
have x R
1 / x = 1
sqrt(x) = 0
```
Both factual lines produce `error`: the first lacks `x != 0`; the second lacks
`0 <= x`.
### Ordered assumptions during well-definedness
The premises of a `forall` and the facts in an `exist` body are checked
from left to right in their temporary binder scope. After one fact is known to
be well-defined, Litex records it there as an assumption and runs its sound
inference. A positive concrete predicate may therefore expose its definition,
including a universal clause needed by a later object obligation.
The same ordering applies to the domains of `not forall` and
`forall … <=>:` during their independent WD checks, including definition
bodies and claim goals. A checked domain such as `y != 0` can guard a later
`1 / y`. For an iff, only the common domain guards both branches; a condition
on one branch does not justify objects on the other branch. These local
assumptions do not prove the quantified fact or escape its binder scope.
See [the executable guarded-quantifier example](../examples/wd/fact/guarded_quantifier_domains.lit).
**Checked example.**
```litex
prop nonzero_on(E power_set(R), g fn(x E) R):
forall x E:
g(x) != 0
forall E power_set(R), f, g fn(x E) R:
$nonzero_on(E, g)
=>:
fn(x E) R {f(x) / g(x)} $in fn(x E) R
```
Here the checked predicate premise exposes `forall x E: g(x) != 0`, so the
anonymous function body is meaningful throughout `E`. This is scoped
definition use, not unrestricted proof search: recursion guards still apply,
an `abstract_prop` has no body to expose, and omitting the predicate premise
still leaves the division ill-defined. The temporary assumptions and inferred
facts do not escape the quantified or existential check.
The equivalent facts in a `struct` `<=>:` block are also checked from left to
right in a temporary field scope. Each successful fact is staged without
definition inference before the next fact is checked. This lets a filter guard
justify a later partial expression, both when the struct is defined and when
an instantiated struct carrier is checked:
**Checked example.**
```litex
struct NonzeroPair:
value R
tag N
<=>:
value != 0
1 / value = 1 / value
```
Source order is significant: omitting `value != 0`, or placing it after the
reciprocal, leaves the reciprocal ill-defined. These temporary filter facts do
not escape the struct check and are not proved merely by appearing in the
definition.
### Where to find object obligations
Each [O entry](#object-dictionary) owns its precise domain and common native
properties. For example, [O01](#o01-division) checks the denominator guard;
[O79](#o79-function-spaces) checks the complete fixed signature;
[O92](#o92-definition-owned-field-access) distinguishes field WD from releasing
struct properties. [S04](#s04-arbitrary-members) and
[P06](#p06-arbitrary-have-needs-nonemptiness) explain why introducing an arbitrary
member requires nonemptiness. These conditions are checked before truth search.
## Proof Process
The proof process answers one question: why may the current statement be added
to the verified context? The checker follows a small set of routes and reports
the route that succeeded or the point that failed.
`claim`, `sketch`, `strategy`, and block forms of extensionality, enumeration,
range proofs and induction require a nonempty proof process. A `?` goal is the
target, not a proof step; goals alone or comments alone produce a parse error.
Every `case` branch and each explicitly written induction base/step section
also needs a nonempty body. An `impossible fact` closing statement counts as a
proof step, so a contradiction body may consist of that statement alone.
Named `thm` declarations may omit their proof process when ordinary verification
already closes the target. Inline commands such as `by extension A = B`,
`by def $P(args)` and `witness ... from value` remain available. Adding a trailing
proof-body `:` to a witness, Choice or Zorn command requires actual indented
proof statements. These syntax checks do not establish truth: every goal and
proof step must still pass ordinary verification.
Any indented colon block must contain actual source content. A comment-only
body is rejected while building the token blocks, before statement parsing.
This also applies to explicit fact bodies such as `trust:` and `have x R:`.
### Basic decisions before writing a proof
This is the writing entry for a reader or AI that knows the intended
mathematics but has not yet chosen its Litex form. The dictionaries own
the exact contracts; the decisions below connect them into a small proof.
Keep the mathematical domain, quantifier order and conclusion fixed while
choosing syntax or repairing a verification miss.
| Decision | Basic distinction | Contract to consult |
|---|---|---|
| Introduce or name a value | `have x R` introduces an arbitrary real; `have x R = 2` specifies its value; `let` names an expression | [S04](#s04-arbitrary-members), [S05](#s05-typed-values-given-by-equality), [S03](#s03-equality-aliases) |
| Define a condition or a function | `prop` names a proposition; `$P(a)` asserts an instance; `have fn` defines a callable value | [R02](#r02-choose-the-language-form-by-mathematical-role), [R04](#r04-a-relation-and-its-selected-value-have-different-roles) |
| State a conditional result | Put hypotheses before `=>:` and conclusions after it; without the arrow the listed facts are conclusions | [Universal facts](#universal-facts) |
| Execute proof actions | A bare `forall` contains facts; commands such as `by def`, `witness`, `obtain` and local declarations need a statement/proof surface | [S33](#s33-local-claims) |
| Use a goal parameter | A claim activates its goal's binders and premises; use those names directly | [S33](#s33-local-claims), [scope](#scope-and-failure) |
| Prove or consume existence | Supply a value with `witness`; extract a value with `obtain` from an existence fact that verifies | [S35](#s35-existential-witnesses), [S07](#s07-extract-existential-witnesses) |
| Claim uniqueness | `exist!` requires uniqueness as well as a satisfying witness | [S36](#s36-unique-existential-witnesses) |
| Use a logical fact | An implication needs its premise; a disjunction does not select a branch | [Compound facts](#conjunctions-chains-and-disjunctions), [S39](#s39-proof-by-exhaustive-cases) |
| Make an expression meaningful | Put its actual domain/guard in the interface before using it; `N` subtraction and division are not total closure rules | [WD](#well-defined-objects), [P01–P03](#p01-reflexivity-does-not-bypass-well-definedness) |
| Connect equal expressions | Expose the changed value or defining equation before a larger calculation when needed | [P04](#p04-connect-division-and-multiplication-explicitly), [P05](#p05-a-function-equation-may-need-to-be-exposed-before-substitution), [P07](#p07-name-the-value-equality-before-arithmetic) |
| Prove equality of structured values | Element membership, set inclusion, set equality and function equality have different obligations | [F01](#f01-membership-and-nonmembership), [S45](#s45-set-extensionality), [S46](#s46-function-extensionality) |
| Read a failed check | Distinguish parse, WD and proof-search failures; an unknown fact does not prove its negation | [Output](#reading-verifier-output), [P12](#p12-a-search-miss-does-not-disprove-an-inequality) |
#### Separate values, definitions and facts
An arbitrary member is not a chosen numerical value. Naming a mathematical
expression also does not perform mutable assignment. The calculation below
keeps the named expression and its intermediate value visible:
```litex
have arbitrary R
have chosen R = 2
let twice = 2*chosen
twice = 2*chosen = 2*2 = 4
```
`arbitrary=0` is not justified by its declaration. A second `let` with the
same active name is a rebinding error, not an update to a variable. Likewise,
declaring `prop is_above_two(t R): t>2` defines the condition; it does not
establish that an arbitrary real satisfies it. Establish the instance:
```litex
prop is_above_two(t R):
t > 2
have a R = 3
by def $is_above_two(a)
```
The defining function equation and a declared output carrier have separate
roles too. A return carrier makes a value usable at that type; it does not
give every equation one might want about the value. See the
[function-law example](#prove-a-law-of-the-function).
#### Make the goal, hypotheses and block role explicit
**Checked goal/proof form:** the `? forall` header introduces `x` and its
local hypothesis. The body uses that same `x` and executes the proof action.
After success the universal result is available at a concrete argument.
```litex
prop is_positive(t R):
t > 0
claim:
? forall x R:
x > 0
=>:
$is_positive(x)
by def $is_positive(x)
have a R = 3
$is_positive(a)
```
The explicit `by def` command belongs in the proof body. Moving it into
the conclusions of a bare `forall` is a parse error:
```litex
prop is_positive(t R):
t > 0
forall x R:
x > 0
=>:
by def $is_positive(x)
```
A bare universal may state the factual conclusion `$is_positive(x)` directly
when its verification route already works; `claim` is the surface for the
explicit command, not a mandatory wrapper for every true universal.
Without `=>:`, `forall x R: x>0; x!=0` claims both conclusions for every
real and is false. With the arrow, the first is a hypothesis for the second:
```litex
forall x R:
x > 0
=>:
x != 0
```
Claim parameters and local hypotheses do not become global names or facts.
Do not reintroduce an already active `x` with another `forall x`, or use it
after the claim. A statement such as `(1/2)*2=1` proves one numerical instance;
it does not prove `forall x R: (1/2)*x=1`. For a universal proof, work with
the active arbitrary parameter and the exact stated hypotheses.
#### Preserve witness dependencies and distinguish existence from uniqueness
**Checked dependent witness:** in “for every `x`, there is a `y`”, the
witness may depend on the active `x`. Choose it inside that scope.
```litex
claim:
? forall x R:
exist y R st {y = x+1}
witness exist y R st {y = x+1} from x+1
```
A single `have y R = 1` outside the universal is a fixed value and cannot
stand for this varying witness. Keep quantifier order and dependencies intact.
**Checked introduction and elimination:** first supply a satisfying value,
then extract a named value from the verified existence fact.
```litex
witness exist w R st {w^2 = 4} from 2
obtain root from exist w R st {w^2 = 4}
root^2 = 4
```
`obtain` checks its source itself. A separate identical `exist` line before
it is unnecessary when that check already succeeds. It cannot manufacture
an unproved existence fact, such as a real root with `w^2=-1`.
A witness proves the substituted body; it need not repeat that same body in
an indented proof unless an actual intermediate step is needed.
Uniqueness is an additional mathematical obligation. Supplying `2` proves
`exist w R st {w^2=4}` but not `exist!`: `-2` is another solution. The linear
specification has a unique witness:
```litex
witness exist! w R st {w = 2} from 2
```
Finally, `forall x S` does not assert that `S` is nonempty. An empty-domain
universal can be true vacuously, while `have x S` needs nonemptiness. See
[P06](#p06-arbitrary-have-needs-nonemptiness) and the
[empty-domain discussion](#universal-facts).
#### Keep logical directions and branches separate
If `P(x)=>Q(x)` is available, first establish `P(x)` before using its
conclusion. `Q(x)` alone does not give the converse. The following strict
example uses abstract predicate signatures and local mathematical hypotheses;
no instances of either predicate are assumed globally:
```litex
abstract_prop is_first(x)
abstract_prop is_second(x)
forall x R:
$is_first(x)
forall t R:
$is_first(t)
=>:
$is_second(t)
=>:
$is_second(x)
```
Similarly, `P(x) or Q(x)` gives neither selected branch. To prove one common
conclusion, establish it in both cases. Empty branch bodies are sufficient
here because each case plus its supplied implication already closes the goal:
```litex
abstract_prop is_first(x)
abstract_prop is_second(x)
abstract_prop is_result(x)
claim:
? forall x R:
$is_first(x) or $is_second(x)
forall t R:
$is_first(t)
=>:
$is_result(t)
forall t R:
$is_second(t)
=>:
$is_result(t)
=>:
$is_result(x)
by cases:
? $is_result(x)
case $is_first(x):
$is_result(x)
case $is_second(x):
$is_result(x)
```
Use the [fact-shape grammar](#binder-and-fact-shape-guide) when combining
quantifiers and logical operators. Mathematical equivalence does not imply
that arbitrary nested logical source forms are valid grammar.
#### Check the exact object, domain and mathematical claim
The following facts have related meanings but distinct argument roles:
```litex
have A set = {1,2}
1 $in A
{1} $subset A
{1} $in power_set(A)
```
The first membership concerns a number, the inclusion concerns a set, and
the last membership concerns a subset as a member of a power set. Set
equality requires both inclusion directions. Function equality requires
the complete domain and agreement there; `f(0)=g(0)` supplies only one
application equality. For example, `f(t)=t` and `g(t)=t^2` agree at `0` but
differ at `2`. Use [extensionality](#s46-function-extensionality) when that
is the mathematical goal.
Keep carrier and arithmetic conditions attached to operations. For natural
`n`, `n-1` need not be natural because `n` may be zero. The guarded version is:
```litex
forall n N+:
n-1 $in N
```
Closed rational arithmetic is exact, not a floating-point tolerance check:
```litex
1/3 != 0.333333
1/3 + 1/6 = 1/2
```
`eval` computes on its supported executable surface; it is not a replacement
for the symbolic universal statement one intended to prove. Likewise, a few
numerical examples do not replace a universal proof.
#### A short write-check-edit loop
1. Write the exact goal, carrier, hypotheses and witness dependencies.
2. Choose the mathematical action and its S/O/F entry; use an existing native
or library interface before recreating its definition locally.
3. Make the target and declared interface WD before their proof bodies.
A later proof-body fact cannot repair a rejected goal header.
4. Check the first failing stage. Fix syntax, a justified domain obligation,
or the smallest missing mathematical bridge at that point. Preserve the
theorem's meaning; do not add an unproved premise or `trust` to force success.
5. After a proof works, try the shorter route and remove redundant echoes;
retain the mathematical spine and demonstrated bridges. Replay the complete
snippet in a clean strict context and inspect its run/statement results.
An entry saying that a bridge was needed in an audited build is dated evidence,
not a permanent requirement to repeat it in every later version. The same
principle applies to a recorded direct-search miss. Use the current checker
and keep version-specific observations distinct from the mathematical contract.
### The core loop
For an ordinary atomic fact, Litex follows this public progression:
1. Parse the statement and check that every object is well-defined.
2. Reuse an already known fact, including transport through known equalities,
or evaluate a closed expression directly.
3. Read indexed special properties and try finite constructor matching.
4. Try a bounded builtin mathematical rule, then builtin/user strategies.
5. Try a concrete definition or known `forall`, followed by permitted rewrite.
6. On success, store the fact and run builtin inference on the new information.
Atomic truth search uses one shared permission ceiling. Level 0 (`Direct`)
first reads stored facts/identity/alpha paths, then tries closed exact calculation
and deterministic structural membership.
Preview: integer division composes here when both operands have integer
carrier evidence and the exact zero-remainder equality is already known.
Thus `(a/b)^2 $in Z` can use stored `a%b=0` without first publishing
`a/b $in Z`; the enclosing division WD still requires `b!=0`. This route
cites the known equality rather than starting another builtin search, and
does not infer a natural or positive quotient. See the
[zero-remainder composition example](../examples/proof_nodes/atomic/direct_integer_quotient_zero_remainder.lit).
Special properties (level 1) may use level-0 premises; builtin rules (level 2)
may use level 1; strategies (level 3) and definition/forall (level 4) may use
level 2. Rewrite is available at level 4 once per branch. Numeric and atomic
rewrites keep level 4 with rewriting disabled; one-step function-application
unfold substitution caps its equality residual at level 3, so it does not
reopen generic definition/forall search. WD checks inherit the current ceiling.
The function-unfold fallback reads the function head's exact stored equality
to an anonymous function. `have fn ... = body` publishes such an equality;
a local `forall` premise or another checked equality can supply it too. It unfolds
original outermost calls under supported scalar constructors once; call
arguments and inserted bodies are not revisited. Both application-domain
checks remain required. Ordinary rule premises and the residual cannot restart
rewrite. Separate root facts, top-level universal conclusions and chain
segments can each inherit an opportunity; this is not a theorem-wide limit.
One layer can still create a large expression. The
[verifier design agreement and cost observations](../src/execute/README.md#design-agreement)
record the current boundaries and the evidence needed before widening them.
**Preview: addition by a checked zero.** Numeric `a+b=c` can use checked
premises `b=c`, `a=0`, or `a=c`, `b=0`; reversed equality is supported too.
The builtin routes retain both proofs at their existing lower premise ceiling.
After a tuple call passes WD, its literal numeric coordinate can obtain a
carrier from the selected closed value. Thus this needs no projection facts:
```litex
have x R × R
((0, 0)(1) + x(1), x(2) + (0, 0)(2)) = (x(1), x(2))
```
The [plane identity tracer](../examples/proof_nodes/equal/by_builtin_rule/add_zero_from_equalities.lit)
also checks function unfolding and reconstruction. Unknown/nonzero summands,
unequal remaining terms and invalid indices still fail. Detailed JSON records
`AddZeroLeftFromEqualities` / `AddZeroRightFromEqualities` with
`remaining_equal`, `zero_equal`, and `LiteralTupleNumericCoordinate` with its
closed membership calculation. These new routes have no Lean replay yet;
compilation fails closed.
Closed calculation has no access to the environment or recursive proof search.
It covers closed numeric equality, real comparisons and standard-set membership
with exact decimal, rational or complex evidence. It does not substitute known
values for symbols or unfold user functions. For example, `1/3 < 1/2` can close
a level-0 premise; `1/0 = 1/0` still fails WD. Detailed JSON identifies this
route as `by_closed_calculation` and retains normalized values. Unsupported or
overflowing calculations return a search miss, never an assumed proof.
Structural membership checks numeric carriers along strictly smaller expression
subtrees. For example, nested natural addition and a squared real difference
need no intermediate type assertions:
```litex
have n N
((n+1)+1)+1 $in N
have a,b cart(R,R)
0 <= (b(1)-a(1))^2
```
Its leaves cite stored memberships, calculate closed values, or read the fixed
codomain of a builtin whose object WD has already succeeded. Standard-set
inclusion uses a finite table. It does not call SP, ordinary proof search,
definition unfolding, or rewrite. User-function and tuple-projection types
remain SP capabilities unless their memberships are already stored. Division,
negative powers, finite cardinalities and projections retain all WD conditions;
`m-n` is not automatically natural, nor is integer division automatically integer.
Detailed output retains the constructor tree under `by_structural_membership`.
This is type propagation; symbolic equalities and order proofs keep their own rules.
When an atomic predicate's domain recheck fails, a standard numeric membership
may reuse the exact argument's object WD already checked in that same atomic
proof. The structural membership certificate names that argument index; it
does not publish a new WD cache entry or reopen a wider search ceiling. All
argument guards still run first. Detailed output calls this domain route
`by_checked_argument_membership`; it supplies formation evidence, not the
truth of the comparison. See the [finite-difference cardinality tracer](../examples/wd/checked_argument_numeric_domain.lit).
Two fixed scalar rules (preview) consume already available guards. For a real
`x`, `x != 0` permits `|x| > 0`; zero and non-real arguments retain their
normal rejection boundaries. For real nonnegative `x,y`, `x^2 <= y^2` permits
`x <= y`, and the reverse-written comparison works in the opposite direction.
Both nonnegative guards remain required by this rule; a weak squared comparison
does not establish a strict conclusion. These leaves use the inherited
builtin-premise ceiling rather than generating case splits or a square-root
proof. See the [absolute-value positivity tracer](../examples/proof_nodes/atomic/by_builtin_rule/abs_positive_from_nonzero.lit)
and [square-order tracer](../examples/proof_nodes/atomic/by_builtin_rule/nonnegative_square_order_reflection.lit).
Detailed output identifies `AbsPositiveFromNonzero` with `argument_nonzero`,
and `NonnegativeSquareOrderReflection` with `left_nonnegative`,
`right_nonnegative` and `squared_order`; each field retains its checked source
proof. These new routes currently have no Litex-to-Lean adapter and compilation
fails explicitly rather than emitting an assumed proof.
```litex
forall x R:
x != 0
=>:
|x| > 0
```
```litex
forall x,y R:
x >= 0
y >= 0
x^2 <= y^2
=>:
x <= y
```
This is goal-directed verification, not unrestricted theorem search. A builtin
rule may ask for its documented premises, but it does not silently build an
arbitrary chain of other builtin rules. When a mathematically valid jump is
a soft miss, expose one or two intermediate facts in the source; those facts make
the intended route readable to both the checker and the reader.
```litex
abstract_prop P(x)
forall x, y R:
$P(x)
x = y
=>:
$P(y)
```
Here the conclusion matches the known local fact `$P(x)` after equality
matching. No theorem name is required.
Matching is not arbitrary search:
```text
abstract_prop P(x, y)
trust $P(1, 1)
$P(1, 2)
```
The last fact soft-fails; no known equality makes the second arguments match.
### Goal-shape routing
Use the [Learner Cheatsheet's proof-action table](Litex_Learner_Cheatsheet.md#6-small-proofs-write-the-route-only-when-needed)
before expanding a proof manually. It owns the compact goal-to-action index;
this Manual owns the exact syntax, generated obligations, directional
boundaries, and executable examples for each proof surface.
### Known facts, universal facts, and theorem calls
An accepted fact becomes available to later statements. A `forall` fact can be
instantiated when its parameter domains and assumptions hold. A `thm` adds the
same universal interface and also permits explicit citation.
```litex
forall x R:
x > 0
=>:
x != 0
have a R = 2
a > 0
a != 0
```
Litex can also package an instantiated implication into its classical
disjunction. If `P(t) => Q(t)` is available, then
`not P(t) or Q(t)` verifies by checking `Q(t)` in the temporary `P(t)` case.
This rule does not reverse the implication.
Do not add a theorem call merely to repeat the same fact after it has already
matched:
```text
release thm positive_is_nonzero(a)
a != 0
```
The second line is usually redundant if `release thm` already stored its
conclusions. Keep an explicit restatement only when a verifier run shows that a
bridge fact is needed.
### Indexed facts and equality lookup
Before builtin or strategy search, non-equality atomic goals use the shared
`by_known` entry: first read stored atomic facts using identity or stored
equality paths only; on a miss, try parameter transformations and then
`known_special_property`. A direct stored hit does not launch argument proof search.
For a well-defined function application, an exact-object definition-time
signature can establish membership in its substituted return set or in
`fn_range(f)`, without proving a new premise, entering a builtin rule or a strategy.
Normal output identifies this route as `known_special_property`; Detailed
output carries the definition citation and stored equality matches. Fixed
builtin premises can retain the same evidence as nested proofs.
Equality first checks IR/alpha identity and already stored equality paths,
then its separate `ByKnownSpecialProperty` step, then builtin rules. This
order also applies inside strategy search. Re-reading a released equality
cites its existing path before attempting rules with new premises; it still
requires WD. See the [release-and-read tracer](../examples/proof_nodes/equal/by_equivalence_class/stored_equality_before_builtin.lit).
The later equality-class stage also reuses one stored equality when both
endpoints differ only by structurally alpha-equivalent bound names, including
anonymous functions inside sums. It cites the original equality plus both
endpoint identities; free functions, bodies, carriers and bounds must still
match. This is stored-fact reuse, with no new mathematical premise or graph
mutation. See the [aggregate replay tracer](../examples/proof_nodes/equal/by_equivalence_class/stored_aggregate_alpha.lit).
Known Cartesian membership supplies the complete finite domain and ordered
coordinate carriers; a stored tuple equality supplies coordinate beta evidence.
For example, `have p cart(R,R) = (a,b)` permits `p(1) = a` after application WD.
Function-valued coordinates retain their own checked domains and guards on
later calls. Stored equalities and selected definitions retain their source
FactIds; a common return upper bound alone does not establish callability.
Coordinate bounds remain mandatory. See the
[coordinate tracer](../examples/infer/atomic/cart_exact_function_coordinates.lit)
and [nested-call tracer](../examples/proof_nodes/equal/by_object_definition/by_fn_application/finite_function_coordinate_call.lit).
Stored `forall` equality conclusions use a nested constructor index for both
endpoints, with parameter holes, function positions and separate application
groups. Fixed objects retain their actual identities and may match through
existing equality paths. Binder objects use conservative index branches and
still require the full alpha/capture checks. An index hit only selects a
candidate: instantiated parameter carriers and domain facts remain mandatory.
During argument matching, a subtree containing none of the selected forall's
parameters first checks equality of the complete value at Direct permission.
On a miss, supported matching constructors descend to Direct-only leaves;
this does not restart forall, definition or rewrite search. A function
parameter can bind a curried function-valued prefix. For example:
```litex
forall f, g fn(x R) R, a R:
f(0) = g(0)
forall y R:
y + f(0) = y
=>:
a + g(0) = a
```
Here `f(0)` is fixed relative to the inner parameter `y`; its existing
equality with `g(0)` supplies the argument transport. This does not assert
that the functions `f` and `g` are equal. The
[rigid-application tracer](../examples/proof_nodes/equal/by_known_forall/rigid_application_alias.lit)
has executable missing-equality and wrong-carrier controls in its focused tests.
### Reading verifier output
Default Normal JSON identifies each statement, its success or failure,
`proof_method`, `stores`, and `infers`. Builtin explanations use `rule_name`
and `message`. Compound proofs can have summary explanations; Normal omits
well-definedness subtrees and does not expose the full recursive result IR.
Chinese output localizes both field names and explanations. The Rust JSON API
also has Compact and Detailed projections, but the CLI currently exposes only
Normal. See the [output contract](cli.md#json-output-contract).
When a statement soft-fails, read the failed node rather than adding broad
automation immediately:
| Unknown shape | Useful next question |
|---|---|
| Atomic | Is an equality, membership, sign, domain condition, or matching lemma missing? For a nested function application, `detail` may name the unmatched application, the nearest known prefix equality, and the remaining unapplied argument count. |
| Conjunction | Which component failed? |
| Chain | Which adjacent step failed? |
| Universal | Which local conclusion failed under the displayed assumptions? |
| Universal equivalence | Which direction and clause failed? |
Do not infer trust from a natural-looking success message. Inspect citations,
trusted imports, `trust` summaries, and the builtin or inference rule involved.
---
## Entry contract and coverage framework
| Entry type | What the reader can find in one place |
|---|---|
| Statement | Mathematical action; prerequisites; actual execution; stored/exported results; scope/boundary; checked example; source; related entries |
| Object | Meaning and spelling; exact WD/domain; common native properties; how to establish/use them; boundary; multiple uses; source; related entries |
| Atomic fact | Meaning and argument orientation; positive/negative domains; definitions and relationships; verification versus inference; examples and boundaries |
The S, O and F numbers are stable lookup identifiers. Related public spellings
share an entry when their mathematical contract is identical. Semantically
different modes have separate entries: arbitrary `have`, value `have`, and
specification `have` are not one undifferentiated command. Unique witnesses
have a separate statement entry even though they share an AST family.
### Classification map
| Dictionary | Groups to browse |
|---|---|
| Statements | Fact checking; object introduction; function construction; vocabulary and struct/template definitions; named results and strategies; assumptions; releases; local proofs; witnesses; proof methods; registrations; evaluation |
| Objects | Names and calls; constants; standard number sets; scalar/integer/trigonometric/logarithmic/complex operations; set operations and formers; products and sequences; function spaces/images; iteration; finite statistics; struct fields; template instances |
| Atomic facts | Equality; real order; sethood/nonemptiness/finiteness; membership; inclusion; arithmetic predicates; mapping properties; choice specifications |
| Mathematical routes | Select a value or witness; define a callable object; assert a relation; instantiate a declaration family; prove equality or a local law |
Package manifests and CLI execution are described in [cli.md](cli.md).
Imported standard-library interfaces extend this native inventory; they do
not become native objects or builtin predicates merely because an example
imports them. A source-defined `$P(...)` belongs to the concrete/abstract
predicate entries, rather than the builtin-family count.
Removed forms have a separate [compatibility section](#removed-and-renamed-public-forms). C entries describe certificate predicates generated and consumed by native theorem interfaces, rather than ordinary user predicate definitions. Reserved theorem calls have a separate index.
Property lists are source-backed native families with their actual guards;
the checked examples show concrete supported uses. They do not promise that
every mathematically equivalent spelling or larger combination is discovered
automatically. Prefer the listed explicit interface when it carries quantified
or compound requirements.
### Binder and fact-shape guide
| Form | Meaning and important boundary | Primary route |
|---|---|---|
| `forall x S: ...` | A proposition for every member; its binder stays local and no nonemptiness assertion is implied | Bare fact, claim or theorem |
| `forall A set: ...` | A meta-level set parameter, not membership in a writable universal set | Typed binder |
| `finite_set` / `nonempty_set` binder category | Supplies the named predicate obligations, rather than a host carrier object | Typed binder |
| Premises followed by `=>:` | Local mathematical hypotheses used for the conclusions | Guarded universal/claim |
| `exist ... st {facts}` | At least one complete witness tuple | Witness; obtain for elimination |
| `exist! ... st {facts}` | Existence plus componentwise uniqueness of complete candidates | Unique witness and specification function |
| Flat `and` | All supported atomic components | Check/store components |
| `or` | At least one supported branch; neither branch is chosen merely by storing it | Prove a branch or use exhaustive cases |
| Equality/order chain | The adjacent steps and their supported transitive consequences | Explicit intermediate expressions |
| `forall ... <=>:` | Both directions under the common domain; a guard on one side does not guard the other | Two directional obligations |
| `not exist` / `not forall` | Quantified negation with the supported De Morgan/counterexample shape | Explicit contradiction/witness routes |
Fact nesting is bounded: existential and builder bodies are quantifier-free;
a direct quantified condition can be named by a real concrete `prop`.
Universal conclusions cannot contain an extra nested universal; use a single
compatible parameter header when that preserves the mathematical dependency.
Universal hypotheses, as in the Zorn interface, have their supported scoped
role. A bare universal body contains facts; proof commands belong in a proof
statement's body. The examples in the dictionaries show the active-binder form.
## Two lookup indexes
### I know the syntax
| Public form | Mathematical use | Entry |
|---|---|---|
| `have fn f(...) T = body` | Define a callable value by an expression | [S01](#s01-expression-defined-functions) |
| `a / b` | Divide scalars by a nonzero scalar | [O01](#o01-division) |
| `x $in S`, `not x $in S` | Assert membership or nonmembership | [F01](#f01-membership-and-nonmembership) |
| `claim` with an equality chain | Prove a goal through explicit algebraic steps | [P04](#p04-connect-division-and-multiplication-explicitly) |
| `witness $is_nonempty_set(S) from value` | Certify a set contains a concrete object | [P06](#p06-arbitrary-have-needs-nonemptiness) |
### I know the mathematics
| Mathematical intention | Route through the dictionary |
|---|---|
| Choose basic declaration, proof and scope actions for a mathematical sentence | [Basic writing decisions](#basic-decisions-before-writing-a-proof) |
| Construct a witness that depends on a universally quantified input | [Witness dependencies](#preserve-witness-dependencies-and-distinguish-existence-from-uniqueness) → [S35](#s35-existential-witnesses) |
| Use an implication or a disjunction without reversing or selecting it | [Logical directions](#keep-logical-directions-and-branches-separate) → [S39](#s39-proof-by-exhaustive-cases) |
| Define the reciprocal on nonzero reals | [R01](#r01-define-and-use-a-reciprocal-function) → [S01](#s01-expression-defined-functions) → [O01](#o01-division) |
| Make `1 / x` meaningful | [O01 domain](#domain-and-well-definedness) → [P01](#p01-reflexivity-does-not-bypass-well-definedness) |
| Learn what follows from a carrier declaration | [F01 relationships](#relationships-with-other-facts) |
| Turn `a / b = c` into `a = c * b` | [P04](#p04-connect-division-and-multiplication-explicitly) |
| Use a function equation inside a product | [R01 proof](#prove-a-law-of-the-function) → [P05](#p05-a-function-equation-may-need-to-be-exposed-before-substitution) |
| Select an arbitrary member of a defined set | [P06](#p06-arbitrary-have-needs-nonemptiness) |
| Choose between naming a value and asserting a property | [R02](#r02-choose-the-language-form-by-mathematical-role), [R04](#r04-a-relation-and-its-selected-value-have-different-roles) |
| Build a function over each carrier set | [R03](#r03-a-declaration-family-over-an-arbitrary-carrier) |
| Define a piecewise function and prove a law | [R05](#r05-a-piecewise-definition-and-a-universal-law) |
| Prove `a^2+b^2 >= 2*a*b` by completing a square | [R06](#r06-complete-a-square-and-translate-the-bound) → [P12](#p12-a-search-miss-does-not-disprove-an-inequality) |
| Move a term across an inequality or compose bounds | [R07](#r07-translate-add-subtract-and-compose-bounds) → [F05](#f05-weak-less-than) |
| Multiply or divide an inequality | [R08](#r08-scale-an-inequality-with-the-correct-sign) → [P13](#p13-preserve-sign-strictness-and-expression-shape) |
| Prove a polynomial bound using sums of squares | [R09](#r09-build-a-sum-of-squares-proof) |
| Use an absolute-value or triangle bound | [R10](#r10-expose-absolute-value-bounds) → [P13](#p13-preserve-sign-strictness-and-expression-shape) |
| Determine a product's sign, detect zero factors, or cancel a factor | [R11](#r11-product-signs-zero-factors-and-cancellation) |
| Multiply bounds for two varying nonnegative factors | [R11 product bounds](#bound-a-product-with-two-varying-factors) |
| Compare squares, recover absolute values, or take square roots | [R12](#r12-squares-absolute-values-and-equality-cases) |
| Bound a squared sum, use a weighted estimate or two-dimensional Cauchy–Schwarz | [R13](#r13-reusable-quadratic-certificates) |
| Find when a square-based bound is an equality | [R12 zero cases](#zero-and-strictly-positive-square-sums), [R13 equality cases](#recover-the-equality-case) |
| Clear positive denominators or bound a general positive quadratic | [R14](#r14-clear-denominators-and-bound-a-positive-quadratic) |
| Use even powers, odd-power signs, or power zero cases | [R15 parity](#power-signs-parity-and-zero-cases) → [O27](#o27-powers) |
| Decide which direction a power inequality takes | [R15](#r15-power-signs-and-two-kinds-of-monotonicity) |
| Compare powers with different integer exponents | [R15 exponent order](#order-arbitrary-integer-exponents) |
| Find a familiar scalar inequality and its checked proof | [R16](#r16-common-real-inequalities-at-a-glance) |
| Construct a uniquely specified callable value | [S13](#s13-functions-from-unique-existence), [S36](#s36-unique-existential-witnesses) |
| Prove an image value has a source | [S09](#s09-extract-function-preimages), [O81](#o81-function-images) |
| Prove a set or function equality | [S45](#s45-set-extensionality), [S46](#s46-function-extensionality) |
| Supply pointwise facts to a native constructor interface | [Reserved interfaces](#reserved-builtin-theorem-interfaces) |
| Read a nested struct law | [S27](#s27-open-one-struct-definition-layer), [O92](#o92-definition-owned-field-access) |
| Establish primality by its explicit definition | [P09](#p09-an-explicit-definition-proof-has-its-own-obligations) |
| Interpret a retired source spelling | [Compatibility](#removed-and-renamed-public-forms) |
## Statement dictionary
| ID | Public form | Mathematical role | Example status |
|---|---|---|---|
| [S01](#s01-expression-defined-functions) | `have fn ... = body` | Expression-defined functions | checked |
| [S02](#s02-bare-factual-statements) | `fact` | Bare factual statements | checked |
| [S03](#s03-equality-aliases) | `let name = expression` | Equality aliases | checked |
| [S04](#s04-arbitrary-members) | `have x S` | Arbitrary members | checked |
| [S05](#s05-typed-values-given-by-equality) | `have x S = value` | Typed values given by equality | checked |
| [S06](#s06-members-satisfying-a-proved-specification) | `have x S: facts` | Members satisfying a proved specification | checked |
| [S07](#s07-extract-existential-witnesses) | `obtain names from exist ...` | Extract existential witnesses | checked |
| [S08](#s08-extract-witnesses-through-a-predicate) | `obtain names from $P(args)` | Extract witnesses through a predicate | checked |
| [S09](#s09-extract-function-preimages) | `have by fn_preimage: names from value $in fn_range(f)` | Extract function preimages | checked |
| [S10](#s10-replacement-images) | `have by replacement_axiom: Img from prop P, set A` | Replacement images | checked |
| [S11](#s11-piecewise-functions) | `have fn ... by cases:` | Piecewise functions | checked |
| [S12](#s12-functions-by-decreasing-integer-measure) | `have fn ... by induc n from lower:` | Functions by decreasing integer measure | checked |
| [S13](#s13-functions-from-unique-existence) | `have fn f by exist!:` | Functions from unique existence | checked |
| [S14](#s14-concrete-predicates) | `prop P(parameters): facts` | Concrete predicates | checked |
| [S15](#s15-abstract-predicate-signatures) | `abstract_prop P(parameters)` | Abstract predicate signatures | checked |
| [S16](#s16-structured-carriers) | `struct Name:` | Structured carriers | checked |
| [S17](#s17-parameterized-declaration-families) | `template:` | Parameterized declaration families | checked |
| [S18](#s18-named-theorems) | `thm name: ? goal` | Named theorems | checked |
| [S19](#s19-named-axioms) | `axiom name: ? goal` | Named axioms | assumption demonstration |
| [S20](#s20-reusable-proof-strategies) | `strategy name: ? forall ...` | Reusable proof strategies | checked |
| [S21](#s21-executable-functions-by-cases) | `algo ... by cases:` | Executable functions by cases | checked |
| [S22](#s22-executable-functions-by-induction) | `algo ... by induc measure from lower:` | Executable functions by induction | checked |
| [S23](#s23-explicitly-trusted-facts) | `trust: facts` | Explicitly trusted facts | assumption demonstration |
| [S24](#s24-trusted-witness-introduction) | `trust have names carriers: facts` | Trusted witness introduction | assumption demonstration |
| [S25](#s25-publish-theorem-conclusions) | `release thm name(arguments)` | Publish theorem conclusions | checked |
| [S26](#s26-select-one-theorem-consequence) | `by thm name(arguments) => atomic_fact` | Select one theorem consequence | checked |
| [S27](#s27-open-one-struct-definition-layer) | `release struct def expression` | Open one struct definition layer | checked |
| [S28](#s28-replay-an-object-definition) | `release obj def identifier` | Replay an object definition | checked |
| [S29](#s29-expand-finite-integer-membership) | `expand: value $in range(...)` | Expand finite integer membership | checked |
| [S30](#s30-regularity-release) | `release regularity_axiom(S)` | Regularity release | checked |
| [S31](#s31-choice-release) | `release axiom_of_choice: set F:` | Choice release | checked |
| [S32](#s32-zorn-release) | `release zorn_lemma: set S, prop P, prop U, prop M:` | Zorn release | checked |
| [S33](#s33-local-claims) | `claim: ? goal` | Local claims | checked |
| [S34](#s34-local-sketches) | `sketch: statements` | Local sketches | checked |
| [S35](#s35-existential-witnesses) | `witness exist ... from values` | Existential witnesses | checked |
| [S36](#s36-unique-existential-witnesses) | `witness exist! ... from values` | Unique existential witnesses | checked |
| [S37](#s37-witnesses-for-named-existential-properties) | `witness $P(args) from values` | Witnesses for named existential properties | checked |
| [S38](#s38-nonempty-set-witnesses) | `witness $is_nonempty_set(S) from value` | Nonempty-set witnesses | checked |
| [S39](#s39-proof-by-exhaustive-cases) | `by cases:` | Proof by exhaustive cases | checked |
| [S40](#s40-proof-by-contradiction) | `by contra:` | Proof by contradiction | checked |
| [S41](#s41-finite-set-enumeration) | `by enumerate finite_set:` | Finite-set enumeration | checked |
| [S42](#s42-ordinary-induction) | `by induc n from lower:` | Ordinary induction | checked |
| [S43](#s43-strong-induction) | `by strong_induc n from lower:` | Strong induction | checked |
| [S44](#s44-finite-range-iteration) | `by for:` | Finite range iteration | checked |
| [S45](#s45-set-extensionality) | `by extension A = B` | Set extensionality | checked |
| [S46](#s46-function-extensionality) | `by fn_extension f = g` | Function extensionality | checked |
| [S47](#s47-explicit-definition-folding) | `by def positive_fact` | Explicit definition folding | checked |
| [S48](#s48-register-reflexive-predicate-laws) | `register reflexive: ? forall ...` | Register reflexive predicate laws | checked |
| [S49](#s49-register-symmetric-predicate-laws) | `register symmetric: ? forall ...` | Register symmetric predicate laws | checked |
| [S50](#s50-register-transitive-predicate-laws) | `register transitive: ? forall ...` | Register transitive predicate laws | checked |
| [S51](#s51-exact-evaluation) | `eval expression` | Exact evaluation | checked |
| [S52](#s52-release-a-tuple-definition) | `release tuple def object` | Publish an exact finite-sequence contract and coordinates | checked |
### S01. Expression-defined functions
**Public form:** `have fn f(parameters: optional guards) T = body`.
This entry covers the expression-defined form. See S11 for cases, S12 for
induction, and S13 for the unique-existence construction.
#### Mathematical function
Introduce a mathematical function, its callable domain, and its defining
expression. The declaration also checks that the body lies in the written
return set for admissible inputs. It is a definition of a value that later
lines can call; a predicate about a value has a different role.
```litex
have fn successor(n N) N = n + 1
successor(2) = 3
successor $in fn(n N) N
```
The first line defines `successor`; the second uses the defining expression;
the third checks its function-space membership. `n` is a local function
parameter. It does not become a top-level object.
#### Parameters, domain, and return set
The parameter carrier says which values may be supplied. Guards further
restrict admissible inputs. The final carrier states where every output lies.
For division, the nonzero condition belongs to the callable domain:
```litex
have fn reciprocal(x R: x != 0) R = 1 / x
reciprocal(2) = 1 / 2
reciprocal(-2) = -1 / 2
```
This is a reciprocal on nonzero real inputs. `R` in the result position is a
return bound; it does not assert that the function can be called at every real.
The guard must also hold at each application.
Multiple parameters follow the same principle:
```litex
have fn divide(a, b R: b != 0) R = a / b
divide(6, 2) = 3
```
In current function signatures, the parameter carrier expressions and return
carrier cannot reference the signature's own parameter names. Guards and the
expression body can use those names. The examples here use fixed carriers.
#### Execution flow
For the ordinary nonempty input domains in these examples, the pipeline is:
1. Construct the anonymous function corresponding to the declaration.
2. Check parameter carrier objects, introduce local parameter names and their
membership facts, and check the guards as local assumptions.
3. Check the return carrier and the expression body. In the reciprocal,
checking `1 / x` consumes the local `x != 0` guard.
4. Verify the expression's membership in the return set. For example,
`1 / x $in R` follows from real arithmetic closure after division WD.
5. Check the function-space object for the signature.
6. Occupy the new name and store its function-space membership and equality
with the anonymous defining function, with ordinary inference.
7. Commit the successful statement's local transaction to the parent context.
The implementation also has an independently checked empty-complete-domain
case for the pointwise return obligation. Header, return-carrier, and body WD
still apply. The samples here do not exercise that case.
#### What success leaves available
For the guarded reciprocal, the stored mathematical interfaces are:
- Function-space membership: `reciprocal $in fn(x R: x != 0) R`.
- Equality with the anonymous function: `reciprocal = fn(x R: x != 0) R {1 / x}`.
- Callable applications satisfying the parameter and guard checks.
- Defining application equalities, as illustrated by `reciprocal(2) = 1 / 2`.
The defining equation can prove an application equality. It does not promise
that every larger expression is automatically rewritten everywhere; see
[P05](#p05-a-function-equation-may-need-to-be-exposed-before-substitution).
In the verified output, calls such as `reciprocal(2) = 1 / 2` use
`proof_method.type: object_definition`. Function-space membership is stored
rather than left as a conjecture.
#### Scope and failure
The function name becomes available in the surrounding scope. Parameters and
local WD assumptions stay inside their binder scope. The statement executes
in a temporary environment; failed execution does not merge that environment.
Writing a return set does not establish the return obligation.
**Expected rejection — phase `have_fn_equal`; the pointwise return bound fails:**
```litex
have fn wrong(x R) N = x
```
An arbitrary real is not necessarily natural. The rejected declaration has
not supplied a definition of a function from all reals to naturals. Choose the
actual mathematical domain and codomain rather than a convenient output label.
For the intended identity on reals, the return carrier is `R`:
```litex
have fn identity(x R) R = x
identity(1 / 2) = 1 / 2
```
**Evidence:** S01–S04 and D07–D08 in the verification record.
**Source:** [function statement executor](../src/execute/execute_have_fn_equal_stmt.rs),
[anonymous-function WD](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/binder.rs),
[statement transaction](../src/execute/exec_stmt.rs).
### S02. Bare factual statements
**Public form:** `fact`.
**Mathematical function.** Ask the checker to establish a proposition from the current mathematical context.
**Before execution.** The fact and every expression it contains must be well-defined; quantified facts introduce their own scoped binders and premises.
**Execution and result.** Check WD, then the fact-shaped verification route. On success store the fact and its applicable ordinary inferred consequences. A search miss commits no successful fact.
**Nearest boundary.** A failed assertion is not a proof of its negation. Proof commands belong in proof bodies, not in a bare universal conclusion list.
**Checked example.**
```litex
have x R = 2
x + 1 = 3
forall t R:
t + 0 = t
```
**Source:** [implementation](../src/execute/execute_fact_stmt/exec_fact_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership).
### S03. Equality aliases
**Public form:** `let name = expression`.
**Mathematical function.** Give an already meaningful value a fresh local name, including a callable value.
**Before execution.** The right-hand object must be WD and the name must be fresh in its scope.
**Execution and result.** Check the expression, occupy the name, and store the defining equality with inference. No carrier is explicitly declared by the syntax; applicable membership can be checked from the value.
**Nearest boundary.** An alias is not an additional hypothesis that its value satisfies an arbitrary property.
**Checked example.**
```litex
let a = 2
a + 1 = 3
let identity = fn(x R) R {x}
identity(4) = 4
```
**Source:** [implementation](../src/execute/execute_let_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Naming repeated mathematical roles
Litex checks the right side before committing the new name, then records the
exact defining equality `x = value`. The definition itself does not require or
create a defined type or membership fact. It accepts exactly one fresh name
and one value: `let x = x` fails when there was no earlier `x`, and multiple
bindings, destructuring, recursive definitions, and template-body `let` forms
are not part of this preview. The word `let` is reserved and cannot be reused
as an identifier.
A template defines the reusable family; a local name can freeze the fixed
parameter bundle used throughout one proof. This prevents accidental variation
without adding an opaque definition or a wrapper theorem. A `let` alias does
not attach a definition-owned struct carrier to its result. When field
projection is needed, use `have value &Struct = expression` with the exact
carrier; [O92](#o92-definition-owned-field-access) explains the field-view boundary.
Use a local name when a nontrivial object recurs and the proof treats it as one
mathematical atom. Prefer a role-based name such as `event_union`,
`probability_terms`, or `negative_x` over a name that only reports its source
syntax. Use `let name = value` for a pure abbreviation whose carrier is not a
new proof fact; use `have name S = value` when later steps consume `name $in S`
or the defined carrier `S`. Keep a public theorem statement in its canonical
mathematical form and introduce the shorter name inside the proof body.
Do not apply this by character count alone. A one-use transparent calculation
is usually clearer when expanded, while a long proposition or existential
package needs a real `prop` rather than an object alias. If the same parameter
bundle recurs across independent proofs, improve the reusable predicate,
`struct`, template, or function interface instead of adding the same local
alias everywhere. After choosing a local name, use it as the proof's canonical
spelling; if that would require a stack of equality-transport adapters under
larger constructors, name the outer mathematical object instead.
### S04. Arbitrary members
**Public form:** `have x S`.
**Mathematical function.** Introduce an arbitrary member of a proved nonempty carrier.
**Before execution.** The carrier must be valid and nonempty; dependent parameter types must be available in declaration order.
**Execution and result.** Check the carrier/nonempty obligations, introduce the names, store their membership or parameter-type facts, and run ordinary inference. Direct struct-typed symbol bindings open one outer struct layer.
**Nearest boundary.** The declaration does not choose a specific numerical value. Nonempty selection is different from universal binding, which does not require a nonempty domain.
**Checked example.**
```litex
have n N
0 <= n
have x R*
x != 0
1 / x $in R
```
**Source:** [implementation](../src/execute/execute_have_obj_in_nonempty_set_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S05. Typed values given by equality
**Public form:** `have x S = value`.
**Mathematical function.** Name a specific mathematical value while checking its carrier.
**Before execution.** The value must be WD and belong to the declared carrier; the fresh name cannot replace a failed membership proof.
**Execution and result.** Check the type/value requirements, occupy the name, then store membership and the defining equality, with ordinary inference.
**Nearest boundary.** An integer output carrier cannot be justified merely by writing Z next to a noninteger value.
**Checked example.**
```litex
have x R = 1 / 2
x $in R
x + 1 / 2 = 1
```
**Source:** [implementation](../src/execute/execute_have_obj_equal_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Carrier mismatch diagnostics
For `have x S = value`, Litex checks `value $in S` before committing `x`. A
carrier-mismatch error names the required carrier,
the narrowest standard numeric carrier currently provable for `value` when one
is available, and confirms that the binding was not stored. For example,
`q * x % p` is definition-time `Z` data even when `p`, `q`, and `x` are
positive naturals; defining it directly as `N` is rejected rather than
silently narrowed.
### S06. Members satisfying a proved specification
**Public form:** `have x S: facts`.
**Mathematical function.** Introduce witnesses satisfying a mathematical specification.
**Before execution.** The synthesized existential with exactly these carrier and body facts must verify; construct or prove it beforehand when the ordinary existential route does not close.
**Execution and result.** Build the existential goal, verify it, introduce fresh witnesses, and store their carrier and body facts. This checks existence; it does not simply assume the written body.
**Nearest boundary.** Use trust have only when an explicitly assumed witness is intended; ordinary have cannot skip existence.
**Checked example.**
```litex
witness exist x R st {x = 2} from 2
have a R:
a = 2
a + 1 = 3
```
**Source:** [implementation](../src/execute/execute_have_obj_by_exist_facts_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S07. Extract existential witnesses
**Public form:** `obtain names from exist ...`.
**Mathematical function.** Eliminate an established existential by naming its witnesses.
**Before execution.** The source existential must verify, witness count must match, and carriers may depend on earlier parameters. The exist! form additionally carries uniqueness.
**Execution and result.** Verify the source, instantiate its dependent types and quantifier-free body with fresh names, and store the resulting facts. The values are opaque witnesses, not guessed concrete numbers.
**Nearest boundary.** The existential is not itself a value; obtain gives names for use in later expressions. A local claim does not export its witness names.
**Checked example.**
```litex
witness exist! z R st {z = 1} from 1
obtain uniq from exist! z R st {z = 1}
uniq = 1
```
**Source:** [implementation](../src/execute/execute_obtain_obj_from_exist_fact_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S35 Existential witnesses](#s35-existential-witnesses), [S36 Unique existential witnesses](#s36-unique-existential-witnesses).
#### Definition elimination boundaries
The `obtain ... from $P(args)` shorthand is a checked definition-elimination
step. The source
`$has_copy(2)` must itself verify, and the concrete prop definition must have
exactly one clause whose outer form is positive `exist` or `exist!`. Litex
substitutes the call arguments into that clause and then uses the ordinary
existential eliminator. `abstract_prop`, negated prop facts, `not exist`,
ordinary nonexistential definitions, and multi-clause definitions are rejected.
The witness must satisfy the displayed body:
```text
witness exist x R st {x^2 = 4} from 1:
1 $in R
```
This proof soft-fails: the witness membership is not enough to establish
`1^2 = 4`.
### S08. Extract witnesses through a predicate
**Public form:** `obtain names from $P(args)`.
**Mathematical function.** Use a named existential property as the witness interface.
**Before execution.** The predicate instance must verify and its concrete definition must have the supported single positive existential clause. An abstract signature supplies no clause.
**Execution and result.** Resolve and instantiate the definition, project its existential, then perform the usual witness elimination and inference.
**Nearest boundary.** Extra definition clauses and other quantified shapes are not silently discarded. Use an explicit existential interface when the named form does not match.
**Checked example.**
```litex
prop has_copy(a R):
exist x R st {x = a}
$has_copy(2)
obtain copy from $has_copy(2)
copy = 2
copy $in R
```
**Source:** [implementation](../src/execute/execute_obtain_obj_from_atomic_fact_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S35 Existential witnesses](#s35-existential-witnesses), [S36 Unique existential witnesses](#s36-unique-existential-witnesses), [S07 Extract existential witnesses](#s07-extract-existential-witnesses).
### S09. Extract function preimages
**Public form:** `have by fn_preimage: names from value $in fn_range(f)`.
**Mathematical function.** Name input witnesses for an established image membership.
**Before execution.** The known image-membership source and callable signature must match; replacement images have their corresponding relation interface.
**Execution and result.** Verify the source membership, recover input domains, introduce opaque input witnesses, and store their types and application/relation equations.
**Nearest boundary.** Keep the source image constructor visible; an arbitrary equal set alias does not necessarily fit this structural statement interface.
**Checked example.**
```litex
have fn shift(x R) R = x + 1
shift(2) $in fn_range(shift)
have by fn_preimage: source from shift(2) $in fn_range(shift)
source $in R
shift(2) = shift(source)
```
**Source:** [implementation](../src/execute/execute_have_by_fn_preimage_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Preimage facts retained by elimination
The statement does not only bind names. For `fn_range` it also stores the
parameter memberships and any extra domain facts of `f` at those names, plus
the application equality (e.g. `z = f(x, y)`), so a later call `f(x, y)` is
well-defined. For `replacement` it stores `x $in A` and `$P(x, y)`.
### S10. Replacement images
**Public form:** `have by replacement_axiom: Img from prop P, set A`.
**Mathematical function.** Construct a named image set by a functional relation, using Replacement.
**Before execution.** The source is a set, the predicate has the required binary relation shape, and the uniqueness condition on each source input is proved.
**Execution and result.** Check the relation/source/uniqueness contract and introduce a named replacement image with its definition-owned membership/preimage interface.
**Nearest boundary.** This is a foundational construction, not an anonymous replacement_image expression or permission to choose several unrelated outputs.
**Checked example.**
```litex
prop image_rel(x, y set):
y = x
forall x {1, 2}, y, y2 set:
$image_rel(x, y)
$image_rel(x, y2)
=>:
y = y2
have by replacement_axiom: Img from prop image_rel, set {1, 2}
$is_set(Img)
release obj def Img
```
**Source:** [implementation](../src/execute/execute_have_by_replacement_axiom_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Why replacement is a tagged statement
An arbitrary binary relation is not enough: without the exact uniqueness
universal over `A`, `have by replacement_axiom: …` soft-fails on its
functionality obligation before any membership goal is considered.
> **Preview:** this statement is the surface for the **Axiom of
> Replacement**: after binary `prop`/`abstract_prop` `P` is known to be
> functional on source set `A`, introduce a named image set `Img` and store
> `$is_set(Img)` plus introduction/elimination foralls.
>
> It is intentionally **not** an anonymous Obj such as `replacement(P, A)`.
> An Obj written with parentheses would have to take the **prop name** as a
> parenthesized argument, but in Litex parentheses normally carry only **objs**
> (calls, set formers, …). Passing a prop name that way would look odd and
> blur the prop/obj boundary. The tagged form
> `have by replacement_axiom: Img from prop P, set A` (same style as
> `release axiom_of_choice: set F` / `release zorn_lemma: …`) keeps `P` labeled as a prop
> and `A` as a set. `fn_range(f)` stays available for function ranges. Tracer:
> [`examples/stmt_nodes/definition/have_by_replacement_axiom.lit`](../examples/stmt_nodes/definition/have_by_replacement_axiom.lit).
### S11. Piecewise functions
**Public form:** `have fn ... by cases:`.
**Mathematical function.** Define one function using exhaustive disjoint mathematical cases.
**Before execution.** Each guard is WD; coverage, pairwise disjointness, body WD and return membership must check under the corresponding case.
**Execution and result.** Check all case obligations before storing the function signature and guarded equations. These equations become available at calls whose case facts verify.
**Nearest boundary.** A case at zero alone does not define a total function on R. A formula in an unreachable branch still has its required WD checks.
**Checked example.**
```litex
have fn absolute(x R) R by cases:
case x >= 0: x
case x < 0: -x
absolute(-2) = 2
absolute(3) = 3
```
**Source:** [implementation](../src/execute/execute_have_fn_equal_case_by_case_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S01 Expression-defined functions](#s01-expression-defined-functions), [O79 Function spaces](#o79-function-spaces), [O03 Function applications](#o03-function-applications).
**Further detail:** [Case equations and compound guards](#case-equations-and-compound-guards).
### S12. Functions by decreasing integer measure
**Public form:** `have fn ... by induc n from lower:`.
**Mathematical function.** Define a recursive function whose recursive calls decrease an integer measure.
**Before execution.** The measure, lower bound, cases and return carrier are valid; every recursive call is in-domain and strictly smaller in the selected measure, and its substituted lower bound is no smaller than the current lower bound.
**Execution and result.** Check base and recursive cases with the controlled recursive signature, then store the callable interface and guarded defining equations.
**Nearest boundary.** A recursive call to the same or a larger measure is not licensed merely because it has the same output type.
**Checked example.**
```litex
have fn countdown(n N) N by induc n from 0:
case n = 0: 0
case n >= 1: countdown(n - 1)
countdown(0) = 0
countdown(1) = countdown(0) = 0
```
**Source:** [implementation](../src/execute/execute_have_fn_by_induc_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S01 Expression-defined functions](#s01-expression-defined-functions), [O79 Function spaces](#o79-function-spaces), [O03 Function applications](#o03-function-applications).
**Further detail:** [Nested cases and decreasing calls](#nested-cases-and-decreasing-calls).
### S13. Functions from unique existence
**Public form:** `have fn f by exist!:`.
**Mathematical function.** Turn a proved input-to-unique-output specification into a callable mathematical function.
**Before execution.** The forall ... exist! statement and its function-space carrier must be WD and verified, including uniqueness for complete output tuples.
**Execution and result.** Store callable membership, the specification at f(input), and the corresponding uniqueness universal. This has no formula body to unfold into an evaluation equation.
**Nearest boundary.** A proof of existence alone is insufficient. Use the property interface at f(x), rather than inventing an expression defining its output.
**Checked example.**
```litex
prop F(x, y R):
y = x
have A set = R
have B set = R
claim:
? forall x A:
exist! y B st {$F(x, y)}
witness exist! y B st {$F(x, y)} from x:
by def $F(x, x)
have fn f by exist!:
? forall x A:
exist! y B st {$F(x, y)}
forall x A:
$F(x, f(x))
```
**Source:** [implementation](../src/execute/execute_have_fn_by_forall_exist_unique_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S01 Expression-defined functions](#s01-expression-defined-functions), [O79 Function spaces](#o79-function-spaces), [O03 Function applications](#o03-function-applications).
**Further detail:** [Selection facts and binder replay](#selection-facts-and-binder-replay).
### S14. Concrete predicates
**Public form:** `prop P(parameters): facts`.
**Mathematical function.** Define mathematical vocabulary by concrete defining clauses.
**Before execution.** Parameters and clauses must be WD. Earlier checked clauses may guard later partial expressions within definition WD.
**Execution and result.** Store the concrete definition. A verified positive instance can expose its clauses; by def checks the defining obligations explicitly. Definition alone does not assert every instance.
**Nearest boundary.** A predicate describes truth. Use have fn when later code needs a callable returned value.
**Checked example.**
```litex
prop is_positive(x R):
x > 0
by def $is_positive(2)
$is_positive(2)
```
**Source:** [implementation](../src/execute/execute_def_prop_stmt/exec_def_prop_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S15. Abstract predicate signatures
**Public form:** `abstract_prop P(parameters)`.
**Mathematical function.** Introduce a predicate signature for an external or uninterpreted property.
**Before execution.** The declaration and later calls must use the valid name and arity. No definition body or instance proof is supplied.
**Execution and result.** Store only the abstract predicate interface. Calls can be used as premises, or proved from actual assumptions/interfaces; there are no defining clauses to unfold.
**Nearest boundary.** An abstract_prop declaration is not an axiom proving $P(a). Strict mode allows the signature itself.
**Checked example.**
```litex
abstract_prop marked(x)
forall x R:
$marked(x)
=>:
$marked(x)
```
**Source:** [implementation](../src/execute/execute_def_abstract_prop_stmt/exec_def_abstract_prop_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S16. Structured carriers
**Public form:** `struct Name:`.
**Mathematical function.** Define a product carrier with named fields and optional defining conditions.
**Before execution.** Field carriers and conditions are checked in declaration order. Membership in the resulting struct must satisfy its complete coordinate and property contract.
**Execution and result.** Store the definition-owned carrier, field schema and laws. Direct bindings x &Struct open one outer layer; other expressions can use explicit release struct def.
**Nearest boundary.** Declaring the carrier does not create an instance. Field WD is not a request to expose every nested struct law.
**Checked example.**
```litex
struct Point:
x R
y R
(1, 2) $in &Point
struct PosPoint:
x R
y R
<=>:
x > 0
(1, 2) $in &PosPoint
```
**Source:** [implementation](../src/execute/execute_def_struct_stmt/exec_def_struct_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S17. Parameterized declaration families
**Public form:** `template:`.
**Mathematical function.** Define a reusable family of supported ordinary definitions indexed by mathematical parameters.
**Before execution.** Template parameters, guards, allowed declaration shape, and each instantiated definition contract must check.
**Execution and result.** Store the family. The object spelling \Name specializes it; a fully instantiated callable definition can then be applied. The ordinary declaration determines released facts.
**Nearest boundary.** Template parameters are not runtime function arguments. Instantiation must satisfy its own carrier and guard obligations.
**Checked example.**
```litex
template:
have carrier_copy set = S
\carrier_copy = R
```
**Source:** [implementation](../src/execute/execute_def_template_stmt/exec_def_template_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Template body forms and call stages
The current `TemplateDefEnum` permits arbitrary/value/specification `have`,
replacement images, `trust have`, existential or predicate `obtain`, and the
four function-definition modes (expression, cases, induction, unique existence).
The body is one supported ordinary declaration. It is not a container for an
arbitrary mixed chapter of statements. Each body retains its own existence,
uniqueness, WD and trust contract; template trust-have is rejected in strict
mode. Struct parameterization belongs to the struct declaration itself.
`\identity` is one specialized function value;
`\identity(2)` then applies that value. The two stages have different
argument contracts. See R03 for the checked family and both calls. The source
enumeration is [TemplateDefEnum](../src/ast/stmt.rs).
A checked specialized function has its full declared function type even when
the bound parameter is renamed. Its domain conditions, return carrier and
free owners must still match, and instantiation must satisfy every template
argument and guard. See the [checked function-type example](../examples/wd/template_function_declared_type.lit).
**Further detail:** [Carrier families and function arguments](#carrier-families-and-function-arguments).
### S18. Named theorems
**Public form:** `thm name: ? goal`.
**Mathematical function.** Give a proved result a reusable named mathematical interface.
**Before execution.** The goal is WD in the existing context. Its active binders and premises provide the local proof scope; every conclusion must verify.
**Execution and result.** Run the proof and store the theorem interface. Universal theorem facts are reusable by ordinary matching as well as explicit theorem calls. A body may be empty when it already closes.
**Nearest boundary.** A later declaration in the proof body cannot make an earlier undefined goal WD. Helpers remain local.
**Checked example.**
```litex
thm add_zero:
? forall x R:
x + 0 = x
release thm add_zero(2)
```
**Source:** [implementation](../src/execute/execute_def_thm_stmt/exec_def_thm_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S33 Local claims](#s33-local-claims), [S34 Local sketches](#s34-local-sketches).
#### Theorem fact shapes and call spelling
`thm` proves and names one reusable `Fact`, using the same goal shapes as
`claim`. Both reject a root `forall ... <=>:` goal before WD or proof execution,
with a `goal_unsupported` user diagnostic; this is not an internal error.
For an equivalence, prove the two directions as separate ordinary `forall`
theorems. See the [theorem-goal boundary tracer](../examples/stmt_nodes/definition/def_thm_forall_iff_boundary.lit).
A universal
theorem is available both for explicit theorem calls and ordinary
known-`forall` matching. `axiom` remains universal-only and gives the same
parenthesized call interface to a trusted fact without proving it.
> **Preview:** theorem calls accept plain or qualified names
> (`export::thm`, `Mod::export::thm`, `Mod:::thm`). Lookup uses the live Env
> stack for plain names and a finished export file's Env for qualified names —
> the same path as `release obj def`. Fact search still does not merge another
> module's ambient facts; only the named theorem definition is resolved.
> `axiom` is wired the same way as `thm` for storage: after a successful
> `axiom` statement the named interface is stored and its `forall` enters
> ambient known facts (no proof body). `release thm name(args)` and
> `by thm name(args) => fact` resolve axiom names as well as theorem names.
The call spelling records whether instantiation is taking place:
- call a root `forall` theorem, including a zero-parameter `forall`, with
parentheses: `name(args)` or `name()`;
- cite every other theorem fact without parentheses: `name`.
An ordinary theorem fact is already stored when the theorem is defined. Its
bare call is therefore an exact citation, not a second store operation:
```litex
thm one_is_one:
? 1 = 1
release thm one_is_one
by thm one_is_one => 1 = 1
```
`one_is_one()` is rejected, just as a bare call to a root `forall` theorem is
rejected. Reserved builtin theorem calls and `axiom` calls also keep their
parentheses.
### S19. Named axioms
**Public form:** `axiom name: ? goal`.
**Mathematical function.** Name an explicitly assumed proposition for reuse.
**Before execution.** The interface and its expressions must be WD. Truth is assumed, not proved; strict mode rejects the declaration.
**Execution and result.** Store the named assumed interface and applicable universal information with its trust boundary. Calls still check their arguments and premises.
**Nearest boundary.** A successful ordinary run containing an axiom is not a trust-free proof of that axiom.
**Assumption demonstration.** Checked in ordinary mode; this is not a trust-free proof. Strict mode rejects the assumed declaration.
```litex
axiom background:
? forall x R:
x = x
release thm background(2)
```
**Source:** [implementation](../src/execute/execute_axiom_stmt/exec_axiom_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S33 Local claims](#s33-local-claims), [S34 Local sketches](#s34-local-sketches), [S18 Named theorems](#s18-named-theorems).
### S20. Reusable proof strategies
**Public form:** `strategy name: ? forall ...`.
**Mathematical function.** Prove a reusable pattern for the dedicated non-equality atomic strategy route.
**Before execution.** The goal is WD and the local proof establishes its conclusions; the current parser/executor permits the documented theorem-like proof body.
**Execution and result.** Store a strategy definition. Later applicable non-equality atomics can use known_strategy; the result is not injected as an ordinary ambient known-forall theorem.
**Nearest boundary.** There is no use/stop activation state. A strategy is not a global arbitrary goal-search program.
**Checked example.**
```litex
prop is_one(x R):
x = 1
strategy use_is_one:
? forall x R:
x = 1
=>:
$is_one(x)
$is_one(x)
have a R = 1
$is_one(a)
```
**Source:** [implementation](../src/execute/execute_def_strategy_stmt/exec_def_strategy_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Strategy storage and search stage
A `strategy` proves a named, restricted atomic universal pattern. Once the
definition succeeds, later non-equality atomics may apply it through the
dedicated known-strategy search stage. There is no ambient known-forall
injection and no separate activation state.
> **Preview:** `strategy` is parse+exec wired like `thm`'s
> forall path. The goal is checked for well-definedness before the proof body;
> body statements run in its local forall scope with normal failure rollback. The named interface is stored under
> `strategy_definitions`. The proved forall is **not** injected into ordinary
> known_forall matching; non-equality atomics apply it through `known_strategy`
> (after by-definition, before known forall), returning `ByKnownStrategy`.
> Tracer:
> [`examples/stmt_nodes/definition/def_strategy.lit`](../examples/stmt_nodes/definition/def_strategy.lit).
### S21. Executable functions by cases
**Public form:** `algo ... by cases:`.
**Mathematical function.** Define a checked piecewise function together with an executable presentation for eval.
**Before execution.** The same coverage, disjointness, WD and return obligations as the piecewise function apply.
**Execution and result.** Define the callable function and store the executable cases. eval computes through this presentation and checks executed defining equations.
**Nearest boundary.** An algorithm declaration does not waive mathematical domain or coverage requirements.
**Checked example.**
```litex
algo nonzero_flag(x R) R by cases:
case x = 0: 0
case x != 0: 1
eval nonzero_flag(2)
```
**Source:** [implementation](../src/execute/execute_def_algo_by_cases_stmt/exec_def_algo_by_cases_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S01 Expression-defined functions](#s01-expression-defined-functions), [O79 Function spaces](#o79-function-spaces), [O03 Function applications](#o03-function-applications).
**Further detail:** [Checked algorithm execution](#checked-algorithm-execution).
### S22. Executable functions by induction
**Public form:** `algo ... by induc measure from lower:`.
**Mathematical function.** Define a decreasing recursive function with an executable presentation.
**Before execution.** The induction-function obligations hold, including in-domain decreasing recursive calls and result membership.
**Execution and result.** Store the checked recursive function and executable algorithm. Exact eval checks the equations for the path actually executed.
**Nearest boundary.** Execution is not an independent proof of arbitrary facts about all inputs.
**Checked example.**
```litex
algo countdown(n N) N by induc n from 0:
case n = 0: 0
case n >= 1: countdown(n - 1)
eval countdown(2)
```
**Source:** [implementation](../src/execute/execute_def_algo_by_induc_stmt/exec_def_algo_by_induc_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S01 Expression-defined functions](#s01-expression-defined-functions), [O79 Function spaces](#o79-function-spaces), [O03 Function applications](#o03-function-applications).
### S23. Explicitly trusted facts
**Public form:** `trust: facts`.
**Mathematical function.** Record deliberately assumed facts.
**Before execution.** All expressions and fact signatures must be WD; strict mode rejects user trust.
**Execution and result.** Skip truth search, then store the trusted facts with inference. This cannot repair an ill-defined expression such as division by zero.
**Nearest boundary.** Trust is a visible assumption boundary, not a proof technique that establishes truth.
**Assumption demonstration.** Checked in ordinary mode; this is not a trust-free proof. Strict mode rejects the assumed declaration.
```litex
trust:
7 = 7
7 = 7
```
**Source:** [implementation](../src/execute/execute_unsafe_stmt/exec_trust_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S24. Trusted witness introduction
**Public form:** `trust have names carriers: facts`.
**Mathematical function.** Introduce objects and assume their specified facts without proving the matching existential.
**Before execution.** Parameter types, names and body expressions remain checked for WD. Strict mode rejects the statement.
**Execution and result.** Introduce typed names and store trusted body facts in one transaction. Subsequent proof steps are relative to these assumptions.
**Nearest boundary.** This differs from ordinary specification-have, whose existence must be proved.
**Assumption demonstration.** Checked in ordinary mode; this is not a trust-free proof. Strict mode rejects the assumed declaration.
```litex
trust have denominator R:
denominator != 0
1 / denominator = 1 / denominator
```
**Source:** [implementation](../src/execute/execute_unsafe_stmt/exec_trust_have_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S25. Publish theorem conclusions
**Public form:** `release thm name(arguments)`.
**Mathematical function.** Instantiate a reusable theorem and publish all its conclusions.
**Before execution.** The theorem exists, its argument syntax matches its goal shape, and all parameter domains and instantiated premises verify.
**Execution and result.** Instantiate and check the call, then store every resulting conclusion and its inference. Root forall theorems require parentheses even with no parameters; ordinary theorem facts use a bare name.
**Nearest boundary.** The form has no selection arrow or proof body. Bare by thm is supported as the unselected compatibility spelling.
**Checked example.**
```litex
thm zero_sides:
? forall x R:
x + 0 = x
0 + x = x
release thm zero_sides(2)
2 + 0 = 2
0 + 2 = 2
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_thm_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S26. Select one theorem consequence
**Public form:** `by thm name(arguments) => atomic_fact`.
**Mathematical function.** Select one directly returned atomic conclusion of a theorem instance.
**Before execution.** Arguments, domains and premises verify; the requested target is a supported single atomic fact.
**Execution and result.** Match the selected fact against the instance's directly returned atomic conclusions, retaining a citation to the matched conclusion. Publish only that selection with inference. Independently provable targets and combinations of conclusions are rejected.
**Nearest boundary.** An existential, universal, conjunction or chain is not a selectable atomic target; release the complete result when that shape is needed.
**Checked example.**
```litex
thm add_zero:
? forall x R:
x + 0 = x
by thm add_zero(2) => 2 + 0 = 2
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_thm_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Atomic selection and the temporary call scope
For `by thm name(args) => fact`, `fact` must be well-defined in the parent
context and match a directly returned atomic conclusion of this theorem
instance. Explicit conjunction components and adjacent chain components are
selectable. Matching permits structural identity and renaming bound variables;
it does not compute or rewrite arguments, reverse an equality, combine
conclusions, or select facts produced by inference. A target already known in
the parent must satisfy the same matching requirement.
Litex checks argument types, premises and conclusion well-definedness in a
temporary child environment. The selected proof cites the matched conclusion
from this call, even when ordinary verification could prove the target without
it. The child is discarded afterward. On success, only `fact` is committed as
the parent seed and ordinary inference runs from that seed; on failure, the
parent environment is unchanged. Positive and negative atomic conclusions are
supported. Compound, quantified, existential, disjunctive, conjunctive, and
chain targets are not accepted. The selected form requires `=> fact`; only
the separate bare legacy alias omits the arrow.
To combine several returned conclusions, release them explicitly and write a
separate derivation:
```litex
thm zero_sides:
? forall x R:
x + 0 = x
0 + x = x
release thm zero_sides(2)
2 + 0 = 0 + 2
```
`by thm zero_sides(2) => 2 + 0 = 0 + 2` is rejected because that equality is
not directly returned. See the [strict-selection tracer](../examples/stmt_nodes/by/by_thm_strict_selection.lit).
For a root `forall`, `release thm name(args)` stores all instantiated
conclusions. For an ordinary theorem fact, `release thm name` cites the
already-stored theorem FactId. A bare legacy `by thm name(args)` call has the
same all-conclusions behavior, while a selected `by thm ... => fact` call
stores only the requested atomic fact and its ordinary inferred consequences.
### S27. Open one struct definition layer
**Public form:** `release struct def expression`.
**Mathematical function.** Expose the tuple/coordinate bridges, carriers and laws of a selected struct view.
**Before execution.** The expression has a definition-owned struct view and its membership in that carrier verifies.
**Execution and result.** Resolve the selected declaration, instantiate and store exactly one outer layer of structural bridges, field carriers and laws.
**Nearest boundary.** Opening an outer struct does not recursively open every struct-valued field. Call release on the nested expression when its laws are needed.
**Checked example.**
```litex
struct Coordinates:
x R
y R
<=>:
x = 0
struct TaggedPoint:
point &Coordinates
tag N
claim:
? forall p &TaggedPoint:
p.point.x = 0
release struct def p.point
```
**Source:** [implementation](../src/execute/release_one_struct_layer.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
**Further detail:** [One-layer release and its published facts](#one-layer-release-and-its-published-facts).
### S28. Replay an object definition
**Public form:** `release obj def identifier`.
**Mathematical function.** Expose the stored mathematical interfaces belonging to an identifier definition.
**Before execution.** The source is a supported stored identifier definition, not an arbitrary object expression or a binder-only ParamType.
**Execution and result.** Re-store the definition-owned type, equality, body or function facts using the written identifier spelling. Unique-existence functions replay membership, property and uniqueness.
**Nearest boundary.** This does not discover a new theorem or erase the original definition obligations.
**Checked example.**
```litex
have fn identity(x R) R = x
release obj def identity
identity(2) = 2
```
**Source:** [implementation](../src/execute/execute_release_obj_def_stmt/exec_release_obj_def_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
**Further detail:** [Definition lookup and supported source owners](#definition-lookup-and-supported-source-owners).
### S29. Expand finite integer membership
**Public form:** `expand: value $in range(...)`.
**Mathematical function.** Turn a known finite integer-range membership into equality alternatives.
**Before execution.** The range/closed-range has the supported concrete enumerable shape and at most 1024 values, checked with overflow-safe arithmetic before allocation. The membership must then verify.
**Execution and result.** Enumerate the range values and store a disjunction value = first or ... . This exposes cases without choosing one of them.
**Nearest boundary.** Expansion is not proof that an arbitrary object lies in the range. The closed upper endpoint differs from range’s excluded endpoint.
**Checked example.**
```litex
claim:
? forall x range(1, 3):
x = 1 or x = 2
expand: x $in range(1, 3)
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_expand_range_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S30. Regularity release
**Public form:** `release regularity_axiom(S)`.
**Mathematical function.** Apply the fixed set-theoretic Regularity foundation through its checked release interface.
**Before execution.** The displayed set and nonemptiness obligations verify.
**Execution and result.** Check the inputs and expose the foundational conclusion for the given set. This named release is allowed by current strict mode.
**Nearest boundary.** Passing strict mode does not mean the foundation itself was derived without foundational assumptions.
**Checked example.**
```litex
release regularity_axiom({1})
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_regularity_axiom_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
The current checker does not propagate transitive trust taint to later facts
or theorems. A successful strict run still depends on the fixed foundation
used by this release; inspect the explicit source boundary.
### S31. Choice release
**Public form:** `release axiom_of_choice: set F:`.
**Mathematical function.** Obtain a choice-function existence fact for a family of nonempty sets.
**Before execution.** F is a set and every A in F has a verified nonemptiness fact; the body proves these obligations in the caller context.
**Execution and result.** Store the existential choice-function fact with the appropriate function-space and atomic choice specification. Witness names require a later obtain.
**Nearest boundary.** Axiom of Choice does not establish nonemptiness of the family members; it uses it as an input. This is fixed foundational support.
**Checked example.**
```litex
claim:
? forall F set:
forall A F:
$is_nonempty_set(A)
=>:
exist f fn(A F) family_union(F) st {$is_choice_function_for(F, F, fn(B F) F {B}, f)}
release axiom_of_choice: set F:
forall A F:
$is_nonempty_set(A)
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_axiom_of_choice_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S32. Zorn release
**Public form:** `release zorn_lemma: set S, prop P, prop U, prop M:`.
**Mathematical function.** Use Zorn’s Lemma to establish existence of a maximal element.
**Before execution.** The exact named upper-bound/maximality definitions, nonempty poset, partial-order laws and chain-upper-bound condition must check.
**Execution and result.** Resolve the definitions, verify the semantic interface and all hypotheses, then store exist m S st {$M(m)}. The relation and supplied predicate definitions are part of the checked contract.
**Nearest boundary.** The theorem cannot replace a missing chain bound or an arbitrary predicate merely named maximal. The foundation is explicit.
**Checked example.**
```litex
have S set
abstract_prop leq(x, y)
prop upper_bound(c power_set(S), u S):
forall x c:
$leq(x, u)
prop maximal(m S):
forall x S:
$leq(m, x)
=>:
x = m
claim:
? forall:
$is_nonempty_set(S)
forall x S:
$leq(x, x)
forall x, y, z S:
$leq(x, y)
$leq(y, z)
=>:
$leq(x, z)
forall x, y S:
$leq(x, y)
$leq(y, x)
=>:
x = y
forall c power_set(S):
forall x, y c:
$leq(x, y) or $leq(y, x)
=>:
exist u S st {$upper_bound(c, u)}
=>:
exist m S st {$maximal(m)}
release zorn_lemma: set S, prop leq, prop upper_bound, prop maximal:
$is_nonempty_set(S)
forall x S:
$leq(x, x)
forall x, y, z S:
$leq(x, y)
$leq(y, z)
=>:
$leq(x, z)
forall x, y S:
$leq(x, y)
$leq(y, x)
=>:
x = y
forall c power_set(S):
forall x, y c:
$leq(x, y) or $leq(y, x)
=>:
exist u S st {$upper_bound(c, u)}
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_zorn_lemma_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### General partial-order and chain interfaces
**Assumption demonstration (ordinary mode):** the example below explicitly assumes
the partial-order and chain-upper-bound background. Its native release checks those
interfaces; the source assumptions are rejected in strict mode.
`release zorn_lemma` requires the two quantified conditions that occur below
existentials to be named concrete props. Their signatures and definitions are
checked exactly (IR alignment) before any obligation is accepted. Local proof
bodies accept ordinary statements in a child scope (same pattern as
`release axiom_of_choice`):
```litex
have S set
abstract_prop leq(x, y)
prop upper_bound(c power_set(S), u S):
forall x c:
$leq(x, u)
prop maximal(m S):
forall x S:
$leq(m, x)
=>:
x = m
trust $is_nonempty_set(S)
trust:
forall x S:
$leq(x, x)
forall x, y, z S:
$leq(x, y)
$leq(y, z)
=>:
$leq(x, z)
forall x, y S:
$leq(x, y)
$leq(y, x)
=>:
x = y
forall c power_set(S):
forall x, y c:
$leq(x, y) or $leq(y, x)
=>:
exist u S st {$upper_bound(c, u)}
release zorn_lemma: set S, prop leq, prop upper_bound, prop maximal:
$is_nonempty_set(S)
forall x S:
$leq(x, x)
forall x, y, z S:
$leq(x, y)
$leq(y, z)
=>:
$leq(x, z)
forall x, y S:
$leq(x, y)
$leq(y, x)
=>:
x = y
forall c power_set(S):
forall x, y c:
$leq(x, y) or $leq(y, x)
=>:
exist u S st {$upper_bound(c, u)}
obtain m from exist m S st {$maximal(m)}
```
The choice-backed `index_cart_nonempty_by_choice_from_family` and
`index_cart_nonempty_by_choice_from_pointwise` theorem interfaces remain
available when only nonemptiness of a general Cartesian product is needed.
### S33. Local claims
**Public form:** `claim: ? goal`.
**Mathematical function.** Prove and export one target while keeping helper definitions and witnesses local.
**Before execution.** The target is WD in the existing context, before its proof-body declarations. Every proof statement and final goal must verify.
**Execution and result.** Introduce the goal’s local binders and premises, execute the proof body, verify the target, and export the target only.
**Nearest boundary.** A successfully introduced local witness or function does not escape the claim merely because the target succeeded.
**Checked example.**
```litex
claim:
? 3 = 3
have local R = 3
local = 3
3 = 3
```
**Source:** [implementation](../src/execute/execute_proof_block_stmt/exec_claim_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S34 Local sketches](#s34-local-sketches), [S18 Named theorems](#s18-named-theorems).
### S34. Local sketches
**Public form:** `sketch: statements`.
**Mathematical function.** Check a small development in a discarded lexical scope.
**Before execution.** Every contained statement must succeed; a failed child fails the sketch.
**Execution and result.** Execute the local statements and discard the sketch environment afterwards. No contained name or fact is exported.
**Nearest boundary.** A sketch’s success is not a declaration of a reusable outside theorem.
**Checked example.**
```litex
sketch:
have fn identity(x R) R = x
identity(2) = 2
1 = 1
```
**Source:** [implementation](../src/execute/execute_proof_block_stmt/exec_sketch_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S33 Local claims](#s33-local-claims), [S18 Named theorems](#s18-named-theorems).
### S35. Existential witnesses
**Public form:** `witness exist ... from values`.
**Mathematical function.** Prove an existential by giving concrete witnesses.
**Before execution.** Witness count, dependent carriers and expression WD check; the substituted body must verify, optionally using local proof steps.
**Execution and result.** Substitute the supplied values, check each obligation, and store the exact existential fact. Its bound names and proof helpers stay local.
**Nearest boundary.** Providing a value does not establish an unrelated body condition, nor does it make the existential binder globally usable.
**Checked example.**
```litex
witness exist x R st {x = 2} from 2
obtain a from exist x R st {x = 2}
a = 2
```
**Source:** [implementation](../src/execute/execute_witness_stmt/exec_witness_exist_fact.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S36 Unique existential witnesses](#s36-unique-existential-witnesses), [S07 Extract existential witnesses](#s07-extract-existential-witnesses).
#### Witness identities and local proof scopes
> **Preview:** `witness exist` / `exist!` / `$P(args)` /
> `$is_nonempty_set(S)` are wired at top level. Each form may be a flat one-line
> header, or end with `:` and an indented local proof body (full Stmt list,
> claim-style). Ambient WD and each concrete witness's substituted type are
> verified before the existential binders and their equalities are introduced.
> The proof body then runs in a local env; substituted body and (for `exist!`)
> uniqueness obligations are verified there after the proof steps. The proof
> body cannot establish a witness type by citing its own assumed binder type.
> Helpers stay in the discarded local env; only the target fact
> is stored. `exist!` verifies the generated two-candidate uniqueness forall
> via the same builder as `obtain` from `exist!`. `witness $P` requires a
> concrete prop whose sole clause is ordinary `exist` (reject `exist!` /
> `not exist` / multi-clause / `abstract_prop`); after witness checks it stores
> `$P` (definition inference may expose the exist). Nonemptiness stores
> `$is_nonempty_set(S)` after verifying `o $in S` — there is **no**
> FnSet/codomain shortcut. `obtain … from exist` / `exist!` / `$P` is also
> wired at top level and as a `template` body (still no indented body on
> `obtain`). A destination already visible in the current proof is rejected,
> like a duplicate `let` or `have`. In `obtain k from exist k ...`, the source
> quantifier ends before the fresh destination begins; their IDs are distinct.
> Nested witness/WD locals may bind the same surface name as an ambient obtain
> (e.g. `obtain k from $odd(n)` then `witness $odd(n) from k`).
The existential binder and an ambient witness may also have the same spelling:
```litex
prop has_copy(a R):
exist g R st {g = a}
have g R = 2
witness $has_copy(g) from g
```
Lookup uses the identity already attached to each reference. A name-identical
inner binder does not invalidate an outer witness or a qualified file-owned
definition. Failed witnesses retain their failure phase and nested goal in
Detailed output, and publish no target fact. See the
[same-name witness tracer](../examples/wd/witness_same_named_binder.lit).
### S36. Unique existential witnesses
**Public form:** `witness exist! ... from values`.
**Mathematical function.** Prove existence and uniqueness of a complete witness tuple.
**Before execution.** All ordinary witness checks apply; the generated two-candidate uniqueness universal must also verify.
**Execution and result.** Store the unique existential and its applicable uniqueness information after checking both existence and uniqueness.
**Nearest boundary.** One positive real witness is not a proof that there is exactly one positive real.
**Checked example.**
```litex
witness exist! x R st {x = 2} from 2
obtain a from exist! x R st {x = 2}
a = 2
```
**Source:** [implementation](../src/execute/execute_witness_stmt/exec_witness_exist_fact.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S35 Existential witnesses](#s35-existential-witnesses), [S07 Extract existential witnesses](#s07-extract-existential-witnesses).
### S37. Witnesses for named existential properties
**Public form:** `witness $P(args) from values`.
**Mathematical function.** Prove a supported concrete existential predicate through its witness interface.
**Before execution.** Arguments have their declared types and the definition has the supported single positive ordinary existential clause.
**Execution and result.** Check the projected existential witnesses and publish the predicate with ordinary definition inference.
**Nearest boundary.** For unique existence use witness exist! followed by explicit definition folding; extra clauses are not silently omitted.
**Checked example.**
```litex
prop has_copy(a R):
exist x R st {x = a}
witness $has_copy(2) from 2
```
**Source:** [implementation](../src/execute/execute_witness_stmt/exec_witness_atomic_fact.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S35 Existential witnesses](#s35-existential-witnesses), [S36 Unique existential witnesses](#s36-unique-existential-witnesses), [S07 Extract existential witnesses](#s07-extract-existential-witnesses).
### S38. Nonempty-set witnesses
**Public form:** `witness $is_nonempty_set(S) from value`.
**Mathematical function.** Prove that a set contains at least one element.
**Before execution.** The proposed object is WD and its membership in S verifies.
**Execution and result.** Check the membership in the optional local proof scope, then publish nonemptiness. This can license a later arbitrary have.
**Nearest boundary.** A value outside S cannot prove nonemptiness; a definition of S alone may not provide a witness route.
**Checked example.**
```litex
witness $is_nonempty_set({t R: t > 0}) from 1
have a {t R: t > 0}
a > 0
```
**Source:** [implementation](../src/execute/execute_witness_stmt/exec_witness_nonempty_set.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S35 Existential witnesses](#s35-existential-witnesses), [S36 Unique existential witnesses](#s36-unique-existential-witnesses), [S07 Extract existential witnesses](#s07-extract-existential-witnesses).
### S39. Proof by exhaustive cases
**Public form:** `by cases:`.
**Mathematical function.** Prove a target in each branch of an established exhaustive case split.
**Before execution.** The case disjunction and all branch facts are supported and verify; every branch closes the target or reaches a checked contradiction.
**Execution and result.** Create local branch scopes, assume their case facts, check their proof bodies, and publish the target only after all branches succeed.
**Nearest boundary.** A convenient but nonexhaustive list of cases does not prove a universal conclusion.
**Checked example.**
```litex
by cases:
? 1 = 1
case 1 = 1:
1 = 1
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_cases_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Explicit proof cases
Every proof case requires `:` and a nonempty body, even when the branch
assumption already supports its target. A checked `impossible` tail alone is
a complete process for a contradictory branch:
```litex
by cases:
? 1 = 1
case 1 = 1:
1 = 1
case 1 != 1:
impossible 1 = 1
```
Function and algorithm cases use their separate return-expression syntax.
### S40. Proof by contradiction
**Public form:** `by contra:`.
**Mathematical function.** Prove a supported goal by assuming its negation and deriving a contradiction.
**Before execution.** The target and generated negation are WD; impossible must certify an actual contradictory fact in the local context.
**Execution and result.** Open the negated-goal scope, execute the proof, verify the explicit contradiction, and store the requested target.
**Nearest boundary.** A bare unsupported impossible assertion is not a contradiction certificate. Negating a compound goal follows its supported fact shape.
**Checked example.**
```litex
by contra:
? 1 = 1
impossible 1 != 1
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_contra_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Classified opposites and contradiction payloads
`by contra` assumes the classified logical opposite of its target in a local
proof scope. Targets may be atomic facts, `exist` / `not exist`, `exist!`,
conjunctions, disjunctions, chains, `not forall`, and ordinary `forall` or
forall-iff whose premises and conclusions are quantifier-free. Negating several
forall conclusions means that at least one conclusion fails; it does not
require all of them to fail. An iff target negates the complete equivalence,
rather than one direction. Quantified premises or existential conclusions
still exceed the current quantifier-free counterexample payloads.
For an `exist!` target, the reverse assumption says that every satisfying
candidate has a distinct satisfying alternative. This covers both absence
of any witness and multiple witnesses. It uses existing forall/exists shapes;
there is no unified `NotFact` or new `not exist!` syntax.
`impossible fact` accepts the same classified Fact families as the goal,
including conjunctions, disjunctions, chains, existence and multiline forall
or iff facts. Quantified premises or conclusions inside forall/iff still
exceed the current counterexample representation. The block closes only
after the complete fact and its classified opposite both verify. A failed
or unknown verification is not proof of the opposite. Only the target is
published outside the block; reverse assumptions and obtained witnesses stay
local.
```litex
by contra:
? not forall x R:
x^2 >= x
impossible 0.5^2 >= 0.5
```
A universal exclusion can be used in an explicit negative-existence proof:
```litex
by enumerate finite_set:
? forall x {0}:
x != 1
x != 1
by contra:
? not exist x {0} st {x = 1}
obtain a from exist x {0} st {x = 1}
a != 1
impossible a = 1
```
### S41. Finite-set enumeration
**Public form:** `by enumerate finite_set:`.
**Mathematical function.** Prove a universal by checking every element of its finite displayed domains.
**Before execution.** The exact domains are concretely enumerable; each instantiated premise and conclusion has the supported shape.
**Execution and result.** Instantiate each domain combination, assume matching premises, execute the per-case proof, and publish the universal when all cases close.
**Nearest boundary.** A merely known finite set is not necessarily a displayed enumeration. Proof commands belong in this proof body, not the bare forall’s fact list.
**Checked example.**
```litex
by enumerate finite_set:
? forall x {1, 2}:
x < 3
x < 3
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_enumerate_finite_set_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Conditional assignments and enumeration scope
`by enumerate finite_set` and `by for` prove a forall by checking every
assignment from displayed finite list sets, `range(start, end)`, or
`closed_range(start, end)`. Multiple independently enumerable parameters are
supported. A named finite set without a displayed domain is not expanded;
`cart(...)` domains are not supported, even when their factors are finite.
The Cartesian product of the enumerated domains is generated lazily, one
assignment at a time. Before any assignment is built, the product cardinality
is checked with overflow-aware arithmetic against a fixed assignment budget of
1024; products above that budget fail with a domain diagnostic instead of
allocating the full product. Each numeric range is also limited to 1024 values,
with overflow-checked cardinality before materialization. This per-range limit
also applies to `expand:`, which turns known numeric-range membership into
equality cases for later `by cases`. Empty ranges remain empty; oversized ranges
fail with a domain diagnostic, even if another enumerated domain is empty.
Conditional targets are checked as implications for each assignment. A proved
negation of an atomic premise skips that assignment. Otherwise premises are
assumed only in the assignment's local proof scope, and every conclusion must
verify there. Failure to prove a premise's negation never counts as a skipped
case. Premises are introduced in source order, so earlier guards can license
later objects.
```litex
by enumerate finite_set:
? forall n {0, 1, 2}:
n > 0
=>:
n != 0
n != 0
```
Optional proof bodies may use the quantified names and nested proof methods.
Each assignment binds those names to its concrete values. Declarations and
helper facts stay local; only the verified universal is stored outside.
### S42. Ordinary induction
**Public form:** `by induc n from lower:`.
**Mathematical function.** Prove a supported discrete universal by a base case and one-step induction.
**Before execution.** The active parameter, carrier, lower bound, hypotheses and invariant match the induction interface.
**Execution and result.** Check the base and inductive successor obligations in scoped contexts, then store the resulting universal.
**Nearest boundary.** The induction binder is part of the proof interface. A differently named mirror universal is not the original active goal.
**Checked example.**
```litex
by induc n from 0:
? n = n
n = n
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_induc_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Induction scopes and structured goals
`by induc n from base` proves a discrete target from a base case and a
successor step. `by strong_induc` supplies the corresponding bounded universal
induction hypothesis. Structured goals use `? from`, `? induc`, and
`? strong_induc`. An unstructured proof body is checked once in the base
scope without an induction hypothesis and once in the successor scope with
one; both checks must succeed.
Goal well-definedness is checked under `n $in Z` and `n >= base`, without an
induction hypothesis. Thus a function on `N` can be called in an induction
from zero. Each base/step body accepts the same checked statements as an
ordinary proof body, including local `have`, `let`, `by def`, theorem calls,
claims, and witnesses. Local definitions remain inside that case.
```litex
have fn f(x N) N = x
by induc n from 0:
? f(n) = f(n)
n $in N
have a N = 0
```
Binder recovery traverses all object constructors in the targets and proof
actions. A genuinely unused binder is permitted; no redundant reflexive goal
is required. Nested binders and module-qualified identifiers retain their own
identity. Normal JSON failure details identify the failing induction phase
and zero-based goal/proof-step index; Detailed JSON also contains both
successful base and step proof trees.
```litex
abstract_prop P(n)
claim:
? forall n Z:
$P(0)
forall k Z:
k >= 0
$P(k)
=>:
$P(k + 1)
n >= 0
=>:
$P(n)
by induc n from 0:
? $P(n)
? from n = 0:
$P(0)
? induc:
$P(n + 1)
```
### S43. Strong induction
**Public form:** `by strong_induc n from lower:`.
**Mathematical function.** Use the invariant for all smaller admissible indices to prove the current index.
**Before execution.** The measure, bound and supported discrete goal shape check; the strong hypothesis is limited to smaller in-domain indices.
**Execution and result.** Check the base and strong inductive obligations, then publish the universal result.
**Nearest boundary.** The hypothesis does not include the current index or an out-of-domain smaller value.
**Checked example.**
```litex
by strong_induc m from 0:
? m = m
m = m
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_induc_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S44. Finite range iteration
**Public form:** `by for:`.
**Mathematical function.** Prove a universal over supported finite integer ranges or finite Cartesian domains.
**Before execution.** The domain is a supported finite iterable shape and all generated conditional goals are WD.
**Execution and result.** Enumerate the supported domain, execute local proof steps for each active assignment, and store the original universal.
**Nearest boundary.** This is not an arbitrary-set loop or a general-purpose programming for statement.
**Checked example.**
```litex
by for:
? forall n range(0, 3):
n < 3
n < 3
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_for_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S45. Set extensionality
**Public form:** `by extension A = B`.
**Mathematical function.** Prove two sets equal by both membership directions.
**Before execution.** Both objects are WD and the two subset obligations verify; the block form may establish needed intermediates.
**Execution and result.** Check A subset B and B subset A, then store ordinary equality with extensionality evidence.
**Nearest boundary.** One inclusion is insufficient. Use function extensionality when proving callable equality through complete input domains.
**Checked example.**
```litex
by extension intersect(R, R) = R
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_extension_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S46. Function extensionality
**Public form:** `by fn_extension f = g`.
**Mathematical function.** Prove functions equal from equal complete input domains and pointwise agreement.
**Before execution.** Both callable interfaces are established, complete domains agree, and values agree at every admissible input.
**Execution and result.** Check domain and pointwise obligations, then store ordinary equality f = g for later congruence.
**Nearest boundary.** Agreement at one input or equality of a codomain does not establish function equality. Local agreement belongs in a forall.
**Checked example.**
```litex
have fn f(x R) R = x
have fn g(x R) R = x
by fn_extension f = g
have fn add1(x R, y R) R = x + y
have fn add2(a R, b R) R = a + b
by fn_extension add1 = add2
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_fn_extension_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Complete-domain function extensionality
> **Preview:** `by fn_extension` proves ordinary function
> equality `f = g` when both sides have equal complete input domains and
> the reconstructed pointwise forall succeeds. Domains may match by binder
> alpha equality or by checked inclusion in both directions, including guards.
> Return upper bounds may differ. Each curried application layer proves its
> own equality; returned functions are not flattened. It stores `f = g`, not a
> separate `$fn_eq` fact. One-line and block forms mirror `by extension`:
>
```litex
have fn f(x R) R = x
have fn g(x R) R = x
by fn_extension f = g
```
>
**Contextual alternative:** the same previously declared `f` and `g`.
```litex
by fn_extension f = g
```
>
> Local agreement on a proper subset of the domain remains an ordinary
> `forall`; global extensionality still requires equal complete domains.
### S47. Explicit definition folding
**Public form:** `by def positive_fact`.
**Mathematical function.** Prove a concrete user or builtin predicate by its exact defining obligations.
**Before execution.** The target is a supported positive definitional fact and every instantiated clause verifies.
**Execution and result.** Resolve the concrete definition, check all clauses, and store the target with explicit definition provenance.
**Nearest boundary.** Closed truth and an explicit definition proof can have different routes. For example prime(5) computes directly, but by def prime(5) still requires its trial-divisor universal.
**Checked example.**
```litex
prop is_zero(x R):
x = 0
by def $is_zero(0)
```
**Source:** [implementation](../src/execute/execute_by_stmt/exec_by_def_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Definition search versus an explicit fold
At the top-level verification entry, an ordinary positive concrete predicate may
be proved from its definition before Litex tries known `forall` facts or user
strategies. Litex instantiates the `prop`, verifies every clause with the full
verifier, and accepts the positive predicate only after all clauses succeed.
This includes packaging an exact existential clause already established by a
`witness`. Once an accepted positive predicate is stored, forward inference may
also expose its positive defining consequences; that is the other direction.
Use the canonical inline form when the proof should request and record the
definition route explicitly:
```text
by def $P(args)
```
> **Preview:** `$P` may be plain or qualified
> (`$export::P`, `$Mod::export::P`, `$Mod:::P`). Definition expansion looks up
> the concrete `prop` in the live Env stack or in a finished export file's Env.
> Ambient by-definition search and statement `by def` share this lookup. Other
> modules' stored facts are still not searched automatically.
>
> The same ByDefinition stage also expands **builtin** positive predicates that
> have an official definition (for example `$subset` / `$superset` → membership
> forall; `$proper_subset` → subset plus
> inequality; `$injective` / `$surjective` / `$bijective`; `$prime` / `$coprime` /
> `$dvd`; `$is_choice_function_for`). These builtins are **dedicated
> `AtomicFact` variants** in the kernel AST; `NormalAtomicFact` is only for
> user-defined `$prop(...)`. User `prop` and builtin predicates share one fork:
> builtin first, then user `prop`. Design note:
> `src/execute/execute_fact_stmt/verify_atomic_fact/verify_atomic_except_equality/by_definition_design.md`.
> Finite list-set inclusions such as `{1} $subset {1, 2}` use the same
> forall definition; every resulting membership obligation must verify.
Unlike ordinary atomic verification, explicit `by def` rechecks the definition
even if the target predicate is already known. It accepts exactly one positive
atomic target with a supported concrete or official builtin definition. The
execution entry calls definition expansion directly; known facts, computation,
strategies, and rewriting cannot replace this first step. Defining clauses use
the full ordinary verifier. Arithmetic comparisons, equalities, and SetBuilder
membership have no entry in this definition interface, so requests such as
`by def 1 > 0` and `by def 1 $in {x R: x > 0}` fail even though the ordinary
facts verify. The older `by def:` goal block remains accepted for compatibility.
`by def` also names the mathematical-definition route for these builtin
positive forms: subset, superset, proper subset, proper superset,
`$prime`, `$coprime`, `$dvd`, `$injective`, `$surjective`, `$bijective`,
`$is_choice_function_for`.
The prime definition currently requires a separately verified trial-divisor
`forall`; bare `by def $prime(5)` fails. Ordinary `$prime(5)` remains supported
by closed-numeric computation.
`$fn_eq` and `$fn_eq_in` are removed.
When a grouped universal law binds shared convenience variables, a conclusion
may use only some of them. Litex stores the corresponding reduced universal
rule when every omitted parameter has an independent, known-nonempty domain.
For example, a clause using only `a` and `x` inside
`forall a, b R, x, y E` becomes reusable as a rule over `a` and `x` when `E`
is nonempty. It does not make this projection across an empty or unresolved
omitted domain.
Automatic definition verification does not manufacture witnesses for
existential clauses such as basis, span, and linear combination. It can package
the predicate after the required existential fact has already been proved.
### S48. Register reflexive predicate laws
**Public form:** `register reflexive: ? forall ...`.
**Mathematical function.** Register a proved reflexive law for a concrete binary predicate.
**Before execution.** The exact binary-predicate forall shape matches, the concrete predicate exists, and the universal law verifies.
**Execution and result.** Check the shape and predicate arity, verify the law in a local scope, then store the reusable rewrite-property route.
**Nearest boundary.** There is one shaped goal and no indented proof body. Registration cannot assume an unproved law or attach this interface to an arbitrary arity.
**Checked example.**
```litex
prop same(x set, y set):
x = y
register reflexive:
? forall x set:
$same(x, x)
have a set
$same(a, a)
```
**Source:** [implementation](../src/execute/execute_register_stmt/exec_register_reflexive_prop_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
#### Registration shape and execution contract
The following forms verify and register reusable behavior for a user-defined
binary predicate. Spell them as `register reflexive` / `register symmetric` /
`register transitive`. Each takes exactly one shaped `? forall …` goal and
**no** indented proof body. Prove the forall in the ambient environment first
(or rely on ordinary search / `by def`); the statement only registers the
rewrite property.
| Form | Required mathematical shape | Later use |
|---|---|---|
| `register reflexive` | `P(x, x)` | Close reflexive positive goals. |
| `register symmetric` | One nontrivial argument permutation | Retry positive goals in that permutation. |
| `register transitive` | `P(x, y)` and `P(y, z)` imply `P(x, z)` | Store non-adjacent chain consequences. |
> **Preview:** older spellings `by reflexive_prop` / `by symmetric_prop` /
> `by transitive_prop` are removed.
### S49. Register symmetric predicate laws
**Public form:** `register symmetric: ? forall ...`.
**Mathematical function.** Register a proved symmetric law for a concrete binary predicate.
**Before execution.** The exact binary-predicate forall shape matches, the concrete predicate exists, and the universal law verifies.
**Execution and result.** Check the shape and predicate arity, verify the law in a local scope, then store the reusable rewrite-property route.
**Nearest boundary.** There is one shaped goal and no indented proof body. Registration cannot assume an unproved law or attach this interface to an arbitrary arity.
**Checked example.**
```litex
prop same(x set, y set):
x = y
register symmetric:
? forall x, y set:
$same(x, y)
=>:
$same(y, x)
forall a, b set:
$same(a, b)
=>:
$same(b, a)
```
**Source:** [implementation](../src/execute/execute_register_stmt/exec_register_symmetric_prop_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S50. Register transitive predicate laws
**Public form:** `register transitive: ? forall ...`.
**Mathematical function.** Register a proved transitive law for a concrete binary predicate.
**Before execution.** The exact binary-predicate forall shape matches, the concrete predicate exists, and the universal law verifies.
**Execution and result.** Check the shape and predicate arity, verify the law in a local scope, then store the reusable rewrite-property route.
**Nearest boundary.** There is one shaped goal and no indented proof body. Registration cannot assume an unproved law or attach this interface to an arbitrary arity.
**Checked example.**
```litex
prop same(x set, y set):
x = y
register transitive:
? forall x, y, z set:
$same(x, y)
$same(y, z)
=>:
$same(x, z)
```
**Source:** [implementation](../src/execute/execute_register_stmt/exec_register_transitive_prop_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S51. Exact evaluation
**Public form:** `eval expression`.
**Closed-numeric source WD.** When the source is a closed numeric tree (number literals under arithmetic / integer / supported `sqrt`/`log` ops, no free identifiers), `eval` uses a dedicated linear well-definedness mode: child formation and non-carrier domain checks only, then one root `$in C` gate. This avoids the ordinary per-node `$in C` re-entry that is exponential on long left-associated products such as `2*2*…*2`. It does not change ordinary object WD for `let` / facts, and it does not write exploratory WD into ExecEnv memory.
**Mathematical function.** Compute a supported closed expression or algorithm call and record its result equality.
**Before execution.** Source/result expressions are WD; the exact computation and every executed algorithm defining equation must check.
**Execution and result.** Compute the value, verify the computation evidence, display the result, and store expression = value in the current scope.
**Nearest boundary.** A failed or out-of-domain computation commits no result. eval is not a proof-search command for arbitrary symbolic goals.
**Checked example.**
```litex
eval 2 + 3
2 + 3 = 5
```
**Source:** [implementation](../src/execute/execute_eval_stmt/exec_eval_stmt.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements).
### S52. Release a tuple definition
**Public form:** `release tuple def object`.
**Mathematical function.** Publish the exact `finite_seq` membership and coordinate facts of a checked tuple value or Cartesian member. Literal tuples and their direct stored aliases use a union of singleton coordinate sets; repeated coordinates keep their original length. When no literal value is known, a Cartesian member uses the union of its factor sets and retains each factor's coordinate bound.
**Before execution.** A checked tuple value or Cartesian membership supplies the shape. The complete domain must equal `closed_range(1,n)`. Every return premise, generated membership and coordinate must check before publication.
**Execution and result.** Store the membership and each coordinate through the ordinary fact store, with source locations and FactIds. `tuple()` releases `finite_seq({},0)` without coordinates; `tuple(a)` releases `finite_seq({a},1)` and is printed as `(a,)` so it cannot be mistaken for scalar grouping. Failed statements and local sketches publish no partial package.
**Nearest boundary.** Scalars, ill-defined values and infinite-domain functions reject. The command does not discover arbitrary function bodies, does not traverse transitive alias chains, and does not publish size, image or dimension facts. A function with complete domain `N+` cannot become a length-two function by this command or by `fn_set_member`.
**Checked example.**
```litex
let t=(1,2)
release tuple def t
t $in finite_seq(union({1},{2}),2)
t(1)=1
t(2)=2
```
**Source:** [executor](../src/execute/execute_release_tuple_def_stmt.rs), [runnable tracer](../examples/stmt_nodes/release_and_expand/release_tuple_def.lit).
**Related entries:** [O78 Finite tuples](#o78-finite-tuples). `release cart def cart(A,B)` publishes the complete set definition described there; this command publishes facts about an individual value.
## Object dictionary
Well-definedness (WD) checks child expressions before the current operation’s
domain conditions. Result membership and other properties are established by
the corresponding fact rules. Each entry lists its conditions, supported
properties, and examples.
| ID | Public form | Mathematical role | Example status |
|---|---|---|---|
| [O01](#o01-division) | `a / b` | Division | checked |
| [O02](#o02-names-and-qualified-references) | `name; export::name; module::export::name; module:::name` | Names and qualified references | checked |
| [O03](#o03-function-applications) | `f(arguments)` | Function applications | checked |
| [O04](#o04-exact-numeric-literals) | `integer or decimal literal` | Exact numeric literals | checked |
| [O05](#o05-imaginary-unit) | `i` | Imaginary unit | checked |
| [O06](#o06-eulers-number) | `e` | Euler’s number | checked |
| [O07](#o07-pi) | `pi` | Pi | checked |
| [O08](#o08-natural-numbers-including-zero-n) | `N` | Natural numbers including zero: N | checked |
| [O09](#o09-positive-natural-numbers-n) | `N+; Z+` | Positive natural numbers: N+ | checked |
| [O10](#o10-integers-z) | `Z` | Integers: Z | checked |
| [O11](#o11-rational-numbers-q) | `Q` | Rational numbers: Q | checked |
| [O12](#o12-real-numbers-r) | `R` | Real numbers: R | checked |
| [O13](#o13-complex-numbers-c) | `C` | Complex numbers: C | checked |
| [O14](#o14-positive-rationals-q) | `Q+` | Positive rationals: Q+ | checked |
| [O15](#o15-positive-reals-r) | `R+` | Positive reals: R+ | checked |
| [O16](#o16-negative-rationals-q-) | `Q-` | Negative rationals: Q- | checked |
| [O17](#o17-negative-integers-z-) | `Z-` | Negative integers: Z- | checked |
| [O18](#o18-negative-reals-r-) | `R-` | Negative reals: R- | checked |
| [O19](#o19-nonzero-rationals-q) | `Q*` | Nonzero rationals: Q* | checked |
| [O20](#o20-nonzero-integers-z) | `Z*` | Nonzero integers: Z* | checked |
| [O21](#o21-nonzero-reals-r) | `R*` | Nonzero reals: R* | checked |
| [O22](#o22-nonzero-complexes-c) | `C*` | Nonzero complexes: C* | checked |
| [O23](#o23-addition) | `a + b` | Addition | checked |
| [O24](#o24-subtraction) | `a - b` | Subtraction | checked |
| [O25](#o25-additive-inverse) | `-a` | Additive inverse | checked |
| [O26](#o26-multiplication) | `a * b` | Multiplication | checked |
| [O27](#o27-powers) | `a^b` | Powers | checked |
| [O28](#o28-real-absolute-value) | `abs(x)`, `\|x\|` | Real absolute value | checked |
| [O29](#o29-minimum-of-two-reals) | `min(a, b)` | Minimum of two reals | checked |
| [O30](#o30-maximum-of-two-reals) | `max(a, b)` | Maximum of two reals | checked |
| [O31](#o31-floor) | `floor(x)` | Floor | checked |
| [O32](#o32-ceiling) | `ceil(x)` | Ceiling | checked |
| [O33](#o33-sign) | `sign(x)` | Sign | checked |
| [O34](#o34-integer-remainder) | `a % d` | Integer remainder | checked |
| [O35](#o35-integer-quotient) | `quot(a, d)` | Integer quotient | checked |
| [O36](#o36-greatest-common-divisor) | `gcd(a, b)` | Greatest common divisor | checked |
| [O37](#o37-least-common-multiple) | `lcm(a, b)` | Least common multiple | checked |
| [O38](#o38-factorial) | `factorial(n); n!` | Factorial | checked |
| [O39](#o39-sine) | `sin(x)` | Sine | checked |
| [O40](#o40-cosine) | `cos(x)` | Cosine | checked |
| [O41](#o41-tangent) | `tan(x)` | Tangent | checked |
| [O42](#o42-cotangent) | `cot(x)` | Cotangent | checked |
| [O43](#o43-principal-arcsine) | `arcsin(x)` | Principal arcsine | checked |
| [O44](#o44-principal-arccosine) | `arccos(x)` | Principal arccosine | checked |
| [O45](#o45-principal-arctangent) | `arctan(x)` | Principal arctangent | checked |
| [O46](#o46-principal-arccotangent) | `arccot(x)` | Principal arccotangent | checked |
| [O47](#o47-exponential) | `exp(x)` | Exponential | checked |
| [O48](#o48-natural-logarithm) | `ln(x)` | Natural logarithm | checked |
| [O49](#o49-logarithm-with-specified-base) | `log(b, x)` | Logarithm with specified base | checked |
| [O50](#o50-principal-square-root) | `sqrt(x)` | Principal square root | checked |
| [O51](#o51-real-coordinate) | `re(z)` | Real coordinate | checked |
| [O52](#o52-imaginary-coordinate) | `img(z)` | Imaginary coordinate | checked |
| [O53](#o53-complex-modulus) | `C_abs(z)` | Complex modulus | checked |
| [O54](#o54-binary-union) | `union(A, B); A ∪ B` | Binary union | checked |
| [O55](#o55-binary-intersection) | `intersect(A, B); A ∩ B` | Binary intersection | checked |
| [O56](#o56-set-difference) | `set_minus(A, B)` | Set difference | checked |
| [O57](#o57-union-of-a-family) | `family_union(F)` | Union of a family | checked |
| [O58](#o58-intersection-of-a-family) | `family_intersect(F)` | Intersection of a family | checked |
| [O59](#o59-power-set) | `power_set(A)` | Power set | checked |
| [O60](#o60-indexed-union) | `index_union(I, X, A)` | Indexed union | checked |
| [O61](#o61-indexed-intersection) | `index_intersect(I, X, A)` | Indexed intersection | checked |
| [O62](#o62-indexed-cartesian-product) | `index_cart(I, S, g)` | Indexed Cartesian product | checked |
| [O63](#o63-finite-displayed-sets) | `{a, b, ...}; {}` | Finite displayed sets | checked |
| [O64](#o64-bounded-set-builders) | `{x A: filters}` | Bounded set builders | checked |
| [O65](#o65-half-open-integer-ranges) | `range(a, b)` | Half-open integer ranges | checked |
| [O66](#o66-closed-integer-ranges) | `closed_range(a, b); a...b` | Closed integer ranges | checked |
| [O67](#o67-finite-sequence-spaces) | `finite_seq(S, n)` | Finite sequence spaces | checked |
| [O68](#o68-infinite-sequence-spaces) | `seq(S)` | Infinite sequence spaces | checked |
| [O69](#o69-open-lower-rays) | `'(a,)` | Open lower rays | checked |
| [O70](#o70-closed-lower-rays) | `'[a,)` | Closed lower rays | checked |
| [O71](#o71-open-upper-rays) | `'(,b)` | Open upper rays | checked |
| [O72](#o72-closed-upper-rays) | `'(,b]` | Closed upper rays | checked |
| [O73](#o73-open-real-intervals) | `'(a,b)` | Open real intervals | checked |
| [O74](#o74-open-closed-real-intervals) | `'(a,b]` | Open-closed real intervals | checked |
| [O75](#o75-closed-open-real-intervals) | `'[a,b)` | Closed-open real intervals | checked |
| [O76](#o76-closed-real-intervals) | `'[a,b]` | Closed real intervals | checked |
| [O77](#o77-finite-cartesian-products) | `cart(S1, ..., Sn); S1 × S2` | Finite Cartesian products | checked |
| [O78](#o78-finite-tuples) | `(a, b, ...); tuple(a, ...); tuple()` | Finite tuples | checked |
| [O79](#o79-function-spaces) | `fn(parameters: guards) T` | Function spaces | checked |
| [O80](#o80-anonymous-functions) | `fn(parameters: guards) T {body}` | Anonymous functions | checked |
| [O81](#o81-function-images) | `fn_range(f)` | Function images | checked |
| [O82](#o82-sums-over-integer-ranges) | `sum(a,b,f)` | Sums over integer ranges | checked |
| [O83](#o83-products-over-integer-ranges) | `product(a,b,f)` | Products over integer ranges | checked |
| [O84](#o84-finite-set-sums) | `finite_set_sum(S,f)` | Finite-set sums | checked |
| [O85](#o85-finite-set-products) | `finite_set_product(S,f)` | Finite-set products | checked |
| [O86](#o86-ordered-folds) | `reduce(a,b,f,op,seed)` | Ordered folds | checked |
| [O87](#o87-finite-set-folds) | `finite_set_reduce(S,f,op,seed)` | Finite-set folds | checked |
| [O88](#o88-finite-cardinality) | `finite_set_size(S)` | Finite cardinality | checked |
| [O89](#o89-maximum-of-a-finite-set) | `finite_set_max(S)` | Maximum of a finite set | checked |
| [O90](#o90-minimum-of-a-finite-set) | `finite_set_min(S)` | Minimum of a finite set | checked |
| [O91](#o91-struct-carriers) | `&Name` | Struct carriers | checked |
| [O92](#o92-definition-owned-field-access) | `value.field` | Definition-owned field access | checked |
| [O93](#o93-template-instances) | `\Name` | Template instances | checked |
### O01. Division
**Public form:** `a / b`.
**Mathematical function:** divide a complex scalar by a nonzero complex scalar.
Real and rational inputs can support more specific result membership. Integer
inputs do not imply an integer quotient.
### Domain and well-definedness
| Obligation | Meaning | Typical way to establish it |
|---|---|---|
| Both child expressions are WD | Their names, applications, and internal operations are legal | Introduce their names; meet their own domain conditions |
| `b != 0` | The divisor is nonzero | A justified premise, a nonzero carrier, a positive carrier, or a proved inequality |
| `a $in C` | The dividend is a complex scalar | Stored carrier membership, numeric inclusion, or structural membership |
| `b $in C` | The divisor is a complex scalar | The same carrier routes |
The current WD implementation checks child objects first, then nonzero,
then the two complex memberships. A stated real carrier supports complex
membership through the numeric inclusion relationship; it does not supply
nonzeroness on its own.
For a theorem about arbitrary nonzero reals, the local premise is sufficient:
```litex
forall x R:
x != 0
=>:
1 / x = 1 / x
```
The premise is part of the mathematical statement. It is not an assumption
that may be added to an unrelated theorem merely to make its proof pass.
For a reusable function, place the condition in the signature as in S01.
#### Common builtin properties
Every row below requires all expressions to be WD. Nonzero conditions needed
for division remain required even in a formula that looks trivially true.
| Property | Additional mathematical conditions | Current use |
|---|---|---|
| `a / 1 = a` | `a $in C` | State the equality directly |
| `0 / b = 0` | `b $in C`, `b != 0` | State the equality directly |
| `b / b = 1` | `b $in C`, `b != 0` | State the equality directly |
| `(a / b) * b = a` | `a, b $in C`, `b != 0` | Direct identity; useful as an algebraic bridge |
| `a / b $in R` | `a, b $in R`, `b != 0` | Carrier/structural membership after WD |
| `a / b != 0` | `a, b $in R`, `a != 0`, `b != 0` | Direct builtin verification in the checked example |
The first four identities are checked together here:
```litex
forall a, b C:
b != 0
=>:
a / 1 = a
0 / b = 0
b / b = 1
(a / b) * b = a
```
Closure in the reals:
```litex
forall a, b R:
b != 0
=>:
a / b $in R
```
A nonzero numerator and divisor give a nonzero quotient:
```litex
forall a, b R:
a != 0
b != 0
=>:
a / b != 0
```
These are representative native division properties. Rational carriers,
quotient/remainder, sign and other transformations are indexed through the
related object and atomic-fact entries; a larger combined expression may need
the explicit bridge described below.
#### Boundary: integer division
**Expected rejection — phase `search_proof`:**
```litex
have a Z = 1
have b Z = 2
a / b $in Z
```
`a / b` is meaningful here, but its value is `1 / 2`, which is not an integer.
The correction is to use the actual result carrier, or to supply and prove a
relevant divisibility condition when an integer result is mathematically needed.
Membership and nonmembership of this closed quotient are checked in F01.
**Evidence:** D01–D06.
**Source:** [division WD](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs),
[structural membership](../src/execute/execute_fact_stmt/verify_atomic_fact/search_structural_membership.rs),
[nonzero quotient rule](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_atomic_except_equality/search_atomic_except_equality_fact_proof_by_builtin_rules/not_equal.rs).
**Related:** [S01](#s01-expression-defined-functions), [P01](#p01-reflexivity-does-not-bypass-well-definedness),
[P04](#p04-connect-division-and-multiplication-explicitly).
### O02. Names and qualified references
**Public form:** `name; export::name; module::export::name; module:::name`.
**Mathematical function.** Refer to an introduced mathematical object or a visible exported definition. Qualified spelling changes lookup, not the object’s mathematical role.
**Well-definedness and domain.** The name and definition owner must be visible at this source position. Export loading order and manifest aliases govern qualified paths.
**Common native properties and proof routes.** Stored equality and carrier information can be reused. Equal aliases may support congruence; a name does not imply any arbitrary numerical value.
**Nearest boundary.** Undefined names and not-yet-loaded exports are rejected. Manifest dependencies are not source import statements. A two-step alias can require a direct value equality before arithmetic; the example deliberately exposes b = a = 2.
**Checked example.**
```litex
have a R = 2
a = 2
let b = a
b = a = 2
b + 1 = 3
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O03. Function applications
**Public form:** `f(arguments)`.
**Mathematical function.** Evaluate or refer to the value of a callable mathematical object at admissible arguments.
**Well-definedness and domain.** The callable signature is known; arity, every argument carrier, instantiated guards and nested call WD must verify. Finite function calls require their exact input domain.
The parser supports identifier, anonymous-function, definition-owned field,
and template-instance application heads. Name another callable expression
with `let` when its raw object shape is not a supported call head. A name for
a function-space object does not make that space a callable function value.
**Common native properties and proof routes.** Legal applications satisfy the declared return carrier. Expression-defined functions expose defining equalities; opaque functions give no arbitrary evaluation formula.
**Nearest boundary.** A real input does not meet a nonzero guard by itself. Field, template and returned-function calls retain their own signature owner.
**Checked example.**
```litex
have fn shift(x R) R = x + 1
shift(2) = 3
forall x R:
shift(x) $in R
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/core.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [S01 Expression-defined functions](#s01-expression-defined-functions), [S46 Function extensionality](#s46-function-extensionality).
**Further detail:** [Function-valued arguments and indexed signatures](#function-valued-arguments-and-indexed-signatures).
### O04. Exact numeric literals
**Public form:** `integer or decimal literal`.
**Mathematical function.** Represent exact numeric constants; a decimal is an exact value rather than an approximate host float.
**Well-definedness and domain.** The token is a valid supported numeral. Negative literals use the unary negation operation.
**Common native properties and proof routes.** Closed arithmetic and numeric carrier membership use exact calculation. Natural numbers include zero.
**Nearest boundary.** A decimal’s appearance does not make it an integer. Use an explicit nonmembership check when needed.
**Checked example.**
```litex
0.1 + 0.2 = 0.3
1 / 2 $in Q
not 1 / 2 $in Z
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O05. Imaginary unit
**Public form:** `i`.
**Mathematical function.** The complex scalar whose square is -1.
**Well-definedness and domain.** Native named constant; no input-domain parameter.
**Common native properties and proof routes.** i $in C; re(i) = 0 and img(i) = 1; i^2 = -1.
**Nearest boundary.** A constant is an object; an equation or membership about it is a fact. Exact symbolic support does not imply arbitrary transcendental evaluation.
**Checked example.**
```litex
i^2 = -1
re(i) = 0
img(i) = 1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O06. Euler’s number
**Public form:** `e`.
**Mathematical function.** The native positive real constant used by exponential and logarithm operations.
**Well-definedness and domain.** Native named constant; no input-domain parameter.
**Common native properties and proof routes.** e $in R+; exp(1) = e and ln(e) = 1.
**Nearest boundary.** A constant is an object; an equation or membership about it is a fact. Exact symbolic support does not imply arbitrary transcendental evaluation.
**Checked example.**
```litex
e $in R+
exp(1) = e
ln(e) = 1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
#### Primitive constants and evaluation
`e` and `pi` are primitive scalar objects. They are parsed directly into
dedicated object forms: neither is a decimal `Number`, an ordinary `Atom`, nor
a name introduced by a Litex definition. In particular, `std/basics` does not
define or trust either constant.
Both names are hard-reserved and cannot be rebound as definitions,
parameters, indices, or fields. Longer names such as `e1`, `epsilon`, and
`pi_value` remain ordinary identifiers.
The symbolic evaluator does not replace these constants with decimal runtime
values.
### O07. Pi
**Public form:** `pi`.
**Mathematical function.** The native positive real circle constant used by trigonometric rules.
**Well-definedness and domain.** Native named constant; no input-domain parameter.
**Common native properties and proof routes.** pi $in R+; sin(pi) = 0 and cos(pi) = -1.
**Nearest boundary.** A constant is an object; an equation or membership about it is a fact. Exact symbolic support does not imply arbitrary transcendental evaluation.
**Checked example.**
```litex
pi $in R+
sin(pi) = 0
cos(pi) = -1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O08. Natural numbers including zero: N
O08–O22 list the number sets and their signed or nonzero subsets. Membership
provides the conditions defining that set, without choosing a specific value.
For example, `x $in R` does not imply `x != 0`, whereas `x $in R+` implies
`x > 0`. `Z+` is an alias for `N+`; use the spellings listed in each entry.
**Public form:** `N`.
**Mathematical function.** Natural numbers including zero. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** 0 <= x. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
0 $in N
2 $in N
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O09. Positive natural numbers: N+
**Public form:** `N+; Z+`.
`Z+` is normalized to `N+` during parsing; both spellings denote the same set `{1, 2, 3, ...}`. Canonical output uses `N+`, including in variable declarations and function domains or codomains.
**Mathematical function.** Positive natural numbers. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** 0 < x; 0 <= x; x != 0. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
1 $in N+
2 $in Z+
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O10. Integers: Z
**Public form:** `Z`.
**Mathematical function.** Integers. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** Z is included in Q, R and C; integers are closed under +, -, *. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
-2 $in Z
0 $in Z
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O11. Rational numbers: Q
**Public form:** `Q`.
**Mathematical function.** Rational numbers. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** Q is included in R and C; division needs a nonzero divisor. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
1 / 2 $in Q
-3 $in Q
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O12. Real numbers: R
**Public form:** `R`.
**Mathematical function.** Real numbers. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** R is included in C; real arithmetic and order retain their domain guards. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
sqrt(2) $in R
1 / 2 $in R
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O13. Complex numbers: C
**Public form:** `C`.
**Mathematical function.** Complex numbers. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** Complex arithmetic is available; ordered comparisons still require real operands. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
i $in C
2 + 3 * i $in C
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O14. Positive rationals: Q+
**Public form:** `Q+`.
**Mathematical function.** Positive rationals. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** 0 < x; 0 <= x; x != 0; x $in Q. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
1 / 2 $in Q+
2 $in Q+
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O15. Positive reals: R+
**Public form:** `R+`.
**Mathematical function.** Positive reals. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** 0 < x; 0 <= x; x != 0; x $in R. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
1 / 2 $in R+
2 $in R+
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O16. Negative rationals: Q-
**Public form:** `Q-`.
**Mathematical function.** Negative rationals. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** x < 0; x <= 0; x != 0; x $in Q. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
-1 / 2 $in Q-
-2 $in Q-
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O17. Negative integers: Z-
**Public form:** `Z-`.
**Mathematical function.** Negative integers. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** x < 0; x <= 0; x != 0; x $in Z. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
-1 $in Z-
-2 $in Z-
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O18. Negative reals: R-
**Public form:** `R-`.
**Mathematical function.** Negative reals. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** x < 0; x <= 0; x != 0; x $in R. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
-1 / 2 $in R-
-2 $in R-
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O19. Nonzero rationals: Q*
**Public form:** `Q*`.
**Mathematical function.** Nonzero rationals. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** x != 0; x $in Q, without choosing its sign. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
1 / 2 $in Q*
-2 $in Q*
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O20. Nonzero integers: Z*
**Public form:** `Z*`.
**Mathematical function.** Nonzero integers. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** x != 0; x $in Z, without choosing its sign. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
1 $in Z*
-2 $in Z*
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O21. Nonzero reals: R*
**Public form:** `R*`.
**Mathematical function.** Nonzero reals. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** x != 0; x $in R, without choosing its sign. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
1 / 2 $in R*
-2 $in R*
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O22. Nonzero complexes: C*
**Public form:** `C*`.
**Mathematical function.** Nonzero complexes. These are mathematical set objects, not different runtime host types.
**Well-definedness and domain.** Native set object. Membership and a typed declaration establish facts about its elements; the set object itself requires no input guard.
**Common native properties and proof routes.** x != 0; x $in C; real sign is not available for general complex values. Signed/nonzero consequences are stored by inference; widening to larger standard carriers is available to structural membership checking.
**Checked example.**
```litex
i $in C*
2 $in C*
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O23. Addition
**Public form:** `a + b`.
**Mathematical function.** Scalar addition.
**Well-definedness and domain.** a, b $in C. Every child expression must first be WD.
**Common native properties and proof routes.** Commutativity, associativity, zero identity, and appropriate numeric carrier closure.
**Nearest boundary.** Integers/reals widen to C; a general complex result is not automatically ordered.
**Checked example.**
```litex
2 + 3 = 5
forall a, b C:
a + b = b + a
a + 0 = a
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O24. Subtraction
**Public form:** `a - b`.
**Mathematical function.** Scalar difference.
**Well-definedness and domain.** a, b $in C. Every child expression must first be WD.
**Common native properties and proof routes.** a - a = 0; a - 0 = a; integer/real/complex closure.
**Nearest boundary.** Natural-number subtraction can be negative; N is not closed under arbitrary subtraction.
**Checked example.**
```litex
3 - 5 = -2
forall a C:
a - a = 0
a - 0 = a
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O25. Additive inverse
**Public form:** `-a`.
**Mathematical function.** The additive inverse of a scalar.
**Well-definedness and domain.** a $in C. Every child expression must first be WD.
**Common native properties and proof routes.** -(-a) = a; a + (-a) = 0; appropriate carrier closure.
**Nearest boundary.** Unary minus is distinct from binary subtraction and does not supply order on general C.
**Checked example.**
```litex
-(-3) = 3
forall a C:
a + (-a) = 0
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O26. Multiplication
**Public form:** `a * b`.
**Mathematical function.** Scalar multiplication.
**Well-definedness and domain.** a, b $in C. Every child expression must first be WD.
**Common native properties and proof routes.** Commutativity, associativity, one/zero identities and carrier closure.
**Nearest boundary.** Cancelling a factor requires a justified nonzero condition; zero factors cannot be divided away. Exact evaluation also declines products whose normalized decimal length would exceed the shared exact-decimal digit budget used by integer powers and factorial — including when each factor alone is within budget (for example `10^99 * 10^99`).
**Checked example.**
```litex
2 * 3 = 6
forall a, b C:
a * b = b * a
a * 1 = a
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O27. Powers
**Public form:** `a^b`.
**Mathematical function.** A native scalar power in a supported domain branch.
**Well-definedness and domain.** R or C base with exponent in N; nonzero C base with exponent in Z; positive real base with any real exponent; nonnegative real base with a positive real exponent; also closed positive rational base with a rational noninteger exponent. Every child expression must first be WD. Natural powers retain `0^0=1`.
**Common native properties and proof routes.** Closed powers and supported exponent identities. Natural exponent zero uses the native a^0 = 1 convention.
**Nearest boundary.** Negative bases with noninteger exponents and general complex exponents remain unsupported. Zero to a negative power is rejected. WD does not imply that every symbolic identity or exact calculation is available. Exact integer-power evaluation declines results above the shared exact-decimal digit budget; multiplication chains cannot bypass that budget by combining in-budget powers.
**Checked example.**
```litex
2^3 = 8
4^(1 / 2) = 2
2^(-1) = 1 / 2
forall a R+, t R:
a^t $in R
forall x R:
exp(x) = e^x
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
For checked signs, parity and order recipes, see
[R15 power signs and monotonicity](#r15-power-signs-and-two-kinds-of-monotonicity).
### O28. Real absolute value
**Public form:** `abs(x)` or `|x|`; see the [bars input preview](#absolute-value-bars-preview).
**Mathematical function.** The nonnegative magnitude of a real scalar.
**Well-definedness and domain.** x $in R. Every child expression must first be WD.
**Common native properties and proof routes.** |-x| = |x|; |x| >= 0; square/magnitude and signed-value rules.
**Nearest boundary.** Use C_abs for a general complex value rather than silently treating i as real.
**Checked example.**
```litex
|-3| = 3
|0| = 0
forall x R:
|x| >= 0
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O29. Minimum of two reals
**Public form:** `min(a, b)`.
**Mathematical function.** The smaller of two real numbers.
**Well-definedness and domain.** a, b $in R. Every child expression must first be WD.
**Common native properties and proof routes.** Commutativity, idempotence and lower-bound laws.
**Nearest boundary.** Arguments are real, not arbitrary sets or unordered complex scalars.
**Checked example.**
```litex
min(3, 2) = 2
forall x R:
min(x, x) = x
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O30. Maximum of two reals
**Public form:** `max(a, b)`.
**Mathematical function.** The larger of two real numbers.
**Well-definedness and domain.** a, b $in R. Every child expression must first be WD.
**Common native properties and proof routes.** Commutativity, idempotence and upper-bound laws.
**Nearest boundary.** The binary operator differs from finite_set_max, whose input is one finite nonempty set.
**Checked example.**
```litex
max(-1, 2) = 2
forall x R:
max(x, x) = x
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O31. Floor
**Public form:** `floor(x)`.
**Mathematical function.** The greatest integer no greater than x.
**Well-definedness and domain.** x $in R. Every child expression must first be WD.
**Common native properties and proof routes.** Integer result; floor(x) <= x < floor(x) + 1; exact values for closed inputs.
**Nearest boundary.** For a negative input, floor rounds toward negative infinity, not toward zero.
**Checked example.**
```litex
floor(3.7) = 3
floor(-1.2) = -2
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O32. Ceiling
**Public form:** `ceil(x)`.
**Mathematical function.** The least integer no less than x.
**Well-definedness and domain.** x $in R. Every child expression must first be WD.
**Common native properties and proof routes.** Integer result; ceil(x) - 1 < x <= ceil(x); exact values for closed inputs.
**Nearest boundary.** Ceiling and floor differ at noninteger arguments, including negative ones.
**Checked example.**
```litex
ceil(3.2) = 4
ceil(-1.2) = -1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O33. Sign
**Public form:** `sign(x)`.
**Mathematical function.** The real sign value -1, 0 or 1.
**Well-definedness and domain.** x $in R. Every child expression must first be WD.
**Common native properties and proof routes.** Integer codomain and branches determined by positive, zero or negative x.
**Nearest boundary.** This is real sign, not the phase of a complex number.
**Checked example.**
```litex
sign(-3) = -1
sign(0) = 0
sign(2) = 1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O34. Integer remainder
**Public form:** `a % d`.
**Mathematical function.** Native integer remainder.
**Well-definedness and domain.** a, d $in Z and d != 0. Child WD is also required.
**Common native properties and proof routes.** For a positive divisor, the remainder is in [0,d). Closed signed dividends use the Euclidean remainder convention.
**Nearest boundary.** The divisor cannot be zero; this differs from real division.
**Checked example.**
```litex
(-7) % 3 = 2
7 % 3 = 1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O35. Integer quotient
**Public form:** `quot(a, d)`.
**Mathematical function.** The integer quotient in a = d * quot(a,d) + a % d.
**Well-definedness and domain.** a $in Z; d $in N+. Child WD is also required.
**Common native properties and proof routes.** Integer result and the quotient/remainder decomposition for a positive divisor.
**Nearest boundary.** The quotient interface requires a positive divisor, stricter than modulo’s nonzero integer divisor.
**Checked example.**
```litex
quot(-7, 3) = -3
quot(7, 3) = 2
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O36. Greatest common divisor
**Public form:** `gcd(a, b)`.
**Mathematical function.** The positive greatest common divisor of an integer pair not both zero.
**Well-definedness and domain.** a, b $in Z; a != 0 or b != 0. Child WD is also required.
**Common native properties and proof routes.** Positive natural result; sign-insensitivity, common divisibility and familiar closed values.
**Nearest boundary.** The disjunction excludes only the all-zero pair; proving one particular operand nonzero is not always necessary.
**Checked example.**
```litex
gcd(54, -24) = 6
gcd(0, 3) = 3
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
#### Positive common-divisor bound
`gcd(a,b)` requires integer arguments that are not both zero. A positive
common divisor satisfies `d <= gcd(a,b)` when `d $in N+`,
`a % d = 0`, and `b % d = 0` are proved. The
`PositiveCommonDivisorLeGcd` rule checks these three premises with the
inherited search permissions and records their evidence; it retains the
existing gcd and remainder WD requirements.
### O37. Least common multiple
**Public form:** `lcm(a, b)`.
**Mathematical function.** The nonnegative least common multiple of two integers.
**Well-definedness and domain.** a, b $in Z. Child WD is also required.
**Common native properties and proof routes.** Natural result; zero-input and sign-insensitivity laws.
**Nearest boundary.** Unlike gcd, lcm permits the all-zero pair. Distinguish the two domain contracts.
**Checked example.**
```litex
lcm(12, -18) = 36
lcm(0, 3) = 0
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O38. Factorial
**Public form:** `factorial(n); n!`.
**Mathematical function.** The factorial of a natural number.
**Well-definedness and domain.** n $in N. Child WD is also required.
**Common native properties and proof routes.** Positive natural result; 0! = 1 and the successor recurrence.
**Nearest boundary.** Negative or noninteger arguments do not satisfy the native factorial domain. Exact evaluation of `factorial(n)` / `n!` shares the integer-power exact-decimal digit budget: results whose normalized decimal length would exceed that budget decline calculation instead of expanding unbounded intermediates.
**Checked example.**
```litex
0! = 1
3! = 6
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O39. Sine
**Public form:** `sin(x)`.
**Mathematical function.** Sine as a native real operation.
**Well-definedness and domain.** x $in R. Establish guards before using the object.
**Common native properties and proof routes.** Real result, bounded by -1 and 1; oddness, periodicity and the Pythagorean identity.
**Nearest boundary.** Inverse composition in the opposite direction needs a principal-range restriction. Realness alone does not supply tangent/cotangent nonzero denominators.
**Checked example.**
```litex
sin(0) = 0
sin(pi / 2) = 1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
#### Native operator names and higher-order values
The names `sin`, `cos`, `tan`, `cot`, `arcsin`, `arccos`, `arctan`, and `arccot`
are hard-reserved. Their bare names are not first-class function values;
higher-order code can use `fn(x R) R {sin(x)}`. The evaluator does not assign
approximate runtime values to symbolic trigonometric expressions. The supported
exact identities, bounds, sign intervals, and monotonicity shapes are summarized
under [Trigonometric rules](#trigonometric-rules).
### O40. Cosine
**Public form:** `cos(x)`.
**Mathematical function.** Cosine as a native real operation.
**Well-definedness and domain.** x $in R. Establish guards before using the object.
**Common native properties and proof routes.** Real result, bounded by -1 and 1; evenness, periodicity and the Pythagorean identity.
**Nearest boundary.** Inverse composition in the opposite direction needs a principal-range restriction. Realness alone does not supply tangent/cotangent nonzero denominators.
**Checked example.**
```litex
cos(0) = 1
cos(pi) = -1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O41. Tangent
**Public form:** `tan(x)`.
**Mathematical function.** Tangent as a native real operation.
**Well-definedness and domain.** x $in R; cos(x) != 0. Establish guards before using the object.
**Common native properties and proof routes.** Real result; tan(x) = sin(x) / cos(x) in its domain.
**Nearest boundary.** Inverse composition in the opposite direction needs a principal-range restriction. Realness alone does not supply tangent/cotangent nonzero denominators.
**Checked example.**
```litex
tan(0) = 0
tan(pi / 4) = 1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O42. Cotangent
**Public form:** `cot(x)`.
**Mathematical function.** Cotangent as a native real operation.
**Well-definedness and domain.** x $in R; sin(x) != 0. Establish guards before using the object.
**Common native properties and proof routes.** Real result; cot(x) = cos(x) / sin(x) in its domain.
**Nearest boundary.** Inverse composition in the opposite direction needs a principal-range restriction. Realness alone does not supply tangent/cotangent nonzero denominators.
**Checked example.**
```litex
cot(pi / 4) = 1
cot(pi / 2) = 0
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O43. Principal arcsine
**Public form:** `arcsin(x)`.
**Mathematical function.** Principal arcsine as a native real operation.
**Well-definedness and domain.** x $in R; -1 <= x <= 1. Establish guards before using the object.
**Common native properties and proof routes.** Principal real result; sin(arcsin(x)) = x on [-1,1].
**Nearest boundary.** Inverse composition in the opposite direction needs a principal-range restriction. Realness alone does not supply tangent/cotangent nonzero denominators.
**Checked example.**
```litex
arcsin(0) = 0
arcsin(1) = pi / 2
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O44. Principal arccosine
**Public form:** `arccos(x)`.
**Mathematical function.** Principal arccosine as a native real operation.
**Well-definedness and domain.** x $in R; -1 <= x <= 1. Establish guards before using the object.
**Common native properties and proof routes.** Principal real result; cos(arccos(x)) = x on [-1,1].
**Nearest boundary.** Inverse composition in the opposite direction needs a principal-range restriction. Realness alone does not supply tangent/cotangent nonzero denominators.
**Checked example.**
```litex
arccos(1) = 0
arccos(0) = pi / 2
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O45. Principal arctangent
**Public form:** `arctan(x)`.
**Mathematical function.** Principal arctangent as a native real operation.
**Well-definedness and domain.** x $in R. Establish guards before using the object.
**Common native properties and proof routes.** Principal real result; tan(arctan(x)) = x, with its principal-range domain facts.
**Nearest boundary.** Inverse composition in the opposite direction needs a principal-range restriction. Realness alone does not supply tangent/cotangent nonzero denominators. The initial bare arctan(1) = pi / 4 goal missed current search; this entry demonstrates valid real output without claiming that exact evaluation route.
**Checked example.**
```litex
arctan(0) = 0
arctan(1) $in R
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O46. Principal arccotangent
**Public form:** `arccot(x)`.
**Mathematical function.** Principal arccotangent as a native real operation.
**Well-definedness and domain.** x $in R. Establish guards before using the object.
**Common native properties and proof routes.** Principal real result; cot(arccot(x)) = x; the zero value is pi/2 in the native convention.
**Nearest boundary.** Inverse composition in the opposite direction needs a principal-range restriction. Realness alone does not supply tangent/cotangent nonzero denominators. The initial bare arccot(1) = pi / 4 goal missed current search; the exact zero value and real-output membership are checked separately.
**Checked example.**
```litex
arccot(0) = pi / 2
arccot(1) $in R
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O47. Exponential
**Public form:** `exp(x)`.
**Mathematical function.** The native real exponential.
**Well-definedness and domain.** x $in R. Child WD also applies.
**Common native properties and proof routes.** Positive real codomain; exp(0) = 1; exp(1) = e; exponential/logarithm identities.
**Nearest boundary.** `exp(x)=e^x` is checked for real x through the positive-base power domain. General complex exponential arguments and complex exponents remain unsupported.
**Checked example.**
```litex
exp(0) = 1
exp(1) = e
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O48. Natural logarithm
**Public form:** `ln(x)`.
**Mathematical function.** The natural logarithm of a positive real.
**Well-definedness and domain.** x $in R; x > 0. Child WD also applies.
**Common native properties and proof routes.** Real codomain; ln(1) = 0; ln(e) = 1; inverse relations with exp.
**Nearest boundary.** Nonzero alone permits negative reals and is insufficient for ln.
**Checked example.**
```litex
ln(1) = 0
ln(e) = 1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O49. Logarithm with specified base
**Public form:** `log(b, x)`.
**Mathematical function.** The real logarithm of x with base b.
**Well-definedness and domain.** b, x $in R; b > 0; b != 1; x > 0. Child WD also applies.
**Common native properties and proof routes.** log(b,1) = 0; log(b,b) = 1 under the exact base/argument conditions.
**Nearest boundary.** Argument order is base then value. A positive base equal to one remains invalid.
**Checked example.**
```litex
log(2, 8) = 3
log(2, 1) = 0
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O50. Principal square root
**Public form:** `sqrt(x)`.
**Mathematical function.** The nonnegative real square root.
**Well-definedness and domain.** x $in R; 0 <= x. Child WD also applies.
**Common native properties and proof routes.** Nonnegative real codomain; sqrt(x)^2 = x and sqrt(x^2) = |x| for real x.
**Preview: squaring a quotient equation.** From a checked `sqrt(a) = p / q`,
the equality builtin verifies `p^2 = a * q^2`, including reversed equality
and swapped product factors. The source equation must itself be well-defined:
`a` is a nonnegative real, and scalar `q` is nonzero. The scalar numerator and
denominator may be complex; `sqrt` keeps its real domain. This is a forward
implication and supplies no sign condition for the converse. See the
[checked rule and sqrt(2) proof](../examples/proof_nodes/equal/by_builtin_rule/sqrt_quotient_square.lit).
**Nearest boundary.** A complex square-root interpretation is not supplied by this real primitive; sqrt(x^2) is not x for arbitrary real x.
**Checked example.**
```litex
sqrt(4) = 2
sqrt((-3)^2) = |-3| = 3
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O51. Real coordinate
**Public form:** `re(z)`.
**Mathematical function.** The real coordinate of a complex scalar.
**Well-definedness and domain.** z $in C.
**Common native properties and proof routes.** Real result and the scalar reconstruction z = re(z) + img(z) * i.
**Nearest boundary.** img(z) is a real coefficient, not img(z) * i. Use abs only for a real argument.
**Checked example.**
```litex
re(2 + 3 * i) = 2
re(i) = 0
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O52. Imaginary coordinate
**Public form:** `img(z)`.
**Mathematical function.** The real coefficient of i in a complex scalar.
**Well-definedness and domain.** z $in C.
**Common native properties and proof routes.** Real result; img(i) = 1 and img(real) = 0.
**Nearest boundary.** img(z) is a real coefficient, not img(z) * i. Use abs only for a real argument.
**Checked example.**
```litex
img(2 + 3 * i) = 3
img(2) = 0
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O53. Complex modulus
**Public form:** `C_abs(z)`.
**Mathematical function.** The nonnegative real modulus of a complex scalar.
**Well-definedness and domain.** z $in C.
**Common native properties and proof routes.** Nonnegative real result; squared modulus is re(z)^2 + img(z)^2; agrees with abs for real z.
**Nearest boundary.** img(z) is a real coefficient, not img(z) * i. Use abs only for a real argument.
**Checked example.**
```litex
C_abs(i) = 1
C_abs(-3) = 3
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/scalar.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [O01 Division](#o01-division).
### O54. Binary union
**Public form:** `union(A, B); A ∪ B`.
**Mathematical function.** The union of two sets.
**Well-definedness and domain.** Child set objects must be WD. In Litex’s pure-set foundation, these constructors do not introduce a new universal host carrier.
**Common native properties and proof routes.** Membership gives a disjunction; commutativity, associativity, idempotence and empty-set identity.
**Nearest boundary.** Membership introduction and elimination can have different proof routes. A conjunction does not select a disjunct or an existential witness automatically.
**Checked example.**
```litex
union(R, Z) = union(Z, R)
union({1}, {}) = {1}
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O55. Binary intersection
**Public form:** `intersect(A, B); A ∩ B`.
**Mathematical function.** The intersection of two sets.
**Well-definedness and domain.** Child set objects must be WD. In Litex’s pure-set foundation, these constructors do not introduce a new universal host carrier.
**Common native properties and proof routes.** Membership exposes both memberships; commutativity, associativity, idempotence and empty-set laws.
**Nearest boundary.** Membership introduction and elimination can have different proof routes. A conjunction does not select a disjunct or an existential witness automatically.
**Checked example.**
```litex
intersect(R, Z) = intersect(Z, R)
intersect({1}, {}) = {}
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O56. Set difference
**Public form:** `set_minus(A, B)`.
**Mathematical function.** Elements of A not in B.
**Well-definedness and domain.** Child set objects must be WD. In Litex’s pure-set foundation, these constructors do not introduce a new universal host carrier.
**Common native properties and proof routes.** Membership exposes x in A and not x in B; difference by the empty set and by itself.
**Nearest boundary.** Membership introduction and elimination can have different proof routes. A conjunction does not select a disjunct or an existential witness automatically.
**Checked example.**
```litex
set_minus({1}, {1}) = {}
set_minus(R, {}) = R
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O57. Union of a family
**Public form:** `family_union(F)`.
**Mathematical function.** The union of all member sets in a family.
**Well-definedness and domain.** Child set objects must be WD. In Litex’s pure-set foundation, these constructors do not introduce a new universal host carrier.
**Common native properties and proof routes.** Membership has an intermediate member-set witness; singleton-family and power-set union identities.
**Nearest boundary.** Membership introduction and elimination can have different proof routes. A conjunction does not select a disjunct or an existential witness automatically.
**Checked example.**
```litex
family_union({{1, 2}}) = {1, 2}
family_union(power_set({1, 2})) = {1, 2}
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O58. Intersection of a family
**Public form:** `family_intersect(F)`.
**Mathematical function.** The native family intersection.
**Well-definedness and domain.** Child set objects must be WD. In Litex’s pure-set foundation, these constructors do not introduce a new universal host carrier.
**Common native properties and proof routes.** A member belongs to every member set; quantified membership introduction uses a reserved theorem. The current checked example explicitly supplies the family-member universal rather than relying on literal intersection evaluation.
**Nearest boundary.** Membership introduction and elimination can have different proof routes. The membership release takes the family_intersect object as its second argument, not the raw family. Absolute empty-family intersection has no writable universal-set interpretation here; the explicit set-valued membership/projection interfaces require a nonempty family and the factor obligations. Constructor WD alone does not supply those facts.
**Checked example.**
```litex
$is_set(family_intersect({{1}}))
1 $in {1}
forall A {{1}}:
1 $in A
release thm family_intersect_member(1, family_intersect({{1}}))
1 $in family_intersect({{1}})
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [S25 Publish theorem conclusions](#s25-publish-theorem-conclusions).
### O59. Power set
**Public form:** `power_set(A)`.
**Mathematical function.** The set of subsets of A.
**Well-definedness and domain.** Child set objects must be WD. In Litex’s pure-set foundation, these constructors do not introduce a new universal host carrier.
**Common native properties and proof routes.** B in power_set(A) corresponds to B subset A; {} and A are members; membership supplies a subset interface.
**Nearest boundary.** Membership introduction and elimination can have different proof routes. A conjunction does not select a disjunct or an existential witness automatically.
**Checked example.**
```litex
{} $in power_set({1, 2})
by def {1} $subset {1, 2}
{1} $in power_set({1, 2})
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O60. Indexed union
**Public form:** `index_union(I, X, A)`.
**Mathematical function.** Union of a nonempty indexed family of subsets of X.
**Well-definedness and domain.** I is nonempty; I and X are sets; A belongs to fn(k I) power_set(X). All three objects are WD.
**Common native properties and proof routes.** A singleton index identifies the family member. Intersection membership introduction requires pointwise membership and index_intersect_member; union membership exposes an index witness.
**Nearest boundary.** The current WD contract excludes an empty index even if a different mathematical convention could assign it a value. The family’s return carrier must be the required power set.
**Checked example.**
```litex
let family = fn(k {1}) power_set(N) {{1}}
let result = index_union({1}, N, family)
$is_set(result)
result = result
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [S25 Publish theorem conclusions](#s25-publish-theorem-conclusions).
### O61. Indexed intersection
**Public form:** `index_intersect(I, X, A)`.
**Mathematical function.** Intersection in ambient X of a nonempty indexed family.
**Well-definedness and domain.** I is nonempty; I and X are sets; A belongs to fn(k I) power_set(X). All three objects are WD.
**Common native properties and proof routes.** A singleton index identifies the family member. Intersection membership introduction requires pointwise membership and index_intersect_member; union membership exposes an index witness.
**Nearest boundary.** The current WD contract excludes an empty index even if a different mathematical convention could assign it a value. The family’s return carrier must be the required power set.
**Checked example.**
```litex
let family = fn(k {1}) power_set(N) {{1}}
let result = index_intersect({1}, N, family)
$is_set(result)
result = result
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [S25 Publish theorem conclusions](#s25-publish-theorem-conclusions).
### O62. Indexed Cartesian product
**Public form:** `index_cart(I, S, g)`.
**Mathematical function.** The set of choice-like functions selecting one value from each indexed member g(alpha).
**Well-definedness and domain.** I is a nonempty set; S is a nonempty family-set carrier; g belongs to fn(alpha I) S. The native membership contract retains the complete input domain.
**Common native properties and proof routes.** A candidate’s pointwise selections can be introduced through index_cart_member. Nonemptiness from nonempty factors uses the explicit Choice-based native interfaces; product WD alone does not prove that factors are nonempty.
**Nearest boundary.** Knowing g is a function does not establish every factor is nonempty. Do not infer construction projections or a Cartesian dimension.
**Checked example.**
```litex
let family = fn(k {1}) power_set(N) {{1}}
let product_set = index_cart({1}, power_set(N), family)
$is_set(product_set)
product_set = product_set
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [S25 Publish theorem conclusions](#s25-publish-theorem-conclusions).
### O63. Finite displayed sets
**Public form:** `{a, b, ...}; {}`.
**Mathematical function.** Construct a finite set from an explicit list of distinct values.
**Well-definedness and domain.** Each element is WD; every pair of displayed elements must verify unequal. The empty list requires no element or distinctness proof.
**Common native properties and proof routes.** Finiteness and displayed cardinality; singleton membership implies equality, and longer-list membership exposes equality alternatives. Displayed membership can use a matching element equality.
**Nearest boundary.** Unlike informal set notation, duplicate entries or unknown pairwise inequality can fail WD. Distinctness is part of this constructor contract. Displayed lists also share the finite-term element budget used by aggregates: lists longer than that budget fail WD without expanding the full pairwise check.
**Checked example.**
```litex
$is_finite_set({1, 2})
finite_set_size({1, 2}) = 2
1 $in {1, 2}
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O64. Bounded set builders
**Public form:** `{x A: filters}`.
**Mathematical function.** Form the subset of a given base set consisting of values satisfying quantifier-free filters.
**Well-definedness and domain.** The base object is WD; bind x locally and check the filters in their source order. Valid earlier guards can license later partial expressions.
**Common native properties and proof routes.** Membership projects the base membership and instantiated filters. Introduction can explicitly verify those conditions through set_builder_member; alpha-equivalent bound names describe the same builder.
After the complete builder passes WD, a positive atomic filter `value $in {}`
makes the builder empty for every carrier; other conjuncts may remain present.
The `SetBuilderObviouslyEmpty` builtin handles this and its reverse equality.
A negative membership or an `or` containing a satisfiable branch does not use
this case. The rule never bypasses a failed partial-expression guard.
See [empty-membership builders](../examples/proof_nodes/equal/by_builtin_rule/set_builder_empty_membership.lit).
**Nearest boundary.** This is bounded separation, not unrestricted comprehension over a universal set. A direct forall filter must be packaged in real concrete predicate vocabulary.
**Checked example.**
```litex
release thm set_builder_member(2, {x R: x > 0})
forall x {t R: t > 0}:
x $in R
x > 0
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/binder.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O65. Half-open integer ranges
**Public form:** `range(a, b)`.
**Mathematical function.** Integers n with a <= n < b.
**Well-definedness and domain.** a, b $in Z; child WD. The range object does not require a <= b.
**Common native properties and proof routes.** Finite membership bounds and finite expansion; reversed or equal endpoints give an empty range.
**Nearest boundary.** Check which upper endpoint convention the proof or iteration statement expects.
**Checked example.**
```litex
1 $in range(1, 3)
not 3 $in range(1, 3)
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/iterated.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O66. Closed integer ranges
**Public form:** `closed_range(a, b); a...b`.
**Mathematical function.** Integers n with a <= n <= b.
**Well-definedness and domain.** a, b $in Z; child WD. The range object does not require a <= b.
**Common native properties and proof routes.** Finite membership bounds and expansion including the upper endpoint; reversed endpoints give an empty range. Equality search may prove `closed_range(a, b) = {a,...,b}` (and the half-open `range` dual) for concrete integer endpoints when the displayed list matches, without materializing oversized intervals.
**Nearest boundary.** Check which upper endpoint convention the proof or iteration statement expects. The literal range-to-list equality builtin only accepts intervals of size at most 1024 (same ceiling as finite enumeration / `expand:`); larger intervals soft-fail that route instead of allocating the full list.
**Checked example.**
```litex
2 $in closed_range(1, 2)
2 $in 1...2
closed_range(1, 3) = {1, 2, 3}
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/iterated.rs); equality expansion [wave13](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_equality/verify_equality_by_builtin_rules/by_equality_identities_wave13.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O67. Finite sequence spaces
**Public form:** `finite_seq(S, n)`.
**Mathematical function.** Functions on the exact finite index domain 1 through n, with values in S.
**Well-definedness and domain.** S is WD as a set and n belongs to N. A member’s calls require an index in its complete input domain.
**Common native properties and proof routes.** Equals fn(k closed_range(1,n)) S, with the zero-length domain {}. Coordinate membership is ordinary callable membership, not an attached tuple_dim.
**Automatic reconstruction (preview).** For a stored membership in `finite_seq(S,n)` with literal length n, equality builtin search accepts `x=(x(1),...,x(n))` and its reverse, with every coordinate in order and on the same exact subject. Zero length reconstructs `tuple()` and length one uses `tuple(x(1))`. The rule cites the original membership FactId; it performs no additional premise search. Arbitrary symbolic lengths or aliased carrier sets are not resolved by this leaf. Litex-to-Lean compilation of this new builtin evidence remains unsupported and fails closed.
**Nearest boundary.** A function merely defined at some coordinates need not have this complete domain. Index zero and n+1 are outside a positive length-n sequence.
**Checked example.**
```litex
finite_seq(R, 0) = fn(k {}) R
finite_seq(R, 2) = fn(k closed_range(1, 2)) R
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/iterated.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [S01 Expression-defined functions](#s01-expression-defined-functions), [S46 Function extensionality](#s46-function-extensionality).
### O68. Infinite sequence spaces
**Public form:** `seq(S)`.
**Mathematical function.** Functions from positive natural indices to S.
**Well-definedness and domain.** S is a WD set object. Sequence calls require positive natural indices.
**Common native properties and proof routes.** seq(S) equals fn(k N+) S. Legal calls inherit the return-carrier membership; function-space membership introduction has a native theorem interface.
**Nearest boundary.** The sequence convention is one-based; do not assume that index zero is admitted.
**Checked example.**
```litex
seq(R) = fn(k N+) R
seq(N) = fn(k N+) N
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/iterated.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [S01 Expression-defined functions](#s01-expression-defined-functions), [S46 Function extensionality](#s46-function-extensionality).
### O69. Open lower rays
**Public form:** `'(a,)`.
**Mathematical function.** Real values greater than a.
**Well-definedness and domain.** The finite endpoint is WD and belongs to R.
**Common native properties and proof routes.** Membership gives realness and the indicated strict or weak bound; the ray is a subset of R.
**Nearest boundary.** The apostrophe is the interval prefix. Missing infinite endpoints are notation, not an infinity object usable in arithmetic.
**Checked example.**
```litex
1 $in '(0,)
not 0 $in '(0,)
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O70. Closed lower rays
**Public form:** `'[a,)`.
**Mathematical function.** Real values greater than or equal to a.
**Well-definedness and domain.** The finite endpoint is WD and belongs to R.
**Common native properties and proof routes.** Membership gives realness and the indicated strict or weak bound; the ray is a subset of R.
**Nearest boundary.** The apostrophe is the interval prefix. Missing infinite endpoints are notation, not an infinity object usable in arithmetic.
**Checked example.**
```litex
0 $in '[0,)
1 $in '[0,)
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O71. Open upper rays
**Public form:** `'(,b)`.
**Mathematical function.** Real values less than b.
**Well-definedness and domain.** The finite endpoint is WD and belongs to R.
**Common native properties and proof routes.** Membership gives realness and the indicated strict or weak bound; the ray is a subset of R.
**Nearest boundary.** The apostrophe is the interval prefix. Missing infinite endpoints are notation, not an infinity object usable in arithmetic.
**Checked example.**
```litex
-1 $in '(,0)
not 0 $in '(,0)
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O72. Closed upper rays
**Public form:** `'(,b]`.
**Mathematical function.** Real values less than or equal to b.
**Well-definedness and domain.** The finite endpoint is WD and belongs to R.
**Common native properties and proof routes.** Membership gives realness and the indicated strict or weak bound; the ray is a subset of R.
**Nearest boundary.** The apostrophe is the interval prefix. Missing infinite endpoints are notation, not an infinity object usable in arithmetic.
**Checked example.**
```litex
0 $in '(,0]
-1 $in '(,0]
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O73. Open real intervals
**Public form:** `'(a,b)`.
**Mathematical function.** The subset of reals satisfying a < x < b.
**Well-definedness and domain.** Both endpoints are WD and belong to R. Reversed endpoints still form a WD empty interval.
**Common native properties and proof routes.** Membership exposes the precise endpoint inequalities; changing a bracket changes boundary membership.
**Nearest boundary.** These are real intervals. range and closed_range are integer sets and have different finiteness consequences.
**Checked example.**
```litex
1 $in '(0,2)
not 0 $in '(0,2)
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O74. Open-closed real intervals
**Public form:** `'(a,b]`.
**Mathematical function.** The subset of reals satisfying a < x <= b.
**Well-definedness and domain.** Both endpoints are WD and belong to R. Reversed endpoints still form a WD empty interval.
**Common native properties and proof routes.** Membership exposes the precise endpoint inequalities; changing a bracket changes boundary membership.
**Nearest boundary.** These are real intervals. range and closed_range are integer sets and have different finiteness consequences.
**Checked example.**
```litex
2 $in '(0,2]
not 0 $in '(0,2]
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O75. Closed-open real intervals
**Public form:** `'[a,b)`.
**Mathematical function.** The subset of reals satisfying a <= x < b.
**Well-definedness and domain.** Both endpoints are WD and belong to R. Reversed endpoints still form a WD empty interval.
**Common native properties and proof routes.** Membership exposes the precise endpoint inequalities; changing a bracket changes boundary membership.
**Nearest boundary.** These are real intervals. range and closed_range are integer sets and have different finiteness consequences.
**Checked example.**
```litex
0 $in '[0,2)
not 2 $in '[0,2)
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O76. Closed real intervals
**Public form:** `'[a,b]`.
**Mathematical function.** The subset of reals satisfying a <= x <= b.
**Well-definedness and domain.** Both endpoints are WD and belong to R. Reversed endpoints still form a WD empty interval.
**Common native properties and proof routes.** Membership exposes the precise endpoint inequalities; changing a bracket changes boundary membership.
**Nearest boundary.** These are real intervals. range and closed_range are integer sets and have different finiteness consequences.
**Checked example.**
```litex
0 $in '[0,2]
2 $in '[0,2]
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O77. Finite Cartesian products
**Public form:** `cart(S1, ..., Sn); S1 × S2`.
**Mathematical function.** The set of exact finite functions whose k-th value lies in the k-th factor.
**Well-definedness and domain.** All factor objects are WD. Membership checks the candidate’s complete finite input domain and all coordinate conditions.
**Common native properties and proof routes.** Coordinate membership; zero factors give a singleton containing the empty function; finite cardinality is the product of factor cardinalities; an empty factor makes a nonzero-factor product empty.
**Nearest boundary.** A Cartesian set has no retained construction dimension or projection operator. Equal Cartesian sets are not distinguished by the expression used to construct them.
**Checked example.**
```litex
(1, 2) $in cart(R, Z)
tuple() $in cart()
finite_set_size(cart()) = 1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O78. Finite tuples
**Public form:** `(a,); (a, b, ...); tuple(a, ...); tuple()`.
**Mathematical function.** An exact finite function on indices 1 through its displayed length, with the displayed values.
**Well-definedness and domain.** Each component is WD. Calls to a named tuple require an in-domain index and its checked finite-function interface.
**Common native properties and proof routes.** Coordinate values and exact finite-sequence membership. Equality from coordinates requires both complete domains and every coordinate, through tuple_equal_from_coordinates.
**Nearest boundary.** Ordinary calls also accept literal tuple heads: `(1,2)(1)=1` and `((1,2),3)(1)(2)=2`. Every call checks its receiver's complete domain; `(1,2)(3)` and `((1,2),3)(2)(1)` fail WD. Old `[index]`, dimension and constructor-projection syntax is removed. A singleton uses `(value,)` or `tuple(value)`, since `(value)` is grouping. Bare `()` is rejected; write `tuple()` for the empty tuple. Parenthesized tuple syntax requires a comma at its own nesting level; an optional trailing comma is accepted.
See [S52](#s52-release-a-tuple-definition) for `release tuple def object`, which publishes the exact finite-sequence membership and known coordinates of a value.
`release cart def cart(A,B)` verifies and stores the complete equality
`cart(A,B)={p finite_seq(union(A,B),2):p(1) $in A,p(2) $in B}`.
It also supports `cart(A)` and `cart()`; the zero-factor definition is
`cart()=finite_seq({},0)`. Factors must be sets, the command accepts one
`cart(...)` constructor with no body, and failures publish no partial facts.
See [the command tracer](../examples/stmt_nodes/release_and_expand/release_cart_def.lit).
**Checked example.**
```litex
have p cart(R, Z) = (1, 2)
p(1) = 1
p(2) = 2
(fn(x R) R {x}, 0)(1)(2) = 2
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O79. Function spaces
**Public form:** `fn(parameters: guards) T`.
**Mathematical function.** A set of functions having the complete input domain described by the parameter carriers and guards, returning values in T.
**Well-definedness and domain.** Parameter carrier objects, guards and return set are WD. Current signature carriers cannot refer to this signature’s own parameter names; enclosing parameters may be used.
**Common native properties and proof routes.** Membership supplies callable domain and return contracts. Alpha-renamed parameters give an equivalent signature; explicit fn_set_member checks the full pointwise obligation.
**Nearest boundary.** A function-space object is not itself a function to call. A return bound is not automatically the actual image.
**Checked example.**
```litex
have fn identity(x R) R = x
identity $in fn(t R) R
fn(x R) R = fn(t R) R
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/binder.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [S01 Expression-defined functions](#s01-expression-defined-functions), [S46 Function extensionality](#s46-function-extensionality).
**Further detail:** [Complete domains, restrictions and fixed signatures](#complete-domains-restrictions-and-fixed-signatures).
### O80. Anonymous functions
**Public form:** `fn(parameters: guards) T {body}`.
**Mathematical function.** Construct a function directly from an expression without introducing a name.
**Well-definedness and domain.** The function-space checks apply; under its local binders/guards the body is WD and belongs to T. The empty-complete-domain exception only concerns pointwise return membership, not body WD.
**Common native properties and proof routes.** A matching function-space membership and checked beta/evaluation equalities. Named or direct applications use the same domain conditions. A template `have fn ... = body` application can also unfold using the parent equality's checked template arguments and complete application domain. The selected declared body must have the same input carriers and guards; its substituted residual keeps the existing definition-premise truth permissions. This supports set-valued bodies without rechecking a synthetic anonymous application. When cached WD supplies only an ID, the rule rechecks the declared template's argument memberships and guards with the existing definition-premise ceiling. Detailed evidence distinguishes the parent domain from this rechecked domain and retains `template_instance`, the instantiated `function`, `checked_domain`, each argument/guard proof, and the residual proof. See the [set-valued template tracer](../examples/proof_nodes/equal/by_object_definition/by_template/set_valued_application.lit).
**Nearest boundary.** Writing the desired T cannot make an incompatible body return-typed. Use a real guard for a partial expression.
**Checked example.**
```litex
fn(x R) R {x + 1}(2) = 3
fn(x R: x != 0) R {1 / x}(2) = 1 / 2
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/binder.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [S01 Expression-defined functions](#s01-expression-defined-functions), [S46 Function extensionality](#s46-function-extensionality).
### Preview Function composition
`compose(f,g)` and `f ∘ g` construct the same native function: apply `g` first,
then `f`. The outer function must be unary; the inner function may have any
fixed positive number of arguments, including different carriers and guards.
The complete inner domain is preserved. Construction checks `f(g(args))` for
every legal inner input, using the existing anonymous-function WD pipeline.
It does not silently restrict that domain to satisfy an outer guard.
```litex
have fn square(t R) R = t^2
have fn gap(x,y R: x=0`, and `abs(f(x))<=M` give `abs(I)<=M*abs(b-a)`. |
| `riemann_integrable_continuous(f,a,b)` | Continuity at every point of the closed interval supplies integrability. |
| `riemann_integral_newton_leibniz(f,F,a,b)` | Integrable `f`, closed-interval continuity of `F`, and `F'=f` at every interior point give value `F(b)-F(a)`. |
| `riemann_integral_step(f,a,c,b,L,U)` | For `a<=c<=b`, constants on `[a,c)` and `(c,b]` give `L*(c-a)+U*(b-c)`; the value at `c` may differ. |
| `darboux_enclosure_from_definition(f,a,b,n,p,l,u)` | Check a positive-length partition and pointwise lower/upper cell bounds to introduce `$is_darboux_enclosure(...)`. |
| `darboux_enclosure_to_definition(f,a,b,n,p,l,u)` | Expose those finite partition and bound conditions. |
The enclosure certificate has seven arguments. Its finite index families use
guarded integer domains (`p`: `0<=k<=n`; `l,u`: `1<=k<=n`). Merely writing
the certificate never proves it. The integral definition quantifies over
arbitrary precision and bounds the function throughout every cell. Convergence
of one sampled sum sequence alone does not establish integrability.
See the [primary example](../examples/real_analysis/riemann_integral.lit),
[explicit theorem examples](../examples/stmt_nodes/release_and_expand/builtin_thm/riemann_integral_power.lit),
and [implementation](../src/execute/execute_fact_stmt/riemann_integral.rs).
LaTeX output renders the selected integral; Lean compilation of these new
integral objects and proof routes is currently unsupported and rejects them.
### O82. Sums over integer ranges
**Public form:** `sum(a,b,f)`.
**Mathematical function.** The inclusive scalar sum over integer indices a through b.
**Well-definedness and domain.** a,b in Z; a <= b; f unary, defined throughout the index range, with return carrier a subset of C. All child objects are WD.
**Common native properties and proof routes.** Scalar carrier closure, singleton and splitting identities, and pointwise comparison through explicit native theorem interfaces.
**Nearest boundary.** Unlike range(a,b), this operator includes b; its current WD contract does not admit a reversed empty range.
**Checked example.**
```litex
sum(1, 3, fn(k Z) Z {k}) = 6
sum(2, 2, fn(k Z) Z {k}) = 2
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/iterated.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
#### Scalar return carriers and empty aggregate domains
All four aggregate forms require a unary iterand whose definition specifies a
scalar return carrier: Litex must prove `return_set $subset C` under the
function's parameter and domain assumptions. The function body must separately
belong to that defined return carrier. Range `sum` and `product` also require
integer endpoints with `first <= last`; finite-set aggregates require a finite
set and a function defined on the aggregated domain.
Consequently, `finite_set_sum(3...1, fn(k Z) Z {0}) = 0` and the analogous
empty product equal to `1` are well-defined, while range `sum(3,1,...)` and
`product(3,1,...)` remain outside the nonempty range-aggregate contract.
All four aggregate forms use the function return set to select their result
carrier. A `C`-valued function gives a result in `C`; functions returning
`N`, `Z`, `Q`, or `R` keep their narrower established result. Empty finite
sums and products remain `0` and `1`. The interval forms still require the
first index to be at most the last. Ordered, positive, and absolute-value
aggregate rules still require a real-valued iterand.
### O83. Products over integer ranges
**Public form:** `product(a,b,f)`.
**Mathematical function.** The inclusive scalar product over integer indices a through b.
**Well-definedness and domain.** The same index/domain/scalar-return requirements as sum. All child objects are WD.
**Common native properties and proof routes.** Scalar carrier closure, singleton and splitting identities, and nonzero-factor properties.
**Nearest boundary.** A usable callable signature must cover every index, not merely the two endpoints.
**Checked example.**
```litex
product(1, 3, fn(k Z) Z {k}) = 6
product(2, 2, fn(k Z) Z {k}) = 2
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/iterated.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O84. Finite-set sums
**Public form:** `finite_set_sum(S,f)`.
**Mathematical function.** A scalar sum indexed by a finite set.
**Well-definedness and domain.** S finite; f unary with a domain covering S and return carrier a subset of C. All child objects are WD.
**Common native properties and proof routes.** Empty sum zero, singleton evaluation, set partition/reindex identities, and pointwise comparison through native interfaces.
**Nearest boundary.** Finiteness and domain coverage are separate obligations.
**Checked example.**
```litex
finite_set_sum({}, fn(k Z) Z {k}) = 0
finite_set_sum({1, 2}, fn(k Z) Z {k}) = 3
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/iterated.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O85. Finite-set products
**Public form:** `finite_set_product(S,f)`.
**Mathematical function.** A scalar product indexed by a finite set.
**Well-definedness and domain.** S finite; f unary with a domain covering S and return carrier a subset of C. All child objects are WD.
**Common native properties and proof routes.** Empty product one, singleton evaluation, partition/reindex identities and nonzero-factor laws.
**Nearest boundary.** The empty product is one; it is not an empty sum convention.
**Checked example.**
```litex
finite_set_product({}, fn(k Z) Z {k}) = 1
finite_set_product({2, 3}, fn(k Z) Z {k}) = 6
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/iterated.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O86. Ordered folds
**Public form:** `reduce(a,b,f,op,seed)`.
**Mathematical function.** Fold iterand values through a homogeneous binary operation and initial seed.
**Well-definedness and domain.** Integer endpoints; f unary into T over the indices; op belongs to fn(x,y T) T; seed in T. All child objects are WD.
**Common native properties and proof routes.** A reversed empty range returns the seed; scalar addition folds can connect to sums.
**Nearest boundary.** T is the actual homogeneous carrier; arbitrary seed/operation types cannot be mixed.
**Checked example.**
```litex
reduce(2, 1, fn(k Z) Z {k}, fn(a,b Z) Z {a+b}, 7) = 7
reduce(1, 2, fn(k Z) Z {k}, fn(a,b Z) Z {a+b}, 0) = 3
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/iterated.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
#### Ordered and unordered fold contracts
The generic folds are not restricted to scalar arithmetic. For both forms,
`op` must have an unconditional homogeneous signature `fn(x, y T) T`, `f`
must be unary with return set `T`, and `seed` must belong to `T`; the result
then belongs to `T`. `reduce` visits the closed integer interval from left to
right and returns `seed` when `last < first`. Thus its defining nonempty step
is `op(reduce(first, last - 1, f, op, seed), f(last))`. Equivalently, it may
consume the first value into the seed and continue at `first + 1`:
`reduce(first + 1, last, f, op, op(seed, f(first)))`.
Because a finite set has no iteration order, `finite_set_reduce` additionally
requires Litex to verify that `op` is associative and commutative on `T`.
Displayed-set order is used only to produce an evaluation witness. The empty
set returns `seed`; `seed` need not be an identity element. If order matters
or `op` is noncommutative, provide an explicit integer enumeration and use
`reduce` instead.
Closed `reduce` expressions can be evaluated with an ascending left fold;
closed `finite_set_reduce` expressions can be evaluated after both operation
laws pass. Both share the existing finite-aggregate term budget. A multiplication
fold with seed `1` also matches `product` over the same interval and function.
See [ordered-fold calculation](../examples/proof_nodes/equal/by_builtin_rule/legacy_reduce_calculation.lit)
and [multiplication bridge](../examples/proof_nodes/equal/by_builtin_rule/legacy_reduce_product.lit).
The checked equality, partition, congruence, and reindexing laws for these
aggregates are listed in [Powers, logarithms, sums, products, and
remainder](#powers-logarithms-sums-products-and-remainder). In particular,
`reduce` is order-sensitive; arbitrary bijective reindexing belongs to the
associative-commutative `finite_set_reduce` interface instead.
### O87. Finite-set folds
**Public form:** `finite_set_reduce(S,f,op,seed)`.
**Mathematical function.** The native finite-set fold with an initial value.
**Well-definedness and domain.** S finite; f covers S and returns T; binary op is homogeneous on T; seed belongs to T. All child objects are WD.
**Common native properties and proof routes.** Empty-set fold returns seed; singleton step uses finite_set_reduce_singleton; additive folds connect to finite_set_sum.
**Nearest boundary.** Typing alone does not certify a chosen operation is commutative. Claims about changing enumeration need separately justified laws.
**Checked example.**
```litex
finite_set_reduce({}, fn(k Z) Z {k}, fn(a,b Z) Z {a+b}, 7) = 7
finite_set_reduce({1,2}, fn(k Z) Z {k}, fn(a,b Z) Z {a+b}, 0) = finite_set_sum({1,2}, fn(k Z) Z {k}) = 3
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/iterated.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O88. Finite cardinality
**Public form:** `finite_set_size(S)`.
**Mathematical function.** The number of elements of a finite set.
**Well-definedness and domain.** S is proved finite.
**Common native properties and proof routes.** Natural result; empty/singleton/list size and inclusion/finite-product cardinality laws.
**Nearest boundary.** A set object is not automatically finite; displayed lists also require pairwise distinctness.
**Checked example.**
```litex
finite_set_size({}) = 0
finite_set_size({1,2}) = 2
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O89. Maximum of a finite set
**Public form:** `finite_set_max(S)`.
**Mathematical function.** The largest element of a finite nonempty real-valued set.
**Well-definedness and domain.** S finite, nonempty, and a subset of R.
**Common native properties and proof routes.** Real result, membership in S and upper-bound laws.
**Nearest boundary.** Neither an empty set nor an arbitrary finite complex-valued set supplies this maximum.
**Checked example.**
```litex
finite_set_max({1,3,2}) = 3
finite_set_max({1,3,2}) $in {1,3,2}
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
#### Finite extrema selection evidence
`finite_set_max(S)` and `finite_set_min(S)` are not total default-value
operators. If finiteness, nonemptiness, or `S $subset R` is unavailable, the
object is ill-defined rather than assigned an arbitrary endpoint.
After these WD obligations hold, membership rules prove
`finite_set_max(S) $in S` and `finite_set_min(S) $in S`. The target set
must match the operator’s set structurally, allowing bound-variable renaming;
these rules do not skip WD or establish membership in an unrelated set.
Detailed output records `FiniteSetMaxMember` / `FiniteSetMinMember` and
`set_equal` identity/alpha evidence.
For displayed sets of closed rational numbers, the equality rule selects an
original member and records every exact comparison against that member.
Detailed output exposes `FiniteSetMaxSelection` or `FiniteSetMinSelection`,
`selected_index` (zero-based), `selected_member`, and `comparisons` with
normalized operands and `less` / `equal` / `greater` outcomes. These certificates
follow the whole-object WD checks, including pairwise distinctness. Successful
`eval` now publishes the checked source-to-result equality. See
[the rational extrema tracer](../examples/proof_nodes/equal/by_builtin_rule/finite_set_rational_extrema.lit).
### O90. Minimum of a finite set
**Public form:** `finite_set_min(S)`.
**Mathematical function.** The smallest element of a finite nonempty real-valued set.
**Well-definedness and domain.** S finite, nonempty, and a subset of R.
**Common native properties and proof routes.** Real result, membership in S and lower-bound laws.
**Nearest boundary.** The binary min takes two real arguments; this operator takes a single set.
**Checked example.**
```litex
finite_set_min({1,3,2}) = 1
finite_set_min({1,3,2}) $in {1,3,2}
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/sets.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality).
### O91. Struct carriers
**Public form:** `&Name`.
**Mathematical function.** The carrier selected by a particular struct definition and its parameter instantiation.
**Well-definedness and domain.** The declaration owner exists, arguments match its parameter contracts, and its instantiated field/condition schema is WD.
**Common native properties and proof routes.** Membership means the exact finite coordinate structure and declared laws. Direct typed bindings open one layer; explicit struct_member introduces membership when a supported structural proof needs it.
**Nearest boundary.** A field name does not choose a struct owner. Qualified and template-instantiated views retain their actual definition owner.
**Checked example.**
```litex
struct Point:
x R
y R
(1, 2) $in &Point
struct PosPoint:
x R
y R
<=>:
x > 0
(1, 2) $in &PosPoint
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [S16 Structured carriers](#s16-structured-carriers), [S27 Open one struct definition layer](#s27-open-one-struct-definition-layer).
**Further detail:** [Struct representation and law publication](#struct-representation-and-law-publication).
### O92. Definition-owned field access
**Public form:** `value.field`.
**Mathematical function.** Select a named coordinate of a known struct view.
Field substitution and struct-layer release preserve the same ordered path
as source syntax: substituting `scalars = space.scalars` in `scalars.mul`
produces `space.scalars.mul`. This also applies to callable fields and to
arguments such as `space.scalars.zero`; it does not license missing fields or
interchange receivers. See the
[nested-field instantiation tracer](../examples/stmt_nodes/definition/struct_nested_field_instantiation.lit).
**Well-definedness and domain.** The receiver’s definition-owned struct view, membership and field must verify. Callable or nested fields retain their declared signature/view.
**Common native properties and proof routes.** Field WD makes the path legal; release struct def exposes the selected layer’s carriers, coordinate bridges and laws when needed in proof.
**Nearest boundary.** A WD path does not automatically open every nested struct definition or assert every surrounding property.
**Checked example.**
```litex
struct Point:
x R
y R
forall p &Point:
p.x = p.x
p.y = p.y
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [S16 Structured carriers](#s16-structured-carriers), [S27 Open one struct definition layer](#s27-open-one-struct-definition-layer).
**Further detail:** [Field WD, automatic opening and selected views](#field-wd-automatic-opening-and-selected-views).
### O93. Template instances
**Public form:** `\Name`.
**Mathematical function.** Specialize a parameterized declaration family to concrete mathematical arguments.
**Well-definedness and domain.** The family exists and its argument carriers/guards and instantiated ordinary definition contract check.
**Common native properties and proof routes.** The instance obtains the ordinary definition’s value or callable interface; release obj def and equality/application routes use that stored definition.
**Nearest boundary.** Angle-bracket arguments specialize the family. Parenthesized arguments apply a fully specialized function.
**Checked example.**
```litex
template:
have carrier_copy set = S
\carrier_copy = R
```
**Source:** [implementation](../src/execute/execute_fact_stmt/well_defined_results/verify_obj/entry.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S05 Typed values given by equality](#s05-typed-values-given-by-equality), [S17 Parameterized declaration families](#s17-parameterized-declaration-families), [S28 Replay an object definition](#s28-replay-an-object-definition).
**Further detail:** [Instance ownership and automatic definition facts](#instance-ownership-and-automatic-definition-facts).
## Builtin atomic fact dictionary and relationships
Atomic fact verification first checks argument WD and predicate domains, then
looks for a proof through known facts, calculation, builtin rules, or definitions.
A successful fact and its applicable consequences are stored. Negative facts
do not inherit the positive form’s definition expansion.
| ID | Public form | Mathematical role | Example status |
|---|---|---|---|
| [F01](#f01-membership-and-nonmembership) | `x $in S; not x $in S` | Membership and nonmembership | checked |
| [F02](#f02-equality-and-inequality) | `a = b; a != b` | Equality and inequality | checked |
| [F03](#f03-strict-less-than) | `a < b; not a < b` | Strict less-than | checked |
| [F04](#f04-strict-greater-than) | `a > b; not a > b` | Strict greater-than | checked |
| [F05](#f05-weak-less-than) | `a <= b; not a <= b` | Weak less-than | checked |
| [F06](#f06-weak-greater-than) | `a >= b; not a >= b` | Weak greater-than | checked |
| [F07](#f07-sethood) | `$is_set(A); not $is_set(A)` | Sethood | checked |
| [F08](#f08-nonemptiness) | `$is_nonempty_set(S); not $is_nonempty_set(S)` | Nonemptiness | checked |
| [F09](#f09-finiteness) | `$is_finite_set(S); not $is_finite_set(S)` | Finiteness | checked |
| [F10](#f10-subset) | `A $subset B; not A $subset B` | Subset | checked |
| [F11](#f11-superset) | `A $superset B; not A $superset B` | Superset | checked |
| [F12](#f12-proper-subset) | `A $proper_subset B; not A $proper_subset B` | Proper subset | checked |
| [F13](#f13-proper-superset) | `A $proper_superset B; not A $proper_superset B` | Proper superset | checked |
| [F14](#f14-primality) | `$prime(n); not $prime(n)` | Primality | checked |
| [F15](#f15-coprimality) | `$coprime(a, b); not $coprime(a, b)` | Coprimality | checked |
| [F16](#f16-divisibility-with-dividend-first) | `$dvd(a, d); not $dvd(a, d)` | Divisibility with dividend first | checked |
| [F17](#f17-injectivity) | `$injective(A, B, f); not $injective(A, B, f)` | Injectivity | checked |
| [F18](#f18-surjectivity) | `$surjective(A, B, f); not $surjective(A, B, f)` | Surjectivity | checked |
| [F19](#f19-bijectivity) | `$bijective(A, B, f); not $bijective(A, B, f)` | Bijectivity | checked |
| [F20](#f20-choice-function-specification) | `$is_choice_function_for(I, S, g, f); not $is_choice_function_for(I, S, g, f)` | Choice-function specification | checked |
| ID | Public form | Mathematical role | Example status |
|---|---|---|---|
| [C01](#c01-native-least-upper-bound-certificate) | `$is_real_least_upper_bound(A, value)` | Native least-upper-bound certificate | checked |
| [C02](#c02-native-greatest-lower-bound-certificate) | `$is_real_greatest_lower_bound(A, value)` | Native greatest-lower-bound certificate | checked |
### F01. Membership and nonmembership
**Positive form:** `x $in S`.
**Negative form:** `not x $in S`.
**Argument order:** element first, containing set second.
#### Mathematical function
Assert that an object belongs, or does not belong, to a set. A carrier
annotation such as `have n N` introduces membership information about `n`.
It does not change a host-language runtime type. Litex's pure-set model uses
one mathematical object universe, with membership as a fact between objects.
Checking WD of `x` and `S` precedes checking the membership's truth. In
particular, `1 / x $in R` must first satisfy the divisor condition even though
its target carrier is real.
#### Basic checked examples
```litex
2 $in N
-2 $in Z
not -2 $in N
1 / 2 $in Q
not 1 / 2 $in Z
```
These closed facts use `proof_method.type: by_closed_calculation` in the
verified output. Exact closed nonmembership is supported; lack of a proof of
membership is not itself a proof of nonmembership.
#### Relationships with other facts
| Available information | Consequence | How it becomes usable in these samples |
|---|---|---|
| `n $in N` | `n $in Z`, `Q`, `R`, `C` | Numeric inclusion is checked by `by_structural_membership` |
| `n $in N` | `0 <= n` | Eager inference stores the bound; the later line uses `cite_known` |
| `x $in R+` | `0 < x`, `0 <= x`, `x != 0` | Signed-carrier inference stores these facts |
| `x $in R+` | `x $in R` | Structural membership from the numeric carrier |
| Stored `0 < x` | `x > 0` | Verification uses the converse-order builtin rule |
| A checked function signature | The result of a legal call belongs to its return carrier | Callable result contract; the call's domain must still check |
| Membership in `{t R: t > 0}` | Membership in `R` and the filter `x > 0` | Set-builder membership inference stores these clauses |
| `A $subset B` and `x $in A` | `x $in B` | Inclusion exposes a universal membership implication |
The distinction between inference and verification matters. Numeric widening
such as `N` to `R` is available to structural membership checking; this is not
claimed to mean that every widened membership was eagerly stored. By contrast,
the nonnegative bound in the next example is already stored.
```litex
have n N
n $in Z
n $in Q
n $in R
n $in C
0 <= n
```
A positive real carrier also supplies the divisor guard:
```litex
have x R+
x $in R
x > 0
x != 0
1 / x $in R
```
Here `x != 0` is a stored consequence of the carrier. There is no need to add
an unrelated theorem or assume nonzeroness again. The final line checks real
membership after division WD.
#### Function-space membership
```litex
have fn square(x R) R = x^2
square $in fn(x R) R
forall t R:
square(t) $in R
```
`have fn` has already stored the function-space membership. It makes each
legal call return an object in `R`; it does not assert that this function is
injective or surjective. Those mapping properties are separate atomic facts.
#### Set-builder membership
```litex
witness $is_nonempty_set({t R: t > 0}) from 1
have x {t R: t > 0}
x $in R
x > 0
x != 0
1 / x $in R
```
The first line establishes nonemptiness using a concrete member. `have` can
then introduce an arbitrary member. Membership in the builder exposes the
base-carrier and filter facts; strict order supports the later nonzero check.
The explicit consequence lines are retained here to show what can be read
from the membership, rather than because every one must be repeated in proofs.
#### Inclusion and membership are different fact shapes
```litex
forall A, B set, x A:
A $subset B
=>:
x $in B
```
Subset relates two sets. Membership relates one object to a containing set.
An inclusion lets existing membership move in its indicated direction; it
does not identify the two sets or establish the opposite inclusion.
#### Negative boundary
**Expected rejection — phase `search_proof`:**
```litex
have x R
not x $in Z
```
Being real does not establish nonmembership in the integers. This failed
check also does not establish `x $in Z`. Keep an unproved goal distinct from
its negation.
**Evidence:** M01–M07.
**Source:** [atomic WD](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_well_defined.rs),
[structural membership](../src/execute/execute_fact_stmt/verify_atomic_fact/search_structural_membership.rs),
[signed-carrier inference](../src/store_fact_and_infer/infer_fact/infer_atomic_fact/infer_atomic_except_equality/membership_signed_standard_set.rs),
[builder projection](../src/store_fact_and_infer/infer_fact/infer_atomic_fact/infer_atomic_except_equality/infer_in_fact.rs),
[subset inference](../src/store_fact_and_infer/infer_fact/infer_atomic_fact/infer_atomic_except_equality/subset.rs).
#### Alpha matching and restricted equality transport
> **Preview:** FnSet, AnonymousFn and SetBuilder structural alpha equality
> belongs to the equality-specific `ByTheyAreTheSame` stage, after WD and before
> builtin rules. Bound names may differ; free identifiers, types and bodies
> must correspond. This stage also runs with builtin entry disabled.
> Known forall facts can also infer their free parameters inside FnSet
> signatures, including function-space carriers of set builders. Signature
> traversal proposes bindings; complete strict equality must still check
> bound occurrences, argument types, guards and the return carrier. Local
> signature binders cannot escape into those free bindings. See the
> [function-space carrier tracer](../examples/proof_nodes/atomic/by_known_forall/fnset_free_parameter_carrier.lit).
> Known `$in` reuses the same argument-equality pipeline. Its unified
> `ByEquivalenceClass` stage can cite stored paths and compare peers once using
> identity, permitted builtin rules, or restricted constructor matching. Peer
> comparison cannot recursively expand another class or enable a disabled builtin entry.
> See the [equality pipeline](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_equality/README.md).
### F02. Equality and inequality
**Public form:** `a = b; a != b`.
**Mathematical function.** Assert equality of mathematical objects, or its negation. The objects can be numeric, sets, functions or structured values.
**Well-definedness and domain.** Both objects must be WD. Equality is not limited to real scalars; ordered comparisons have their own stricter carrier requirements.
**Relationships and inference.** Equality supports symmetry, transitivity and justified congruence. Set equality is extensional; function equality can be proved by complete-domain extensionality. An inequality is not inferred merely from a failed equality search.
**Nearest boundary.** A known value equality can require an explicit intermediate line before rewriting inside a larger expression; see P05.
**Checked example.**
```litex
1 + 1 = 2
1 != 2
by enumerate finite_set:
? forall x {1, 2}:
x $in {2, 1}
x $in {2, 1}
by enumerate finite_set:
? forall x {2, 1}:
x $in {1, 2}
x $in {1, 2}
by extension {1, 2} = {2, 1}
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_equality/README.md).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
### F03. Strict less-than
**Public form:** `a < b; not a < b`.
**Mathematical function.** a is strictly smaller than b.
**Well-definedness and domain.** Both operands belong to R and are WD. A negated comparison has the same carrier requirements.
**Relationships and inference.** On real operands, not a < b means a >= b. Strict order implies inequality and supports the corresponding weak order.
**Nearest boundary.** General complex values are not ordered here. Multiplying or dividing an inequality needs the appropriate sign and nonzero facts; do not silently preserve its direction for negative factors.
**Checked example.**
```litex
1 < 2
not 2 < 1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_well_defined.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
### F04. Strict greater-than
**Public form:** `a > b; not a > b`.
**Mathematical function.** a is strictly larger than b.
**Well-definedness and domain.** Both operands belong to R and are WD. A negated comparison has the same carrier requirements.
**Relationships and inference.** a > b is the converse of b < a; not a > b means a <= b. The converse may be verified rather than eagerly stored in both spellings.
**Nearest boundary.** General complex values are not ordered here. Multiplying or dividing an inequality needs the appropriate sign and nonzero facts; do not silently preserve its direction for negative factors.
**Checked example.**
```litex
2 > 1
not 1 > 2
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_well_defined.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
### F05. Weak less-than
**Public form:** `a <= b; not a <= b`.
**Mathematical function.** a is no greater than b.
**Well-definedness and domain.** Both operands belong to R and are WD. A negated comparison has the same carrier requirements.
**Relationships and inference.** Equality and strict less-than each imply weak less-than. On reals, not a <= b means a > b; a weak nonnegative bound alone does not imply nonzero.
**Nearest boundary.** General complex values are not ordered here. Multiplying or dividing an inequality needs the appropriate sign and nonzero facts; do not silently preserve its direction for negative factors.
**Checked example.**
```litex
1 <= 1
1 <= 2
not 2 <= 1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_well_defined.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
### F06. Weak greater-than
**Public form:** `a >= b; not a >= b`.
**Mathematical function.** a is no smaller than b.
**Well-definedness and domain.** Both operands belong to R and are WD. A negated comparison has the same carrier requirements.
**Relationships and inference.** a >= b is the converse of b <= a; not a >= b means a < b. Positive/negative signed carriers provide their corresponding bounds.
**Nearest boundary.** General complex values are not ordered here. Multiplying or dividing an inequality needs the appropriate sign and nonzero facts; do not silently preserve its direction for negative factors.
**Checked example.**
```litex
2 >= 1
1 >= 1
not 1 >= 2
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_well_defined.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
### F07. Sethood
**Public form:** `$is_set(A); not $is_set(A)`.
**Mathematical function.** Assert that an object is a set. Litex chooses a pure-set foundation in which every WD mathematical object satisfies sethood.
**Well-definedness and domain.** The argument object must be WD. This predicate is not a host-language runtime-type test.
**Relationships and inference.** Numerals, scalar expressions, functions, standard number sets and user-defined sets all have sethood. Membership in N or R remains a separate mathematical fact.
**Nearest boundary.** not $is_set is syntactically available but no positive non-set primitive is introduced by the current pure-set model. A failed WD expression is not thereby a non-set.
**Checked example.**
```litex
$is_set(1)
$is_set(R)
$is_set(fn(x R) R {x})
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_well_defined.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
### F08. Nonemptiness
**Public form:** `$is_nonempty_set(S); not $is_nonempty_set(S)`.
**Mathematical function.** Assert existence of at least one member, or emptiness.
**Well-definedness and domain.** S is WD. A positive introduction can use a concrete proved member with witness.
**Relationships and inference.** A positive certificate licenses arbitrary have x S. Membership implies nonemptiness mathematically; nonemptiness does not give a specified numerical witness name without a selection statement. Empty displayed sets have the negative property.
**Nearest boundary.** A builder may be nonempty mathematically while cold automatic search has not established it; see P06 for an explicit witness.
**Checked example.**
```litex
$is_nonempty_set({1})
not $is_nonempty_set({})
witness $is_nonempty_set({x R: x > 0}) from 1
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_well_defined.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
### F09. Finiteness
**Public form:** `$is_finite_set(S); not $is_finite_set(S)`.
**Mathematical function.** Assert that a set has finitely many elements, or is not finite.
**Well-definedness and domain.** S is WD; proof routes use its native construction, stored facts or explicit finiteness interfaces.
**Relationships and inference.** Finiteness licenses finite_set_size, with additional conditions for extrema. A subset of a finite set is finite; the native theorem interface is useful for explicit quantified premises. Finiteness does not imply nonemptiness.
**Nearest boundary.** A set object, subset of R, or a written iteration is not a finiteness certificate by itself.
**Checked example.**
```litex
$is_finite_set({})
$is_finite_set({1, 2})
not $is_finite_set(N)
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_well_defined.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
### F10. Subset
**Public form:** `A $subset B; not A $subset B`.
**Mathematical function.** Every member of A belongs to B.
**Well-definedness and domain.** Both set objects are WD. The positive definition uses the corresponding universal membership condition.
**Relationships and inference.** Positive inclusion exposes forall x A: x in B, except a builder route can use its already projected base/filter facts. Both subset directions establish equality by extension.
**Nearest boundary.** Negative inclusion means there is a counterexample; it does not make an arbitrarily selected member of A a counterexample.
**Checked example.**
```litex
{1} $subset {1, 2}
by contra:
? not {1, 2} $subset {1}
2 $in {1, 2}
impossible 2 $in {1}
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_atomic_except_equality/builtin_prop_definition.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
### F11. Superset
**Public form:** `A $superset B; not A $superset B`.
**Mathematical function.** Every member of B belongs to A.
**Well-definedness and domain.** Both set objects are WD. The positive definition uses the corresponding universal membership condition.
**Relationships and inference.** A superset B is the reversed subset relationship. It transports membership from B to A, not from A to B.
**Nearest boundary.** The direction is easy to reverse when writing a forall or calling a theorem.
**Checked example.**
```litex
{1, 2} $superset {1}
by contra:
? not {1} $superset {1, 2}
2 $in {1, 2}
impossible 2 $in {1}
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_atomic_except_equality/builtin_prop_definition.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
### F12. Proper subset
**Public form:** `A $proper_subset B; not A $proper_subset B`.
**Mathematical function.** A is a subset of B and is unequal to B.
**Well-definedness and domain.** Both set objects are WD. The positive definition uses the corresponding universal membership condition.
**Relationships and inference.** Its concrete definition exposes ordinary inclusion and set inequality. Ordinary subset permits equality; proper subset excludes it.
**Nearest boundary.** Negating proper inclusion does not imply proper inclusion in the opposite direction: the sets may be equal or incomparable.
**Checked example.**
```litex
by def {1} $proper_subset {1, 2}
by contra:
? not {1} $proper_subset {1}
impossible {1} != {1}
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_atomic_except_equality/builtin_prop_definition.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
### F13. Proper superset
**Public form:** `A $proper_superset B; not A $proper_superset B`.
**Mathematical function.** A contains B and is unequal to B.
**Well-definedness and domain.** Both set objects are WD. The positive definition uses the corresponding universal membership condition.
**Relationships and inference.** Its definition exposes superset and set inequality; it is the reversal of proper subset.
**Nearest boundary.** A larger-looking expression does not prove proper containment; both inclusion and inequality must be justified.
**Checked example.**
```litex
by def {1, 2} $proper_superset {1}
by contra:
? not {1} $proper_superset {1}
impossible {1} != {1}
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_atomic_except_equality/builtin_prop_definition.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
### F14. Primality
**Public form:** `$prime(n); not $prime(n)`.
**Mathematical function.** Assert that a natural number is prime, or not prime.
**Well-definedness and domain.** n belongs to N and is WD. The positive definition includes n >= 2 and the trial-divisor universal over the native range.
**Relationships and inference.** Closed primality can be decided by native calculation. A verified positive instance exposes its bound and trial-divisor definition. Explicit by def checks the actual definitional clauses rather than replacing them with a calculation request.
**Nearest boundary.** One is not prime. An out-of-domain argument is a WD/domain issue, not a proof of negated primality.
**Checked example.**
```litex
$prime(5)
not $prime(6)
not $prime(1)
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_atomic_except_equality/builtin_prop_definition.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
#### Closed primality computation
`$prime(p)` is a native predicate on `N`. It is false at `0` and `1`;
concrete natural literals that fit in `u64` are decided exactly, while larger
literals are left to proof rather than guessed. `by def $prime(p)` exposes the
symbolic trial-divisor contract (`2 <= p` and no divisor in `range(2, p)`). An
arbitrary integer or real argument is still rejected unless its membership in
`N` is known.
### F15. Coprimality
**Public form:** `$coprime(a, b); not $coprime(a, b)`.
**Mathematical function.** Assert that the two natural arguments have greatest common divisor one.
**Well-definedness and domain.** The current predicate’s argument domains are N and N. Its positive definition contains the non-all-zero guard before the gcd equality.
**Relationships and inference.** A positive instance exposes a != 0 or b != 0 and gcd(a,b) = 1. Natural coprimality and the integer-domain gcd object have different public argument contracts.
**Nearest boundary.** Do not assume this predicate accepts all signed integer pairs merely because many mathematical texts define that extension.
**Checked example.**
```litex
by def $coprime(14, 25)
not $coprime(14, 21)
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_atomic_except_equality/builtin_prop_definition.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
#### Natural-pair totality
`$coprime(a, b)` likewise follows Mathlib's elementary-number-theory surface:
both arguments must belong to `N`, and the predicate means `gcd(a, b) = 1`.
It is total on natural pairs, so `$coprime(0, 1)` holds while
`$coprime(0, 0)` does not. A positive fact exposes both the non-all-zero
condition needed by native `gcd` and the gcd-one equation. Integer or real
arguments require a separate future interface rather than silently changing
this predicate's domain.
### F16. Divisibility with dividend first
**Public form:** `$dvd(a, d); not $dvd(a, d)`.
**Mathematical function.** Assert that a is divisible by d: d divides a. The public argument order is dividend, divisor.
**Well-definedness and domain.** a belongs to Z, d belongs to Z*, and both expressions are WD. Negative divisibility uses the same nonzero divisor condition.
**Relationships and inference.** The positive definition checks a % d = 0 and an integer multiplier witness a = k * d. A positive fact exposes those clauses for later use.
Divisibility builtin rules use `$dvd` directly: an integer product is divisible
by either nonzero integer factor; gcd divides its arguments; lcm is divisible
by the absolute values of its nonzero arguments; common divisors and multiples
compose through gcd and lcm; and an earlier factorial divides a later one.
Integer-quotient membership and common-divisor bounds also consume `$dvd`.
Product rules check the other factor's integer membership from the displayed
expression; they do not search for an unknown multiplier. Known equalities can
transport these facts, as in the
[complete irrationality proof](../examples/proof_nodes/atomic/by_builtin_rule/dvd_unified.lit).
An already stored `a % d = 0` supplies a read-only divisibility certificate.
Zero-remainder goals reuse the native divisibility rules; general remainder
calculations retain `%`.
**Nearest boundary.** This ordering differs from the conventional written relation d | a. A zero divisor is outside the native predicate domain.
**Checked example.**
```litex
4 % 2 = 0
witness exist a Z st {4 = a * 2} from 2
by def $dvd(4, 2)
by contra:
? not $dvd(5, 2)
impossible 5 % 2 = 0
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_atomic_except_equality/builtin_prop_definition.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction).
### F17. Injectivity
**Public form:** `$injective(A, B, f); not $injective(A, B, f)`.
**Mathematical function.** A unary map f from A to B maps distinct inputs to distinct outputs.
**Well-definedness and domain.** A and B are sets; f satisfies the requested unary callable signature. Equivalent carrier spellings require checked interface evidence, and all calls must be WD.
**Relationships and inference.** The definition is forall x,y A: f(x)=f(y) implies x=y. A positive fact exposes this universal; negative injectivity does not automatically select a collision pair.
**Nearest boundary.** A callable signature or equality at one point does not prove injectivity. The carriers are part of the requested mapping interface.
**Checked example.**
```litex
have fn id1(x {1}) {1} = x
by def $injective({1}, {1}, id1)
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_atomic_except_equality/builtin_prop_definition.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction), [S01 Expression-defined functions](#s01-expression-defined-functions), [S35 Existential witnesses](#s35-existential-witnesses).
### F18. Surjectivity
**Public form:** `$surjective(A, B, f); not $surjective(A, B, f)`.
**Mathematical function.** Every value in B has a preimage under f from A.
**Well-definedness and domain.** A and B are sets; f satisfies the requested unary callable signature. Equivalent carrier spellings require checked interface evidence, and all calls must be WD.
**Relationships and inference.** The definition is forall y B: exist x A st {y=f(x)}. Prove that universal with witnesses, then fold by def; positive inference exposes the same interface.
**Nearest boundary.** One existential preimage does not prove surjectivity over the whole codomain. A return bound need not equal the actual image.
**Checked example.**
```litex
have fn identity(x R) R = x
claim:
? forall y R:
exist x R st {y = identity(x)}
witness exist x R st {y = identity(x)} from y
by def $surjective(R, R, identity)
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_atomic_except_equality/builtin_prop_definition.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction), [S01 Expression-defined functions](#s01-expression-defined-functions), [S35 Existential witnesses](#s35-existential-witnesses).
#### Positive mapping facts and universal preimages
A checked positive injective or surjective fact publishes its quantified
definition for later use; a negative property does not. Explicit `by def`
checks all defining clauses. For surjectivity, a checked universal preimage
proof can use `witness exist x A st {y = f(x)} from ...`; one unrelated
existential assertion is not that universal proof. See the
[definition tracer](../examples/proof_nodes/atomic/by_definition/builtin_surjective.lit).
Choice WD retains both `g : I -> S` and `f : I -> family_union(S)` obligations.
Equivalent carrier spellings require checked equality to each declared
signature. The identities `family_union({A}) = A` and
`family_union(power_set(A)) = A` are direct builtin equalities after object WD;
they support the [choice definition tracer](../examples/proof_nodes/atomic/by_definition/builtin_choice_function.lit).
### F19. Bijectivity
**Public form:** `$bijective(A, B, f); not $bijective(A, B, f)`.
**Mathematical function.** The requested map is both injective and surjective on the same domain/codomain.
**Well-definedness and domain.** A and B are sets; f satisfies the requested unary callable signature. Equivalent carrier spellings require checked interface evidence, and all calls must be WD.
**Relationships and inference.** Its definition is the conjunction of injective and surjective on that triple. Positive definition inference exposes the two mapping facts.
**Nearest boundary.** Changing the codomain can change bijectivity even when the pointwise expression is unchanged.
**Checked example.**
```litex
have fn id1(x {1}) {1} = x
by def $injective({1}, {1}, id1)
claim:
? forall y {1}:
exist x {1} st {y = id1(x)}
witness exist x {1} st {y = id1(x)} from y
by def $surjective({1}, {1}, id1)
by def $bijective({1}, {1}, id1)
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_atomic_except_equality/builtin_prop_definition.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction), [S01 Expression-defined functions](#s01-expression-defined-functions), [S35 Existential witnesses](#s35-existential-witnesses).
### F20. Choice-function specification
**Public form:** `$is_choice_function_for(I, S, g, f); not $is_choice_function_for(I, S, g, f)`.
**Mathematical function.** For every alpha in I, f(alpha) is a member of the selected family set g(alpha).
**Well-definedness and domain.** I and S are sets; g satisfies fn(alpha I) S and f satisfies fn(alpha I) family_union(S). Both callable contracts are independent WD requirements.
**Relationships and inference.** The pointwise membership universal is the defining clause. Choice releases produce existential facts with this atomic specification; obtain is needed to name the chosen function.
**Nearest boundary.** An arbitrary function returning into family_union(S) is not necessarily a choice from each particular g(alpha). Carrier equivalence must be checked for both signatures.
**Checked example.**
```litex
have fn family(alpha {1}) power_set({1}) = {1}
have fn choice(alpha {1}) {1} = 1
forall alpha {1}:
choice(alpha) $in family(alpha)
by def $is_choice_function_for({1}, power_set({1}), family, choice)
```
**Source:** [implementation](../src/execute/execute_fact_stmt/verify_atomic_fact/verify_atomic_except_equality/builtin_prop_definition.rs).
**Related entries:** [F01 Membership and nonmembership](#f01-membership-and-nonmembership), [S02 Bare factual statements](#s02-bare-factual-statements), [S47 Explicit definition folding](#s47-explicit-definition-folding), [S40 Proof by contradiction](#s40-proof-by-contradiction), [S01 Expression-defined functions](#s01-expression-defined-functions), [S35 Existential witnesses](#s35-existential-witnesses).
### C01. Native least-upper-bound certificate
**Public form:** `$is_real_least_upper_bound(A, value)`.
**Mathematical function.** The opaque native certificate that value is the supremum of A.
**Well-definedness and domain.** The reserved predicate signature has arity two. Its genuine mathematical evidence comes from the corresponding checked completeness release, whose subset, nonempty and bound hypotheses must verify.
**Checking and use.** The native existence theorem produces an existential certificate. Companion native theorem interfaces use it to project member/bound inequalities.
**Nearest boundary.** Recognizing this builtin signature does not prove any instance or supply a user-editable concrete prop body.
**Checked example.**
```litex
release thm real_least_upper_bound_exists({0}, 1)
exist L R st {$is_real_least_upper_bound({0}, L)}
```
**Source:** [implementation](../src/execute/execute_by_stmt/builtin_thm/real_analysis.rs).
**Related entries:** [S25 Publish theorem conclusions](#s25-publish-theorem-conclusions), [S07 Extract existential witnesses](#s07-extract-existential-witnesses).
### C02. Native greatest-lower-bound certificate
**Public form:** `$is_real_greatest_lower_bound(A, value)`.
**Mathematical function.** The opaque native certificate that value is the infimum of A.
**Well-definedness and domain.** The reserved predicate signature has arity two. Its genuine mathematical evidence comes from the corresponding checked completeness release, whose subset, nonempty and bound hypotheses must verify.
**Checking and use.** The native existence theorem produces an existential certificate. Companion native theorem interfaces use it to project member/bound inequalities.
**Nearest boundary.** Recognizing this builtin signature does not prove any instance or supply a user-editable concrete prop body.
**Checked example.**
```litex
release thm real_greatest_lower_bound_exists({0}, -1)
exist L R st {$is_real_greatest_lower_bound({0}, L)}
```
**Source:** [implementation](../src/execute/execute_by_stmt/builtin_thm/real_analysis.rs).
**Related entries:** [S25 Publish theorem conclusions](#s25-publish-theorem-conclusions), [S07 Extract existential witnesses](#s07-extract-existential-witnesses).
## Reserved builtin theorem interfaces
These are explicit theorem-call interfaces, not extra atomic predicate names.
Use `release thm name(arguments)` or an allowed atomic selection. The exact
constructor shape and quantified/compound requirements are part of the interface;
an arity match alone does not establish those requirements. All interfaces
below have a strict-mode checked example on the final release. Most link their
existing complete fixture; the function-space row links the current checked
example below, with its retained fixture-consumer boundary recorded separately.
| Reserved name | Arity | Mathematical use | Complete checked example |
|---|---|---|---|
| `fn_set_member` | 2 | Introduce function-space membership with a proved complete domain and pointwise return contract. | [checked example](#function-space-membership-and-a-typed-call-alias) |
| `family_intersect_member` | 2 | Introduce intersection membership from nonempty family, sethood and pointwise membership. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/family_intersect_member.lit) |
| `family_intersect_member_facts` | 2 | Project pointwise factor-membership facts from a known intersection member. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/family_intersect_member_facts.lit) |
| `index_intersect_member` | 2 | Introduce indexed-intersection membership from ambient and pointwise membership. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/index_intersect_member.lit) |
| `set_builder_member` | 2 | Introduce bounded-builder membership from the base membership and filters. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/set_builder_member.lit) |
| `defined_set_member` | 2 | Introduce membership through a selected stored set definition. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/defined_set_member.lit) |
| `struct_member` | 2 | Introduce a selected definition-owned struct membership. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/struct_member.lit) |
| `cart_member_from_coordinates` | 2 | Prove the complete finite domain and every factor coordinate before Cartesian membership. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/cart_member_from_coordinates.lit) |
| `index_cart_member` | 2 | Introduce indexed-product membership with the separate callable and choice contracts. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/index_cart_member.lit) |
| `index_cart_nonempty_by_choice_from_family` | 1 | Use a proved nonempty factor family to obtain product nonemptiness. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/index_cart_nonempty_by_choice_from_family.lit) |
| `index_cart_nonempty_by_choice_from_pointwise` | 1 | Use pointwise factor nonemptiness through the Choice interface. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/index_cart_nonempty_by_choice_from_pointwise.lit) |
| `sum_le_sum_from_pointwise` | 2 | Transfer a pointwise comparison on the complete integer range to the two sums. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/sum_le_sum_from_pointwise.lit) |
| `finite_set_sum_le_from_pointwise` | 2 | Transfer pointwise comparison over a finite set to the two sums. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/finite_set_sum_le_from_pointwise.lit) |
| `finite_set_summand_le_sum` | 2 | Bound one summand by the sum under the required positivity conditions. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/finite_set_summand_le_sum.lit) |
| `tuple_equal_from_coordinates` | 2 | Check both complete finite domains and all coordinates before ordinary equality. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/tuple_equal_from_coordinates.lit) |
| `finite_set_sum_substitution` | 2 | Transport a finite sum through the proved set/function substitution conditions. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/finite_set_sum_substitution.lit) |
| `sum_over_bijective_finite_set_enumerations` | 2 | Reindex a finite sum through a verified bijective enumeration. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/sum_over_bijective_finite_set_enumerations.lit) |
| `rational_has_unique_reduced_fraction` | 1 | Produce the native unique reduced-fraction existence specification. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/rational_has_unique_reduced_fraction.lit) |
| `subset_of_finite_set_is_finite` | 2 | Prove finiteness from an inclusion and finite upper set. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/subset_of_finite_set_is_finite.lit) |
| `finite_set_has_bijective_index` | 1 | Produce a finite bijective indexing existence fact. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/finite_set_has_bijective_index.lit) |
| `finite_set_reduce_singleton` | 2 | Expose the singleton fold step with its operation and seed. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/finite_set_reduce_singleton.lit) |
| `real_least_upper_bound_exists` | 2 | Use nonempty real subset and a proved upper bound to produce a supremum certificate. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/real_least_upper_bound_exists.lit) |
| `real_member_le_least_upper_bound` | 3 | Project member <= supremum from the native certificate. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/real_member_le_least_upper_bound.lit) |
| `real_least_upper_bound_le_upper_bound` | 3 | Project supremum <= any proved upper bound. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/real_least_upper_bound_le_upper_bound.lit) |
| `real_greatest_lower_bound_exists` | 2 | Use nonempty real subset and a proved lower bound to produce an infimum certificate. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/real_greatest_lower_bound_exists.lit) |
| `real_greatest_lower_bound_le_member` | 3 | Project infimum <= member from the native certificate. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/real_greatest_lower_bound_le_member.lit) |
| `real_lower_bound_le_greatest_lower_bound` | 3 | Project any proved lower bound <= infimum. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/real_lower_bound_le_greatest_lower_bound.lit) |
| `real_archimedean_natural_upper_bound` | 1 | Produce a positive natural greater than a real argument. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/real_archimedean_natural_upper_bound.lit) |
| `rational_between_reals` | 2 | Produce a rational strictly between two ordered real arguments. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/rational_between_reals.lit) |
| `gcd_with_prime_is_one_or_prime` | 2 | From `$prime(p)`, conclude `gcd(a, p) = 1 or gcd(a, p) = p`. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/gcd_with_prime_is_one_or_prime.lit) |
| `prime_divides_product` | 3 | Euclid's lemma: `$prime(p)` and `$dvd(a * b, p)` imply `$dvd(a, p) or $dvd(b, p)`. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/prime_divides_product.lit) |
| `prime_divides_power` | 3 | From `$prime(p)` and `$dvd(a ^ k, p)` with `k $in N+`, conclude `$dvd(a, p)`. | [fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/prime_divides_power.lit) |
For membership interfaces, pass the complete constructor where the fixture
shows one: `family_intersect_member(x, family_intersect(F))` takes the
intersection object, not F. Function/tuple interfaces check complete domains,
rather than accepting a few valid calls as a substitute. The source registry
is [BuiltinTheoremId](../src/builtin_theorem.rs); the inventory retains exact
fixture commands, hashes and successful results.
Completeness, Archimedean/density, Choice and related native mathematical
interfaces are part of the fixed foundational support. Their checked caller
obligations and native certificates remain distinct from user-written proof
bodies and user trust. Passing strict mode does not erase that foundation.
### Function-space membership and a typed call alias
The native membership call below verifies the same complete finite input
domain while allowing the proved real return bound of an integer-valued
function. The alias then has that declared callable interface. In the final
release, computing its value through this alias uses an explicit canonical
application equality before transport:
```litex
have fn narrow(k closed_range(1,2)) Z = 0
release thm fn_set_member(narrow, finite_seq(R,2))
have F set = fn(k closed_range(1,2)) R
have named F = narrow
narrow(1) = 0
named(1) = narrow(1) = 0
```
The [retained fixture](../examples/stmt_nodes/release_and_expand/builtin_thm/fn_set_member.lit)
contains `named(1) = 0` without that bridge. Its native theorem calls verify,
but that later consumer misses `search_proof` in the final source snapshot.
The journal preserves both results. This is a current proof-search boundary
of the consumer, not a rejection of the function-space theorem interface.
No kernel or existing fixture was changed for this reference.
## Pitfalls and missing proof steps
Each card pairs an exact rejection with an appropriate positive example or a
linked correction. Error-phase labels below are taken from isolated current
runs. A mathematical counterexample, missing premise, and proof-search miss
are different reasons; each card states which applies.
### P01. Reflexivity does not bypass well-definedness
**Intention:** assert the reflexive equality of a reciprocal expression.
**Expected rejection — phase `well_defined`:**
```litex
have x R
1 / x = 1 / x
```
The checker stops before comparing the two sides: `x != 0` is unavailable.
Writing identical expressions does not make an undefined division legal.
The positive counterpart is the guarded universal in
[O01](#domain-and-well-definedness), with the same reflexive goal for inputs
in its actual domain. For a callable construction, use the next card.
### P02. The body must be meaningful throughout the function domain
**Expected rejection — phase `have_fn_equal`; anonymous-function body WD fails:**
```litex
have fn reciprocal(x R) R = 1 / x
```
The declared domain includes zero. The repair for the intended partial
reciprocal is the guarded definition in [S01](#parameters-domain-and-return-set).
This is a domain correction, not proof automation. If the intended mathematics
requires a value at zero, a different definition specifying that value is needed.
### P03. A legal function declaration does not license every call
**Expected rejection — phase `well_defined`:**
```litex
have fn reciprocal(x R: x != 0) R = 1 / x
reciprocal(0) = 0
```
The call violates the written guard. Changing the right side of the equation
cannot repair its argument domain. The positive calls at `2` and `-2` in S01
satisfy the signature.
A guard also does not establish any desired equation involving the expression.
**Expected rejection — phase `search_proof`:**
```litex
forall x R:
x != 0
=>:
1 / x = 1
```
The expressions are WD, but the mathematical universal is false; `x = 2` is
a counterexample. Nonzeroness and the value of the reciprocal are independent
questions. This example must not be diagnosed as another missing WD guard.
### P04. Connect division and multiplication explicitly
**Intention:** from `a / b = c` and `b != 0`, deduce `a = c * b`.
**Direct form — verified:**
```litex
forall a, b, c R:
b != 0
a / b = c
=>:
a = c * b
```
The current checker verifies this implication directly. An explicit equality
chain makes the same mathematical route visible:
```litex
claim:
? forall a, b, c R:
b != 0
a / b = c
=>:
a = c * b
a = (a / b) * b = c * b
```
The chain has two mathematical steps: `(a / b) * b = a` uses division
cancellation, and replacing `a / b` by `c` uses the premise. Its middle
expression connects an implemented identity to a known equality.
The proof uses the active goal parameters `a`, `b`, `c`; it does not introduce
a second universal with renamed parameters inside the proof body.
The reverse direction also verifies directly:
```litex
forall a, b, c R:
b != 0
a = b * c
=>:
a / b = c
```
The same implication with an explicit equality chain:
```litex
claim:
? forall a, b, c R:
b != 0
a = b * c
=>:
a / b = c
a / b = (b * c) / b = c
```
Both direct universal statements and the explicit equality-chain proofs verify
with the stated premises. The chains explain the derivation; they do not imply
that these two facts require a `claim` block. The nonzero-divisor condition
remains part of both statements.
### P05. A function equation may need to be exposed before substitution
The complete reciprocal-law proof is in [R01](#prove-a-law-of-the-function).
It contains these two mathematical steps:
```litex
# Fragment of the full checked R01 proof; x and reciprocal are defined there.
reciprocal(x) = 1 / x
reciprocal(x) * x = 1
```
The first line establishes the specific function value equality. The scalar
identity then verifies directly, and the full R01 claim needs only that value
equation in its body. The longer chain remains a readable optional explanation.
Deleting the value equation still leaves a search miss in this context; a
function definition alone does not publish every symbolic application value.
This boundary concerns the exact reciprocal-law example. It does not mean
that every function application needs a manually repeated defining equation.
Concrete evaluations such as `reciprocal(2) = 1 / 2` already verify directly.
### P06. Arbitrary `have` needs nonemptiness
**Expected rejection — phase `have_in_nonempty`:**
```litex
have x {t R: t > 0}
```
In this cold context, the checker has not established that this builder is
nonempty. It does not follow that the set is empty. The correction in
[F01](#set-builder-membership) supplies `1` as a concrete member using
`witness`, then introduces an arbitrary member with `have`.
A builder's definition, an established member, and an arbitrary selection
are different steps. Do not append uses of `x` after a failed declaration:
that name was not successfully introduced, so a later line has an earlier
name-resolution problem to fix first.
### P07. Name the value equality before arithmetic
In this current two-level alias example the final arithmetic equality misses search. A direct equality chain connects the alias to the numerical value before use; this is a boundary of the example, not a rule that every alias requires an extra line.
**Expected rejection — search_proof:**
```litex
have a R = 2
let b = a
b + 1 = 3
```
**Checked counterpart:**
```litex
have a R = 2
a = 2
let b = a
b = a = 2
b + 1 = 3
```
**Evidence:** `P07` / `N11` in the current inventory journal.
### P08. Displayed sets require proved distinct elements
Repeated elements are harmless in informal set notation, but the native displayed-set constructor requires pairwise verified inequality. With symbolic values, carry the genuine distinctness condition if two elements are intended.
**Expected rejection — let (object well-definedness):**
```litex
let A = {1,1}
```
**Checked counterpart:**
```litex
forall a, b R:
a != b
=>:
$is_finite_set({a, b})
finite_set_size({a, b}) = 2
```
**Evidence:** `P08` / `N01` in the current inventory journal.
### P09. An explicit definition proof has its own obligations
The ordinary closed fact $prime(5) verifies by calculation. A cold by-def request still asks for the lower bound and trial-divisor universal. Prove the finite trial condition explicitly, then fold the definition. This differs from asking the calculation route to repeat its answer.
**Expected rejection — by_def:**
```litex
by def $prime(5)
```
**Checked counterpart:**
```litex
by for:
? forall divisor range(2, 5):
5 % divisor != 0
5 % divisor != 0
by def $prime(5)
```
**Evidence:** `P09` / `N13` in the current inventory journal.
### P10. Divisibility argument order and negative proof
The native form $dvd(a,d) has dividend first, nonzero divisor second. In the checked negative example ordinary search misses; an explicit contradiction uses the positive definition’s remainder equality without changing the mathematical goal.
**Expected rejection — search_proof:**
```litex
not $dvd(5,2)
```
**Checked counterpart:**
```litex
4 % 2 = 0
witness exist a Z st {4 = a * 2} from 2
by def $dvd(4, 2)
by contra:
? not $dvd(5, 2)
impossible 5 % 2 = 0
```
**Evidence:** `P10` / `N12` in the current inventory journal.
### P11. An empty indexed domain is not a zero-factor Cartesian product
The current indexed union/intersection/product constructors require a nonempty index. Ordinary cart() has a separate exact finite-function meaning and cardinality one. These public constructors have different domain contracts.
**Expected rejection — let (object well-definedness):**
```litex
let family = fn(k {}) power_set(N) {{1}}
let U = index_union({}, N, family)
```
**Checked counterpart:**
```litex
tuple() $in cart()
finite_set_size(cart()) = 1
let family = fn(k {1}) power_set(N) {{1}}
let U = index_union({1}, N, family)
$is_set(U)
```
**Evidence:** `P11` / `N14` in the current inventory journal.
### P12. A search miss does not disprove an inequality
**Common mistake:** interpret a failed direct goal as evidence that nonlinear
inequalities, algebraic rearrangement, or the mathematical problem are
impossible to formalize. These are different questions: whether the statement
is true, whether a supplied proof verifies, and whether the checker discovers
that proof from the current facts.
**Observed search boundary:** the following true goal soft-fails at
`search_proof` in the build recorded in the recipe audit. This is a capability
observation, not a false statement or a permanent rejection requirement.
```litex
forall a, b R:
a^2+b^2 >= 2*a*b
```
**Checked repair:** [R06](#r06-complete-a-square-and-translate-the-bound)
proves exactly that goal in strict mode. Expose the square identity, its
nonnegative bound, and the common translation. No new hypothesis is needed.
The shorter proof containing only `(a-b)^2 >= 0` also misses the conclusion
in this build. A subtraction proof works after explicitly storing the
`0 <= difference` spelling consumed by the difference rule.
The active native pipeline uses known facts, exact calculations, builtin
rules, definitions and explicit proof statements. Its atomic checker is not
a generic SMT optimization entrypoint. A search miss does not establish a
limitation of SMT or of other proof assistants. Report the failed step and
the attempted proof route; reserve a kernel-gap claim for a reduced,
source-backed failure of a mathematically valid interface.
A numeric sample check is evidence about those samples, not a proof for all
real inputs. A polynomial identity or sum-of-squares certificate becomes
proof evidence here when its equality and guarded order steps verify.
`trust` remains an assumption even if its comment describes external work;
a comment does not change the checker’s trust boundary.
### P13. Preserve sign, strictness and expression shape
**Mathematical boundaries:** every ordered operand is real. Adding a common
real expression needs no sign condition. Multiplication and division do.
| Incorrect general step | Counterexample | Correct requirement or conclusion |
|---|---|---|
| `a<=b` implies `a*k<=b*k` for arbitrary real `k` | `1<=2`, but `1*(-1)>2*(-1)` | `k>=0` preserves weak order; `k<0` reverses it |
| `a=0` implies `a*k0` for the strict preserved bound |
| `a<=b` implies `a=0` makes `a/k` meaningful | `k=0` is allowed by that premise | Require nonzero WD and the appropriate strictly positive/negative sign |
| `a<=b` implies `a^2<=b^2` on all reals | `-2<=-1`, but `(-2)^2>(-1)^2` | Restrict both bases to the nonnegative region or compare absolute values |
| `z $in C` makes `z^2>=0` an ordered fact | A general complex scalar has no real-order contract | Establish real membership before using a real-order rule |
The numerical counterexamples above are checked without assumptions:
```litex
1 <= 2
1*(-1) > 2*(-1)
1 < 2
1*0 = 2*0
1 <= 1
not 1 < 1
-2 <= -1
(-2)^2 > (-1)^2
```
**Matching boundary:** equal mathematical expressions may have distinct
object shapes. The bound rules used in
[R08](#r08-scale-an-inequality-with-the-correct-sign) and
[R10](#r10-expose-absolute-value-bounds) consume explicit subtraction from
zero. Writing `0-x = -x <= M` exposes the equality and stores the matching
bound; expecting the checker to invent that rewriting inside every order
premise can miss. Similarly, an order rule may consume a stored premise
rather than recursively discovering it. See R06's two spellings of a
nonnegative difference and R09's explicit nonnegative summands.
## Recommended mathematical formulations
### R01. Define and use a reciprocal function
**Ordinary mathematics:** a function on nonzero reals, returning `1 / x`.
**Recommended form:** the guarded expression-defined function from S01:
`have fn reciprocal(x R: x != 0) R = 1 / x`.
The signature states the domain where the expression is meaningful, and the
return carrier states the output contract. Callers can see their obligation
without inspecting the definition body.
**Supported alternative:** use the nonzero-real carrier `R*`:
```litex
have fn reciprocal(x R*) R = 1 / x
reciprocal(2) = 1 / 2
```
`R*` carries real membership and nonzeroness. Both definitions express the
same intended mathematical domain here. The explicit guard spells out the
condition for readers learning WD; the carrier form is useful when the domain
already plays a recurring role. The current public spellings include `R+`
and `R*`; do not infer aliases such as `R_pos` from old notes.
### Prove a law of the function
**Ordinary mathematics:** the reciprocal multiplied by its nonzero argument
is one. Define the callable value, expose its equation at the active argument,
then use the division identity:
```litex
have fn reciprocal(x R: x != 0) R = 1 / x
claim:
? forall x R:
x != 0
=>:
reciprocal(x) * x = 1
reciprocal(x) = 1 / x
```
This example demonstrates the full route through the dictionaries:
1. [S01](#s01-expression-defined-functions) gives the definition and stored
callable contract.
2. [O01](#o01-division) explains the guard and the scalar identity.
3. [F01](#f01-membership-and-nonmembership) explains carrier information and
legal function applications.
4. [P05](#p05-a-function-equation-may-need-to-be-exposed-before-substitution)
explains why the function-value equation is exposed before checking the law.
The proof machinery remains local to the `claim`; the successful statement
exports its universal conclusion. No helper theorem merely restating the
function definition is introduced.
### R02. Choose the language form by mathematical role
| Mathematical intention | Recommended form | Why |
|---|---|---|
| A named callable value given by a formula | `have fn ... = ...` | Later code needs to apply the function and use its return contract |
| A condition on an object | `prop ...` | Names a mathematical proposition with a concrete definition |
| A one-off derived fact requiring intermediate steps | `claim` | Proves and exports the goal while keeping helpers local |
| A routine carrier consequence | State the membership directly | Use the existing carrier machinery without an unnecessary wrapper |
| A division transformation whose cold goal misses | A local equality chain as in P04 | Connects the original expression to the usable identity |
| A reusable mathematical result | A named `thm` interface | Worth naming when later developments need that result |
These are recommendations about roles and proof organization, not a list of
new parser restrictions. Distinguish a mathematical domain requirement from
a source-style choice. For example, multiline `forall` is the recommended
teaching form; the supported inline syntax is not made invalid by that choice.
### R03. A declaration family over an arbitrary carrier
**Mathematical role:** declaration family. **Form:** template with a formula-defined function.
An identity map for each carrier set S. The set changes the declaration’s input and return carrier; later use specializes the family then calls the function.
```litex
template:
have fn identity(x S) S = x
\identity(2) = 2
\identity(-3) = -3
```
The binder category set is not a writable universal set to use as a normal function input domain. An ordinary formula function over real inputs remains have fn, without a template.
**Evidence:** `R03` in the current inventory record; the interface and immediate use both verify in strict mode.
### R04. A relation and its selected value have different roles
**Mathematical role:** relation versus callable value. **Form:** prop for the relation; have fn for the callable value.
A reciprocal relation checks a supplied value and argument; a reciprocal function supplies a value that a caller can apply. The relation’s nonzero domain is encoded in its carrier rather than supplied later by convention.
```litex
prop is_reciprocal_of(value R, argument R*):
value = 1 / argument
by def $is_reciprocal_of(1 / 2, 2)
have fn reciprocal(x R*) R = 1 / x
reciprocal(2) = 1 / 2
```
A proposition about a candidate output is not a replacement for a callable function. Use the relation when callers assert truth about supplied values, and the function when callers need reciprocal(x).
**Evidence:** `R04` in the current inventory record; the interface and immediate use both verify in strict mode.
### R05. A piecewise definition and a universal law
**Mathematical role:** function definition and mathematical result. **Form:** have fn by cases, followed by a local claim.
Define an absolute-value function from two disjoint exhaustive real cases. To prove its agreement with the native abs, use the active input binder and the same mathematical case split.
```litex
have fn absolute(x R) R by cases:
case x >= 0: x
case x < 0: -x
claim:
? forall x R:
absolute(x) = |x|
by cases:
? absolute(x) = |x|
case x >= 0:
0 <= x
absolute(x) = x = |x|
case x < 0:
x <= 0
absolute(x) = -x = |x|
```
The guarded equations of the definition are already usable. In this comparison with native abs, the proof additionally states the weak sign facts consumed by the abs rule before the equality chains. These facts follow from the cases; they are not new mathematical hypotheses. Independent deletion controls identify the necessary bridges.
**Evidence:** `R05` in the current inventory record; the interface and immediate use both verify in strict mode.
### R06. Complete a square and translate the bound
**Ordinary mathematics:** for any real `a,b`, prove `a^2+b^2 >= 2*a*b`.
Complete the square, then add `2*a*b` to both sides of the nonnegative bound.
The added expression can have either sign: translation preserves order.
**Checked recommended form:** keep the equality and order steps together.
```litex
claim:
? forall a, b R:
a^2 + b^2 >= 2*a*b
a^2 - 2*a*b + b^2 = (a-b)^2 >= 0
a^2 + b^2 = (a^2 - 2*a*b + b^2) + 2*a*b >= 0 + 2*a*b = 2*a*b
```
The first chain combines an algebraic identity with even-power
nonnegativity. The second writes the target's left side as the known
nonnegative expression plus the target's right side. Each adjacent equality
or comparison is checked; the chain then supplies the endpoint bound.
This is algebra plus order translation, with no optimization oracle or
assumption. `claim` exposes `a,b` as active real binders inside its proof.
**Checked difference alternative:** turn a nonnegative difference into an
endpoint comparison, explicitly storing the orientation the native rule uses.
```litex
claim:
? forall a, b R:
a^2+b^2 >= 2*a*b
a^2+b^2-2*a*b = (a-b)^2 >= 0
0 <= a^2+b^2-2*a*b
```
The last line is mathematically the converse of the preceding bound;
it supplies the saved `0 <= right-left` premise. In the audited build,
deleting that line leaves the claim's endpoint search unresolved. This is a
proof-matching bridge, not an additional mathematical premise. A chain that
only establishes the square identity and its nonnegativity also leaves the
claim conclusion unresolved. Prefer the first proof when teaching the
mathematical rearrangement; use the second when an existing proof already
has a difference bound.
**Related entries:** [F02 equality](#f02-equality-and-inequality),
[F05/F06 real order](#f05-weak-less-than),
[P12 search boundaries](#p12-a-search-miss-does-not-disprove-an-inequality),
[native order rules](#order-and-comparison-rules).
### R07. Translate, add, subtract and compose bounds
**Ordinary mathematics:** an equality identifies interchangeable endpoints;
an inequality orders them. First expose a useful expression by equality,
then apply the order move with its exact shared term or middle expression.
All variables in the following table are real.
| Mathematical move | Litex fact to write | Condition or proof shape |
|---|---|---|
| Add the same expression | `a+c <= b+c` | `a<=b`; no sign restriction on `c` |
| Subtract the same expression | `a-c <= b-c` | `a<=b` |
| Subtract ordered expressions from a common term | `c-a >= c-b` | `a<=b`; the subtrahend's order reverses |
| Add two bounds | `a+c <= b+d` | `a<=b`, `c<=d`; an explicit shared-addend chain is also available |
| Subtract two bounds | `a-d <= b-c` | `a<=b`, `c<=d`; use `a-d <= b-d <= b-c` |
| Compose weak bounds | `a<=c` | `a<=b`, `b<=c`, with the same middle expression |
| Compose a strict and a weak bound | `a:
a+c <= b+c
a-c <= b-c
c-a >= c-b
forall a, b, c R:
a <= b
b <= c
=>:
a <= c
forall a, b, c R:
a <= b
b < c
=>:
a < c
forall a, b R:
a < b
=>:
a <= b
forall a, b, c R:
a = b
b <= c
=>:
a <= c
forall a, b R:
a <= b
=>:
0 <= b-a
forall a, b R:
0 <= b-a
=>:
a <= b
```
**Checked componentwise proof:** subtract the larger second operand on the
left. The explicit middle term prevents a missing compound search step.
```litex
claim:
? forall a, b, c, d R:
a <= b
c <= d
=>:
a+c <= b+d
a-d <= b-c
a+c <= b+c <= b+d
a-d <= b-d <= b-c
```
**Checked negation by translation:** multiplying by `-1` reverses real
order. An explicit translation chain also proves the result without relying
on automatic matching of a unary negative object.
```litex
claim:
? forall a, b R:
a < b
=>:
-b < -a
-b = a+(-a-b) < b+(-a-b) = -a
```
The native rule families include addition congruence, order transitivity,
order weakening and saved-difference bridges. These checked routes do not
promise arbitrary automatic rearrangement inside a larger expression.
### R08. Scale an inequality with the correct sign
**Ordinary mathematics:** positive factors preserve order, negative factors
reverse it, and a zero factor loses strictness. Division additionally has
the nonzero WD obligation. Establish the sign before writing the scaled bound.
**Checked direct forms:** a nonnegative factor is sufficient for weak
multiplication. A strictly positive factor preserves strict multiplication;
a strictly signed divisor determines the direction and excludes zero.
```litex
forall a, b, k R:
a <= b
k >= 0
=>:
a*k <= b*k
forall a, b, k R:
a < b
k > 0
=>:
a*k < b*k
forall a, b, k R:
a <= b
k > 0
=>:
a/k <= b/k
forall a, b, k R:
a <= b
k < 0
=>:
a/k >= b/k
```
**Checked negative-factor proof:** expose the positive factor `0-k`,
multiply, then reverse order by subtracting from zero. The equalities return
to the requested products.
```litex
claim:
? forall a, b, k R:
a < b
k < 0
=>:
a*k > b*k
a*(0-k) < b*(0-k)
a*k = 0-a*(0-k) > 0-b*(0-k) = b*k
```
The sign check `0-k>0` follows from `k<0` during the positive multiplication
step; it can be written out for explanation but is not required as a separate
statement here. The negative multiplication target alone misses in the audited
build; this proof provides its valid mathematical route. This example also explains
why a table of true laws must distinguish a builtin's immediate matching
shape from a result proved by composing several builtin laws.
### R09. Build a sum-of-squares proof
**Ordinary mathematics:** a real square is nonnegative; sums of
nonnegative terms stay nonnegative. If a polynomial difference equals a
sum of squares with nonnegative coefficients, verify that identity and
each sign step, then translate to the desired endpoints.
**Checked sign primitives:** keep the real carrier. A nonzero real base
gives a strictly positive square; a possibly zero base gives a weak bound.
```litex
forall x R:
x^2 >= 0
x^4 >= 0
forall x R:
x != 0
=>:
0 < x^2
forall u, v R:
u >= 0
v >= 0
=>:
u+v >= 0
u*v >= 0
forall a, b R:
0 <= a
a <= b
=>:
a^2 <= b^2
```
**Checked three-variable example:** prove
`a^2+b^2+c^2 >= a*b+b*c+c*a`. The positive coefficient `1/2` and every
square's real carrier make the certificate's sign clear.
```litex
claim:
? forall a, b, c R:
a^2+b^2+c^2 >= a*b+b*c+c*a
(a-b)^2+(b-c)^2 >= 0
(a-b)^2+(b-c)^2+(c-a)^2 >= 0
((a-b)^2+(b-c)^2+(c-a)^2)/2 >= 0
a^2+b^2+c^2 = ((a-b)^2+(b-c)^2+(c-a)^2)/2 + (a*b+b*c+c*a) >= 0+(a*b+b*c+c*a) = a*b+b*c+c*a
```
The identity is checked algebraically. The preceding statements expose the
accumulated nonnegative sums and quotient before the endpoint chain; their
square signs are checked by native rules without separate square statements.
In the audited build, the certificate identity with an appended `>=0`
alone misses; merely listing its three square bounds before the last chain
also misses. Those failures describe the missing composition, not the
impossibility of multivariable nonlinear inequalities. Finding a suitable
certificate for a different problem is separate mathematical work; this
recipe does not promise a general certificate search algorithm.
### R10. Expose absolute-value bounds
**Ordinary mathematics:** to prove `|x|<=M`, supply the bounds on `x`
and its negative. The native matching form uses `0-x`. Triangle and
reverse-triangle bounds are useful starting facts for sums and differences.
**Checked preview: real distance and binary extrema.** Symmetry and the
distance triangle check directly, without publishing a negation or an
intermediate sum:
```litex
forall x,y,z R:
|x-y| = |y-x|
|x-z| <= |x-y|+|y-z|
|x-y| <= |x|+|y|
```
Two checked coordinate error bounds give the same bound on their minima or
maxima. Strict bounds and reverse-written comparisons also work; the rule
retains each actual source comparison as proof evidence.
```litex
forall a,b,x,y R, epsilon R+:
|a-x| <= epsilon
|b-y| <= epsilon
=>:
|max(a,b)-max(x,y)| <= epsilon
|min(a,b)-min(x,y)| <= epsilon
```
A common positive radius can be bound directly:
```litex
have a,b,c R+
have first_radius R+ = min(a,b)
have common_radius R+ = min(first_radius,c)
```
These are fixed builtin leaves. The extrema rules also recognize already-WD
finite extrema of `union({a},{b})` or a displayed two-member set. Finiteness,
nonemptiness, real membership and displayed-set distinctness still belong to
object WD. Both error bounds or both positive memberships are required. A
nested minimum can use a checked typed intermediate as above; the rules do
not increase the inherited premise ceiling.
Runnable tracers: [maximum bound](../examples/proof_nodes/atomic/by_builtin_rule/max_lipschitz_from_coordinate_bounds.lit),
[minimum bound](../examples/proof_nodes/atomic/by_builtin_rule/min_lipschitz_from_coordinate_bounds.lit),
[positive minimum](../examples/proof_nodes/atomic/by_builtin_rule/min_preserves_positive_carrier.lit),
[distance symmetry](../examples/proof_nodes/equal/by_builtin_rule/abs_difference_symmetry.lit),
and [distance triangle](../examples/proof_nodes/atomic/by_builtin_rule/abs_difference_triangle.lit).
**Checked direct forms:**
```litex
forall x, M R:
x <= M
0-x <= M
=>:
|x| <= M
forall x, y R:
|x+y| <= |x|+|y|
|x|-|y| <= |x-y|
```
**Checked interval proof:** starting from `-M<=x<=M`, translate the lower
bound into the required upper bound on `0-x`.
```litex
claim:
? forall x, M R:
-M <= x
x <= M
=>:
|x| <= M
0-x = -M+(M-x) <= x+(M-x) = M
|x| <= M
```
If the available premise is already `-x<=M`, the corresponding bridge is
`0-x = -x <= M`. This is equality transport, with no extra sign assumption.
Keep the exact verified reverse-triangle orientation above; a nested absolute
value or converse spelling can require additional steps.
See [the native order table](#order-and-comparison-rules) for guarded rule families; these recipes supply complete proof sequences.
### R11. Product signs, zero factors and cancellation
**Ordinary mathematics:** multiplication combines two signs. Applying it to
an order relation additionally needs the common factor's sign. Cancelling a
factor needs nonzeroness; its sign determines the direction for order.
These are separate obligations, even when they concern the same product.
| Mathematical task | Exact condition | Useful conclusion or route |
|---|---|---|
| Nonnegative product | `a>=0`, `b>=0`, or both `a<=0`, `b<=0` | `a*b>=0` |
| Positive product | Both strictly positive or both strictly negative | `a*b>0`; a zero endpoint would invalidate strictness |
| Opposite weak signs | `a>=0`, `b<=0` | `a*b<=0`; expose `a*b<=a*0=0` |
| Opposite strict signs | `a>0`, `b<0` | `a*b<0`; expose `a*b0` | `a<=b` |
| Cancel a negative factor | `a*k<=b*k`, `k<0` | `a>=b` |
All operands here are real. [R08](#r08-scale-an-inequality-with-the-correct-sign)
covers multiplication/division by one fixed factor; this entry covers sign
combinations, reverse use and two varying factors.
**Checked direct sign and zero facts:**
```litex
forall a, b R:
a <= 0
b <= 0
=>:
0 <= a*b
forall a, b R:
a > 0
b > 0
=>:
a*b > 0
forall a, b R:
a < 0
b < 0
=>:
a*b > 0
forall a, b R:
a != 0
b != 0
=>:
a*b != 0
forall a, b R:
a*b = 0
=>:
a = 0 or b = 0
forall a, b R:
a*b = 0
b != 0
=>:
a = 0
```
**Checked opposite-sign routes:** in the audited build, the displayed
translation through the zero product supplies the step that the bare goal
misses. It applies positive/nonnegative multiplication to `b<=0` or `b<0`.
```litex
claim:
? forall a, b R:
0 <= a
b <= 0
=>:
a*b <= 0
a*b <= a*0 = 0
claim:
? forall a, b R:
0 < a
b < 0
=>:
a*b < 0
a*b < a*0 = 0
```
**Checked cancellation:** divide the original product expressions by the
same nonzero factor, then use their equalities with the endpoints.
```litex
claim:
? forall a, b, k R:
k > 0
a*k <= b*k
=>:
a <= b
a = (a*k)/k <= (b*k)/k = b
claim:
? forall a, b, k R:
k < 0
a*k <= b*k
=>:
a >= b
a = (a*k)/k >= (b*k)/k = b
claim:
? forall a, b, k R:
k != 0
a*k = b*k
=>:
a = b
a = (a*k)/k = (b*k)/k = b
```
The bare cancellation conclusions miss in fresh audited runs; these chains
verify. `k>=0` is insufficient for cancellation because it includes `k=0`.
For example, `2*0=1*0` gives no equality or order between `2` and `1`.
#### Bound a product with two varying factors
**Ordinary mathematics:** if `0<=a<=b` and `0<=c<=d`, then `a*c<=b*d`.
The weak bound verifies directly. For a strict result, one comparison must
be strict and the factor multiplying that comparison must be positive.
```litex
forall a, b, c, d R:
0 <= a
a <= b
0 <= c
c <= d
=>:
a*c <= b*d
claim:
? forall a, b, c, d R:
0 <= a
a < b
0 < c
c <= d
=>:
a*c < b*d
a*c < b*c <= b*d
```
The shared intermediate product is `b*c`. The second factor's domain makes
the first step strict; the first factor's bounds supply the nonnegative `b`
needed by the second step. Merely knowing `a<=b` and `c<=d` is insufficient
when signs are unrestricted: `-2<=-1`, `-3<=-2`, but `6>2`.
### R12. Squares, absolute values and equality cases
**Ordinary mathematics:** a square measures magnitude. Order on squares
therefore compares absolute values; order on the original signed values
requires a sign restriction. A real square is zero exactly when its base is
zero. Use that fact to recover the equality cases of nonnegative bounds.
| Mathematical task | Recommended statement or route |
|---|---|
| Remove the sign before squaring | `\|x\|^2 = x^2` |
| Take the root of a square on all reals | `sqrt(x^2) = \|x\|` |
| Take the root of a square with `x>=0` | `sqrt(x^2) = x` |
| Square a square root with `x>=0` | `sqrt(x)^2 = x` |
| Separate a product's magnitude | `\|x*y\| = \|x\|*\|y\|` |
| Remove absolute value from a real square | `x $in R` gives `\|x^2\| = x^2` |
| Compare magnitudes | `a^2<=b^2` gives `\|a\|<=\|b\|` |
| Recover signed order from squares | With `a,b>=0`, `a^2<=b^2` gives `a<=b` |
| Recover zero from a square | `x^2=0` gives `x=0` |
| Recover zero from a square sum | `a^2+b^2=0` gives `a=b=0` |
**Checked conversion identities:**
```litex
forall x R:
|x|^2 = x^2
sqrt(x^2) = |x|
|x^2| = x^2
forall x, y R:
|x*y| = |x|*|y|
forall x R:
0 <= x
=>:
sqrt(x^2) = x
sqrt(x)^2 = x
```
**Checked square-order directions:** the forward magnitude bound verifies
directly. The reverse direction uses square monotonicity on nonnegative
absolute values, with equality transport at the endpoints.
```litex
forall a, b R:
a^2 <= b^2
=>:
|a| <= |b|
claim:
? forall a, b R:
|a| <= |b|
=>:
a^2 <= b^2
a^2 = |a|^2 <= |b|^2 = b^2
```
**Checked signed reflection:** expose the square-root domain facts before
using root monotonicity, then remove the roots using the nonnegative bases.
```litex
claim:
? forall a, b R:
0 <= a
0 <= b
a^2 <= b^2
=>:
a <= b
0 <= a^2
0 <= b^2
a = sqrt(a^2) <= sqrt(b^2) = b
```
Deleting either square-domain statement makes the root comparison miss in
the audited build. They are verified domain bridges, not extra hypotheses.
For squaring in the forward direction, use the nonnegative-base example in
[R09](#r09-build-a-sum-of-squares-proof).
#### Zero and strictly positive square sums
**Checked zero and strict cases:** a nonzero summand's base is sufficient
for strict positivity of a two-square sum. Conversely, a zero square sum
forces both bases to zero.
```litex
forall x R:
x^2 = 0
=>:
x = 0
forall x, y R:
x != 0
=>:
x^2+y^2 > 0
forall a, b R:
a^2+b^2 = 0
=>:
a = 0
b = 0
```
Equal squares do not select a sign: `(-2)^2=2^2` and `not -2=2`.
Likewise `sqrt((-2)^2)=2`, not `-2`. Establish a nonnegative base before
removing the absolute value from a square root.
### R13. Reusable quadratic certificates
**Ordinary mathematics:** several frequently used estimates share one
proof route: write `upper-lower` as a nonnegative square (possibly divided
by a positive parameter), save its nonnegative orientation and compare
the endpoints. The mathematical certificate is the important reusable idea;
each displayed proof composes existing native equalities and order rules.
These are not additional named native predicates or automatic tactics.
| Useful bound | Nonnegative difference | Domain |
|---|---|---|
| `4*a*b <= (a+b)^2` | `(a-b)^2` | Any real `a,b` |
| `(a+b)^2 <= 2*(a^2+b^2)` | `(a-b)^2` | Any real `a,b` |
| `2*a*b <= t*a^2+b^2/t` | `(t*a-b)^2/t` | Real `a,b`; `t>0` |
| `(a*c+b*d)^2 <= (a^2+b^2)*(c^2+d^2)` | `(a*d-b*c)^2` | Any real `a,b,c,d` |
**Checked squared-sum and product bounds:** both allow signed inputs.
```litex
claim:
? forall a, b R:
4*a*b <= (a+b)^2
(a+b)^2-4*a*b = (a-b)^2 >= 0
0 <= (a+b)^2-4*a*b
claim:
? forall a, b R:
(a+b)^2 <= 2*(a^2+b^2)
2*(a^2+b^2)-(a+b)^2 = (a-b)^2 >= 0
0 <= 2*(a^2+b^2)-(a+b)^2
```
**Checked weighted bound:** choosing a positive `t` adjusts the cost of
the two square terms. This is useful when a proof has unequal coefficients.
Positivity gives both the denominator's WD and the certificate's sign.
```litex
claim:
? forall a, b, t R:
0 < t
=>:
2*a*b <= t*a^2+b^2/t
t*a^2+b^2/t-2*a*b = (t*a-b)^2/t >= 0
0 <= t*a^2+b^2/t-2*a*b
```
For `t<0`, the claimed direction is invalid: `a=1`, `b=0`, `t=-1` would
require `0<=-1`. At `t=0`, the formula has an undefined denominator.
The parameter's condition is part of the mathematical interface.
**Checked two-dimensional Cauchy–Schwarz:** the identity also connects the
dot product and the complementary determinant. It works for all signed
real inputs and is a direct certificate for a degree-four polynomial bound.
```litex
claim:
? forall a, b, c, d R:
(a*c+b*d)^2 <= (a^2+b^2)*(c^2+d^2)
(a^2+b^2)*(c^2+d^2)-(a*c+b*d)^2 = (a*d-b*c)^2 >= 0
0 <= (a^2+b^2)*(c^2+d^2)-(a*c+b*d)^2
```
Both certificate statements are needed in the audited proof. The bare
target misses; the full route verifies in strict mode. This example proves
the two-dimensional instance. A general finite-dimensional theorem would
need its own statement, summation interface and proof.
#### Recover the equality case
**Ordinary mathematics:** once a bound was obtained from a square, equality
forces that square to zero. Its base must then be zero. For the bound in
R06 this yields `a=b`; for the Cauchy certificate it yields `a*d=b*c`.
```litex
claim:
? forall a, b R:
a^2+b^2 = 2*a*b
=>:
a = b
(a-b)^2 = a^2+b^2-2*a*b = 0
a-b = 0
claim:
? forall a, b, c, d R:
(a*c+b*d)^2 = (a^2+b^2)*(c^2+d^2)
=>:
a*d = b*c
(a*d-b*c)^2 = (a^2+b^2)*(c^2+d^2)-(a*c+b*d)^2 = 0
a*d-b*c = 0
```
The final difference equalities connect the recovered zero base to the
requested equality. They supply the matching premise rather than inventing
an extra equality assumption.
### R14. Clear denominators and bound a positive quadratic
**Ordinary mathematics:** a positive common denominator lets a product
bound and a fractional bound express the same order. When the denominator
has unknown sign, prove its sign or split into cases before the move.
**Checked cross-multiplication in both directions:** the two denominators
are individually positive, so their product is positive. The displayed
chains preserve the original expressions while multiplying or dividing.
```litex
claim:
? forall a, b, c, d R:
0 < b
0 < d
a/b <= c/d
=>:
a*d <= c*b
(a/b)*b <= (c/d)*b
a*d = ((a/b)*b)*d <= ((c/d)*b)*d = c*b
claim:
? forall a, b, c, d R:
0 < b
0 < d
a*d <= c*b
=>:
a/b <= c/d
0 < b*d
a/b = (a*d)/(b*d) <= (c*b)/(b*d) = c/d
```
Nonzeroness alone permits the divisions but does not justify their order
direction. Use [R08](#r08-scale-an-inequality-with-the-correct-sign) for
negative denominators.
#### Complete a general positive quadratic
**Ordinary mathematics:** when `a>0`, the quadratic `a*x^2+b*x+c` has lower
bound `c-b^2/(4*a)`. Complete the square:
`a*(x+b/(2*a))^2 + c-b^2/(4*a)`.
**Checked recommended form:** encode the positive coefficient with `R+`
and divide by `a` and the closed constants in separate expression nodes.
Thus `(b^2/a)/4` is the same mathematical bound, and `(b/a)/2` is the same
shift. The expressions make the denominator obligations directly usable.
```litex
claim:
? forall a R+, b, c, x R:
a*x^2+b*x+c >= c-(b^2/a)/4
a*(x+(b/a)/2)^2 >= 0
a*x^2+b*x+c = a*(x+(b/a)/2)^2+(c-(b^2/a)/4) >= 0+(c-(b^2/a)/4) = c-(b^2/a)/4
```
The equality checks the algebraic identity; the product is nonnegative
because the coefficient is positive and the other factor is a real square.
The bound is attained at `x=-(b/a)/2`, where that square is zero.
The equivalent literal goal with denominator `4*a` fails at goal WD in the
audited build, before the proof body can supply extra facts. That is a
representation/domain-evidence boundary, not a mathematical exception to
the formula. The reassociated form above verifies the same mathematical
lower bound without adding a hypothesis. For `a<0`, the square term instead
gives an upper bound; for `a=0`, this completed-square formula is undefined.
#### Checked counterexamples for the square/product routes
These examples illustrate why zero cancellation, unsigned square reflection
and multiplication of unrelated signed bounds need their stated conditions.
```litex
2*0 = 1*0
not 2 <= 1
(-2)^2 = 2^2
not -2 = 2
sqrt((-2)^2) = 2
not sqrt((-2)^2) = -2
-2 <= -1
-3 <= -2
(-2)*(-3) > (-1)*(-2)
1*0 = 0
not 1 = 0
not 2*1*0 <= (-1)*1^2+0^2/(-1)
```
Direct facts and composed proofs are labelled separately. These examples require no `trust`, `axiom`, or imports.
### R15. Power signs and two kinds of monotonicity
**Ordinary mathematics:** decide which input to `a^t` is changing. Holding
the exponent fixed and increasing the base is different from holding the
base fixed and increasing the exponent. Specify the exponent's domain, the
base's sign and its position relative to `1` before applying an order rule.
| Task | Exact conditions | Conclusion | Checked route here |
|---|---|---|---|
| Nonnegative even power | `x` real, `n` natural | `x^(2*n)>=0` | Write it as `(x^n)^2` |
| Strictly positive even integer power | `x` nonzero real, `n` integer | `x^(2*n)>0` | Expose `x^n!=0`, then the square |
| Negative odd natural power | `x<0`, `n` natural | `x^(2*n+1)<0` | Factor out a positive even power |
| Positive real power | `a>0`, `t` real | `a^t>0` | Direct checked fact |
| Increase the base | `0<=a<=b`, `n` positive natural | `a^n<=b^n` | Direct checked fact |
| Increase the integer exponent | `a>=1`, integers `m<=n` | `a^m<=a^n` | Nonnegative exponent gap |
| Strict integer-exponent growth | `a>1`, integers `m=1`, `n` positive natural | `a<=a^n` | The integer-exponent order result |
For real exponents, the same mathematical exponent-order directions hold
on a positive base: above `1` they increase, in `(0,1)` they decrease, and
at `1` they are constant. Strict growth requires `a>1`, not merely `a>=1`.
For a fixed real exponent on positive bases, positive exponents preserve
base order, negative exponents reverse it, and exponent zero is constant.
The general-order code certified in this section uses **integer exponents**;
the base-order code uses **positive natural exponents**. The real-exponent
WD/positivity example does not certify a general real-exponent order rule.
#### Power signs, parity and zero cases
**Checked even powers:** the natural version permits a zero base, including
`n=0` under Litex's `0^0=1` convention. The integer version permits negative
exponents and therefore states its nonzero base domain as `R*`.
```litex
claim:
? forall x R, n N:
x^(2*n) >= 0
x^(2*n) = (x^n)^2 >= 0
claim:
? forall x R*, n Z:
x^(2*n) > 0
x^n != 0
x^(2*n) = (x^n)^2 > 0
```
The first identity is a power-of-power equality followed by real-square
nonnegativity. The second proof additionally exposes the intermediate
power's nonzeroness; it is a necessary bridge in the audited proof. Saying
that an exponent is `2*t` is insufficient when `t` is an arbitrary real:
`t=1/4` makes the exponent `1/2`, with a different domain and no parity claim.
**Checked odd negative powers:** retain the sign of the base and split the
odd exponent into its even part plus one.
```litex
claim:
? forall x R, n N:
x < 0
=>:
x^(2*n+1) < 0
x != 0
x^n != 0
x^(2*n+1) = x^(2*n)*x^1 = x^(2*n)*x = (x^n)^2*x < (x^n)^2*0 = 0
```
**Checked constants, output signs and zero recovery:** positive bases admit
all real exponents. Zero powers follow their own natural-exponent convention;
recovering a zero base requires a strictly positive natural exponent.
```litex
forall x R:
x^0 = 1
forall t R:
1^t = 1
0^0 = 1
forall n N+:
0^n = 0
forall a R+, t R:
a^t $in R
a^t > 0
forall x R, n N+:
x^n = 0
=>:
x = 0
```
Zero with a negative exponent has no WD route. A negative base with an
arbitrary noninteger real exponent is outside the supported domain.
See [O27](#o27-powers) for the full power domain branches.
#### Increase the base on the nonnegative region
**Checked natural-power monotonicity:** a positive natural exponent preserves
weak order on nonnegative bases. The larger base is also nonnegative because
it is at least the smaller base.
```litex
forall a, b R, n N+:
0 <= a
a <= b
=>:
a^n <= b^n
```
Even exponents do not preserve signed base order on all reals:
`-2<=-1` but `(-2)^2>(-1)^2`. For magnitude comparisons, use
[R12](#r12-squares-absolute-values-and-equality-cases).
**Checked unit-interval bound:** for a positive natural exponent, repeated
multiplication by a number in `[0,1]` cannot increase the value above that base.
```litex
claim:
? forall a R, n N+:
0 <= a
a <= 1
=>:
0 <= a^n
a^n <= a
by induc n from 1:
? a^n <= a
? from n = 1:
a^n = a^1 = a
? induc:
a^(n+1) = a^n*a^1 = a^n*a <= a^n*1 = a^n <= a
```
#### Increase or decrease an exponent by one
**Checked successor routes:** positive bases keep every integer power positive.
Multiplying by a base at least `1` increases weakly; a base greater than `1`
increases strictly; a base in `(0,1)` decreases strictly.
```litex
claim:
? forall a R+, n Z:
1 <= a
=>:
a^n <= a^(n+1)
a^(n+1) = a^n*a^1 = a^n*a >= a^n*1 = a^n
claim:
? forall a R+, n Z:
1 < a
=>:
a^n < a^(n+1)
a^(n+1) = a^n*a^1 = a^n*a > a^n*1 = a^n
claim:
? forall a R+, n Z:
a < 1
=>:
a^(n+1) < a^n
a^(n+1) = a^n*a^1 = a^n*a < a^n*1 = a^n
```
At base `1`, every power is `1`; use weak monotonicity. Negative bases can
alternate signs as the exponent changes, so their sequence has no analogous
unrestricted monotonicity rule.
#### Order arbitrary integer exponents
**Checked growth package:** first prove that natural powers of a base at
least `1` are at least `1`. For integers `m<=n`, the gap `n-m` is natural.
Multiply its bound by the positive `a^m` and combine the powers. This includes
negative integer exponents. The later claims use that same result to bound
a positive natural power below by its base and to obtain strict order.
```litex
claim:
? forall a R+, n N:
1 <= a
=>:
1 <= a^n
by induc n from 0:
? 1 <= a^n
? from n = 0:
a^n = a^0 = 1
? induc:
a^(n+1) = a^n*a^1 = a^n*a >= 1*a = a >= 1
claim:
? forall a R+, m, n Z:
1 <= a
m <= n
=>:
a^m <= a^n
0 <= n-m
1 <= a^(n-m)
a^m = a^m*1 <= a^m*a^(n-m) = a^(m+(n-m)) = a^n
claim:
? forall a R+, n N+:
1 <= a
=>:
a <= a^n
a = a^1 <= a^n
claim:
? forall a R+, m, n Z:
1 < a
m < n
=>:
a^m < a^n
0 < n-m
a <= a^(n-m)
a^m = a^m*1 < a^m*a^(n-m) = a^(m+(n-m)) = a^n
```
**Checked decay package:** on a positive base at most `1`, natural powers
are at most `1`. Use the same nonnegative gap and multiply its upper bound
by a positive power of the base.
```litex
claim:
? forall a R+, n N:
a <= 1
=>:
a^n <= 1
by induc n from 0:
? a^n <= 1
? from n = 0:
a^n = a^0 = 1
? induc:
a^(n+1) = a^n*a^1 = a^n*a <= a^n*1 = a^n <= 1
claim:
? forall a R+, m, n Z:
a <= 1
m <= n
=>:
a^n <= a^m
0 <= n-m
a^(n-m) <= 1
a^n = a^(m+(n-m)) = a^m*a^(n-m) <= a^m*1 = a^m
```
**Observed real-exponent coverage boundary:** the mathematical growth law
also holds for real `u<=v`. This direct true goal misses at `search_proof`
in the audited release. The integer proofs above do not establish this
stronger real-exponent statement. A source-level log/exp proof attempt was
also not accepted; no claim of mathematical impossibility follows.
```litex
forall a, u, v R:
1 <= a
u <= v
=>:
a^u <= a^v
```
**Checked boundary examples:** these show strictness at base `1`, reversed
direction below `1`, sign changes on negative bases and zero-exponent behavior.
```litex
1^2 = 1^3
(1/2)^3 < (1/2)^2
(-2)^2 > (-1)^2
(-2)^3 < (-1)^3
(-2)^4 > (-2)^2
(-2)^(-2) > 0
(-1)^2 > (-1)^3
0^0 = 1
0^2 = 0
```
Direct facts, composed parity proofs, induction and unproved real-exponent goals are separate coverage categories.
### R16. Common real inequalities at a glance
**Ordinary mathematics:** choose a familiar estimate by its mathematical
shape, then follow its checked proof owner. These bounds are usable results
of native rules and short proofs; their appearance in this table does not
make each one a separate builtin theorem or automatic tactic.
| Familiar bound | Exact domain | Checked proof or interface |
|---|---|---|
| `a^2+b^2 >= 2*a*b` | Any real `a,b`, including opposite signs | [R06 square completion and translation](#r06-complete-a-square-and-translate-the-bound) |
| `x^(2*n) >= 0` | Real `x`, natural `n` | [R15 parity](#power-signs-parity-and-zero-cases) |
| `x^(2*n) > 0` | Nonzero real `x`, integer `n` | [R15 parity](#power-signs-parity-and-zero-cases) |
| `4*a*b <= (a+b)^2` | Any real `a,b` | [R13 quadratic certificates](#r13-reusable-quadratic-certificates) |
| `(a+b)^2 <= 2*(a^2+b^2)` | Any real `a,b` | [R13 quadratic certificates](#r13-reusable-quadratic-certificates) |
| `2*a*b <= t*a^2+b^2/t` | Real `a,b`; `t>0` | [R13 weighted bound](#r13-reusable-quadratic-certificates) |
| `a^2+b^2+c^2 >= a*b+b*c+c*a` | Any real `a,b,c` | [R09 three-square certificate](#r09-build-a-sum-of-squares-proof) |
| `(a*c+b*d)^2 <= (a^2+b^2)*(c^2+d^2)` | Any real `a,b,c,d` | [R13 two-dimensional Cauchy–Schwarz](#r13-reusable-quadratic-certificates) |
| `\|x+y\| <= \|x\|+\|y\|` | Any real `x,y` | [R10 triangle bounds](#r10-expose-absolute-value-bounds) |
| `\|x\|-\|y\| <= \|x-y\|` | Any real `x,y` | [R10 reverse-triangle bound](#r10-expose-absolute-value-bounds) |
| `a*x^2+b*x+c >= c-(b^2/a)/4` | `a>0`, real `b,c,x` | [R14 completed quadratic](#complete-a-general-positive-quadratic) |
| `a^m <= a^n` | `a>=1`, integer `m<=n` | [R15 exponent growth](#order-arbitrary-integer-exponents) |
| `a <= a^n` | `a>=1`, positive natural `n` | [R15 lower range](#order-arbitrary-integer-exponents) |
| `0 <= a^n <= a` | `0<=a<=1`, positive natural `n` | [R15 unit-interval range](#increase-the-base-on-the-nonnegative-region) |
For a strict conclusion or an equality case, return to the proof's
nonnegative term. A square certificate becomes strictly positive when its
base is nonzero; equality makes its base zero. Multiplication additionally
needs a positive factor to preserve strictness. See
[R12 zero cases](#zero-and-strictly-positive-square-sums) and
[R13 equality cases](#recover-the-equality-case).
Keep the mathematical domain attached to the bound. The first square bound
does not require `a,b>=0`; the weighted bound does require `t>0`; an even
power has an integer parity condition; exponent monotonicity has a base-range
condition. Those distinctions determine which estimate is appropriate.
## Advanced interface details
The dictionaries give each interface its meaning, required conditions and
immediate use. This chapter continues those same contracts with complete
domains, scope/representation boundaries and publication details. The linked
S/O entry remains the place to start; each extended contract is maintained
once here.
### Function interfaces
#### Function-valued arguments and indexed signatures
A function-valued parameter can receive a returned function application.
Substitution retains the existing argument groups and appends the parameter's
call. The outer body can be unfolded while its argument remains symbolic:
```litex
have fn mk(x R) cart(R,Z) = (x,2)
have fn first(p cart(R,Z)) R = p(1)
first(mk(7)) = mk(7)(1)
mk(7)(1) = 7
```
The [parameter-application tracer](../examples/proof_nodes/equal/by_object_definition/by_fn_application/function_value_parameter_application.lit)
also checks a returned two-input function. Each input and domain condition
still passes ordinary application WD; separate fixtures reject wrong call
groups, complete lengths, guards and coordinate values.
##### Function qualifications and aliases
Function signatures, bodies, complete domains, return carriers and finite
coordinates are read from declarations and the exact object's indexed special
properties. These structural readers do not construct or traverse equality
classes, and do not recursively inspect the properties of equal objects.
A known `g $in fn(x R) R` supplies a call signature. A directly published
equality to an anonymous function additionally supplies its body:
```litex
have fn f(x R) R = x + 1
let g = f
g = fn(t R) R {t + 1}
g(4) = 5
```
The explicit equality is proved by the ordinary equality verifier and indexed
on `g`. Without it, `let g = f` does not transfer `f`'s signature or body to
`g`. Membership alone cannot prove a numeric value. A checked template
instance can be read directly from its declaration, including when that exact
instance is the value recorded for an alias:
```litex
template:
have fn shift(x R) R = x + a
let shift_two = \shift<2>
shift_two(3) = 5
have fn wrapped_shift(x R) R = \shift<2>(x)
wrapped_shift(3) = 5
```
Carrier inference likewise reads a directly indexed definition; for a chain
`Alias = Base = finite_seq(R, 2)`, publish `Alias = finite_seq(R, 2)` before
introducing a member. Finite-set enumeration for `eval` reads a literal set or
a direct indexed set value, without searching an alias chain.
The application still checks its arguments and guards, then verifies the
substituted body under the existing bounded definition permissions. Structural
transport cites the exact stored fact; its path certificate has at most one
edge. Ordinary equality and fact proving retain their own equality-path
routes, so an author can prove and publish the needed endpoint before use.
Default struct field views retain their definition-owned selection below.
Stored function applications also have a bounded `FnApplicationInStandardSuperset` known-property leaf. After application WD, it compares every applicable stored signature's instantiated numeric return carrier with the target standard set. For example, an R-returning `f(a)` belongs to C. Every candidate must be contained in the target, and at least one inclusion must be strict; an exact-carrier query retains its existing producer. Evidence cites each signature and the known equality path connecting its subject to the applied head. This leaf opens no domain, equality, or general premise search. Nonstandard return carriers and heads with native template/field declarations are left to the existing routes, which own their declaration evidence.
**Entry:** [O03](#o03-function-applications).
#### Complete domains, restrictions and fixed signatures
Membership in `fn(...) ReturnSet` requires the function's complete domain to
equal the declared input domain, including every domain condition. The return
set is an upper bound on values. A function on `N+` cannot also belong to
`fn(k closed_range(1,2)) R` merely because its first two values are real.
Construct an actual restriction when a smaller domain is needed:
```litex
have fn z(i1 N+) Z = 0
have fn z2(k closed_range(1,2)) Z = z(k)
z2 $in finite_seq(Z,2)
release thm fn_set_member(z2, finite_seq(R,2))
```
`seq(S)` has complete domain `N+`; `finite_seq(S,n)` has complete domain
`closed_range(1,n)`. The same function may belong to several return upper
bounds while retaining that domain. `finite_seq(S,0)` has empty domain.
Default membership and `release thm fn_set_member` check the same contract.
An anonymous or named function always checks its header, domain conditions,
return carrier and body for well-definedness. Its return bound concerns only
complete input assignments. A checked empty input domain makes that bound
vacuous, including an empty return carrier; it does not prove that the body
value itself belongs to the empty set. For a guarded domain, first provide
the exclusion proof:
```litex
forall k R:
k<0
=>:
not k>0
have fn empty_body(k R:k>0,k<0) {}=0
empty_body={}
tuple()={}
empty_body=tuple()
empty_body $in finite_seq({},0)
```
`0 $in {}` and `empty_body(1)=0` still fail. An undefined body such as `1/0`
also fails WD even when the complete input domain is empty.
> **Preview:** zero and one Cartesian factors use the same exact-domain
> membership contract as larger products. `tuple()` is the empty function graph,
> `cart()` contains that one graph, and `cart(S)` contains one-coordinate
> functions. `(a)` remains grouping; use `tuple(a)` for one coordinate.
```litex
tuple() = {}
cart() = {tuple()}
tuple(7) $in cart(Z)
have p cart(Z) = tuple(7)
p(1) = 7
finite_set_size(cart()) = 1
```
`p(2)` is outside this member's complete domain and fails WD. A function
space on an empty domain contains exactly the empty function even when its
return carrier is empty; this does not make a nonempty outer curried domain
empty. These boundary examples certify the listed exact-domain paths.
The struct interface separately determines named field views.
Both `have fn f(x S) T = body` and `fn(x S) T {body}` must prove
`body $in T` under the declared parameter types and domain conditions before
the function is accepted. Returning a parameter still requires this proof:
`have fn f(x Z) N = x` is rejected because `x $in N` does not follow from
`x $in Z`. `have fn f(x N) Z = x` is valid, as is the restricted definition
`have fn f(x Z: x >= 0) N = x`.
Function sets use `fn(x A) B`. Nested function sets use `fn(x A) fn(y B) C`.
The former `A -> B` spelling is removed and reports a parse error. Use `=>`
for logical implication.
> **Preview:** every `fn` / anonymous-fn parameter domain and return set
> must be fixed relative to that signature: neither may refer to any of its own
> parameters. `fn(x R, y Z) R` and `fn(p cart(R, Z)) R` are valid shapes;
> `fn(x R, y S(x)) R`, `fn(x R) {x}` and
> `fn(S power_set(R)) fn(x S) R` are rejected during parsing.
> Domain `: conditions` and function bodies may refer to the parameters.
> Ordinary quantifier binders such as `forall S set, x S` remain sequential.
Function parameter names are collected without registering them while their
carriers are parsed. The parser registers the bindings for domain conditions,
closes that scope before parsing the return object, and reopens the same IDs
for an anonymous or named function body. Thus a nested return space cannot
capture an outer function parameter, including inside its own conditions or
body. WD independently enforces the same restriction for constructed objects.
The rule also applies to `have fn`, `algo`, and signatures derived by
`have fn ... by exist!`. It does not change ordinary `forall` / `exist`
parameter dependencies.
An enclosing set is fixed for an inner function, and a fixed function space
may itself be a return set. Disjoint signatures may reuse a parameter spelling
with distinct binding IDs:
```litex
let curried_space = fn(x R) fn(x R) R
curried_space = curried_space
forall A nonempty_set:
fn(x A) A {x} = fn(y A) A {y}
fn(x R: x > 0) R {x + 1}(2) = 3
```
A parameter-dependent output property belongs in a separate fact rather than
the return set. For example, the former `have fn identity(x R) {x} = x`
becomes a fixed-return definition plus its precise membership property:
```litex
have fn identity(x R) R = x
forall a R:
identity(a) $in {a}
```
For families parameterized by an arbitrary carrier, use `template`.
The binder kinds `set`, `nonempty_set`, and `finite_set` are still not ordinary
function domains. Tracer:
[`examples/wd/fixed_function_signature_scopes.lit`](../examples/wd/fixed_function_signature_scopes.lit).
**Entry:** [O79](#o79-function-spaces).
#### Case equations and compound guards
Relation-chain guards contribute every adjacent comparison to the mutual
exclusion check, just as the equivalent flat `and` guard does. This also
applies to `algo ... by cases`; coverage and return checks are still required.
> **Preview:** after `have fn f(...) T = body`, `by cases`, or
> `by induc`, application equalities such as `f(args) = subst(body)` are proved
> by the equality **object-definition** stage (same idea as `\Template(...)`
> and `have` / `let` identifier unfolds). For `by cases` / `by induc`, Litex looks
> up the stored definition, matches a case guard at the concrete arguments, and
> unfolds that case body. The same unfolds apply when the definition lives in a
> `template<…>:` body: `\name(fn_args)` matches the template parameters,
> then the case/induc guards and body, exactly as for ordinary `have fn`.
> Runnable coverage of all nine leaf shapes (identifier `have`/`let`, three
> ordinary `have fn` forms, four template forms) is in
> `examples/object_definition_equalities.lit`.
> `by exist!` still does not get that equality unfold.
**Entry:** [S11](#s11-piecewise-functions).
#### Nested cases and decreasing calls
`have fn ... by induc measure from lower` defines a recursive function. Litex
checks that the measure and lower bound are integers, recursive calls stay in
the domain, and each recursive measure is smaller but not below the current bound.
The lower bound is also substituted at the recursive arguments and must be at
least the current lower bound. Consequently the nonnegative integer
`measure - lower` strictly decreases. Parameter-dependent bounds are permitted
when this obligation is proved; for example, `from b` permits calls from
`(n, b)` to `(n - 1, b)`, but not `(n - 1, b - 1)`.
See the [lower-bound acceptance example](../examples/stmt_nodes/definition/induction_lower_bound.lit).
Every sibling case list, including nested lists, must cover its enclosing
domain and be pairwise disjoint. A nested list is checked under its parent
guard; it need not cover integers excluded by that guard. An invalid list
rejects the declaration before any function or case equation is published.
For a real-valued `x` and a closed numeric expression `c` whose exact value is
positive, the checker proves `x - c < x`. This includes offsets such as `2`,
`1 + 1`, and `1 / 3`; it does not assume that a symbolic offset is positive.
Zero, negative offsets, and nondecreasing recursive calls remain rejected.
See the [two-step recursive domain tracer](../examples/wd/positive_closed_decrement_recursive.lit).
Detailed output records the actual offset as `SubtractPositiveClosedLess`;
the existing literal-one route retains its `SubtractOneLess` label.
```litex
have fn countdown(n N) N by induc n from 0:
case n = 0: 0
case n >= 1: countdown(n - 1)
forall n N:
countdown(n) $in N
```
The stored case equations are directly usable at arguments whose case can be
proved. Litex instantiates the selected equation and performs nested arithmetic
normalization, so a successor argument does not require separate lines for
`n + 1 > 0` and `(n + 1) - 1 = n`. It still refuses to select a case when its
condition is not known.
**Entry:** [S12](#s12-functions-by-decreasing-integer-measure).
#### Selection facts and binder replay
> **Preview:** `have fn … by exist!` is goal-only (no proof
> body). Exec requires the `forall … exist!` goal to be already proved
> (`claim` / `thm` / `trust`), then stores `f $in FnSet(...)`, the property
> forall (`body` with the witness replaced by `f(args)`), and the uniqueness
> forall (`body ⇒ witness = f(args)`). It does **not** store `f = AnonymousFn`,
> so applications do not unfold by equality the way `have fn f(...) T = body`
> does. The name is recorded in the definition table, so `release obj def f`
> re-stores the same three facts.
>
> A `template` may use this form as its body. Instantiating `\Name`
> installs the same three facts as a plain `have fn by exist!` (FnSet
> membership, property forall, uniqueness forall), with subjects equal to
> the instance.
`have fn name by exist!` turns an **already proved** unique-existence
statement into a function. Prove the `forall … exist!` outside; the `have fn`
block only names the goal and selects the function.
An already proved whole `forall` can be replayed with renamed outer
parameters and existential witnesses, including an outer parameter absent
from the conclusion. Replay checks the goal's well-definedness, preserves
the carriers, premises and free definition owners, and cites the stored
source fact. Existential function/set carriers also allow renaming their
nested bound variables; their domains, return carriers, guards and free
identities remain unchanged. Replay does not assign a value to an unused
parameter.
Nested `forall` premises are compared recursively with their own bound-name
renamings, including dependent `exist!` witness carriers. The complete
conditions, existential polarity and free owners must still match. Source
matching does not raise the caller's WD permissions. The
[nested unique-source tracer](../examples/proof_nodes/forall/known_source_nested_unique.lit)
checks the full proof, stored source and exact repeat.
**Entry:** [S13](#s13-functions-from-unique-existence).
### Struct interfaces
#### Struct representation and law publication
Struct `<=>:` conditions are checked in source order in a temporary field scope.
After a condition passes WD, it is assumed locally while checking later conditions;
for example, `x != 0` may precede a condition containing `1 / x`. These assumptions
leave the scope with the definition check and are released only for an actual member.
A `struct` defines a named set together with one definition-owned field view.
Once its header parameters are fixed, `&Name` is one ordinary set, not a
set of sets. Every binder and function signature position that accepts a set
therefore also accepts a struct carrier.
Each actual header argument must satisfy its declared type before the struct
instance is well-defined. For `struct Box:`, `&Box<0>` is valid and
`&Box<-1>` is rejected. This also checks `set`, `nonempty_set`, and `finite_set`
header kinds. Dependent headers such as `S set, a S` use the actual argument
for `S` when checking `a`.
##### Tuple representation
A structure must define at least two fields. It is represented by a tuple in
definition order. If `Point` defines `x` and then `y`, opening a `Point` value
`p` establishes `p.x = p(1)` and `p.y = p(2)`. The field-to-coordinate relation
belongs to the struct definition; Litex does not guess it from field names.
> **Preview:** a struct with fewer than two fields is a parse
> error (`struct definition expects at least two fields`). There is no
> one-field “identity view” of a sole carrier.
The tuple representation is deliberately opaque outside two places:
1. the verifier may inspect it internally while proving `e $in &Struct`; and
2. a successful `release struct def e` (or the automatic direct-binding case below)
stores the public representation facts.
A generic membership fact `e $in &Struct` does not itself store field carriers,
field-to-coordinate equalities, or struct laws.
> **Preview:** `e $in &Struct` is proved by the
> `StructObjMembership` builtin: check field carriers (literal tuple components
> `$in Ti`, or else `e $in cart(T1,…,Tn)` via `CartMembership`) and each
> instantiated `<=>:` law. Success is opaque membership only — still no
> automatic property release. `CartMembership` itself proves
> `e $in cart(A1,…,An)` by its accurate complete domain `closed_range(1,n)`
> and every coordinate's factor membership. Checking a shorter call range,
> a common return upper bound, or only some coordinates is insufficient.
A successful `struct` definition also publishes its checked laws as universal
facts over the original header parameters and an instance of that exact struct.
A consequent universal is flattened into the same parameter list; its premises
are retained and existential witnesses stay inside. For example, a law
`forall x A: exist y A st {add(x,y)=zero}` of `Op` publishes
`forall A nonempty_set, s &Op, x A: exist y A st {s.add(x,y)=s.zero}`.
These are definition consequences, with source FactIds retained in the result.
Ordinary known-forall matching can consume them without an explicit release
when it can verify the instance carrier and every condition. This does not
publish tuple/field-index representation facts or recursively open instances.
Publication follows the definition's existing environment scope. Importing a
module does not inject its universal facts into the caller's ambient environment;
an imported instance can use the existing explicit `release struct def` path.
A top-level `not forall` law remains on the instance-release path because it
is not a supported universal conclusion shape; it is not hoisted or strengthened.
**Entry:** [O91](#o91-struct-carriers).
#### Field WD, automatic opening and selected views
Field syntax and property release are separate. To decide whether `e.y` is a
well-defined object, Litex only determines the definition-owned struct carrier
of `e` and checks that this struct defines `y`. To decide `e.y.z`, it also
checks that `y` is defined directly with a struct carrier that defines `z`.
This WD traversal does not store any field carrier, tuple bridge, or struct
law. The final field's carrier matters only when a surrounding operation needs
it, for example when calling a function-valued field.
A checked Cartesian membership or tuple equality also supplies a field's
complete finite function domain. For example, after `item.point = (0, 0)`,
the field-headed call `item.point(2)` uses the same finite-function evidence
as an ordinary tuple variable. Receiver WD and the exact index domain still
apply; indices zero and three remain invalid for this pair. See the
[Cartesian field coordinate tracer](../examples/wd/cartesian_field_coordinates.lit).
When the receiver has the required definition-owned view, a reflexive field
fact can be well-defined before opening. An explicit `release struct def f(t)`
(or `release struct def f(t).x` for an inner layer) materializes that instance's
representation and property facts. An individual law may instead be checked
from a published struct universal when its carrier and conditions can be
matched; publication does not promise automatic discovery of every such goal.
##### The only automatic property release
A direct syntactic symbol binding written with a struct carrier, such as
`p &Point` or `forall p &Point`, opens one layer automatically. This is why
properties of a directly bound `p` are immediately available.
Other forms do not automatically materialize the whole property package.
A function result with a directly defined struct return and a directly
struct-valued field can supply a definition-owned view for field WD.
Use `release struct def ...` to store that layer's field carriers, tuple
bridges and instantiated laws. The separately published universals described
above are another source of individual law proofs when matching succeeds.
An equality or later membership alone does not choose a new named-field view.
Litex has no `&Point{p}.x` form for selecting another view later.
The direct struct-binding rule also applies in `forall`, `exist`, set builders,
predicates, theorems, templates and function binders. Function results use
their definition-owned return view rather than acquiring a view from arbitrary
membership.
Function, proposition, and theorem argument lists are explicit. Pass struct
fields by name and tuple entries by index:
```litex
struct Point:
x R
y R
release thm struct_member((1, 2), &Point)
have p &Point = (1, 2)
prop has_point_coordinates(x, y R):
x = x
by def:
? $has_point_coordinates(p.x, p.y)
```
Struct header parameters and `<=>:` facts are not positional fields. Tuple
calls likewise name entries explicitly, for example `f(t(1), t(2), t(3))`.
Ordinary arity, membership, and function-domain checks apply to every written
argument.
If a selected field is itself defined directly with a struct type, field
notation may continue through that defined view:
```litex
struct Coordinates:
x R
y R
struct TaggedPoint:
point &Coordinates
tag N
release thm struct_member((1, 2), &Coordinates)
release thm struct_member(((1, 2), 0), &TaggedPoint)
have item &TaggedPoint = ((1, 2), 0)
release struct def item.point
item.point.x $in R
```
Here the definition of `TaggedPoint.point` supplies the owner of the next
field, so the entire path is well-defined before the `by` statement. The
explicit opening is needed only to release `Coordinates`' field-carrier and
representation facts. Parameterized and module-qualified struct field types
work the same way. A final field may be called, as in
`space.scalars.mul(a, b)`. Fields also work after a call when the function's
defined return carrier is a struct, as in `make_box(f).entries(i)`. A callable
field's defined carrier must be a function set.
Function results and template objects use their declared struct carrier
directly. For example, after defining `make(a R) &Box` with an `op` field,
`make(2).op(3)` is a callable expression; a template object declared with
`&Box` likewise supports `\shifted<2>.op(3)`. No intermediate named binding
is needed. Generic return carriers substitute both template and function
arguments before resolving fields. Actual function arguments, template
conditions and callable-field guards remain checked, including when a later
membership supplies another function signature.
Field values project through a checked definition's actual returned tuple.
This does not automatically release the struct's laws or discover function
bodies through arbitrary alias chains. See the runnable
[struct return fields example](../examples/wd/struct_return_field_access.lit).
A vector-space structure can own its scalar system rather than asking each
single-space theorem to carry scalar operations separately. With
`space &VectorSpace`, ordinary code can write
`space.smul(space.scalars.mul(a,b),v)`. A relation that joins two spaces, such
as linearity of a map, records one compatibility fact
`Vspace.scalars = Wspace.scalars`; callers then pass the spaces themselves.
A later membership fact does not add named fields retroactively:
```text
struct Point:
x R
y R
have p cart(R, R) = (1, 2)
release thm struct_member(p, &Point)
p.x = 1
```
The last line is a parse `error`. The membership still exposes the ordinary
struct-membership proposition for later proof use, but it exposes neither
positional Cartesian facts nor `Point` field names. There is deliberately no
`release struct def p as &Point` escape hatch. To use those names, construct a new
definition-owned object explicitly:
Likewise, if `p &Point` later also belongs to `&ComplexPair`, `p.x` remains the
field chosen by its `Point` definition. Write
`have p2 &ComplexPair = (p.x, p.y)` to obtain `p2.real` and `p2.img`.
Chained notation follows only directly defined struct carriers; it does not
follow named set aliases, equalities, or later membership facts.
**Entry:** [O92](#o92-definition-owned-field-access).
#### One-layer release and its published facts
`release struct def e` opens exactly one definition-owned struct layer. It has no
`as &Struct` form: the struct must already be fixed by the definition of `e`,
by a function's explicit return carrier, or by the direct struct carrier of the
previous field in a chain.
Before storing anything, the statement verifies the exact membership
`e $in &Struct`. Failure is atomic: no partial tuple or field facts remain.
For a struct with fields `a : A` and `b : B`, success releases:
- `e $in cart(A, B)`;
- `e.a = e(1)` and `e.b = e(2)`;
- the instantiated field-carrier facts; and
- the struct's instantiated `<=>:` facts.
The Cartesian member carries the accurate complete domain. Opening publishes
no tuple shape predicate, dimension or indexed-object fact. A function-valued
field keeps its domain conditions; a checked equality endpoint may be needed
to connect a field's value to the original coordinate before evaluating it.
See [the struct-coordinate tracer](../examples/stmt_nodes/definition/struct_function_coordinate_bridges.lit).
Repeating the same statement is
idempotent. Opening is never recursive: `release struct def outer` does not also
open a struct-valued `outer.inner`. Its quantified laws may already be usable
through known-forall matching; use `release struct def outer.inner` to materialize
its one-layer representation and property facts.
##### Explicit object-definition release: `release obj def` (preview)
**Entry:** [S27](#s27-open-one-struct-definition-layer).
#### Definition lookup and supported source owners
> **Preview:** `release obj def I` takes exactly one identifier
> `I` (plain or `mod::export::`-qualified). It looks up
> `StoredIdentifierDefinition` for that name — in the live Env stack or in a
> finished export file's Env — and stores the definition's accompanying facts
> into the **current** Env. Subjects use the written spelling of `I`.
>
> Supported sources: `let`, `have` / `have … = …` / `have …:`, `trust have`,
> and `have fn` / `by cases` / `by exist!` / `by induc`. Binder-only `ParamType`
> rows are rejected. This does **not** open a struct layer; use
> `release struct def` for that.
**Entry:** [S28](#s28-replay-an-object-definition).
### Template interfaces
#### Carrier families and function arguments
Read a template as the parameterized counterpart of an ordinary definition
statement. The body is the same kind of definition that would appear outside
(`have …`, `have fn …`, and the other supported definition forms): Litex
checks it as if the angle-bracket parameters were already introduced and
satisfied the header conditions. Instantiating `\name` then gives the
corresponding defined object or function for those concrete arguments.
That is why `template` is necessary and cannot be replaced by a simple
`fn_set` / ordinary function whose domain is written as `set`. A Litex function
parameter must range over one fixed set. The binder kind `set` is not such a
set: it is a surface parameter kind meaning "a set," not an element of a
set-of-all-sets. So a family indexed by an arbitrary set belongs in the
template header, not as a fake function argument. The rejected form
`have fn identity_set(A set) set = A` is recorded earlier under
[Bare facts and `have`](#bare-facts-and-have).
```litex
template:
have fn const_on_S(x S) S = z
\const_on_S(2) = 0
```
**Entry:** [S17](#s17-parameterized-declaration-families).
#### Instance ownership and automatic definition facts
The name uses the ordinary module/export forms: `\export::name`,
`\Module::export::name`, or `\Module:::name` when the imported
module has one export. These forms preserve the same canonical template owner;
knowing an export name does not make a missing template valid. The configured
[qualified-template example](../examples/module_manager/qualified_template_names/main.lit)
checks all three forms and their rejection boundaries.
A template parameter such as `S set` is not a function argument ranging over a
set of all sets. The body is checked once in the parameterized context. On
success, Litex substitutes its defined name with `\name` in the
body definition facts and stores them under the template's universal binders
and header conditions. Later `\name` keeps its surface form; ordinary
known-`forall` search can instantiate those facts, and existing
definition-unfolding routes remain available.
> **Preview:** automatic template definition facts include object membership
> and set kinds, defining equalities, selected-witness properties, function
> signatures and guarded case/recursive equations, unique-selection properties
> and uniqueness, and replacement introduction/elimination. Only facts emitted
> by the successful body definition stores and their ordinary inference escape;
> parameter assumptions and proof-search intermediate facts stay local.
```litex
template:
have member S
\member $in R
forall T nonempty_set:
\member $in T
```
The definition stores `forall S nonempty_set: \member $in S`. It does not
claim that all members of `S` equal the selected object. Header conditions
remain premises of every published fact:
```litex
template:
have selected S
\selected $in R
```
Here the stored fact has binder `S set`, premise `$is_nonempty_set(S)`, and
conclusion `\selected $in S`. An empty-set argument is rejected. Function
domains and case conditions are retained as well. A `trust have` body remains
trusted and is rejected under `-strict`; automatic publication does not prove
its assumptions. The [runnable acceptance example](../examples/stmt_nodes/definition/template_definition_facts.lit)
covers the definition families and direct use of their instances.
#### Template-defined type interfaces
For a checked `template<...>: have name set = RHS` with one defining RHS,
`x $in \name` converts the outer template carrier to its substituted RHS.
The native membership verifier receives the same `VerifyState`; conversion
neither enables a forbidden search stage nor gives another rewrite opportunity.
Nested outer template instances use the same conversion. Ordinary identifiers
stop conversion; this does not add general alias unfolding.
```litex
template:
have pairs set = cart(S,S)
template:
have fn first(p \pairs) S = p(1)
\first((1,2)) = 1
template:
have vectors set = finite_seq(S,n)
have fn second(v \vectors) R = v(2)
second((1,2)) = 2
```
A checked membership or typed binder also exposes the converted membership and
runs the native carrier's existing inference once. For example, the vector
parameter gets the `finite_seq` function signature without a second manual
equality to a function space. Consequences of that native inference remain
store-only; this is not recursive inference on every derived fact.
The [strict acceptance example](../examples/stmt_nodes/definition/template_type_interfaces.lit)
covers function spaces, Cartesian products, finite sequences, power sets,
set-builders, singleton sets, integer intervals, and nested template instances.
Template arguments/guards, complete function domains, builder conditions, and
coordinate bounds are still checked. Detailed output retains the conversion
steps and the native membership proof. Lean replay of template instances and
this evidence is unsupported and fails closed.
Existing equality transport can use the newly provable template membership
through a known equality. That does not give an ordinary alias the direct
carrier interface of a template; alias readers and search permissions retain
their existing rules.
When a template selects a set-builder value, membership in the instance unfolds
to membership in the defining set-builder. **Assumption demonstration (ordinary mode):**
the following example explicitly assumes `$marked(1)`; it is rejected in strict mode.
```litex
abstract_prop marked(x)
template:
have marked_elements set = {x S: $marked(x)}
trust $marked(1)
1 $in R
1 $in \marked_elements
```
Known membership in `\marked_elements` is proved from the base-set membership
and every defining fact of the set-builder after definitional unfold.
> **Preview:** storing `x $in {t S: P(t), …}` (or `x $in Name`
> when `Name` is known equal to that set-builder) also stores `x $in S` and the
> instantiated defining facts. That is the store-time reverse of set-builder
> membership.
This projection also accepts a checked `have ... = ...` template instance whose
RHS is a set-builder. Its template arguments and guards are checked before the
existing definition substitution; the projected carrier then supplies the
usual coordinate and function types. The
[template carrier example](../examples/infer/atomic/template_set_builder_carrier.lit)
checks this with Cartesian carriers. This does not select a branch from a
disjunctive defining condition or admit an invalid template argument.
**Entry:** [O93](#o93-template-instances).
## Builtin Verification Rules
Builtin verification rules are small mathematical patterns implemented by the
checker. They close the current goal; they are different from inference, which
stores useful consequences after a statement has already been accepted.
Automatic rules are intentionally bounded. A direct rule checks its documented
premises; a structural builtin strategy may recurse only through smaller pieces
of the same object shape. Neither route is unrestricted theorem search. The Rust Detailed projection retains nested evidence. Default CLI Normal
output may summarize that evidence.
The catalog below records public mathematical shapes rather than the
checker dispatch order. For example, `sqrt(t) != 0` requires the strict premise
`t > 0`; `t >= 0` is insufficient because `sqrt(0) = 0`. Likewise, interval
nonemptiness depends on the appropriate strict or weak endpoint comparison.
Quantified or compound requirements use the [32 reserved theorem interfaces](#reserved-builtin-theorem-interfaces).
That index owns their arities, premises and checked examples; it also links the
[LUB](#c01-native-least-upper-bound-certificate) and
[GLB](#c02-native-greatest-lower-bound-certificate) certificates.
The two real-bound predicates are reserved opaque certificates. The
completeness theorem introduces them; the four projection theorems consume
them. They cannot be redefined as user props or proved just by naming them.
Choice-backed product nonemptiness is identified as `axiom_of_choice` in
Detailed JSON. Other calls carry `builtin_theorem` provenance, the theorem
identity, arguments, ordered requirement proofs and conclusion WD evidence.
A failed call stores no conclusions. Both JSON views now expose lookup,
arity, shape, argument-type, premise, conclusion-WD or selected-fact failure;
indices are zero-based, and premise failures include the exact goal.
These names are bare global reserved names. They cannot be rebound by user
objects, parameters, theorems, or axioms, and a qualified spelling is rejected.
The rational interface has arity one and requires its argument to be known in
`Q`. The finite-set indexing interface likewise stores an existential and
requires finite `s`; its witness is noncanonical. The finite-subset interface
requires an already verified subset premise and does not enable automatic
subset-chain search. Both finite-set names are kernel interfaces, not
`std/basics` exports.
This section catalogues public rule families. It does not promise that every
mathematically equivalent spelling is recognized. When a goal soft-fails,
write a smaller intermediate fact that exposes a supported shape.
### Exact calculation and native result carriers
The identity `(-1)^(2*m+1)=-1` checks that the matched parameter `m` is an
integer. An integral complete exponent alone does not establish odd parity.
Closed numeric integer powers also accept negative exponents by taking the
reciprocal of a nonzero base. Exact rational comparison covers nonterminating
fractions and binary `min`/`max`; no rounded decimal is used as proof evidence.
The rational fallback uses checked `i128` arithmetic and declines an overflow.
The existing decimal path retains its own bounds.
```litex
2^(-3) = 1 / 8
(-2)^(-3) = -1 / 8
1 / 3 < 1 / 2
min(1 / 3, 1 / 2) = 1 / 3
max(1 / 3, 1 / 2) = 1 / 2
eval 3^(-1)
```
Closed positive rational bases also admit rational exponents. The exact
calculator reduces the exponent to `p/q`, takes exact integer `q`-th roots of
the reduced base's numerator and denominator, then applies the checked integer
power `p`. This supports rational results without approximations and shares
the same producer with `eval`:
```litex
8^(1 / 3) = 2
16^(3 / 4) = 8
(1 / 27)^(-1 / 3) = 3
(8 / 27)^(2 / 3) = 4 / 9
eval (4 / 9)^(1 / 2)
```
This new domain branch checks closed `Q+` bases and closed `Q` exponents;
Symbolic real powers use the separate WD branches below; this exact-calculation
branch does not calculate nonpositive bases with noninteger exponents. The domain does not depend on whether the result is rational:
`let u = 2^(1/3)` is allowed, while `eval 2^(1/3)` declines. Nonperfect roots
and checked `i128` overflow decline calculation; existing integer-power
domains, including `0^0=1`, remain unchanged. Closed exact evaluation also
shares one exact-decimal digit budget across powers, factorial, and ordinary
arithmetic results: a product of in-budget factors can still decline when the
normalized product would exceed that budget.
Exact numeric calls normalize inside ordinary facts or `eval` statements:
```litex
gcd(54, (-24)) = 6
quot(-7, 3) = (-3)
(-7) % 3 = 2
lcm(12, (-18)) = 36
lcm(0, 0) = 0
floor(3.75) = 3
ceil(3.25) = 4
min(7, (-2)) = (-2)
max(7, (-2)) = 7
exp(0) = 1
ln(1) = 0
sign(-9) = (-1)
factorial(10) = 3628800
10! = 3628800
```
Closed calculation also accepts nonterminating rational inputs to `floor`,
`ceil`, and `sign`. Integer functions first check the exact value of each
argument, so an integral fraction expression is eligible while `gcd(1/3,8)`
remains undefined. Perfect rational square roots, bounded numeric radical
normalization, rational-coordinate complex parts, and exact rational logarithms
share their pure arithmetic with `eval`:
```litex
floor(-7 / 3) = -3
ceil(-7 / 3) = -2
sign(1 / 3 - 1 / 2) = -1
gcd((1 / 3) * 6, 8) = 2
sqrt(1 / 9) = 1 / 3
sqrt(12) + sqrt(27) = 5 * sqrt(3)
re((1 + 2 * i) * (3 - i)) = 5
img((1 + 2 * i) / (3 - i)) = 7 / 10
log(8, 4) = 2 / 3
log(1 / 3, 27) = -3
eval sqrt(12) + sqrt(27)
eval log(8, 4)
```
These closed leaves generate no proof premises. Source well-definedness still
precedes calculation, including nonzero divisors, nonnegative square-root
arguments, and positive log arguments with a positive base unequal to one.
Radicals support rational linear combinations, products, integer powers, and
division by a single nonzero radical term. They retain exact `sqrt` expressions;
general inversion of sums of radicals is outside this calculator. Normalization
uses checked `i128` coefficients, at most 64 terms and 64 constructor levels.
Trial factorization stops above divisor 10,000, declining an unproved residual
factorization. Rational logarithms require matching prime-valuation ratios;
`eval log(2,3)` declines rather than supplying an approximate value. Existing
decimal bounds remain in force for large-number calculations.
After input-domain WD, the native result-type builtin proves the following
memberships, including their standard-set supertypes such as `Z` → `R` → `C`.
These facts are also available during nested object WD, without a preceding
membership statement or `trust`. For a separate denominator-nonzero obligation,
first checking `exp(x) $in R+` lets the existing store/infer path establish
positivity before proving `1 / exp(x) $in R`.
| Native object | Required input | Result type |
|---|---|---|
| `sign(a)` | `a $in R` | `Z` |
| `gcd(a, b)` | Integers, at least one provably nonzero | `N+` |
| `lcm(a, b)` | Integers, including two zeros | `N` |
| `exp(x)` | `x $in R` | `R+` |
| `n!`, `factorial(n)` | `n $in N` | `N+`, including `0!` |
```litex
have a R
sign(a) $in Z
sign(a) $in R
sign(0 - a) = 0 - sign(a)
have x R
ln(exp(x)) = x
have u Z*
have v Z
lcm(u, v) $in N
gcd(u, v) $in N+
have n N
n! $in N+
(n + 1)! = (n + 1) * n!
```
The type rule preserves the domains: `gcd(0, 0)` is undefined, `sign(0)` and
`lcm(0, 0)` cannot be assigned `N+`, and complex exponential and negative
factorial inputs remain unsupported.
### Real sequence limits (preview)
`$has_seq_limit(a,L)` is the epsilon-N candidate relation on `a seq(R)`,
equivalently `a fn(k N+) R`, and `L R`. After a candidate or finite convergence
existence is proved, `lim(a)` is a well-defined real object. WD consumes the
proof; it does not infer a limit from the sequence body. For explicit epsilon
proofs, native limit laws, exact premises and compatibility, see
the maintained examples under `examples/wd/`.
```litex
forall a seq(R), L R:
$has_seq_limit(a,L)
=>:
lim(a) = L
lim(a) $in R
```
### Finite-point real function limits (preview)
`$has_limit_at(f,x0,L)` includes both nontrivial approach through the actual
unary real domain and punctured epsilon-delta control. After a candidate or
finite existence proof, `lim(f,x0)` selects the unique real value. The point
need not belong to the domain; empty or isolated domains supply no vacuous
limit. WD consumes proof and never discovers a limit from the function body.
```litex
forall f fn(x R) R, x0,L R:
$has_limit_at(f,x0,L)
=>:
lim(f,x0) = L
lim(f,x0) $in R
```
### Native elementary operation additions
See [Native elementary operations](native-elementary-operators.md) for `conj`,
`sec`, `csc`, `sinh`, `cosh`, `tanh`, `coth`, `sech`, `csch`, and `set_diff`,
including domains, builtin relationships, strict examples and compiler boundaries.
### Native real trigonometry (beta preview)
The expressions remain symbolic, while common exact identities verify:
The original bracket-based migration sketch is retired:
```text
have p2 &Point = (p[1], p[2])
p2.x = p[1]
```
Use ordinary coordinates, then construct a definition-owned struct view:
```litex
sin(0) = 0
cos(0) = 1
forall x R:
sin(x)^2 + cos(x)^2 = 1
forall x R:
(-1) <= x
x <= 1
=>:
sin(arcsin(x)) = x
cos(arccos(x)) = x
(-pi) / 2 <= arcsin(x) <= pi / 2
0 <= arccos(x) <= pi
forall x R:
tan(arctan(x)) = x
cot(arccot(x)) = x
(-pi) / 2 < arctan(x) < pi / 2
0 < arccot(x) < pi
```
The exact-value rule covers rational multiples of `pi` at sixths, quarters,
thirds and halves, including signs and checked integer periods. For example:
```litex
have k Z
tan(pi + 2 * k * pi) = 0
sin(pi / 6 + 2 * k * pi) = 1 / 2
cos(pi / 3 + 2 * k * pi) = 1 / 2
```
The integer membership of each surviving symbolic period term is required.
Reordering products and combining equal linear terms are supported; an
arbitrary real `k` does not establish an integral period. Tangent and cotangent
still require their denominator to be nonzero. The [period regression](../examples/proof_nodes/equal/by_builtin_rule/periodic_trig_exact_values.lit)
contains the supported exact values and the corresponding rejection controls.
Complex trigonometry, analytic definitions, and continuity theorems are outside
this interface. Right inverses require the principal interval:
```litex
forall y R:
(-pi) / 2 <= y
y <= pi / 2
=>:
arcsin(sin(y)) = y
forall y R:
0 <= y
y <= pi
=>:
arccos(cos(y)) = y
forall y R:
(-pi) / 2 < y
y < pi / 2
=>:
arctan(tan(y)) = y
forall y R:
0 < y
y < pi
=>:
arccot(cot(y)) = y
```
For closed rational multiples of `pi`, strict comparison uses exact rational
coefficients and the positive sign of `pi`; it does not approximate angles.
Concrete inverse values can use a forward value, its principal interval, and
an explicit equality chain, as demonstrated by
[the quarter-angle inverse tracer](../examples/proof_nodes/equal/by_builtin_rule/inverse_trig_quarter_angles.lit).
In particular, `arccot(-1)` uses `3*pi/4` in `(0,pi)`.
### Complex symbolic calculation and coordinate laws
```litex
i $in C
i * i = (-1)
i^2 = (-1)
i^4 = 1
i^(-1) = (-i)
i $in C*
not 0 $in C*
have w C*
w $in C
w != 0
re(3) = 3
img(3) = 0
re(i) = 0
img(i) = 1
forall a, b R:
re(a + b * i) = a
img(a + b * i) = b
claim:
? forall z C:
z = re(z) + img(z) * i
C_abs(z) = sqrt(re(z)^2 + img(z)^2)
0 <= C_abs(z)
re(z) $in R
img(z) $in R
z = re(z) + i * img(z) = re(z) + img(z) * i
C_abs(z)^2 = C_abs(re(z) + i * img(z))^2 = re(z)^2 + img(z)^2
0 <= C_abs(z)
re(z)^2 >= 0
img(z)^2 >= 0
re(z)^2 + img(z)^2 >= 0
sqrt(C_abs(z)^2) = C_abs(z)
sqrt(re(z)^2 + img(z)^2) = sqrt(C_abs(z)^2) = C_abs(z)
```
Equality calculation also has a bounded exact complex-algebraic mode. It uses
the ordinary polynomial/rational normalizer, with the additional relation
`i * i = (-1)`:
**Checked example.**
```litex
2 * i + 1 = i * i + 2 + 2 * i
(1 + i) * (1 - i) = 2
1 / i = (-i)
forall z C:
(z + i) * (z - i) = z^2 + 1
forall z, w C:
z * w = 0
=>:
z = 0 or w = 0
```
This route is exact and zero-premise: division side conditions are still
checked by well-definedness, and a successful equality reports
`exact complex algebraic normalization`. It does not introduce approximate
complex evaluation or an order on `C`.
The rectangular identities `re(a+b*i)=a`, `img(a+b*i)=b`, and
`C_abs(a+b*i)^2=a^2+b^2` require both coefficients `a` and `b` in `R`.
A well-defined complex argument does not establish those real memberships.
`re(z)`, `img(z)`, and `C_abs(z)` are dedicated unary builtin expression
forms with domain `C` and result set `R`, at the same object-model level as
`|z|`. Their bare names are not first-class function values; higher-order
code can use `fn(z C) R {re(z)}` and the analogous lambdas. For a real input,
`C_abs(r) = |r|`, while `C_abs(i) = 1`. Equality and inequality (`=`, `!=`)
are available for complex objects. Ordered comparisons, signs, real intervals,
`abs`, `sqrt`, and `log` remain real-domain operations.
For numeric coordinates, `C_abs` computes exact real and imaginary parts,
then uses the nonnegative principal root of their squared sum. Both summand
orders, subtraction and negative imaginary coefficients work:
```litex
C_abs(3 + 4 * i) = 5
C_abs(4 * i + 3) = 5
C_abs(3 - 4 * i) = 5
C_abs(-4 * i + 3) = 5
C_abs(1 + i) = sqrt(2)
eval C_abs(3 - 4 * i)
```
Decimal and rational coordinates are exact. A nonsquare result remains an
exact `sqrt` expression; a negative root is rejected. For every well-defined
complex argument, `C_abs(z) >= 0` and `0 <= C_abs(z)` are builtin facts.
Known complex equalities can be observed through `re` and `img`. The verifier
also supplies the standard coordinate formulas for native complex addition,
subtraction, multiplication, division/inverses, and natural successor powers.
The modulus is multiplicative, satisfies the triangle and reverse-triangle
inequalities, and is strictly positive exactly away from zero. Thus a proof can
reason directly about `re(z * w)`, `img(z / w)`, and `C_abs(z * w)` without
introducing a coordinate-pair compatibility layer.
Natural powers `z^n` are defined for `z` in `C` and `n` in `N`, including the
existing convention `0^0 = 1`. The additional integer-exponent branch requires
a nonzero complex base; the ordinary exponent-addition law remains available
on that branch. General `C^R` or `C^C` exponentiation is not part of this
preview.
The following are deliberately invalid expression shapes, rather than complete
factual statements. Their operation domains reject these arguments:
```litex
i < 1
|i|
sqrt(i)
log(2, i)
i^(1 / 2)
0^(-1)
```
`C`, `i`, `re`, `img`, and `C_abs` are hard-reserved builtin names and cannot
be rebound as definitions, parameters, indices, or fields.
### Indexed-family algebra
For compatibility with the older family-object forms,
`index_union(I, X, A) = family_union(fn_range(A))` and the analogous
`family_intersect(fn_range(A))` bridge use a nonempty `I`.
**Settled empty-family intersection (absolute form):** mathematicians treat
`⋂ ∅` without an ambient universe as the class of *everything* (vacuous
`∀ A ∈ ∅. x ∈ A`), not as the empty set. Litex therefore does **not** prove
`family_intersect({}) = {}`. Empty-index expressions such as `index_intersect({}, X, A)` are outside the current WD contract. `family_intersect({})` may still be a
well-formed object expression; it simply has no “equals empty” builtin identity.
Indexed-family algebra is handled by ordinary one-step builtin rules. Exact
family transformations for singleton domains, family/domain monotonicity,
domain partitions, De Morgan laws, external `union`/`intersect`/`set_minus`,
pointwise binary operations, ranges, powersets, Cartesian products,
nonemptiness, and finiteness are recognized in their existing fact-family
owners. A rule with a mathematical premise consumes an already available
membership, nonempty, subset, `forall`, or `exist` fact and records it in the
proof result; it does not launch recursive theorem search. No wrapper `thm`
definitions are installed for these identities.
For example:
```litex
have fn A(k {1, 2}) power_set(N) = {1}
1 $in {1, 2}
A(1) $in power_set(N)
A(1) $subset N
claim:
? A(1) $subset index_union({1, 2}, N, A)
claim:
? forall x A(1):
x $in index_union({1, 2}, N, A)
x $in N
witness exist k {1, 2} st {x $in A(k)} from 1
x $in index_union({1, 2}, N, A)
by def A(1) $subset index_union({1, 2}, N, A)
have fn complement(k {1, 2}) power_set(N) = set_minus(N, A(k))
by extension:
? set_minus(N, index_union({1, 2}, N, A)) = index_intersect({1, 2}, N, complement)
claim:
? forall x set_minus(N, index_union({1, 2}, N, A)):
x $in index_intersect({1, 2}, N, complement)
claim:
? forall k {1, 2}:
x $in complement(k)
by contra:
? not x $in A(k)
witness exist j {1, 2} st {x $in A(j)} from k
x $in index_union({1, 2}, N, A)
impossible not x $in index_union({1, 2}, N, A)
x $in set_minus(N, A(k))
complement(k) = set_minus(N, A(k))
x $in complement(k)
release thm index_intersect_member(x, index_intersect({1, 2}, N, complement))
claim:
? forall x index_intersect({1, 2}, N, complement):
x $in set_minus(N, index_union({1, 2}, N, A))
by contra:
? not x $in index_union({1, 2}, N, A)
obtain k from exist k {1, 2} st {x $in A(k)}
x $in complement(k)
complement(k) = set_minus(N, A(k))
x $in set_minus(N, A(k))
impossible x $in A(k)
x $in set_minus(N, index_union({1, 2}, N, A))
by extension:
? cart(Z, set_minus(N, {1})) = set_minus(cart(Z, N), cart(Z, {1}))
claim:
? forall pair cart(Z, set_minus(N, {1})):
pair $in set_minus(cart(Z, N), cart(Z, {1}))
pair(1) $in Z
pair(2) $in set_minus(N, {1})
pair(2) $in N
release thm cart_member_from_coordinates(pair, cart(Z, N))
by contra:
? not pair $in cart(Z, {1})
pair(2) $in {1}
impossible not pair(2) $in {1}
pair $in set_minus(cart(Z, N), cart(Z, {1}))
claim:
? forall pair set_minus(cart(Z, N), cart(Z, {1})):
pair $in cart(Z, set_minus(N, {1}))
pair $in cart(Z, N)
pair(1) $in Z
pair(2) $in N
by contra:
? not pair(2) $in {1}
release thm cart_member_from_coordinates(pair, cart(Z, {1}))
impossible not pair $in cart(Z, {1})
pair(2) $in set_minus(N, {1})
release thm cart_member_from_coordinates(pair, cart(Z, set_minus(N, {1})))
```
The matcher keeps one-way laws one-way. In particular, an indexed union of
pointwise intersections is only contained in the intersection of the indexed
unions; a union of powersets is only contained in the powerset of the union;
and a pointwise-union `index_cart` only contains the union of the two
products. For arbitrary `C`, the exact relative-complement law is
```text
C set_minus index_intersect(I, X, A)
= union(
set_minus(C, X),
index_union(I, C, fn(i I) power_set(C) {set_minus(C, A(i))}))
```
The correction term may be omitted only when `C $subset X` is already known.
The complete runnable boundary example is
`examples/infer/atomic/in_index_union.lit` (and sibling `in_index_*` tracers).
### Common rule families
| Family | Typical supported work |
|---|---|
| Exact evaluation | Concrete rational arithmetic and comparisons; complex Calculation reduces the reserved literal `i` using `i² = -1` |
| Algebraic normalization | Polynomial identities and normalized numeric expressions |
| Equality matching | Reflexivity, symmetry, transitivity, substitution, and known-value resolution |
| Order | Real signs, monotonicity, inequality combination, real powers, and real absolute values |
| Membership | Standard number sets, displayed sets, ranges, intervals, products, and function values |
| Set relations | Set shape, nonemptiness, finiteness, subset and proper subset patterns |
| Functions | Application equations, pointwise equality, global function equality, mapping properties |
| Finite aggregates | Sizes, extrema, indexed sums/products, finite-set sums/products, pointwise product distribution, and bijective reindexing |
| Modular arithmetic | Concrete remainders, congruence-preserving operations, and nested-remainder absorption when the outer modulus divides the inner modulus |
| Structured objects | Exact finite functions/tuples, Cartesian products, sequence carriers, structs, and templates |
#### How to read the catalogue
The tables group rules by their mathematical contract, not by implementation
branches. A listed law describes a recognized source shape and
its required facts; it does not promise that every logically equivalent
reformulation is automatic.
Detailed output distinguishes computation, direct builtin rules, structural
strategies, definition routes, and explicit builtin theorem calls. Consult that
proof tree when a nearby spelling soft-fails, then state the missing bridge
fact explicitly.
#### Declarative algebra, nonzero, and order schemas
The following table groups the main algebra, nonzero, and order schemas by
their mathematical role. Mirrored strict and weak orientations are described
together.
| Group | Recognized laws and required premises |
|---|---|
| Absolute-value algebra | `\|x*y\| = \|x\|*\|y\|`; `0 <= \|x\|`; `x <= \|x\|`; `(-x) <= \|x\|`; `(-\|x\|) <= x`; `\|x+y\| <= \|x\|+\|y\|`; `\|x-y\| <= \|x\|+\|y\|`; `\|x\|-\|y\| <= \|x-y\|` and `<= \|x+y\|`; `x != 0` gives `0 < \|x\|`; nonnegative/nonpositive `x` selects `\|x\|=x` or `\|x\|=(-x)`. |
| Nonzero closure | Known nonzero real factors give `a*b != 0`; a nonzero numerator and denominator give `a/b != 0`. Division still requires the denominator fact for well-definedness. |
| Order weakening | `a < b` gives `a <= b`, and `a > b` gives `a >= b`. The converse is not available without disequality or another strict premise. |
| Addition | Weak+weak gives weak order; strict+strict gives strict order; weak+strict and strict+weak give strict order. Adding a common left term preserves either order. Nonnegative summands give a nonnegative sum; the sum is positive when both are positive or one is positive and the other nonnegative. `0 <= b` gives `a <= a+b`. |
| Subtraction | `a <= b` and `0 <= c` give `a-c <= b`; `v <= u` gives `0 <= u-v`; `v < u` gives `0 < u-v`. These are real-order rules and do not totalize subtraction in `N`. |
| Multiplication and division signs | Positive factors/quotients are positive; nonnegative factors/quotients are nonnegative. Quotient rules require a positive denominator, not merely a nonzero denominator. |
| Minimum | `min(a,b)` is below both arguments; a known comparison selects the appropriate argument; `min` is commutative, associative, idempotent, monotone, and satisfies `min(a,max(a,b))=a`. |
| Maximum | `max(a,b)` is above both arguments; a known comparison selects the appropriate argument; `max` is commutative, associative, idempotent, monotone, and satisfies `max(a,min(a,b))=a`. |
These are executable instances of four different groups:
```litex
forall x, y R:
|x * y| = |x| * |y|
|x + y| <= |x| + |y|
|x| - |y| <= |x - y|
forall a, b R:
a != 0
b != 0
=>:
a * b != 0
a / b != 0
forall a, b, c, d R:
a <= b
c < d
=>:
a + c < b + d
claim:
? forall a, b, c, d R:
a <= c
b <= d
=>:
min(a, b) <= min(c, d)
max(a, b) <= max(c, d)
by cases:
? min(a, b) <= min(c, d)
case c <= d:
min(c, d) = c
by cases:
? min(a, b) <= c
case a <= b:
min(a, b) = a <= c
case a > b:
b <= a
min(a, b) = b < a <= c
case c > d:
d <= c
min(c, d) = d
by cases:
? min(a, b) <= d
case a <= b:
min(a, b) = a <= b <= d
case a > b:
b <= a
min(a, b) = b <= d
by cases:
? max(a, b) <= max(c, d)
case d <= c:
max(c, d) = c
by cases:
? max(a, b) <= c
case b <= a:
max(a, b) = a <= c
case a < b:
a <= b
max(a, b) = b <= d <= c
case c < d:
c <= d
max(c, d) = d
by cases:
? max(a, b) <= d
case b <= a:
max(a, b) = a <= c < d
case a < b:
a <= b
max(a, b) = b <= d
```
For example, `a / b != 0` above is not obtained from the multiplication rule
plus another division rule: the declarative quotient schema consumes both
known nonzero premises directly.
#### Declarative set schemas
The declarative set schemas cover the following groups:
| Group | Recognized laws and required premises |
|---|---|
| Union membership and containment | Membership in either operand introduces union membership. Both operands are subsets of the union. If `A $subset S` and `B $subset S`, then `union(A,B) $subset S`; componentwise inclusions also give `union(A,B) $subset union(C,D)`. One stored two-edge subset chain is transitive, and `A $subset B` reduces `union(A,B)` to `B` (with the mirrored operand order). |
| Intersection membership and containment | Membership in the intersection exposes membership in both operands. The intersection is a subset of each operand and of every known upper bound of either operand. A known `A $subset B` reduces `intersect(A,B)` to `A`, with the mirrored form for `B $subset A`. |
| Union/intersection algebra | Both operations are commutative and associative; both are idempotent; union has `{}` as a two-sided identity; `intersect(A,union(B,C))` distributes to the union of the two intersections. |
| Relative complement | Membership exposes membership in the left set and nonmembership in the right; every upper bound of `A` bounds `set_minus(A,B)`, and `A $subset C` gives `set_minus(A,B) $subset set_minus(C,B)`. The two relative De Morgan laws hold. The empty/self laws, `intersect(A,set_minus(B,A)) = {}`, `union(A,set_minus(B,A)) = union(A,B)`, and `set_minus(B,intersect(A,B)) = set_minus(B,A)` are recognized directly. If `B $subset A`, then removing `A \\ B` from `A` recovers `B` in either equality orientation. |
| Finiteness and infiniteness | Union/intersection of finite sets is finite; removing anything from a finite left operand is finite; removing a finite set from an infinite set remains infinite. |
| Nonemptiness | A nonempty union operand makes the union nonempty. `power_set(A)` is nonempty for every set `A`. |
| Power set | `A $subset B` introduces both `A $in power_set(B)` and `power_set(A) $subset power_set(B)`; a finite base gives a finite power set. |
> **Preview:** `A $in power_set(B)` is proved from `A $subset B`.
> In particular `{x S: …} $subset S` is recognized, so
> `have name power_set(S) = {x S: …}` type-checks. Storing `x $in power_set(B)`
> also records `x $subset B`.
| Empty set | `{}` is a subset of every set. |
Representative set algebra and containment rules verify directly:
```litex
forall A, B, D set:
union(A, B) = union(B, A)
union(union(A, B), D) = union(A, union(B, D))
intersect(A, A) = A
intersect(A, set_minus(B, A)) = {}
union(A, set_minus(B, A)) = union(A, B)
set_minus(B, intersect(A, B)) = set_minus(B, A)
intersect(A, union(B, D)) = union(intersect(A, B), intersect(A, D))
set_minus(A, union(B, D)) = intersect(set_minus(A, B), set_minus(A, D))
forall A, B, S set:
A $subset S
B $subset S
=>:
union(A, B) $subset S
forall A, B set:
B $subset A
=>:
set_minus(A, set_minus(A, B)) = B
```
The schemas are directional where their premises are directional. For
example, an intersection equality does not by itself manufacture the subset
premise needed by the corresponding reduction rule.
#### Finite-set cardinality tracer
`finite_set_size(A)` requires a finite set and has a natural-number carrier.
Zero cardinality implies equality with the empty set. Inclusion gives a weak
cardinality bound; strict inclusion is a separate obligation:
```litex
forall A finite_set:
finite_set_size(A) $in N
forall A finite_set:
finite_set_size(A) >= 0
forall A finite_set:
finite_set_size(A) = 0
=>:
A = {}
forall A, B finite_set:
A $subset B
=>:
finite_set_size(A) <= finite_set_size(B)
forall A finite_set:
$is_nonempty_set(A)
=>:
finite_set_size(A) >= 1
```
Any subset of a finite set is finite, even when declared only as `set`.
Equal cardinalities imply equality when one set is contained in the other;
proper inclusion gives a strict cardinality bound:
```litex
forall A set, B finite_set:
A $subset B
=>:
$is_finite_set(A)
forall A set, B finite_set:
A $subset B
=>:
finite_set_size(A) <= finite_set_size(B)
forall A set, B finite_set:
A $subset B
finite_set_size(A) = finite_set_size(B)
=>:
A = B
forall A set, B finite_set:
A $subset B
A != B
=>:
finite_set_size(A) < finite_set_size(B)
forall A set, B finite_set:
A $proper_subset B
=>:
finite_set_size(A) < finite_set_size(B)
```
A stored inclusion also publishes lower-set finiteness when an upper finite
certificate is already available through stored or structural evidence. This
lets the size expression pass WD before a proof body starts. The forward step
retains both its inclusion source and upper finite proof; it does not extend
strategy permissions. The [inference tracer](../examples/infer/atomic/subset_finite_upper_bound.lit)
shows the quantified `A set, B finite_set` case. Arbitrary inclusion chains
still use the existing bounded strategy when no eager certificate is available.
These rules retain the checked inclusion and cardinality premises. Equal
cardinalities alone do not identify sets, and ordinary inclusion alone gives
only the weak bound. Their runnable tracers are
[subset finiteness](../examples/proof_nodes/atomic/by_builtin_strategy/subset_of_finite_set.lit),
[weak comparison through WD](../examples/proof_nodes/atomic/by_builtin_rule/less_equal_finite_set_size_subset_wd.lit),
[equality from equal sizes](../examples/proof_nodes/equal/by_builtin_rule/finite_set_equal_from_subset_size.lit),
and [strict inclusion](../examples/proof_nodes/atomic/by_builtin_rule/less_finite_set_size_proper_subset.lit).
Finite-set constructors also support difference and union cardinality rules.
The decomposition below explicitly lifts the difference identity into the
sum before applying arithmetic cancellation. The subset case explicitly
lifts `intersect(A, B) = B` through `finite_set_size`:
```litex
forall A, B finite_set:
$is_finite_set(intersect(A, B))
$is_finite_set(set_minus(A, B))
$is_finite_set(union(A, B))
finite_set_size(union(A, B)) = finite_set_size(A) + finite_set_size(B) - finite_set_size(intersect(A, B))
finite_set_size(set_minus(A, B)) = finite_set_size(A) - finite_set_size(intersect(A, B))
finite_set_size(intersect(A, B)) + finite_set_size(set_minus(A, B)) = finite_set_size(intersect(A, B)) + (finite_set_size(A) - finite_set_size(intersect(A, B)))
finite_set_size(intersect(A, B)) + (finite_set_size(A) - finite_set_size(intersect(A, B))) = finite_set_size(A)
finite_set_size(A) = finite_set_size(intersect(A, B)) + finite_set_size(set_minus(A, B))
intersect(A, B) $subset A
finite_set_size(intersect(A, B)) <= finite_set_size(A)
finite_set_size(union(A, B)) <= finite_set_size(A) + finite_set_size(B)
forall A, B finite_set:
B $subset A
=>:
intersect(A, B) = B
finite_set_size(intersect(A, B)) = finite_set_size(B)
finite_set_size(set_minus(A, B)) = finite_set_size(A) - finite_set_size(intersect(A, B))
finite_set_size(set_minus(A, B)) = finite_set_size(A) - finite_set_size(B)
```
The runnable [cardinality regression](../examples/_internal/regression/finite_set_cardinality.lit)
also proves the converse empty-set implication, nonemptiness from positive or
nonzero size, and disjoint-union additivity with explicit proof steps.
**Checked example.**
```litex
forall a, b N:
a <= b
=>:
finite_set_size(closed_range(a, b)) = b - a + 1
finite_set_size(range(a, b)) = b - a
```
`finite_set_size(...)` still requires a checked finiteness proof. An arbitrary
`set` without that proof is ill-defined as its argument; inclusion in a finite
upper set can now supply the proof. Appearing in a cardinality expression
alone does not prove a set finite.
Runnable examples for these families are indexed in the
[examples directory](../examples/README.md). Keeping that evidence map there
avoids duplicating a second, quickly stale list of implementation files in the
language reference.
```litex
2 + 3 * 4 = 14
forall a, b Q:
a - b = 4
a * b = 1
=>:
(a + b)^2 = (a - b)^2 + 4 * (a * b) = 20
```
A builtin rule is not an unrestricted solver:
```text
forall x R:
x = 0
```
This soft-fails; the conclusion is false for arbitrary real `x`, and no
builtin pattern closes it.
### Equality rules
Equality routes depend on the outer shape of both sides. The following table
records the public behavior; later subsections expand the power, logarithm,
aggregate, and remainder rows.
| Shape | Recognized equality route |
|---|---|
| Same or known-equal objects | Reflexivity, symmetry, transitivity, equality-chain lookup, replacement of known-equal immediate subobjects, and calculation or rational-expression normalization. Equality is also obtained from both weak-order directions over an ordered numeric carrier. |
| Additive and multiplicative cancellation | `x = y` gives `x-y=0`; `a*b=0` together with either nonzero factor gives the other factor equal to zero; a known `a+b=c` gives `a=c-b`, in either summand order. |
| Division | From `a/b=c` and `b!=0`, Litex proves `a=c*b`. From `a=b*c` and `b!=0`, it proves `a/b=c`. The displayed multiplier and divisor positions must match; the rule does not silently commute a product first. |
| Absolute value and square root | A known sign selects `\|x\|=x` or `\|x\|=(-x)`; `\|x\|=0` gives `x=0`; even powers may replace a real base by its absolute value. Square-root rules include the principal-root square, special values, product/quotient laws under their domains, and `sqrt(a^2)=a` when `a>=0`. |
| Powers and logarithms | Zero/one, exponent addition, iterated power, product power, negative exponent, roots, and inverse logarithm/power shapes are supported only in the carrier branches listed below. |
| Remainder and divisibility | Special residues, Euclidean-remainder uniqueness, compatible nested moduli, and congruence under matching `+`, `-`, and `*` operands. `gcd(a,b)` divides both inputs. A positive common divisor `d` divides `gcd(a,b)`; `lcm(a,b)` for positive integer inputs divides every integer common multiple. `(a*b)%a=(a*b)%b=0` requires integer factors and the respective nonzero divisor. Integer membership of the complete product alone is insufficient. |
| Set and cardinality objects | Union/intersection/difference algebra, intersection reduction from a known subset, cardinality of differences, unions and power sets, concrete product cardinality by expansion, and empty-set equality from emptiness or zero finite cardinality. The general symbolic Cartesian-product cardinality formula remains a migration gap. |
| Tuples and Cartesian products | Tuple reconstruction from exact Cartesian membership; equality from equal complete finite domains and every coordinate; canonical `index_cart` expansion. Retired dimensions and projection operators are not public syntax. |
| Functions and materialized definitions | Application equations, alpha-equivalent anonymous functions, `by fn_extension` / pointwise forall, same-signature function-set equality, and equality of materialized template or struct values when their resolved objects agree. |
| Finite aggregates and reductions | Empty, singleton, endpoint, split, insertion/removal, distribution, congruence, and supported reindexing rules described under [Powers, logarithms, sums, products, and remainder](#powers-logarithms-sums-products-and-remainder). |
```litex
forall x, y R:
x = y
=>:
2 * x + 1 = 2 * y + 1
forall a, b R:
a <= b
b <= a
=>:
a = b
claim:
? forall a, b, c R:
b != 0
a / b = c
=>:
a = c * b
a = (a / b) * b = c * b
claim:
? forall a, b R:
a * b = 0
a != 0
=>:
b = 0
b = (a * b) / a = 0 / a = 0
```
Structural equality is recursive but bounded. Matching constructors descend
to their immediate children; binder-bearing objects compare alpha-equivalent
binders rather than the printed parameter names. This does not equate two
different mathematical presentations merely because an external theorem
could connect them. For functions, use `by fn_extension` or a pointwise
`forall` when extensional agreement is the intended interface.
#### Not-equality routes
`a != b` is a positive fact with its own rules; it is not produced merely
because equality verification failed.
| Group | Recognized route |
|---|---|
| Resolution and symmetry | Distinct resolved numeric values, including objects whose known equality representatives resolve to such values; the reverse known fact `b!=a`; and displayed sets with different structural lengths. Native `e`, `pi`, and `i` have their reviewed distinctness/nonzero facts. |
| Order and membership separation | Any known strict real order proves disequality. A value above a known positive lower bound is nonzero. Membership of one object and known nonmembership of the other in the same set prove the objects distinct. A nonempty set is not `{}`. |
| Addition and subtraction | `a!=b` gives `a-b!=0`, and `a-b!=0` gives `a!=b`. Likewise `a!=(-b)` gives `a+b!=0`, while a nonzero sum gives the corresponding operand-versus-negation fact. The immediate operand positions must match. |
| Products and quotients | Two known nonzero factors in `R` or `C` give a nonzero product; a known nonzero product in either native field gives both factors nonzero. The matching zero-product split is likewise available over `R` and `C`, but not for arbitrary user-defined multiplication. A well-defined quotient is nonzero from a nonzero numerator; its denominator obligation was already checked. |
| Powers, roots, and absolute value | A supported well-defined power is nonzero from a nonzero base, and positive-base power branches are intrinsically nonzero. `\|x\|!=0` follows from `x!=0`; `sqrt(x)!=0` requires `x>0`, not merely `x>=0`. |
| Sums of real squares | Either nonzero component, or the known two-branch component-nonzero disjunction, gives `a^2+b^2!=0` (also for the matching `a*a+b*b` shape). Conversely, the supported disjunction rule exposes that at least one component is nonzero. |
| Native positive values | Well-defined `exp(x)` and `factorial(n)` are nonzero. Dedicated complex-modulus, sign, and trigonometric nonzero rules use the domains and canonical sign intervals described in their object sections. |
```litex
forall a, b R:
a != b
=>:
a - b != 0
forall a, b R:
a * b != 0
=>:
a != 0 and b != 0
forall a, b R:
a != 0
=>:
a^2 + b^2 != 0
```
Large algebraic jumps may still soft-fail. Expose the identity and the
numeric simplifications separately:
```text
(3 - 2 * sqrt(2)) * (3 + 2 * sqrt(2)) = 1
```
If this does not close in the current context, write the checkable chain
`= 3^2 - (2 * sqrt(2))^2 = 9 - 8 = 1` and establish any missing square-root
fact first.
### Order and comparison rules
Every ordered comparison requires both operands to be real; membership in `C`
alone never supplies an order. The order layer recognizes these contracts:
| Group | Recognized premises and consequences |
|---|---|
| Totality and complements | For reals, the trichotomy permutations and the complementary pairs `<`/`>=`, `>`/`<=`, `<=`/`>=` are exhaustive. Known equality or strict order weakens to `<=`/`>=`; a known negated comparison can supply its exact complementary comparison. |
| Transitivity and differences | Strict/weak real comparisons compose through a shared middle term. `a<=b` is equivalent to `0<=b-a`, and similarly for `<`; a saved `00` proves `a=1`; `a1` preserves strict order; a base strictly between `0` and `1` reverses it. Absolute value supplies direct, triangle, and reverse-triangle bounds, including `\|sum(...,f)\| <= sum(...,fn(index Z) R {\|f(index)\|})` and the analogous finite-set sum under the matching index/carrier facts. |
| Finite aggregates and extrema | Pointwise weak/strict order on the relevant index set gives sum order. A nonnegative finite-set summand is at most the total. Finite-set extrema bound every member. Finite subset inclusion bounds cardinality, and union cardinality is at most the sum. |
| Native ordered objects | Floor and ceiling preserve weak order but not strict order. `min` and `max` expose argument bounds and componentwise monotonicity. Native `exp`/`ln` and trigonometric order use the dedicated sections below; complex modulus uses the [complex scalar contract](#complex-scalars-beta-preview). |
The positive-difference builtin consumes an already verified premise. It checks
both strict spellings with fixed known-fact lookups and retains the premise's
citation; it does not search for a new difference bound. The enclosing comparison
still requires real operands. See the runnable
[positive-difference tracer](../examples/proof_nodes/atomic/by_builtin_rule/greater_from_positive_difference.lit).
The complementary saved bridges are `a-b<0 => a a-b<0`,
`a-b<=0 => a<=b`, and `a<=b => a-b<=0`. Each is a dedicated builtin evidence
leaf. Positive and negative weak bridges may consume a stronger strict fact,
but strict conclusions require strict premises. Both orientations of each saved
comparison are checked with fixed known-premise lookups. When the minuend is
literal zero, `0-u`, `-u`, `(-1)*u`, and `u*(-1)` are fixed equivalent
spellings; this does not enable a general symbolic simplifier. The parent WD
check still requires real operands. `>` and `>=` retain the existing strategy
that exchanges the comparison arguments. Detailed JSON keeps the actual chosen
`premise_proof`, including its comparison and citation, under each dedicated
rule name. See [signed differences](../examples/proof_nodes/atomic/by_builtin_rule/signed_difference_order.lit)
and [negative signs](../examples/proof_nodes/atomic/by_builtin_rule/negated_sign_order.lit).
For checked mathematics-first examples, use
[R06–R10](#r06-complete-a-square-and-translate-the-bound). They distinguish
immediate matching from explicit equality transport and composition, including
the saved weak-difference orientation and subtraction-from-zero forms.
```litex
claim:
? forall x R:
0 <= x^2
(-x) <= |x|
x <= |x|
by cases:
? -x <= |x| and x <= |x|
case x > 0:
x $in R+
|x| = x
-x <= 0 <= x = |x|
x = |x|
case x = 0:
|x| = 0
-x = 0 = |x|
x = 0 = |x|
case x < 0:
x $in R-
|x| = -x
x < 0 < -x = |x|
-x = |x|
claim:
? forall a, b, c, d R:
a <= b
c <= d
=>:
a + c <= b + d
a - d <= b - c
a + c <= b + c <= b + d
a - d <= b - d <= b - c
forall m, n Z:
=>:
m <= n
<=>:
m < n + 1
forall a, b, c R:
a < b
0 < c
=>:
a * c < b * c
a / c < b / c
forall a, b R+:
a < b
=>:
log(2, a) < log(2, b)
```
Use [order and comparison rules](#order-and-comparison-rules), the S/O/F/C entries and the [proof-node examples](../examples/proof_nodes/README.md) to find each rule's mathematical premises and verification route.
Displayed finite-set membership can also use the structural strategy route:
```litex
{1, 2} $in {{}, {1, 2}}
not 4 $in {1, 2, 3}
```
The first goal checks one equality to a listed element. The second checks a
disequality to every listed element. The normal well-definedness checks still
apply, including for nonmembership in `{}`. Strategy children retain the
central dispatcher's `BuiltinRule` ceiling; they do not restore definition,
strategy or rewrite search. Detailed output records `ListSetMembership` or
`ListSetNonMembership`, its exact requirement facts and each child proof.
Maintained examples: [membership](../examples/proof_nodes/atomic/by_builtin_strategy/list_set_membership.lit)
and [nonmembership](../examples/proof_nodes/atomic/by_builtin_strategy/list_set_nonmembership.lit).
Stored standard numeric memberships also supply their intrinsic supersets
without verifying a new premise:
```litex
have integer_input Z
integer_input $in R
```
The current Direct route records a `standard_superset` leaf inside
`by_structural_membership`, both carriers and the cited source membership.
The dedicated `StandardNumericSuperset` known-property producer remains a
read-only fallback. That fallback only reads an existing membership; it does not
calculate or unfold a composite expression, or infer a smaller carrier from a
larger one. See the [stored-carrier tracer](../examples/proof_nodes/atomic/by_known_special_property/standard_numeric_superset.lit).
Stored numeric order bounds also pass through subtraction of a closed constant:
```litex
forall x Z:
x >= 2
=>:
x - 1 >= 0
```
`ClosedSubtractionBound` records the original upper/lower bound citation, the
exact subtrahend, the translated bound and the target endpoint. Both weak
comparison orientations are supported. An identical symbolic endpoint is also
supported when the closed offset preserves direction: `x <= b` yields
`x - 1 <= b`, while `x >= b` yields `x - (-1) >= b`. The certificate retains
the actual translated symbolic expression, such as `b - 1`. Strict comparisons
use `ClosedSubtractionStrictBound`: a proper translated bound suffices, or an
already strict source may retain strictness at the translated endpoint.
Thus `x <= b` yields `x - 1 < b`, but does not yield `x - 0 < b`.
A bound must be
sufficient; different symbolic endpoints, unknown constants, opposite bounds,
undefined expressions and exact arithmetic overflow fail closed. This leaf
performs no new premise search. See the
[subtraction-bound tracer](../examples/proof_nodes/atomic/by_builtin_rule/closed_subtraction_bound.lit).
Equality from two-sided weak order accepts either spelling of each direction:
```litex
forall a, b R:
a >= b
b >= a
=>:
a = b
```
`EqualityFromTwoSidedWeakOrder` cites both stored comparisons. It accepts
`<=`, converse `>=`, and mixed spellings, but two copies of the same direction
cannot prove equality. It does not search for missing bounds. See the
[orientation tracer](../examples/proof_nodes/equal/by_builtin_rule/two_sided_weak_order_orientations.lit).
Field expressions over `Q` and `R` have a structural carrier strategy:
```litex
forall a Q:
3 * a + 2 $in Q
forall a, b Q:
b != 0
=>:
(3 * a + 2) / b $in Q
```
It descends through addition, subtraction, negation, multiplication and division,
then checks terminal memberships and every divisor's nonzero requirement at
the strategy's existing child ceiling. Detailed output records
`FieldArithmeticCarrierClosure`, the constructor tree and each checked
requirement. Other constructors remain terminal membership goals; this route
does not unfold definitions or reenable nested strategies. See the
[field-expression tracer](../examples/proof_nodes/atomic/by_builtin_strategy/field_arithmetic_carrier_closure.lit).
The `RealArithmeticConstructorClosure` builtin composes real terminal
certificates across addition, subtraction, negation, multiplication, division
and integer powers. It descends through the finite expression syntax, checking
real leaves and integer exponents with the existing builtin premise ceiling
(at most KnownSpecialProperty). A function's checked return signature can be
such a leaf, so a comparison target containing `f(x)^2 / 4` can check its real
carrier before entering the proof body. Already checked composites can also
be leaves, including an exactly calculated real value such as `i^2`.
Detailed output keeps the constructor tree, terminal proofs and citations;
the enclosing WD proof retains division and negative-power domain guards.
Terminal proofs contain the membership fact and its successful search route;
function argument WD stays in the enclosing verification stage. Thus a
Cartesian-argument call does not have to reprove its argument carrier at the
lower terminal ceiling. The [Cartesian function WD tracer](../examples/wd/real_cart_function_arithmetic.lit)
checks a difference under `abs` and the guarded coordinate quotient.
The rule does not publish new memberships, unfold definitions, raise search
permissions or infer signed/integer refinements. See the
[real constructor tracer](../examples/proof_nodes/atomic/by_builtin_rule/real_arithmetic_constructor_closure.lit).
Complex arithmetic being well-defined does not imply a real-valued result.
General real closure now records `RealOperandArithmeticClosure` operand proofs,
or `RealPower` with its real-base proof and the enclosing power WD's
selected domain evidence. This covers the supported real exponent branches
as well as integer powers. Intrinsically real constructors such as
`abs`, `sqrt`, `log` and `ln` keep their own checked-domain route. Even-power
order requires a checked real base, and strict positivity also requires a
nonzero base:
```litex
forall x R:
0 <= x^2
i^2 < 0
1 + i != 0
(1 + i) / (1 + i) $in Q
```
Closed rational complex expressions can establish scalar membership through
their exact real and imaginary coordinates. The Direct closed-calculation route
records `by_closed_calculation` with these values; the retained builtin entries
record `ClosedExactScalarMembership` or `ClosedComplex` when used directly.
Exact complex inequality compares both coordinates; order
compares only values whose imaginary coordinate is zero. Unsupported inputs,
overflow and invalid domains produce no certificate. Consequently `0 <= i^2`,
`i^2 $in N` and a nonreal result declared in `R` remain rejected. Maintained
[real-operand](../examples/proof_nodes/atomic/by_builtin_rule/real_arithmetic_operand_carriers.lit),
[even-power](../examples/proof_nodes/atomic/by_builtin_rule/even_power_real_carrier.lit),
[scalar](../examples/proof_nodes/atomic/by_builtin_rule/closed_exact_scalar_membership.lit),
[inequality](../examples/proof_nodes/atomic/by_builtin_rule/closed_complex_not_equal.lit)
and [order](../examples/proof_nodes/atomic/by_builtin_rule/closed_complex_real_order.lit)
examples retain the boundary controls in focused Rust tests.
The last equivalence is an integer-adjacency rule: a strict bound immediately
below the successor `n + 1` is the same as the weak bound at `n`. It requires
both compared objects to be known integers.
Sign conditions matter:
```text
forall a, b, c R:
a < b
=>:
a * c < b * c
```
This soft-fails because multiplication reverses or collapses order when the
sign of `c` is not known.
The [gcd universal divisor](../examples/proof_nodes/atomic/by_builtin_rule/dvd_gcd_common_divisor.lit)
and [lcm universal multiple](../examples/proof_nodes/atomic/by_builtin_rule/dvd_lcm_common_multiple.lit)
examples use native `$dvd` facts. The older zero-remainder spellings remain
supported through the same rules. The
[factorial/product theorem](../examples/proof_nodes/equal/by_builtin_rule/factorial_product_relation.lit)
uses existing induction, factorial successor and product endpoint rules on `N+`;
it adds no primitive factorial-product identity and no empty-range convention.
### Trigonometric rules
The symbolic trigonometric interface recognizes the following exact families:
| Family | Recognized laws and required domains |
|---|---|
| Core identities | Values at `0` and `pi / 2`, sine and cosine addition and difference formulas, the unit-circle identity, and `tan(x)=sin(x)/cos(x)` or `cot(x)=cos(x)/sin(x)` when the denominator is known nonzero. |
| Fixed quotient identities | `tan(x)*cot(x)=1` requires real `x`, `sin(x)!=0` and `cos(x)!=0`; `1+tan(x)^2=1/cos(x)^2` requires real `x` and `cos(x)!=0`. Equality direction, factor/summand order and squares written as repeated multiplication are supported. |
| Principal inverse sine | `arcsin(x)` requires `x in [(-1),1]`, returns a value in `[(-pi)/2,pi/2]`, and satisfies `sin(arcsin(x))=x`. Conversely, `arcsin(sin(y))=y` requires `y` in that principal interval. |
| Principal inverse cosine | `arccos(x)` requires `x in [(-1),1]`, returns a value in `[0,pi]`, and satisfies `cos(arccos(x))=x`. Conversely, `arccos(cos(y))=y` requires `y` in `[0,pi]`. |
| Principal inverse tangent | `arctan(x)` is total on `R`, returns a value in `((-pi)/2,pi/2)`, and satisfies `tan(arctan(x))=x`. Conversely, `arctan(tan(y))=y` requires `y` in that open principal interval. |
| Principal inverse cotangent | `arccot(x)` is total on `R`, returns a value in `(0,pi)`, and satisfies `cot(arccot(x))=x`. Conversely, `arccot(cot(y))=y` requires `y` in `(0,pi)`. |
| Exact special values | Rational `pi` coefficients at sixths, quarters, thirds and halves; checked symbolic integer periods and a separate sine/cosine nonzero certificate for tangent/cotangent WD. Sine integer zeros and cosine half-integer zeros require only integer multiples of `pi`; nonzero signed sine/cosine values require multiples of `2*pi`. |
| Symmetry and angles | Odd/even parity, double-angle and cofunction formulas, supported integral and half-integral multiples of `pi`, shifts by `pi` and `pi/2`, and period `2*pi` for sine/cosine or `pi` for tangent/cotangent when defined. |
| Bounds and signs | `(-1) <= sin(x), cos(x) <= 1`, `3 < pi < 4`, and `0 0 sin(a)0` or `cot(x)>0`. Partial-operation WD
retains its ordinary nonzero requirement and the actual bound citations.
See the [quadrant](../examples/proof_nodes/atomic/by_builtin_rule/trig_first_quadrant.lit)
and [quotient WD](../examples/proof_nodes/equal/by_builtin_rule/trig_first_quadrant_quotient_wd.lit)
examples. Missing or weak bounds and poles remain rejected.
Shared negative factors reverse strict real order; shared nonpositive factors
reverse weak order. Fixed rules cover `<`, `>`, `<=`, `>=` and all four product
placements (`c*a`/`c*b`, `a*c`/`b*c`, and the two mixed placements).
The rule checks factor sign first and reversed argument order second. Each
child retains the actual checked comparison and citation; weak rules may use
strict premises as stronger evidence. Strict goals require a strictly negative
factor and strict argument order. The existing positive/nonnegative routes
remain first. See the [strict](../examples/proof_nodes/atomic/by_builtin_rule/negative_common_factor_order.lit)
and [weak](../examples/proof_nodes/atomic/by_builtin_rule/nonpositive_common_factor_weak_order.lit)
examples. Their sign and order premises are part of the rule contract.
Known closed numeric equalities are substituted by matching whole original
scalar terms before their children. A parent rebuilt from changed children
can then use its known value in the same structural pass. For example, with
both `a=0` and `cos(a)=1`, the whole cosine value wins. Equality, order and
`eval` retain each selected equality citation; residual verification keeps its
existing permissions. The [numeric substitution tracer](../examples/proof_nodes/atomic/by_builtin_rewrite/closed_numeric_subterm_priority.lit)
preserves the former process-dependent failure.
One-step function-application unfold substitution is an equality rewrite (preview), tried
after closed numeric substitution. `have fn equal` automatically stores both
function membership and an equality from the function name to its anonymous
function. This is one source of the equality, not a requirement that the head
come from a definition. The rewrite reads any such exact stored equality from
the function head's `AnonymousFn` equality bucket and substitutes actual arguments into the body.
The [exact-property index](../src/exec_env/README.md) separates that bucket from
tuple, cart and individual set constructors while retaining the original equality citation:
```litex
have fn f(x N) N = x + 1
forall x N:
2 * f(x) = 2 + 2 * x
```
A local universal premise can supply the anonymous function without a
`have fn` declaration, while retaining its domain guard:
```litex
forall f fn(t R: t > 0) R, x R:
f = fn(t R: t > 0) R {t}
x > 0
=>:
2 * f(x) = 2 * x
```
The [universal-premise tracer](../examples/proof_nodes/equal/by_builtin_rewrite/fn_application_unfold_substitution_forall_equality.lit)
checks a body-dependent conclusion; `f(x)=f(x)` would need only reflexivity.
No application-value equation is required. Each original outermost call under
scalar constructors unfolds once, on both equality sides. Call arguments and
inserted bodies are not scanned. If one side unfolds exactly to the existing
opposite endpoint, that endpoint stays unchanged. For example, if `outer(x)`
unfolds to `inner(x)`, this rewrite does not also unfold `inner(x)`. Calls with several
application groups, non-scalar constructors and equality-class walks are outside
this route. A function-set membership alone supplies a signature, not a body. Bare
anonymous-literal beta equalities retain their existing definition route.
Original and selected anonymous-function calls must pass domain and guard
checks. Residual truth is checked at Strategy with rewrite disabled, excluding
generic definition/forall expansion. Detailed output names
`FnApplicationUnfoldSubstitution` and records ordered checked beta steps,
head-equality citations, rewritten endpoints and the residual proof; Normal
output retains `builtin_rewrite`. See the [runnable tracer](../examples/proof_nodes/equal/by_builtin_rewrite/fn_application_unfold_substitution.lit).
Lean replay consumes this evidence for supported function and scalar constructors.
Focused compiler tests cover natural-number function declarations and
arithmetic-congruence residuals.
### Native numeric function rules
| Family | Recognized laws and required domains |
|---|---|
| `exp` and `ln` | `exp(0)=1`, `ln(1)=0`, `exp(x)=e^x`, their inverse laws, and the usual addition/product identities. `exp` maps `R` to `R+` and preserves and reflects order and equality. `ln` has the corresponding behavior on `R+` and agrees with `log(e,x)`. |
| `sign` | Returns `(-1)`, `0`, or `1`; is odd, multiplicative, and weakly monotone; characterizes zero and nonzero inputs; and satisfies `sign(x)*\|x\|=x`. |
| `factorial` | Maps `N` to `N+`, evaluates finite natural inputs, exposes the successor recurrence, preserves weak order, is strictly increasing past the `0! = 1!` boundary, and gives divisibility from an earlier to a later factorial. |
| `floor` and `ceil` | Return integers, expose their characteristic bounds, preserve weak order, commute with integer translation, and are dual under negation. |
| `min` and `max` | Select an argument from a known comparison, bound both arguments, preserve componentwise weak order, and satisfy the usual commutative, associative, idempotent, and absorption laws. |
| `gcd` and `lcm` | Are symmetric on their domains; `gcd` divides both integer inputs; `lcm` is nonnegative, has the expected common-multiple bounds, and satisfies `lcm(a,b)*gcd(a,b)=\|a*b\|` when the pair is not both zero. |
Symbolic transcendental expressions are not decimal approximations. Every law
still requires its ordinary well-definedness conditions.
### Powers, logarithms, sums, products, and remainder
The self, one, and same-base-power log rules explicitly check `b>0` and
`b!=1`, covering bases strictly between zero and one as well as bases above
one. Their detailed evidence preserves both requirements. The native constant
bound `e>1` supplies a checked route to `e!=1` and `log(e,e)=1`; see
[the log algebra tracer](../examples/proof_nodes/equal/by_builtin_rule/log_positive_nonunit_base.lit).
Order rules retain their separate base-range conditions.
Power rules first select one supported carrier branch. Complex bases support
natural exponents and, when nonzero, integer exponents. Arbitrary real
exponents are well-defined for a positive real base. A nonnegative real base
also permits any positive real exponent, including a zero base. These domains
retain the actual carrier and sign proofs in the power WD certificate. Integer and positive-natural exponent branches retain
their narrower algebraic carriers. Positivity, monotonicity, roots,
logarithms, and even-power absolute-value rules remain real-only.
Natural powers retain `0^0=1`; zero with a negative exponent, negative bases
with noninteger exponents, and general complex exponents remain outside the
supported domain. WD admits an expression; each identity or calculation still
uses its own checked rule. The [real-power WD tracer](../examples/wd/pow_real_domains.lit)
checks symbolic roots, `exp(x)=e^x`, real carriers and existing integer domains.
The Detailed fixed-base identity is now `ExpAsEulerPower`, reflecting its real
argument domain.
| Family | Exact public laws, subject to well-definedness |
|---|---|
| Power identities | `a^0=1`, `a^1=a`, `1^x=1`, and `0^r=0` for `r in R+` (including positive natural exponents); `a^(m+n)=a^m*a^n`; `(a^m)^n=a^(m*n)`; `(a*b)^x=a^x*b^x`; `a^(-n)=1/a^n` for nonzero `a` and positive-natural `n`. The automatic exponent-addition, iterated-power, and product-power leaves check natural or integer exponents; real-exponent WD alone does not supply these laws. |
| Roots and inverse powers | `(sqrt(x))^2=x` for `x>=0`; `sqrt(a^2)=a` for `a>=0`; product and quotient roots require nonnegative inputs and a positive denominator. `x^(1/n)=z` is recognized from `x=z^n`, `n in N+`, and `z>=0`; equal nonzero integer powers of positive bases can recover equality of the bases. |
| Logarithms | With valid positive arguments and a positive base unequal to one: `log(a,1)=0`, `log(a,a)=1`, product, quotient, reciprocal, and power laws; `log(a,a^b)=b`; `a^c=b` and `log(a,b)=c` are inverse shapes; the direct `a^log(a,x)=x` leaf currently requires `a>1`; change of base accepts any two positive nonunit real bases, including `(0,1)`, and obtains the nonzero logarithm denominator from the nonunit argument. The powered-base formula retains the supported power domains and a nonzero real exponent; positive nonunit bases with nonzero integer exponents supply the powered-base nonunit guard directly. |
| Integer-range `sum`/`product` | Singleton ranges, last-term recurrence, adjacent partition, constants and pointwise congruence; sums also support addition/subtraction and scalar laws. Both support integer shift-reindexing. Bounds are closed integer endpoints with start <= end; source and target legality must be proved. Pointwise facts are required on the consumed range. Empty finite-set aggregates use their separate interface. |
| `finite_set_sum` | Empty/displayed/closed-range expansion, constant and pointwise congruence, insertion or disjoint union, pointwise addition, scalar distribution, Cartesian double-sum/Fubini, unique-cover substitution, and bijective re-enumeration. |
| `finite_set_product` | Empty/displayed/closed-range expansion, insert/remove, constant and pointwise congruence, pointwise multiplication, and bijective substitution. |
| `reduce` | Ascending left-fold evaluation for literals; empty range returns the seed; nonempty ranges consume the first or last value; adjacent ordered partition; order-preserving interval translation; pointwise congruence; additive seed `0` and multiplicative seed `1` bridge to `sum` and `product`. |
| `finite_set_reduce` | Empty set returns the seed; displayed-set enumeration, insertion, disjoint union with one seed, closed-range ascending enumeration, congruence, and bijective substitution require an associative-commutative operation. Additive seed `0` and multiplicative seed `1` bridge to the finite-set aggregates. |
| Remainder | `0%m=0` for nonzero integer `m`; `x%1=0`; `1%k=1` for `k>=2`; Euclidean uniqueness; negation normalization; power congruence; matching `+`, `-`, `*` congruence; same-modulus nesting; and `(a%m)%d=a%d` when positive `d` divides positive `m`. |
The exponent-addition, iterated-power and product-power matchers preserve the
natural-exponent branch on all complex bases, including zero. Their integer
branch checks each original base is nonzero and each exponent belongs to `Z`;
it does not infer these laws for arbitrary fractional exponents. The checked
premises remain in `proof_of_requirement_facts`. Positive real bases also
support cancellation from a stored `x^n = y^n` when `n $in Z` and `n != 0`,
including symbolic `n`; both exponent guards are retained as requirements. See the
[integer-power tracer](../examples/proof_nodes/equal/by_builtin_rule/integer_power_laws.lit).
The exponent-addition matcher accepts a bare copy of the same base for an
exponent of literal `1`, so `x^(n+1) = x^n * x` verifies directly for `x R, n N`
and more generally for `x C, n N` or `x C*, n Z`. Factor order, addition order,
and equality direction may be reversed. The base may itself be a compound
expression, provided the complete equality is well-defined. The same original
base and exponent requirements are retained by `PowerProductSameBase`; this
does not add a rule for arbitrary real exponents. See the
[first-power factor tracer](../examples/proof_nodes/equal/by_builtin_rule/power_product_same_base_unit_exponent.lit).
Mathematically, a real exponent distributes over positive real factors in
either equality direction. The current symbolic proof interface distinguishes integer and real exponents:
The symbolic product-power leaf checks integer exponents on positive real
bases. This supported instance verifies:
```litex
forall a, b R+, n Z:
(a * b)^n = a^n * b^n
```
For an arbitrary real exponent, the mathematical identity remains:
```text
forall a, b R+, x R:
(a * b)^x = a^x * b^x
```
This real-exponent form remains outside the current automatic symbolic rule.
It is a mathematical boundary example, not an executable proof claim.
Positivity is required for this mathematical law. The real-exponent mathematical form does
not establish a checked automatic rule for arbitrary real exponents.
Aggregate rules consume the displayed function and index shape. They do not
silently replace a summand by an extensionally equal function outside the
relevant domain; provide the exact pointwise universal. The
subtraction rule also requires one common additive carrier among `Z`, `Q`,
`R`, and `C`, so it does not totalize natural-number subtraction.
```litex
have f fn(index Z) R
have g fn(index Z) R
forall m, n Z:
m <= n
=>:
sum(m, n, fn(difference_index Z) R {f(difference_index) - g(difference_index)}) = sum(m, n, fn(minuend_index Z) R {f(minuend_index)}) - sum(m, n, fn(subtrahend_index Z) R {g(subtrahend_index)})
forall X finite_set, p, q fn(x X) Z:
finite_set_product(X, fn(x X) Z {p(x) * q(x)}) = finite_set_product(X, p) * finite_set_product(X, q)
```
```litex
forall m Z:
m != 0
=>:
0 % m = 0
forall a Z:
a % 2 = (a % 8) % 2
```
The second fact uses `2 | 8`. In general, `(a % m) % d = a % d` is automatic
only when `a` is an integer, `m` and `d` are positive integers, and `m % d = 0`.
Domain obligations are never supplied by an algebra rule:
```text
have x R
log(1, x) = 0
```
This is an `error`: base `1` is outside the logarithm domain, and positivity of
`x` is also missing.
### Membership and type-predicate rules
Membership rules are directional introduction or elimination rules. A known
constructor fact is not interchangeable with every logically equivalent
presentation.
| Target family | Recognized construction or elimination |
|---|---|
| Standard numeric carriers | Literal classification; the inclusion chain among signed/nonzero `N`, `Z`, `Q`, `R`, and `C`; arithmetic closure at the narrowest supported carrier; refinement from integer/real carrier plus known sign; nonmembership for resolved literals; `floor`/`ceil` in `Z`, `sign` in `Z`, `factorial(N)` in `N+`, and numeric carriers for gcd/lcm/extrema/aggregates. |
| Displayed sets and builders | Equality with one displayed element introduces membership, and disequality from every element introduces nonmembership. Builder membership requires base membership and all instantiated defining facts; stored builder membership exposes those facts. A builder over a finite base is finite. |
| Binary set operations | Either-side membership introduces union membership; intersection requires both sides; difference requires left membership and right nonmembership. Corresponding stored intersection/difference facts expose their component facts. |
| Family and image operators | `family_union` uses a member-set witness; `index_union(I,X,A)` uses an index witness; `index_intersect(I,X,A)` uses ambient membership plus every indexed fiber; `replacement` uses its functional relation witness; `fn_range` uses a well-defined application. Stored membership exposes the corresponding existential or universal source described in the object section. |
| Ranges and intervals | `range(a,b)` uses integer `a<=i:
$is_nonempty_set(closed_range(a, b))
$is_finite_set(closed_range(a, b))
```
A familiar name does not provide a missing shape fact:
```text
have A set
$is_finite_set(A)
```
The second line soft-fails; arbitrary sets need not be finite.
### Inclusion and function rules
Subset verification reduces to universal membership where needed. Proper
inclusion combines ordinary inclusion with inequality. Function equality
reduces to compatible function interfaces and pointwise equality.
| Interface | Definition or derived builtin consequence |
|---|---|
| `A $subset B` / `B $superset A` | Dual spellings of the same inclusion. Reflexivity, structural constructor containment, one-edge membership lifting, and subset chains are supported. Componentwise Cartesian inclusions, integer range into its numeric carrier, real interval into `R`, `fn_range(f)` into its codomain, and union containment from both operands have dedicated shapes. Proper relations unfold to ordinary inclusion plus inequality. Preview: `not A $subset B` from known `not B $superset A`, and `not A $superset B` from known `not B $subset A`; binary `union(A,B) $subset union(C,D)` from componentwise subsets; `range` / `closed_range` into `N`/`N+` when the start inhabits that carrier (and into any standard set above `Z` with no extra premise). |
| `by fn_extension: f = g` | Function extensionality to ordinary `f = g` when complete input domains are proved equal (preview). Local agreement remains a bare `forall`. |
| `$injective(A,B,f)` | Definition route: members of `A` with equal images are equal. For finite `A`, injectivity gives `finite_set_size(fn_range(f)) = finite_set_size(A)`. |
| `$surjective(A,B,f)` | Definition route: each member of `B` has a preimage in `A`. A finite source makes the codomain finite and gives `finite_set_size(B) <= finite_set_size(A)`. |
| `$bijective(A,B,f)` | Definition route combines injectivity and surjectivity. A stored certificate and `y $in B` prove `exist! x A st {f(x)=y}`. For finite source and target, it preserves cardinality; it also enables finite aggregate reindexing. |
Here the definition proofs register the mapping facts, after which the
cardinality rules consume them directly:
```litex
have fn mapping_identity(x {1, 2, 3}) {1, 2, 3} = x
forall x1, x2 {1, 2, 3}:
mapping_identity(x1) = mapping_identity(x2)
=>:
x1 = mapping_identity(x1) = mapping_identity(x2) = x2
x1 = x2
by def $injective({1, 2, 3}, {1, 2, 3}, mapping_identity)
claim:
? forall y {1, 2, 3}:
exist x {1, 2, 3} st {y = mapping_identity(x)}
y = mapping_identity(y)
witness exist x {1, 2, 3} st {y = mapping_identity(x)} from y
by def $surjective({1, 2, 3}, {1, 2, 3}, mapping_identity)
by def $bijective({1, 2, 3}, {1, 2, 3}, mapping_identity)
by extension:
? fn_range(mapping_identity) = {1, 2, 3}
claim:
? forall y fn_range(mapping_identity):
y $in {1, 2, 3}
y $in {1, 2, 3}
claim:
? forall y {1, 2, 3}:
y $in fn_range(mapping_identity)
mapping_identity(y) = y
mapping_identity(y) $in fn_range(mapping_identity)
$is_finite_set({1, 2, 3})
$is_finite_set(fn_range(mapping_identity))
finite_set_size(fn_range(mapping_identity)) = finite_set_size({1, 2, 3})
```
The finite mapping rules require the exact finite-set and mapping facts; they
do not infer finiteness from a cardinality expression and do not select an
inverse function globally.
A membership goal may also use one directly known inclusion on demand. If
`x $in A` and either `A $subset B`, `B $superset A`, or
`A $in power_set(B)` is known, the verifier can prove `x $in B`. This lookup
does not itself store `x $in B` or traverse a second inclusion edge. Existing
universal-membership facts may still compose several ordinary proof steps.
This rule only answers membership goals; it does not rewrite an order goal
such as `0 < x` into membership in a positive-number set.
```litex
by def {1} $subset {1, 2}
forall B set, A power_set(B), x A:
x $in B
claim:
? forall A, B set:
A $subset B
A != B
=>:
A $proper_subset B
B $proper_superset A
by def A $proper_subset B
by def B $proper_superset A
have fn identity(x R) R = x
have fn same_identity(y R) R = y
by fn_extension:
? identity = same_identity
forall t R:
identity(t) = t = same_identity(t)
identity(t) = same_identity(t)
```
`$fn_eq` and `$fn_eq_in` are removed. The mapping predicates `$injective`,
`$surjective`, and `$bijective` may be negated, but the checker does not
automatically search for a counterexample.
### Existential and disjunctive builtin results
`exist`, `exist!`, and `or` have dedicated verifiers. They recognize exact
canonical fact shapes rather than treating an equivalent formula as an atomic
rule target.
| Existential shape | Required known information |
|---|---|
| A real comparison witness | Every non-witness operand is real. The canonical one- or two-parameter body compares the witness by `=`, `!=`, `<`, `>`, `<=`, or `>=`; the witness may occur on either side. |
| `exist x A st {x $in A}` | `$is_nonempty_set(A)`. This proves existence but does not install a global choice object. |
| Rational representations | `q $in Q`. Supported forms are an integer numerator with positive-integer denominator, an integer numerator with nonzero-integer denominator, and the reduced positive-denominator form. The reduced form may be `exist` or `exist!` and may state reducedness by `gcd(p,d)=1` or the canonical common-positive-divisor condition. |
| `exist! q Z st {a = d*q + a%d}` | `a $in Z` and `d $in N+`. Uniqueness is part of this exact Euclidean-quotient rule. |
| `exist k Z st {a=b*k}` | `a,b $in Z`, `b!=0`, and `a%b=0`. |
| `exist n N+ st {1/n < epsilon}` | `epsilon $in R+` (Archimedean reciprocal bound). |
| `exist q Q st {a1` for `exist c Z st {a=1` for the weak-endpoint form. |
| Greatest natural member | The body has the canonical membership-and-upper-bound shape, while `S` is finite, nonempty, and `S $subset N`. |
> **Preview:** exist builtins currently include (each its own
> result struct + tracer under
> [`examples/proof_nodes/exist/by_builtin_rule/`](../examples/proof_nodes/exist/by_builtin_rule/)):
> real-line comparison witness, equality witness from membership, nonempty-set
> member witness, rational integer/`Z*` ratio (`exist a Z, b Z* st {q = a / b}`),
> integer multiple from zero remainder (`exist k Z st {a = b * k}`), Archimedean
> reciprocal (`exist n N+ st {1 / n < ε}`), and real density midpoint
> (`exist r R st {a < r < b}`).
> For a ratio witness, the `Z*` denominator form records nonzeroness directly
> in the binder. The general ordered-body WD contract is described under
> [ordered assumptions](#ordered-assumptions-during-well-definedness).
> Also: closed-integer `$prime` / `not $prime` / `$coprime` / `not $coprime` by
> computation under
> [`examples/proof_nodes/atomic/by_builtin_rule/`](../examples/proof_nodes/atomic/by_builtin_rule/)
> (`prime_by_computation.lit`, …). These computation rules attach to the
> dedicated `PrimeFact` / `CoprimeFact` / `NotPrimeFact` / `NotCoprimeFact`
> families (`NormalAtomicFact` is user `$prop` only). Trust-free ByDefinition
> tracers for `$injective` / `$surjective` / `$bijective` / `$prime` /
> `$is_choice_function_for` live under
> [`examples/proof_nodes/atomic/by_definition/`](../examples/proof_nodes/atomic/by_definition/)
> (`builtin_injective.lit`, `builtin_prime.lit`, …). The choice-function tracer
> needs atomic **FnApplicationUnfold** rewrite (preview): under a finite
> `forall`, unfold top-level `f(args)` via `have fn` definitions so
> `f_choice(alpha) $in g_choice(alpha)` becomes `1 $in {1}` without first
> storing the pointwise equalities.
```litex
claim:
? forall epsilon R+:
exist n N+ st {1 / n < epsilon}
release thm real_archimedean_natural_upper_bound(1 / epsilon)
obtain bound from exist n N+ st {1 / epsilon < n}
bound $in R+
1 = (1 / epsilon) * epsilon < bound * epsilon
1 / bound < (bound * epsilon) / bound = epsilon
witness exist n N+ st {1 / n < epsilon} from bound
claim:
? forall a, b R:
a < b
=>:
exist q Q st {a < q < b}
exist r R st {a < r < b}
release thm rational_between_reals(a, b)
obtain middle from exist q Q st {a < q and q < b}
witness exist q Q st {a < q < b} from middle
witness exist r R st {a < r < b} from middle
claim:
? forall a, b R:
a < b
b - a > 1
=>:
exist c Z st {a < c < b}
floor(a) <= a
a < floor(a) + 1
floor(a) + 1 <= a + 1
a + 1 < a + (b - a) = b
witness exist c Z st {a < c < b} from floor(a) + 1
claim:
? forall a Z, d N+:
exist! q Z st {a = d * q + a % d}
claim:
? forall x, y Z:
a = d * x + a % d
a = d * y + a % d
=>:
x = y
d * x = a - a % d = d * y
x = (d * x) / d = (d * y) / d = y
witness exist! q Z st {a = d * q + a % d} from quot(a, d)
```
Outside those canonical builtin shapes, ordinary existential proof routes
still apply: cite a known existential, instantiate a known `forall`, use
`witness`, or prove an `exist` plus its generated uniqueness universal to
obtain `exist!`. A direct builtin for `exist` never upgrades an arbitrary
equivalent spelling to `exist!`.
The `or` verifier recognizes these exhaustive forms:
| Disjunction | Requirement |
|---|---|
| `P or not P` | Two exactly complementary atomic facts. |
| Real order alternatives | Real operands; complementary strict/weak pairs, trichotomy permutations, or equality plus strict order when the matching weak comparison is already known. |
| `\|x\|=x or \|x\|=(-x)` | Canonical two-branch absolute-value split. |
| Complete residues | Every canonical equality `n % k = r` for `r=0,...,k-1`, with a positive literal/canonical modulus shape. |
| Integer successor tail | Known `x,base $in Z` and `x>=base`; the branches list consecutive equalities from `base` followed by the matching strict tail. |
| `a=0 or b=0` | `a,b $in R` and known `a*b=0` (either product order). |
| `a!=0 or b!=0` | A known real square-sum nonzero fact in the supported `a^2+b^2` or `a*a+b*b` shape. |
| `not A or B` | Classical implication packaging: under a temporary local assumption `A`, the ordinary atomic verifier proves `B`. |
> **Preview:** real-line trichotomy currently matches only these
> exact branch orders (each is its own builtin, with nested proofs of
> `left $in R` and `right $in R`):
> `a = b or a < b or a > b`,
> `a < b or a = b or a > b`,
> `a > b or a = b or a < b`.
> Also ported (each its own builtin / result struct):
> `P or not P` (complementary atomics),
> `|x| = x or |x| = (-x)` (either branch order),
> `a = 0 or b = 0` when `a, b $in R` and known `a * b = 0` (either product /
> branch order),
> `n = 0 or n >= 1` for `n $in N`,
> complementary strict/weak pairs `a < b or a >= b` and `a > b or a <= b`
> (either branch order; structs `OrBuiltinLessOrGreaterEqual` /
> `OrBuiltinGreaterOrLessEqual`),
> weak-order comparability `a <= b or a >= b` (either branch order;
> `OrBuiltinWeakOrderLeOrGe`),
> equality-plus-strict covering a known weak bound
> (`a = b or a < b` from `a <= b`, and the `>` / `>=` dual;
> `OrBuiltinEqualityPlusStrictCoversWeak`),
> complete residues `n % m = 0 or … or n % m = m-1` for positive literal `m`
> (`OrBuiltinCompleteResidues`),
> integer successor tail from a known lower bound
> (`OrBuiltinIntegerSuccessorTail`),
> square-sum nonzero `a != 0 or b != 0` from known `a^2+b^2 != 0`
> (`OrBuiltinSquareSumComponentNonzero`),
> classical packaging `not A or B` under local assume-`A`-prove-`B`
> (`OrBuiltinClassicalImplication`; exactly one negative-polarity arm;
> top-level examples may use `a != 0 or …` when `not $p(…)` cannot start a
> statement),
> and integer discrete split `x <= n or x >= n + 1` (or predecessor dual;
> `OrBuiltinIntegerDiscreteSplit`).
> One `.lit` per rule:
> [`examples/proof_nodes/or/by_builtin_rule/`](../examples/proof_nodes/or/by_builtin_rule/).
```litex
forall a, b R:
a * b = 0
=>:
a = 0 or b = 0
forall a, b R:
a <= b
=>:
a = b or a < b
forall x R:
|x| = x or |x| = (-x)
```
Branch order is flexible only where the matcher explicitly treats it as a
permutation. Adding unrelated branches, changing the bound pattern, or hiding
the operands behind a user predicate can make the direct builtin route
soft-fails; use an ordinary theorem or proof block for that presentation.
## Builtin Inference
After an accepted or trusted fact is stored, builtin inference may add routine
consequences to the same environment. These consequences become ordinary
known information for later statements.
Inference runs once for an accepted seed. Each named rule guarantees the
formation and truth of its direct consequences and stores them without another
WD or inference pass. Genuine applicability conditions, such as a nonzero
factor for multiplication cancellation, remain checked and recorded.
Temporary binder facts used while checking these conditions also store only.
An explicit later statement may reuse that consequence as a new inference seed.
This separates routine publication from recursively expanding every new fact.
For example, if `outer` defines `inner`, storing `$outer(value)` may publish
`$inner(value)`. It does not also publish all of `inner`'s defining clauses.
Writing `$inner(value)` as the next checked statement requests that next step.
See the [strict one-step tracer](../examples/infer/atomic/one_step_store_only.lit).
### Verification versus inference
```litex
have n N
0 <= n
```
The `have` statement stores `n $in N` and eagerly infers `0 <= n`, so the
second line succeeds as a known fact.
Inference does not prove an arbitrary desired consequence:
```text
have n N
n = 0
```
The equality still soft-fails.
### Facts that trigger inference
Most triggers are atomic facts. A few larger shapes have explicit behavior.
| Stored fact | Typical inferred information |
|---|---|
| Equality | Numeric values, simple linear solved values, tuple/cart/set-builder/sequence/function structure, and positive-real membership transported from a known power side. Literal `u-v=0` ⇒ `u=v` is verify-time `EqualFromKnownDifferenceZero`. |
| Scalar arithmetic equality with a direct common operand | Cancel a common addend/minuend/subtrahend; cancel a certified nonzero common factor, denominator or numerator. Division retains its denominator nonzero conditions. No expansion, reassociation or alias matching. |
| `by fn_extension` success | Ordinary object equality `f = g`, so known-equality congruence can use it. |
| Positive concrete or builtin predicate | Instantiated parameter-type and defining clauses. Proper inclusion exposes inclusion plus inequality; `$prime` exposes its lower bound and trial-divisor universal; `$coprime(a,b)` exposes `a != 0 or b != 0` and `gcd(a,b)=1`; `$dvd(x,y)` exposes `x % y = 0` and an integer multiple witness; mapping properties expose their exact definitions. Abstract predicates have no clauses to expose. |
| Membership | Constructor-specific carrier, shape, bound, component, disjunction, or existential information listed below. |
| Weak lower bound `b <= n` or `n >= b` | Stores `n $in N` when an integer certificate for `n` and a nonnegative certificate for `b` are available. These premise checks inherit the caller's ceiling and use at most KnownSpecialProperty; they do not invoke strategy or forall search. Weak bounds alone do not imply `N+` or nonzero. |
| Cartesian membership | Exact finite input domain and the ordinary membership of each coordinate in its factor. No constructor dimension is inferred for the set. |
| Subset or superset | One fresh universal membership consequence in the corresponding direction. A builder on the subset side skips this eager universal because builder membership already exposes its domain and filters. |
| Proper inclusion | Through its builtin definition: ordinary inclusion and set inequality. |
| Order against a resolved concrete bound | *(verify)* Selected sign spelling and mul-by-`(-1)` flip via `OrderSignFromPositive/NegativeLiteralBound` / `OrderFlipMulMinusOne` — not eager infer. |
| `exist!` | A universal saying any two complete witness tuples satisfying the body are componentwise equal. |
| `not exist` | The corresponding universal De Morgan negation when the body shape is supported. |
| `not forall` | An existential counterexample: domain facts plus negated conclusions, all quantifier-free by syntax. |
| Equality/order chain | Atomic consequences from its finite transitive closure; those consequences are stored without another infer pass. |
An outer `and`, `or`, or `forall` does not receive the same general extra
inference pass merely because it was stored. Their locally processed atomic
parts may still contribute information when the relevant statement form
stores or assumes them.
### Equality and structural inference
Equality inference remembers usable values and shapes.
```litex
have x R = 2
x + 1 = 3
have t cart(R, Z) = (1, 2)
t(1) = 1
t(2) = 2
t $in finite_seq(R, 2)
have s set = cart(R, R)
(1, 2) $in s
```
Typical consequences include:
- scalar `a+k=b+k` publishes `a=b`; `a*k=b*k` does so only when `k!=0`
is already available at the restricted inference stage;
- `u - v = 0` gives `u = v` when meaningful *(verify-time
`EqualFromKnownDifferenceZero`, not eager infer)*;
- `by fn_extension` stores the ordinary equality `f = g`;
- an equality to a closed numeric expression (decimal literals under
`+ - * / ^ abs min max floor ceil sign`, integer-domain `% quot gcd lcm !`,
and foldable `sqrt` / `log`) enables later numeric substitution;
- supported simple linear equalities record a solved value;
- equality to a tuple or product is ordinary object equality; a directly indexed
tuple value or exact-object membership supplies its complete function domain
and coordinates, without traversing an alias chain;
- equality to an anonymous function records the
corresponding structural information;
- a known concrete `prop` call may expose instantiated definition clauses.
A stored strict lower bound `b < x` (or `x > b`) also publishes `0 < x`
when `0 <= b` has an available stored/structural or closed numeric proof at
the restricted inference stage. For example, `1 < x` supplies the positivity
needed for `log(2, x)` WD before a proof body begins. Negative or unknown
bounds, and a nonstrict zero bound, do not supply positivity. The inference
retains its strict source and bound proof without enabling deeper search.
See the [strict-bound tracer](../examples/infer/atomic/strict_lower_bound_positive.lit).
A checked nonzero real square also transports positive membership to its
named result:
```litex
have base R*
have square R = base^2
square $in R+
```
The base may be negative. The declaration reuses the existing nonzero-real
even-power rule before trying the positive-base route. Zero and complex bases
do not satisfy that rule. Source WD and explicit proof checking retain their
ordinary permissions. See the [square tracer](../examples/infer/equal/nonzero_real_square.lit).
Direct scalar cancellation works across the standard numeric carriers,
including complex numbers:
| Stored equality | Required nonzero certificates | Published equality |
| --- | --- | --- |
| `a+k=b+k` | None | `a=b` |
| `a-k=b-k` | None | `a=b` |
| `k-a=k-b` | None | `a=b` |
| `a*k=b*k` | `k!=0` | `a=b` |
| `a/k=b/k` | `k!=0` | `a=b` |
| `k/a=k/b` | `k!=0`, `a!=0`, `b!=0` | `a=b` |
Addition and multiplication allow all four positions of the common operand.
Subtraction and division require the common operand in the same position;
`a-k=k-b` and `a/k=k/b` do not imply `a=b`.
```litex
forall a, b, k R:
k != 0
a * k = b * k
=>:
a = b
```
The product equality triggers inference; its source and the operand C-membership
and nonzero proofs are retained. Premise checks inherit the caller's ceiling
and use at most KnownSpecialProperty, without strategy or forall search.
`k*a=b*k` is also supported. Matching requires a directly identical common
operand; the rule does not expand or reassociate expressions, or chase aliases.
Derived equality retains ordinary WD and storage, without another cancellation
pass. Publish the checked intermediate equality explicitly to request its next
cancellation. An already-known remaining equality is skipped.
Zero or an unavailable required nonzero proof does not cancel; in particular,
`0/a=0/b` supplies no equality of `a` and `b`. A quotient with an unproved or
zero denominator fails WD before its source equality can be stored. A nonzero fact arriving
after the product equality does not retrigger it; the equality can be restated
once the certificate is present. These inference consequences are not yet
replayed by the Lean compiler; a citation to one fails at `FactId/Producer`.
See the [additive tracer](../examples/infer/equal/additive_cancellation.lit),
[subtractive tracer](../examples/infer/equal/subtractive_cancellation.lit),
[nonzero-factor tracer](../examples/infer/equal/nonzero_factor_cancellation.lit),
[common-denominator tracer](../examples/infer/equal/common_denominator_cancellation.lit)
and [nonzero-numerator tracer](../examples/infer/equal/nonzero_numerator_cancellation.lit).
Inference is directional bookkeeping, not a license to solve any equation:
```text
have x R
x^2 = 4
x = 2
```
The last line soft-fails; the stored square equation has two real solutions.
### Membership inference
Membership inference exposes the ordinary information carried by a set.
```litex
have a {1, 2}
a = 1 or a = 2
have i1 Z = 3
i1 $in range(2, 6)
i1 $in Z
2 <= i1 < 6
have u cart(R, Z)
u(1) $in R
u(2) $in Z
```
Main families are:
| Membership | Inferred information |
|---|---|
| `x $in N` | `0 <= x` (and `x >= 0` via OrderDual) |
| Positive numeric subsets `N+` / `Q+` / `R+` | `0 < x` and `0 <= x` |
| Negative numeric subsets `Q-` / `Z-` / `R-` | `x < 0` and `x <= 0` |
| Nonzero numeric subsets `Q*` / `Z*` / `R*` / `C*` | `x != 0` |
| `x $in {a}` / `x $in {a, b, ...}` | Atomic equality for a singleton; otherwise the finite equality disjunction. Empty display adds nothing. |
| `x $in union(A,B)` | `x $in A or x $in B` |
| `x $in intersect(A,B)` | Both component memberships |
| `x $in set_minus(A,B)` | `x $in A` and `not x $in B`; a singleton right side also yields the matching disequality |
| `x $in family_union(F)` | `exist A F st {x $in A}` |
| `x $in index_union(I,X,A)` | `x $in X` and `exist i I st {x $in A(i)}` |
| `x $in index_intersect(I,X,A)` | `x $in X` and `forall i I: x $in A(i)` |
| `y $in Img` after `have by replacement_axiom: Img from prop P, set A` | Use the stored elimination forall for `Img` (existential witness in `A` related by `$P`) |
| `y $in fn_range(f)` | Membership in the defined codomain plus an existential preimage carrying every instantiated domain condition and `y=f(args)` |
| `A $in power_set(B)` | `A $subset B` |
| `x $in cart(A, B, ...)` | Exact complete finite-function domain and coordinate memberships; no retired shape/dimension predicates |
| `f $in index_cart(I,S,g)` | `f $in fn(index I) family_union(S)`, `$is_choice_function_for(I,S,g,f)`, and its pointwise factor-membership universal |
| `$is_choice_function_for(I,S,g,f)` | Its existing definition `forall alpha I: f(alpha) $in g(alpha)`; ordinary known-forall instantiation then gives each fiber membership |
| `x $in range(a, b)` | Integer membership and half-open bounds |
| `x $in closed_range(a, b)` | Integer membership and closed bounds |
| `x` in a real interval | Real membership and endpoint bounds |
| `x $in {y S: filters}` | `x $in S` and instantiated filters |
| Function/sequence type membership | A callable function interface; sequence carriers correspond to function spaces. |
| `x $in &Struct<...>` | No eager public consequences. The membership verifier checks the instantiated tuple carrier and `<=>:` conditions internally; use a definition-owned `release struct def x` to release one layer. |
Membership inference also transports through concrete equal set
representatives and through one checked set-valued function or template
definition. More deeply hidden membership facts may need to be stated and
verified explicitly.
Membership in a broad set does not imply a narrower property:
```text
have x R
x > 0
```
The second line soft-fails; `R` contains positive, zero, and negative values.
### Subset, superset, and order inference
```litex
by def {1} $subset {1, 2}
forall x {1}:
x $in {1, 2}
```
Subset and superset facts retain their reusable universal-membership
interface. A membership goal may use one directly known inclusion, but Litex
does not automatically materialize every lifted membership or compute an
unbounded transitive subset closure.
Proper subset additionally gives subset and inequality; proper superset is
dual. Negated proper relations do not select either branch of their
disjunctive meaning.
Selected comparisons with concrete bounds may produce sign facts, for example
`2 <= x` can imply `0 < x`. Do not depend on a particular inferred spelling
when a direct sign statement is important to the proof; write the sign fact
explicitly and let the verifier check it.
### Reading inference output
Detailed output may show inference under `effects` or an environment delta. A
later success can therefore depend on information not repeated in source text.
When auditing a proof, distinguish:
1. the fact the user wrote;
2. the route that verified it;
3. the consequences inference stored afterward.
This distinction is also part of the trusted boundary: builtin inference rules
are checker code, not source-level theorems silently imported from a library.
## Execution and extraction
After the mathematical interfaces and native rules, this chapter describes
the executable path: `algo` supplies a checked implementation, `eval` checks
and publishes an exact result, and extraction emits a supported Python/C
program from explicitly selected source. The source proof and the target
program have the boundaries stated below.
#### Checked algorithm execution
> **Preview:** the surface is `algo f(x R) R by cases:` or
> `algo f(n N) N by induc n from 0:` (no separate `have fn` required).
> Execution defines the function (same checks as `have fn … by cases` / `by induc`)
> and stores the executable presentation.
> `eval` first checks the source expression's well-definedness, including each
> function argument domain and domain condition. It then substitutes
> `known_closed_numeric_equal` representatives and
> recursively evaluates closed numeric expressions, checked named/literal
> function bodies, finite-function coordinates, and stored algorithms
> (case match → return expr → evaluate again). For `let p=(1,2,3)`,
> `eval p(2)` computes `2` and stores `p(2)=2` without an earlier assertion.
> Nested Cartesian tuple values may continue as functions: after
> `have outer cart(cart(R,R),R)=((1,2),3)`, `eval outer(1)(2)` computes `2`.
> Every call checks its own domain. `outer(2)(1)` and `p(4)` fail WD;
> a carrier membership alone supplies no concrete value to evaluate.
> Each executed algorithm step must also verify its defining function equation
> at the normalized arguments. The exact computation and these checked equations
> establish `expr = evaluated_object`; both sides pass WD before the equality is
> stored and inferred in the current scope. A failure discards the statement's
> temporary facts. Recursive execution keeps its depth/cycle limits and checks
> each recorded equation independently. Normal output lists the stored equality;
> Detailed output retains its FactId, WD, definition evidence and store result.
>
> Finite sums/products evaluate through checked function applications. Nested
> aggregates share a total allowance of 1024 terms; bounds and values use exact
> arithmetic. Named function equations and finite list/range sets are supported.
> An unavailable enumeration or exhausted allowance fails. See
> `examples/stmt_nodes/command/aggregate_eval.lit`.
> Tracers: `examples/stmt_nodes/definition/def_algo.lit`,
> `examples/stmt_nodes/command/eval.lit`.
> Result-publication tracer: `examples/stmt_nodes/command/eval_store_result.lit`.
>
```litex
algo nonzero_flag(x R) R by cases:
case x = 0: 0
case x != 0: 1
eval nonzero_flag(0) + 1
nonzero_flag(0) + 1 = 1
```
**Entry:** [S21](#s21-executable-functions-by-cases).
### Extracting a proved numerical step to Python or C (experimental)
File extraction uses explicit marker pairs. A whole trimmed line containing
`# [-extract]` starts a block at the following line; a whole trimmed line
containing `# [end of -extract]` ends it. Multiple blocks are concatenated in
source order and only that self-contained virtual source is verified and sent
to the Python or C backend. The surrounding file and any configured project
prefix are not loaded by extraction. Missing, nested, unmatched, or unclosed
markers are errors rather than a request to process the whole file. Use an
ordinary `litex -f` command separately to check all surrounding mathematics.
This lets a checked mathematical update and a small executable artifact live
in the same source. The numerical-analysis showcase applies Newton's method to
`x^2 - 2 = 0`, starting from `x_0 = 1`. With
`g_n = |x_n^2 - 2|`, the full checked source proves
```text
g_(n + 1) <= g_n^2 / 4
g_n <= 4 * (1 / 4)^(2^n)
g_2 <= 1 / 64
```
The convergence statements are about the recursive sequence
`sqrt_two_newton_iterate` itself. Its mathematical update has the precise
positive-real interface needed by the proof. A separate total wrapper gives
the experimental extractor its currently supported `fn(x R) R` interface, and
the final claim connects that wrapper back to the proved update.
The current executable definition is copied from the complete source. Its
marker block is self-contained; the full source supplies the positive-return
proof and the recursive convergence development described above.
```litex
# [-extract]
algo newton_sqrt_two_step(x R) R by cases:
case x = 0: 1
case x != 0: (x + 2 / x) / 2
# [end of -extract]
newton_sqrt_two_step(1) = 3 / 2
```
The complete proof and the same executable definition live in
`showcases/math_concepts_in_litex/13_numerical_analysis_in_nutshell/main.lit`.
Verify the full file, then extract the selected executable block with:
```sh
litex -f showcases/math_concepts_in_litex/13_numerical_analysis_in_nutshell/main.lit
litex -extractpython -f showcases/math_concepts_in_litex/13_numerical_analysis_in_nutshell/main.lit
litex -extractc -f showcases/math_concepts_in_litex/13_numerical_analysis_in_nutshell/main.lit
```
The command returns an `extracted_code` artifact whose `content` is:
```python
def newton_sqrt_two_step(x):
if x == 0.0:
return 1.0
elif x != 0.0:
return ((x + (2.0 / x)) / 2.0)
raise AssertionError("unreachable verified Litex cases")
```
The C artifact contains the corresponding C99 fragment:
```c
#include
double newton_sqrt_two_step(double x) {
if (x == 0.0) {
return 1.0;
}
else if (x != 0.0) {
return ((x + (2.0 / x)) / 2.0);
}
abort();
}
```
Do not use Litex names that collide with C library symbols the backend may
emit or include, such as `abort`, `exit`, `malloc`, or names from `` /
``. The extractor does not rename or reject those collisions; choose
user-facing identifiers instead (for example `user_abort`).
The host loop repeats the verified single step in the same pattern as the
recursive `sqrt_two_newton_iterate` definition:
```python
x = 1.0
for _ in range(2):
x = newton_sqrt_two_step(x)
# x == 1.4166666666666665
# abs(x * x - 2.0) == 0.006944444444444198 < 1.0 / 64.0
```
The agreement check matters: changing the nonzero implementation branch, for
example by dividing by `3` instead of `2`, is rejected because it no longer
matches the checked function. The positive-real convergence development also
continues to constrain the mathematical formula rather than merely its Python
spelling.
This path is experimental and deliberately narrower than the Litex language.
Although the exact recursive iterate is visible above, the current extractor
emits only the supported `fn(x R) R` step, not the `N`-indexed recursion or any
proof. The `x = 0` restart is an explicit totalization policy for extraction,
not Newton's ordinary formula; the proved trajectory starts positive and stays
positive, so it does not take that branch. Finally, the Litex inequalities are
exact-real facts, while generated Python and C use IEEE-754 floating point.
They do not prove target behavior for rounding, overflow, compiler choices, or
special values such as NaN; Python NaN reaches the defensive assertion because
it satisfies neither generated branch.
### Aggregate evaluation and published results
`clear` is not a utility statement or a reserved word; it can be used as an
ordinary definition name.
Decimal literals normalize exactly: `2.400 = 2.4`, `2.000 = 2`, and
`-0.000 = 0`. Their unequal counterparts are rejected. The reserved imaginary
unit has builtin nonzero evidence in both orientations; `1 / i = -i` consumes
that evidence for division WD and guarded complex normalization.
```litex
sum(1, 3, fn(k Z) Z {k}) = 6
product(1, 3, fn(k Z) Z {k}) = 6
sum(1, 3, fn(k Z) Q {1 / 3}) = 1
eval sum(1, 3, fn(k Z) Z {k})
```
`eval` displays the exact value and stores the checked equality between the
original expression and that value. Later assertions can cite this fact;
direct equality search retains its own existing permissions. Both reject invalid
argument domains, missing function domain conditions and reversed integer
ranges. Empty finite-set sums/products are 0/1. A finite set without a known
enumeration supports symbolic laws but does not automatically supply a number.
Detailed output retains each argument, checked application, function equation,
value and running fold. See the runnable
[aggregate calculation](../examples/proof_nodes/equal/by_builtin_rule/aggregate_calculation.lit)
and [symbolic identities](../examples/proof_nodes/equal/by_builtin_rule/aggregate_identities.lit).
## Removed and renamed public forms
Retained AST payloads are not evidence that a public spelling is supported.
The following rejected spellings were checked separately; the replacement
describes a supported route, not a promise of automatic source migration.
| Old form | Current direction | Rejection evidence |
|---|---|---|
| `cart_dim( cart(R,Z) ) = 2` | Use exact finite input-domain and Cartesian membership contracts. | `K01`: parser rejection |
| `tuple_dim((1,2)) = 2` | Use complete finite_seq/domain evidence. | `K02`: parser rejection |
| `proj(cart(R,Z),1) = R` | Use the actual complete-domain and coordinate membership statements. | `K03`: parser rejection |
| `p[1] = 1` | Name a callable finite tuple and use p(1). | `K04`: parser rejection |
| `$is_tuple((1,2))` | Use ordinary finite-sequence or Cartesian membership. | `K05`: parser rejection |
| `$is_cart(cart(R,Z))` | Use ordinary set equality or Cartesian membership. | `K06`: parser rejection |
| `$fn_eq(1,1)` | Use function extensionality and ordinary equality. | `K07`: parser rejection |
| `$fn_eq_in(1,1,1)` | Use pointwise forall for local agreement. | `K08`: parser rejection |
| `import "x"` | Declare dependencies in litex.config. | `K09`: parser rejection |
| `have tuple p = (1,2)` | Use have fn for indexed data or a typed exact finite-function value. | `K10`: parser rejection |
| `have by preimage: x from 1 $in {1}` | Use have by fn_preimage with the actual function image. | `K11`: parser rejection |
`have cart`, `have seq`, `have finite_seq` and `have matrix` share the
removed indexed-data declaration dispatch with `have tuple`. Current source
also rejects `setting`, old strategy-control statements and old
`by enumerate range` / `by enumerate closed_range` spellings; finite range
membership expansion uses `expand`. `use` and `stop` can be ordinary names.
Do not infer a source import/export statement from old documentation: package
dependencies and ordered exports live in `litex.config`.
Supported alternatives such as bare `by thm`, inline universals, `Z+` for
`N+`, and documented Unicode aliases are different from removed forms.
New source examples use the recommended ASCII spellings and multiline
universals. Cartesian `×` is not arithmetic multiplication `*`; proper and
non-strict inclusion have distinct spellings.
## Verification and coverage
All dictionary categories have stable entries and source ownership. This
edition distinguishes 51 public statement forms, 93 active object leaves,
20 dedicated builtin atomic families (with their negative counterparts), and
two native certificate predicates. Public aliases share the relevant entry;
the witness/unique-witness distinction is counted as separate statement forms.
The positive runnable fences are self-contained. Most run in strict mode;
assumption demonstrations run in ordinary mode and are explicitly rejected
under strict mode. Expected negative examples are tested separately and skipped
by the positive Markdown collector. The contextual two-line reciprocal fragment
is verified inside the full R01 example, not executed without its binders.
Acceptance uses current-source release CLI Normal JSON: exit 0, `kind: run`,
`run_result: "success"`, `session_terminated: false`, and `termination: null`.
Old `-compact`, `-runner`, `-before`,
`-isolated` and literal `try:` recipes do not apply to this build. Prototype
boundaries and expected rejections are labelled in the entries; a failed
search is never counted as a proof of the opposite fact.
Entries and examples describe covered rule shapes, not every instantiated equality, kernel rule or imported theorem. Historical verification results do not establish a fresh run of every example on the current version.
The current Normal `statement` rendering of expression-defined functions
omits the written return carrier. Original fenced source is retained for
interpretation of return-bound failures. Source facts, execution evidence and
user assumptions remain distinct throughout the entries.
## Design context and references
Litex brings familiar programming-language ideas into a language for checked
mathematics. The references below connect particular design choices to their
sources. Design influences reflect the author's stated inspirations;
mathematical sources guide definitions and foundations; related work places
Litex alongside earlier approaches to readable formal mathematics.
### Language design influences
| Reference | Connection to Litex |
|---|---|
| [Python](https://docs.python.org/3/reference/lexical_analysis.html#indentation) and [Lisp](https://www.lispworks.com/documentation/HyperSpec/Body/02_a.htm) | Litex's syntax draws on both languages. Python is a reference for readable indentation-based blocks; Lisp is a reference for simplicity and compositional expression. Lisp's elegance is an aspiration for the language as a whole. |
| [Go](https://go.dev/ref/spec) | Go influenced Litex's syntax and its preference for a small, consistent set of mechanisms. Inspired by Go's emphasis on simplicity and predictable composition, Litex aims to provide one sufficiently good way to serve each purpose and keep it as the single mechanism wherever possible. This reduces competing choices and helps the system remain consistent. Rob Pike's [Simplicity is Complicated](https://go.dev/talks/2015/simplicity-is-complicated.slide) discusses the value of fewer ways to do things and features that interact predictably. |
| [Lua](https://www.lua.org/manual/5.4/manual.html#pdf-require) | Lua's module-loading approach influenced the import system. Litex declares dependencies in its project manifest; see [project organization](#project-organization) for its loading and naming contracts. |
| Mathematical textbooks | Textbooks inspired both knowledge ordering and theorem/proof organization. Later material cites definitions and results established earlier; Litex similarly gives later statements access to accepted earlier context and runs project exports in declared order. The mathematical idea of stating a theorem and proving it inspired `claim` and `thm`; see [basic proof-writing decisions](#basic-decisions-before-writing-a-proof). |
| [C++ templates](https://eel.is/c++draft/temp) and [Go interfaces](https://go.dev/ref/spec#Interface_types) | C++ inspired parameterization and instantiation in Litex's `template` interfaces: one definition can produce objects or functions for different arguments. Go interfaces also influenced the idea that template parameters must satisfy specified properties. The actual mathematical contract is described under [template interfaces](#template-interfaces). |
| [C/C++ structs](https://eel.is/c++draft/class) | Named fields grouped into a structured value inspired Litex's `struct` interface. Litex applies that organization to mathematical objects, with the conditions and facts described under [advanced interface details](#advanced-interface-details). |
| [JavaScript anonymous functions](https://tc39.es/ecma262/multipage/ecmascript-language-functions-and-classes.html#sec-arrow-function-definitions) | JavaScript inspired the ability to write a function directly as an expression, without first giving it a name. Litex's anonymous functions carry mathematical domains and well-definedness obligations; see [O80](#o80-anonymous-functions). |
| Ctrl+F, [grep](https://www.gnu.org/software/grep/manual/) and [sed](https://www.gnu.org/software/sed/manual/) | Familiar search and substitution tools inspired the proof-search model: find an applicable fact in the available context, match its structure, and reuse it with permitted substitutions. The analogy concerns the workflow; Litex searches structured mathematical facts and checks the relevant conditions. See [verification rules](#builtin-verification-rules) and [inference](#builtin-inference). |
| [TeX](https://www-cs-faculty.stanford.edu/~knuth/abcde.html) | TeX supplies notation for many familiar mathematical objects. That vocabulary strongly influenced the selection of Litex's builtin objects: the aim is to cover much of the everyday mathematics that already has familiar TeX notation. Litex gives those objects domains, definitions and checking rules; their current coverage is recorded in the [object dictionary](#object-dictionary). |
Litex aims for Lisp's elegance and TeX's broad practical usefulness: a language
that people across mathematics can use routinely. These aspirations guide
language design and everyday usability.
The implementation is written in [Rust](https://rust-lang.org/); the
implementation language and the influences on Litex's surface language have
different roles.
### Interpreter architecture references
Litex's interpreter architecture draws on the following books. The design aim
is a straightforward implementation whose path from source text to results is
easy to follow: tokenize input, parse a statement, dispatch its execution, check
its obligations, and record accepted information. The [system pipeline](#system-pipeline)
describes the current components and their responsibilities.
- Harold Abelson and Gerald Jay Sussman, with Julie Sussman,
[*Structure and Interpretation of Computer Programs* (SICP)](https://mitpress.mit.edu/9780262510875/structure-and-interpretation-of-computer-programs/),
second edition, MIT Press, 1996. Its treatment of abstraction, environments
and evaluators provides a conceptual reference for organizing an interpreter
from understandable parts; [Chapter 4](https://mitp-content-server.mit.edu/books/content/sectbyfn/books_pres_0/6515/sicp.zip/full-text/book/book-Z-H-26.html)
develops an evaluator explicitly.
- Thorsten Ball, [*Writing An Interpreter In Go*](https://interpreterbook.com/).
Its step-by-step construction of the Monkey interpreter connects tokens,
parsing, an abstract syntax tree, evaluation and a REPL. It is a practical
reference for making the source-to-result path visible in working code.
- Alfred V. Aho and Jeffrey D. Ullman, *Foundations of Computer Science with C*,
W. H. Freeman/Computer Science Press, 1995
([author's bibliography](https://www.cs.columbia.edu/~aho/books.html)). This is
the C edition of *Foundations of Computer Science*, originally published in
1992. It supplies foundational computer-science background for the architecture.
- Robert Nystrom, [*Crafting Interpreters*](https://craftinginterpreters.com/).
Its [tree-walk interpreter](https://craftinginterpreters.com/contents.html)
presents scanning, parsing and evaluation as explicit implementation stages;
the book also develops a bytecode virtual machine. The relevant architectural
reference here is its clear explanation of how the interpreter's parts fit
together.
### Mathematical sources
The presentation of Litex's set-theoretic foundations draws on Terence Tao's
[*Analysis I*](https://terrytao.wordpress.com/books/analysis-i/) and Hao Zhaokuan
and Yang Yue's *Set Theory: An Exploration of the Concept of Infinity*
(*集合论:对无穷概念的探索*, Fudan University Press, 2014; listed on
[Hao's university page](https://philosophy.fudan.edu.cn/64/96/c14253a222358/page.htm)).
They are references for mathematical definitions, constructions and foundational
exposition. See [trust boundary](#trust-boundary) for Litex's implemented
foundation and checking assumptions.
### Related work in formal mathematics
[Mizar](https://mizar.uwb.edu.pl/language/) is important earlier work on expressing
mathematical writing as machine-checkable text. Its language is derived from
mathematical vernacular, making it a particularly relevant comparison for
Litex's readable, fact-oriented interface.
[Isabelle/Isar](https://isabelle.in.tum.de/Isar/) provides a structured proof
language intended to be readable by humans and checked by a machine. Its
organization of assumptions, intermediate conclusions and proof structure is
relevant to the same readability problem that Litex addresses. Both Mizar and
Isar are related work on readable checked mathematics.
[Lean](https://lean-lang.org/doc/reference/latest/Elaboration-and-Compilation/)
provides a reference for kernel-checked proofs and a target for Litex's supported
proof translations. Generating Lean output and passing real Lean kernel checking
are separate gates. Litex's own checker retains its own trusted boundary; see
[trust boundary](#trust-boundary) for the current preview scope.
## Appendix
### Preview labels
A heading marked **preview** describes an evolving interface. Runnable examples
and explicit migration notes determine its current checked boundary; the label
alone does not certify every example or mathematically equivalent spelling. The label stays
beside the canonical explanation instead of being repeated in a separate
inventory that can drift out of sync.
### Trust and strict mode
| Source of information | Normal run | `-strict` run |
|---|---|---|
| Checked source statement | Verified | Verified |
| `trust`, `trust have` | Explicit assumptions | Rejected when executed |
| `abstract_prop` | Uninterpreted predicate interface | Allowed; no instance is proved |
| `axiom` | Interface checked; truth assumed | Rejected when executed |
| Named set-theoretic releases | Obligations checked; foundation assumed | Still accepted |
| Imports | Cold execution or an import knowledge-base cache hit | Source exports are re-executed with the strict policy; cache hits are bypassed |
The strict check lives in `src/execute/exec_stmt.rs`, including inspection of
a template's `trust have` body. Nested proof statements use the same entry.
It rejects executed `trust`, `trust have`, and user `axiom` before their facts
or definitions are stored. Strict imports bypass cached environments in
`src/run_module/import_kb.rs` and re-execute dependency sources under the same
policy. Earlier root exports are executed in project order. The checker,
builtin rules and named foundation releases remain part of the trusted basis.
### Trust boundary
Litex is not a replacement for Lean, Coq, or Isabelle. Its checker, builtin
objects, builtin verification and inference rules, imported assumptions, and
every explicit `trust` or `axiom` are relevant to the trusted boundary.
`trust` records an assumption; it is not a proof. A successful Litex check is
therefore a claim relative to the checker, its builtin rules, and any visible
trusted inputs. Use `-strict` when a run must reject user `trust`, `trust have`,
and `axiom`, including template trust-have and assumptions inside local proof
bodies or imported dependencies. Pure `abstract_prop` declarations are allowed:
they introduce a predicate signature, not a proved instance or a definition
body. Named set-theoretic releases remain part of the fixed mathematical
foundation and are allowed under strict mode.
Lean rechecking is a separate preview direction. `litex -lean -f `
replays supported typed verification results from a standalone source file.
The [semantic interface](../lean/Litex.lean) and
[generated example pairs](../lean/examples/) document supported routes;
generation and real Lean kernel checking remain separate gates. Unsupported
proof routes fail compilation rather than becoming assumptions. See the
[compiler guide](Litex_To_Lean_Compiler_Guide.md) for maintained examples and the
[CLI boundary](cli.md#lean-compiler-boundary) for invocation restrictions.
### Documentation and test contract
Every unskipped `litex` fenced block in this manual is intended to be
self-contained and is run by
`python3 tests/tooling/run_docs_markdown_files.py` (after
`cargo build --release`). A skipped
`litex` block carries an adjacent `litex:skip-test` marker: it is an
illustration, an expected rejection, or an example still awaiting migration; a `text` block is either another deliberately invalid example, a
non-executable shape, or an output sketch. The surrounding paragraph states
the intended reading and, for failures, whether checking soft-fails or
reports an `error` presentation of Failed.
The language implementation is the final source of truth when this manual and
the runner disagree. Such disagreement is a documentation or diagnostic bug
to fix, not a reason to reinterpret a failed example silently.
### Maintenance ownership
Keep a spelling's mathematical contract in its S/O/F/C entry. Extend native
rule sections for additional law shapes, not another copy of that definition.
Use P entries for a failed/working pair and R entries for complete recommended
formulations. Keep project and output contracts in their dedicated guide sections.
When code changes, update the relevant entry and affected examples together.
## LaTeX conversion (preview)
The parse-only command `litex -latex -lang zh -f example.lit` turns current
Litex statements into mathematical LaTeX with localized prose. All ten CLI
languages are supported. Add `-document` for a complete XeLaTeX article with
a language-specific font setup; the default is an embeddable fragment.
Conversion preserves the supplied mathematical statement and proof structure;
it does not check truth, perform `eval`, or fill in missing proofs. Thus `1 = 2`
can convert, and `eval 1 + 1` becomes a request to calculate rather than a computed
equality. Explicit assumptions, axioms and sketches keep their labels. The JSON
artifact has stable keys, a LaTeX `content` string and `verified: false`.
Project exports retain manifest order. Dependency configs provide module names,
without executing imported source. See [CLI conversion](cli.md#latex-conversion-preview)
and the [compiler guide](../src/compile_to_latex/README.md) for the complete
input, typography and error contracts.
The zero-base positive-real rule records the checked exponent membership as `ZeroToPositiveRealPower` evidence. `0^0=1` remains unchanged; nonpositive or untyped exponents do not use this rule. See [the strict tracer](../examples/proof_nodes/equal/by_builtin_rule/zero_to_positive_real_power.lit). This rule currently has no Lean replay; the compiler rejects its builtin evidence.