Generic operational safety and partial correctness #
This file defines reusable infrastructure for relations that have not yet been given a concrete language semantics. It is not an interpreter or a model of Rust or MIR. A future semantics must supply its own states, transition relation, terminal outcomes, and proofs that its relation is complete.
Terminal outcomes distinguish successful returns from undefined behavior,
blocked proof obligations, and unsupported cases. Safe rejects each of the
three non-success outcomes and requires every finitely reachable state to have
an explicit transition or terminal outcome. This lets infinite executions be
safe without treating a missing transition or an unimplemented case as success.
A terminal result of a semantics supplied by a client.
- returned
{Value : Type v}
{UB : Type w}
{Obligation : Type x}
: Value → Outcome Value UB Obligation
A computation returned a value.
- undefinedBehavior
{Value : Type v}
{UB : Type w}
{Obligation : Type x}
: UB → Outcome Value UB Obligation
The computation reached an undefined-behavior outcome.
- blocked
{Value : Type v}
{UB : Type w}
{Obligation : Type x}
: Obligation → Outcome Value UB Obligation
A required semantic or verification obligation remains blocked.
- unsupported
{Value : Type v}
{UB : Type w}
{Obligation : Type x}
: Obligation → Outcome Value UB Obligation
The computation reached a case not supported by the supplied semantics.
Instances For
Whether a terminal result is a successful return.
Equations
Instances For
A small-step transition system with explicit terminal outcomes.
- step : State → State → Prop
One permitted finite transition. Multiple successors encode nondeterminism.
A terminal outcome permitted at a state.
Instances For
Finite reachability, including the zero-step path.
- refl {State : Type u} {Value : Type v} {UB : Type w} {Obligation : Type x} {sys : System State Value UB Obligation} (state : State) : sys.Reaches state state
- step {State : Type u} {Value : Type v} {UB : Type w} {Obligation : Type x} {sys : System State Value UB Obligation} {start middle finish : State} : sys.Reaches start middle → sys.step middle finish → sys.Reaches start finish
Instances For
Progress holds at every state reachable by a finite path from start.
This premise rules out unclassified dead ends. Divergent states satisfy it by having at least one successor, even if no terminal result is ever produced.
Equations
- sys.CompleteFrom start = ∀ (state : State), sys.Reaches start state → sys.CanProgress state
Instances For
UB freedom excludes UB outcomes after every permitted finite execution. This property alone does not certify semantic coverage or resolve unsupported cases.
Equations
- sys.NoUndefinedBehavior start = ∀ (reason : UB), ¬sys.ReachesOutcome start (Miri.OperationalSafety.Outcome.undefinedBehavior reason)
Instances For
Safety over all finite paths and all terminal outcomes.
Safe requires explicit progress at every reachable state and permits only
successful terminal returns. Because quantification is over every successor
and every terminal outcome, this definition is demonic with respect to
nondeterminism. It does not require termination.
Equations
- sys.Safe start = (sys.CompleteFrom start ∧ ∀ (outcome : Miri.OperationalSafety.Outcome Value UB Obligation), sys.ReachesOutcome start outcome → outcome.isReturn)
Instances For
Partial correctness: every reachable successful return satisfies post.
This assertion is conditional on return; it does not claim that a return is reachable.
Equations
- sys.PartialCorrect start post = ∀ (value : Value), sys.ReachesOutcome start (Miri.OperationalSafety.Outcome.returned value) → post value
Instances For
Every finite reachable state satisfies an invariant preserved by each step.
A local property of all reachable successful terminal states proves partial correctness.
Certified safety implies UB freedom; its progress/coverage requirements are additional requirements for accepting a Safe result.
A safe system cannot reach an undefined-behavior outcome.
A safe system cannot reach a blocked obligation.
A safe system cannot reach an unsupported case.
Invariants are an optional proof method for operational safety. Each permitted transition must preserve the invariant; progress excludes unclassified dead ends and terminalSuccess excludes unresolved outcomes.