Statement/showable/process/algorithm checking: checkStatement/checkBlock/checkBranches/
checkPlusCalDeclarations/checkProcess/checkAlgorithm, turning a CorePlusCal.Algorithm (Option Typ) (CoreTLAPlus.Expression (Option Typ)) (α still the optional, user-written
@type annotation) into a TypedPlusCal.Algorithm.
A few notable points:
[Multicast]'se1premise is checked againstSet(τ)for the channel's own declared domainτ:e1is the set of recipients, and each is what indexes the channel.- Algorithm-level
variables(Algorithm.globalState.variables) are checked the same way as a process's own local variables (checkVariablesbelow, shared by both). - A
with-bound variable's/variablesentry's optional annotation is checked against when present, otherwise inferred from the initializer. Amulticastrecipient's is not consulted at all — see[Multicast]below. [Goto]performs no type check at all — label existence is the well-formedness pass's job.- A
receive/send's channel reference, and awith/variablesentry's Ref-typed destination, are checked viainferRefbelow, notElaborator/Expressions.lean'sinferExpr/checkExpr:CorePlusCal.Refis a distinct type fromCoreTLAPlus.Expression, needing its own small synthesis judgment — aΓ-lookup onnamefollowed byElaborator/Expressions.lean's ownindexIntoonce per bracket group. - A channel/FIFO declaration's Γ-binding domain follows the same
n = 1/n > 1reconciliation as function definitions (Elaborator/Declarations.lean):m = 1binds a channel's own Γ-type at plainAddress → Channel(τ);m > 1needs the tupled⟨Address,...⟩ → Channel(τ)domain.
Equations
Instances For
Equations
Instances For
Equations
Instances For
Instances For
Equations
Instances For
Equations
Instances For
Equations
Instances For
The showable predicate, used by print: Int/Bool/Str/Address atomic;
Function/Set/Seq/Tuple/Record recursively (a Function is showable when both its domain
and range are). Operator/Channel/Const/rigid type variables, and anything containing them,
are not showable. Pure and non-monadic — callers must resolve τ's metavariables first
(instantiateMVars, at the point of use) so .mvar _ => false only fires on a
genuinely unresolved metavariable, not one already pinned to something showable. partial: nested
List recursion over Tuple/Record's fields isn't visibly structurally decreasing to Lean.
The sendable predicate, used by a channel's own declared element type
(checkChannelDecl): the same restriction as showable (a CONSTANT isn't sendable either — it
gets substituted by the user only after code generation, and an unsendable instantiation would
silently break this invariant once compiled). Identical in shape to showable but defined
separately since the two restrictions only happen to coincide today, not the same rule reused.
Same non-monadic, resolve-first contract as showable.
Needed for the partial defs below to type-check at all (an arbitrary m isn't otherwise
known nonempty).
Equations
- instInhabitedStatement_elaborator = { default := pure Inhabited.default }
Instances For
Equations
- instInhabitedBlock_elaborator = { default := pure Inhabited.default }
Instances For
Equations
- instInhabitedBranches_elaborator = { default := pure Inhabited.default }
Instances For
Declarations checking, shared by both Algorithm.globalState and a Process's own
localState: variables first, then channels/fifos, each stage's bindings in scope for the
next.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Γ|Ξ⊩S ok — a transform, not a pure ok-judgment: every embedded
CoreTLAPlus.Expression/Ref becomes a checked TypedPlusCal.Expression/Ref, and receive
additionally gains its Coercion.
partial: no structurally-decreasing measure across the mutual group visible to Lean
(Block's begin : List (Statement _ _ false) field).
Γ|Ξ⊩B ok for atomic blocks — check every non-terminal statement, then the terminal one.
either's own branch list, checked pointwise — no dedicated rule beyond [Either]
reusing Γ|Ξ⊩B ok per branch.
Γ|Ξ⊩ p∈S ⋆ x1=e1;...;xm=em ⋆ T1...Tn ok: S must be Set(Address), checked without self
in scope; everything else about a process — mailbox, local variables, every thread — is
checked with self:Address already in scope. mailbox's filter/index expressions are inferred,
unconstrained, but still need self in scope (@mailbox: agt[self]; is the standard idiom).
process (p = e) checks e against Address directly, not Set(Address) (dispatches on
proc.«=|∈» rather than constructing a singleton set {e} and checking that).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Γ|Ξ⊩ fifos c1:τ1,...,cm:τm; P1∥...∥Pn ok: every channel declaration checked (also covers
globalState.variables), then every process checked against Γ extended by those bindings.
Those bindings stay scoped to the algorithm itself — PlusCal declarations don't leak into the
surrounding TLA⁺ module's own Γ.
Equations
- One or more equations did not get rendered due to their size.