Inv ⟶ AtLeastOneYWhenDone

(I know it sounds odd to call a predicate an “invariant” when it’s vacuously true except for one state). It might not strictly be necessary here, I haven’t tried doing the proof without that clause in the invariant.

I should really learn Isabelle/HOL so I can read your proofs!

]]>The invariant in your TLA+ file [1] feels quite odd to me, particularly that the `AtLeastOneYWhenDone` clause is sufficient. It seems too weak. It is quite rare to be able to use an invariant that only carries any weight at one state (termination), and more usual to use an invariant to carry some fact about the system across multiple states. That’s not to say it doesn’t work (it certainly does, see [2]) so much as to say that the invariant I arrived at for this algorithm is quite different [3], effectively saying:

(∀n < N. y[n] is defined ⟶ x[n] = 1) ∧ ((∀n < N. x[n] = 1) ⟶ (∃ n < N. y[n] is undefined ∨ y[n] = 1))

This works as well, and it's interesting to see a situation where there's a choice of satisfactory invariants.

[1] https://github.com/lorin/teaching-concurrency/blob/d44b4cf2e360afadebb366b34cb7cbbaa2ebffc5/Simple.tla#L68-L70

[2] https://github.com/DaveCTurner/tla-examples/blob/bd66616d05445434c67a1342485ba4d7bfebf3e3/HochsteinLamport.thy#L267

[3] https://github.com/DaveCTurner/tla-examples/blob/6f27f9f79f1798eb6873dee9161187053b984a5b/HochsteinLamport.thy#L56-L61

Hillel also has this website: https://learntla.com

]]>It is quite frequent that safety in a system is obtained by pulling in some kind of subsystem designed for that goal. Therefore, when the subsystem fails… I suppose you can design a system such that safety is derived from how the system is structured (rather than added as an extra), but I’m not sure if you can do that on purpose!

]]>