Properties of the monadic-interpreter↔semantics contract #
Lemmas about the definitions of InterpreterSemanticsSpec.lean: the engine-realizable relations
against the reference semantics, the engine-check side condition, and the observation laws of
InterpObs applied to the engine.
Key theorems:
EngineChecksAgree.toFrom: the global engine-check obligation implies the derivation-relative one;engineChecksAgreeFrom_of_storeFree: the derivation-relative obligation holds outright on configurations with no.initand no.set;EvalCmdEngE.toEvalCmdE,StepEngE.toStepStmtE,StepEngStarE.toStepStmtStarE: the engine-realizable relations are sub-relations of the reference semantics;StepDetE.toStepEngE: a choice-free reference step is engine-realizable, under the engine-check obligation;StepEngParamE.not_done: no engine-realizable step leaves a.terminalor.exitingconfiguration;Calls.stepEngParamE_imp: the engine-realizable step is monotone in its command relation;StepStmtStarE.toStepEngStarEFrom,StepStmtStarE.toStepEngStarE: a reference run from a deterministic configuration is engine-realizable, under the engine-check obligation;StepStmtStarE.toStepEngParamStarE: a reference run along which the engine agrees (EngineAgreesFrom) is engine-realizable;engineAgreesFrom_of_deterministicdischarges the agreement on deterministic programs;obs_run_zero,obs_run_succ,obs_runInterp_ok_final,obs_forM_emit:obs.runof the driver at zero and successor fuel, the shape of a returned configuration, and the trace of emitting a list of events;obs_run_throw_bind: a throw before a bind leaves the state untouched;obs_stepInterp_cmd_fwd,obs_ite_det_true_fwd,obs_ite_det_false_fwd,obs_loop_det_enter_fwd,obs_loop_det_exit_fwd,obs_seq_fwd,obs_block_fwd:obs.runof onestepInterpstep, forward, on a base command, a deterministiciteorloop, and an inner sequence or block step.
Engine-check agreement and the store-free fragment #
If every deterministic reference base-command evaluation passes the engine's value checks
(EngineChecksAgree R), then from any configuration c every configuration reachable by
choice-free reference steps passes them at its active base command
(EngineChecksAgreeFrom R c): the derivation-relative form never demands more
than the global one.
The derivation-relative engine-check agreement on the store-free fragment. From a
configuration whose remaining program text contains no .init and no .set, every
configuration reachable by choice-free reference steps passes the engine's value checks at its
active base command (EngineChecksAgreeFrom R), for every choice record R.
Soundness of the engine-realizable relations #
The refinement is sound: an EvalCmdEngE evaluation is a reference
EvalCmdE evaluation with the same store and the same events.
The engine-realizable command relation is monotone in its choice record.
Soundness of the refinement at statement level: an engine-realizable step is a
reference StepStmtE step with the same events and the same successor.
Every engine-realizable step over base commands (StepEngE) is a reference StepStmtE step
over EvalCmdE with the same events and the same successor.
Every engine-realizable run over base commands (StepEngStarE) is a reference StepStmtStarE
run over EvalCmdE with the same events and the same final configuration.
No engine-realizable step leaves a .terminal or .exiting configuration, so
the driver's stopping test is exactly the absence of a next step.
The engine-realizable statement step is monotone in its command relation.
Choice-free reference runs are engine-realizable #
A bounded evaluator that reaches every reference value at some fuel (BoundedEvalComplete)
reaches the reference value of every expression on every store (EngEvalReach).
A reference run from a deterministic configuration is an engine-realizable run with the same
events, provided every configuration reachable from its start by choice-free reference steps
passes the engine's value checks at its active base command (EngineChecksAgreeFrom), the
bounded evaluator reaches every reference value (BoundedEvalComplete) and runtime guard
values agree with the reference ones (EngineGuardsAgree).
A choice-free reference step is an engine-realizable step, provided every deterministic
reference base-command evaluation passes the engine's value checks (EngineChecksAgree), the
bounded evaluator reaches every reference value (BoundedEvalComplete) and runtime guard
values agree with the reference ones (EngineGuardsAgree).
Reference run on a deterministic program ⇒ engine-realizable run: a reference run from a
deterministic configuration is an engine-realizable run with the same events, provided every
deterministic reference base-command evaluation passes the engine's value checks
(EngineChecksAgree), the bounded evaluator reaches every reference value
(BoundedEvalComplete) and runtime guard values agree with the reference ones
(EngineGuardsAgree).
If every reference step out of a configuration reachable from c is also an
engine-realizable step (EngineAgreesFrom), then every reference run from c is an
engine-realizable run with the same events.
On a deterministic program c, if every configuration reachable by choice-free reference
steps passes the engine's value checks at its active base command (EngineChecksAgreeFrom),
then every reference step out of a configuration reachable from c is an engine-realizable
step (EngineAgreesFrom), for every choice record, when the bounded evaluator reaches every
reference value (BoundedEvalComplete) and runtime guard values agree with the reference ones
(EngineGuardsAgree).
One engine step, forward #
Each statement form's stepInterp step computed under obs.run, from the reference step's
premises.
If stepBaseCmdStore runs a base command cmd from ρ's store to σ', then
stepInterp baseStepCmd on .stmt (.cmd cmd) ρ runs to .terminal { ρ with store := σ' },
with the same final state.
On a deterministic ite whose guard the bounded evaluator reduces to tt, stepInterp returns
the then-branch block, leaving the state unchanged.
On a deterministic ite whose guard the bounded evaluator reduces to ff, stepInterp returns
the else-branch block, leaving the state unchanged.
On a deterministic loop whose guard the bounded evaluator reduces to tt, stepInterp
returns the body block followed by the loop again, leaving the state unchanged.
On a deterministic loop whose guard the bounded evaluator reduces to ff, stepInterp
terminates with the current environment, leaving the state unchanged.
If stepInterp steps a non-terminal, non-exiting configuration inner to inner', it steps
.seq inner ss to .seq inner' ss, with the same final state.
If stepInterp steps a non-terminal, non-exiting configuration inner to inner', it steps
.block label frame inner to .block label (frame.record inner.levelCmd?) inner', with the
same final state.
The driver under obs.run #
At fuel 0, runInterp on a non-terminal, non-exiting configuration runs to the
fuel-exhaustion error with the state unchanged.
At successor fuel, runInterp on a non-terminal, non-exiting configuration runs one
stepInterp step, then continues from the resulting configuration and state, stopping at
the first error.
A run that returned .ok stopped at a terminal or an exiting configuration:
those are the only two shapes runInterp hands back without throwing.
Emitting a list of events prepends exactly that list to the trace.
A computation that throws before a bind runs to the error with the state untouched.
BoundedEvalSound is BoundedEvalSoundAt at every factory.