Cairn.Claims.Deliver
lean/Cairn/Claims/Deliver.lean
The claim guarantees, carried through the runtime.
Cairn.Runtime.step_delivers_quiet says a runtime step passes App.update exactly the routed
actions, via Runtime.deliver, for an app that ignores the world (every machine's toApp). For an app whose update is a machine's, the lemmas here say what
that means for a whole batch of actions: every effect came from an enabled move handler answering
one of the actions, and a batch that names no move's claim changes nothing.
Imports Cairn.Claims.Machine, Cairn.Runtime.Step, Cairn.Runtime.WorldProofs
Theorems 5
deliver_effect {S : Type} (M : Machine S) {st : S} {acts : List Action}
{e : Effect} (he : e ∈ (Runtime.deliver M.update st acts).snd) :
∃ a,
a ∈ acts ∧
∃ s m,
m ∈ M.moves ∧
∃ h,
h ∈ m.handlers ∧
m.id = a.claim ∧
h.trigger = a.trigger ∧ m.enabled s a.key = true ∧ e ∈ (h.apply s a).sndEvery effect the runtime runs comes from a move. Each effect of delivering a batch of actions to a machine was emitted by an enabled handler of one of its moves, answering one of the actions (and owning its claim).
deliver_unclaimed {S : Type} (M : Machine S) {st : S} {acts : List Action}
(h : ∀ (a : Action), a ∈ acts → ∀ (m : Move S), m ∈ M.moves → m.id ≠ a.claim) :
Runtime.deliver M.update st acts = (st, [])No behaviour without a claim, through the runtime: a batch of actions none of which names a move's claim leaves the app state alone and runs no effects.
deliver_run {S : Type} (M : Machine S) (st : S) (acts : List Action) :
(Runtime.deliver M.update st acts).fst = M.run st actsDelivering a batch of actions to a machine runs them in order.
steps_reachable {S : Type} (M : Machine S) (surfaces : List (Surface S))
(claims : List ClaimInfo) (cfg : Runtime.Config) (size : Size) (scale : Nat)
(es : List Event) (initFocus : Option ControlRef := none)
(hq : ∀ (s : S) (m : Msg), (M.receive s m).fst = s := by intro _ _; rfl) :
M.Reachable
(Runtime.steps (M.toApp surfaces claims initFocus) cfg
(Runtime.start (M.toApp surfaces claims initFocus) cfg size scale) es).fst.appInvariants hold on screen. In an app whose update is a machine's, the app state of every
runtime state reached from start by events is reachable in the machine, so every invariant
(Invariant.reachable) holds in it.
steps_reachableAll {S : Type} (M : Machine S) (app : App S)
(hi : app.init = M.init) (hu : app.update = M.update) (hr : app.receive = M.receive)
(cfg : Runtime.Config) (size : Size) (scale : Nat) (es : List Event) :
M.ReachableAll (Runtime.steps app cfg (Runtime.start app cfg size scale) es).fst.appInvariants hold on screen, with the world. In any app whose start, update and receive
are a machine's (M.toApp, possibly with subscriptions and init effects added), the app state of
every runtime state reached from start by any events (input, the clock, timers, replies,
subscription events) is reachable in the machine by actions and messages, so every invariant
(Invariant.reachableAll) holds in it.