Hierarchical proofs

Our proof requires the following properties of GCDs, which for simplicity we just assume:

Known and usable facts

At any point in a TLA+ proof, there is a current obligation that is to be proved. The obligation contains a context of known facts, definitions, and declarations, and a goal. The obligation claims that the goal is logically entailed by the context. Some of the facts and definitions in the context are marked as usable for reasoning, while the remaining facts and definitions are hidden. That obligation is then sent to a backend (Zenon, Isabelle, SMT solvers – see the tactics section) that tries to prove it. The smaller the context is, the faster those backends are. Hence TLAPS tries to keep that context as small as possible. For example, the axioms about GCD stated above are not directly usable by the backends: they are known but not usable. As we have seen in the simple proof section, you have to explicitly USE or cite a fact in order for it to be included in the context of the obligation sent to backends. As an exception to this rule, domain facts of the form x \in S are always usable in a proof. (Such assumptions are typically introduced in an ASSUME … PROVE construct, most frequently in the form of an assumption NEW x \in X.) Moreover, unnamed proof steps (see below) are aways usable. The other known facts are hidden by default.

Let us get back to our example. Now that we have proved that the initial state satisfies the invariant, let us prove that this invariant is preserved by the next-state relation Next


Let us first simplify the goal to be proved by using a SUFFICES construct:

This step asserts that it is sufficient to prove InductiveInvariant' while assuming InductiveInvariant and Next. Because the step is unnamed, both facts InductiveInvariant and Next are also made usable for the remainder of the proof. For more information about SUFFICES, see the section about other proof constructs.


We'll need the definitions of InductiveInvariant and Next to be usable in the entire body of the proof. Hence, rather than making them usable with a BY DEF construct in each step, we can make them usable for all proof steps by using the USE DEF construct once, at the beginning of the proof:

The general form of a USE step is:

USE e1, …, em DEF d1, …, dn

which asserts that the definitions d1, … dn are to be made usable, and the facts e1, …, em are to be checked and then added to the context as usable. When checking these facts, all other known facts are temporarily considered to be usable, so it is possible to say USE e /\ f when e and f are in the context but hidden. Observe that the USE directive is syntactically similar to BY, but it obviously does not check if the current assertion follows from the cited facts.

The QED step

To prove the theorem NextProperty, we have to reason by cases, and prove that InductiveInvariant' is true when one of the actions of Next is performed (i.e. when x < y and also when x > y). Let us write this outer level of the hierarchical proof:

<1>1, <1>a, <1>b and <1>2 are step names (the <1> part of the step name indicates the step's level, which is 1. The proof itself consists of four claims named by these step names (plus the two first unnamed steps); the first three are unjustified, while the last is justified by the cited facts <1>1, <1>a and <1>b. The QED step asserts the main goal of the theorem. Let us verify that it can be proved from steps <1>1, <1>a and <1>b:


After having asked TLAPS to prove the theorem, the QED step gets colored green. This means that facts mentioned by steps <1>1, <1>a and <1>b are sufficient to prove the theorem. But as you can see, those proof steps are colored yellow, which means that their proofs are omitted. (The Toolbox allows you to change what colors are used to indicate the proof status of a step, and also what proof statuses are displayed.) Let us now prove these proof steps.

Non-QED steps

First, the proofs of the SUFFICES step and step <1>1 are obvious as you can see in the following screenshot. In particular, step <1>1 follows from the usable fact Next introduced in the unnamed SUFFICES step and the definition of Next, which is also usable.


Let us now prove step <1>a. We subdivide this proof into two steps of level 2. The first step asserts that y - x \in Number and that y is not less than x. The second, QED step proves the main goal from the case assumption of step <1>a, the just established step <2>1, and axiom GCDProperty3.


Let us now prove step <2>1. We have to use the case assumption <1>a and make the definition of Number usable:

The proof of the y < x case is quite similar:

Then theorem NextProperty is proved by TLAPS:


Wrapping up the proof

Now we have InitProperty and NextProperty, we can prove the main theorem.

First we prove that a stuttering step (i.e. a step that leaves all variables unchanged) keeps the invariant unchanged. This is proved simply by checking that the definition of InductiveInvariant involves no variables other than x and y:

Then we can prove that any process that follows the specification must keep InductiveInvariant true at all times, by using the previous step and the InitProperty and NextProperty theorems:

Unfortunately, that doesn't work:


Indeed, none of the default back-end provers (SMT, Zenon, and Isabelle) can deal with temporal logic. But TLAPS includes an interface to a propositional temporal logic prover (LS4), which can be invoked by adding PTL to the set of usable facts. Since PTL is defined in the TLAPS.tla standard module, we have to explicitly extend the TLAPS module:

Then we can use the PTL backend to prove step <1>2:


Finally we prove that, at any point in time, our invariant entails the correctness of the result, then use that to prove the main theorem:

And this concludes the proof of correctness of Euclid's algorithm.


This is the whole file, with the specification and proofs: