Hello,
Some time ago, I wrote a (long) tutorial on TLA+ intended for engineers.
It is very proof-oriented, using a “correct by construction” approach, as presented by J-R. Abrial, the author of Event-B. The idea is to start with a very abstract model and refine it as many times as necessary until you arrive at a version that can be easily translated into code. For each model, the invariants (safety) and refinement are proven.
The tutorial therefore covers these different concepts, but also how to break down a model into sub-models, and finally how to verify that the implementation (the code) complies with the model.
The approach is illustrated by several examples and finishes by a client-server system, implemented in C++20 / ZeroMQ.
There is nothing new in this work, but I have tried to present what I have learned here and there in a way that I hope is coherent. I also feel that there are not many introductions to proof with TLA+.
The PDF is here: https://github.com/jskri/modeling-with-tla/releases/download/v0.1/modeling-with-tla-v0.1.pdf
(the TLA+ specifications and C++ sources are in the repository)
I am interested in any constructive feedback.
Thanks!
--
You received this message because you are subscribed to the Google Groups "tlaplus" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tlaplus+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/tlaplus/646a785a-88eb-46b5-a691-ff9992c3ace1n%40googlegroups.com.
The “All model sources can be found here.”
Link does not appear to work?!
Is this the correct place to send minor edits?
Thanks
Dave
--
You received this message because you are subscribed to a topic in the Google Groups "tlaplus" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/tlaplus/TXK5vZ762vI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to tlaplus+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/tlaplus/014501dc2c82%2469f33770%243dd9a650%24%40gmail.com.
To view this discussion visit https://groups.google.com/d/msgid/tlaplus/CABj%3DxUXhQuKB_KwZYapadnywpgFXPL2vYjCN7d73i9C%3DW9ge5g%40mail.gmail.com.
Thank you for your feedback.
I think that the direction—from abstract to concrete or vice versa—doesn't matter as long as the two are connected in the end.
Regarding Unicode, in the tutorial, the TLA+ code actually only uses ASCII (you can see this by pasting the code into a text editor). It is only the font used that performs special rendering via ligatures.
You are welcome to mention this tutorial wherever you like. Here is the latest version, with licenses added: https://github.com/jskri/modeling-with-tla/releases/download/v0.3/modeling-with-tla-v0.3.pdf
Regarding the composition of specifications, the tutorial's approach is to share variables for communication and use interleaving composition. This approach seems quite natural to me because it has little impact on the way components are written.
Thanks for the links, I need to study all this!
To view this discussion visit https://groups.google.com/d/msgid/tlaplus/CABj%3DxUX1M2BPs_kq1ESkgfX-aqfM7jZPxdy-9%3DEG7cukDcf_9Q%40mail.gmail.com.
Thank you for your thorough review. I agree with most of your comments.
The links have been fixed in the v0.2.
Regarding strict alternation (p. 37), IIRC the logic of the text is to follow intuition and first use a conjunctive Next to represent parallel composition ("simultaneity"). Then, relax the constraints and use a strict alternate disjunction instead (since a mapping to the conjunctive spec exists), and finally relax to obtain an interleaving composition, which is acceptable in many cases. This shows that a disjunctive Next allows all the forms of composition that we consider here.
Concerning IsNewestOfItsTheme as a parameter rather than a definition (p.41, module ThemeCommon1), the aim is to avoid ending up with distinct definitions in different instantiations, which would require a bit more work with the prover.
For now, I haven't made any structural changes, but I have made many targeted corrections and additions.
You can see the diffs here and here.
The corresponding PDF is: https://github.com/jskri/modeling-with-tla/releases/download/v0.4/modeling-with-tla-v0.4.pdf
Thank you again.
On Tuesday, September 30th, 2025 at 15:52, Stephan Merz stepha...@gmail.com wrote:
Thank you indeed for the tutorial: I find it very nicely presented, with helpful illustrations, and a useful complement to existing material.
Here are a few comments and suggestions (I haven’t checked your updated version):
- Throughout, almost all links are broken.
- p.3 bottom: "where hour is in 0 .. 12" – clearly, this should be either 0 .. 11 or 1 .. 12, and you opt for the latter in the formal spec.
- p.4: The current version of the VS Code extension lives at [1], and it does support the prover. At the moment, the "decompose proof" command is not yet there, but it should be available before the end of the year.
- following paragraph: I find it a little unfortunate that you deviate from the usual TLA+ terminology of "specification" for a generic description of a system at a given level of abstraction and "model" for a concrete instance of a specification used for model checking. This might confuse newcomers.
- p.12, def. UserSetsAlarm: Note that this action allows a transition from unset to ringing, which is not represented in the system diagram.
- p.13 top: "random" may suggest probabilities, which are not covered by TLA+, so I’d avoid that word.
- p.13 middle: UNCHANGED <<now, ringing>> is not actually a "shortcut" (in the sense of a macro) for UNCHANGED now /\ UNCHANGED ringing, but the two formulas are logically equivalent.
- p.29: For the refinement proof, perhaps you could have adapted the example a little so that the type correctness invariant was actually required for proving refinement, and take the opportunity to show how a previously proved property can be used in a later proof. This is indeed required for most refinement proofs in practice. You show how to use a previously proved invariant in section 2.2.6, but personally, I think the technique could be explained for invariants first, and then applied in the refinement proof, which could help readers get the idea.
- p. 37 top: Here you enforce a strict alternation between the two components, and I wonder why you did this, as it may make later refinements harder. Indeed, later you rather stick to disjunctive ("interleaving") representations: I would have introduced this first and perhaps mentioned later that you can enforce strict alternation if required.
- p. 37 middle: "The above disjunctive Next" – this should certainly be "conjunctive"
- p.41, module ThemeCommon1: I do not really understand why you make IsNewestOfItsTheme a parameter rather than a definition?
- p. 42 top: You say that the alternative to constants are definitions, but constants such as Theme and Pack are naturally parameters, it is not clear to me what their definitions would be. Concerning the choice between accessor functions such as PackTheme or PackVersion and an explicit record representation, I think the main advantage of the former is greater (or more obvious) abstraction. It becomes clearer that the spec just describes the part of the real world that is relevant to the current level of abstraction, without pretending to be a full representation of the actual system state.
- p.42, Fig.16: Here "newPack" is both an input and an output to the system, whereas at the beginning of the chapter you said that the two sets had to be disjoint.
- p.50: In the initial condition, I would have expected knownIds to be initialized to { PackId[InitialPack] }, although it does not make a real difference for the behavior. In DeviceSendsListRequest, I find the guard "packs # Pack" quite strange since "unnecessary" list requests may be sent at other times (in the sense that the device will not learn of new packs). Also, realistically the set Pack could be open-ended, without the device really having access to this set, and indeed later you say that you will not implement this condition, so I’d just suggest to remove it.
- Sect. 4.1, par.2: One way of avoiding this way of reconstructing / completing model states is to log updates to the model state rather than the model state itself. This is what we do in our approach to trace validation [2], and we also allow the set of logged variables to be incomplete, relying on TLC to find suitable values in order to complete the trace. (Obviously, there is a tradeoff between convenience and completeness of logging and precision of the verdict.)
- Sect. 5, par. 4: I also find it useful that the different tools are based on the same language (or, more precisely, on subsets of the same language). For example, one can extensively run the model checker before starting a proof, and also go back to model checking when the proof suggests a strengthening of an invariant, in order to make sure that the asserted theorem has a chance of being true. I also find it useful to use Apalache (which you do not cover here) to check if an invariant is indeed inductive.
Thanks again for the nice text and best regards,
Stephan[1] https://marketplace.visualstudio.com/items?itemName=tlaplus.vscode-ide
[2] https://link.springer.com/chapter/10.1007/978-3-031-77382-2_8On 23 Sep 2025, at 12:30, 'Jskri' via tlaplus tla...@googlegroups.com wrote:
Hello,
Some time ago, I wrote a (long) tutorial on TLA+ intended for engineers.
It is very proof-oriented, using a “correct by construction” approach, as presented by J-R. Abrial, the author of Event-B. The idea is to start with a very abstract model and refine it as many times as necessary until you arrive at a version that can be easily translated into code. For each model, the invariants (safety) and refinement are proven.
The tutorial therefore covers these different concepts, but also how to break down a model into sub-models, and finally how to verify that the implementation (the code) complies with the model.
The approach is illustrated by several examples and finishes by a client-server system, implemented in C++20 / ZeroMQ.
There is nothing new in this work, but I have tried to present what I have learned here and there in a way that I hope is coherent. I also feel that there are not many introductions to proof with TLA+.
The PDF is here: https://github.com/jskri/modeling-with-tla/releases/download/v0.1/modeling-with-tla-v0.1.pdf
(the TLA+ specifications and C++ sources are in the repository)
I am interested in any constructive feedback.
Thanks!--
You received this message because you are subscribed to the Google Groups "tlaplus" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tlaplus+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/tlaplus/646a785a-88eb-46b5-a691-ff9992c3ace1n%40googlegroups.com.
--
You received this message because you are subscribed to a topic in the Google Groups "tlaplus" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/tlaplus/TXK5vZ762vI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to tlaplus+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/tlaplus/270296D6-3560-4FDC-981F-7DD096F496B8%40gmail.com.