TLA+ proof constructs

SUFFICES

An ordinary expression or ASSUME … PROVE … in a step stands for an assertion of that step. Its subproof proves it, and the rest of the proof in the same level is allowed to use the assertion as an assumption. SUFFICES reverses these two roles. Succinctly, the following two proof fragments are equivalent.

<4>1. t1 <5>1. s1 <5>2. s2 … <5>m. QED <4>2. t2 <4>3. t3 … <4>n. QED
 
<4>1. SUFFICES t1 <5>1. t2 <5>2. t3 … <5>n-1. QED <4>2. s1 <4>3. s2 … <4>m+1. QED

In the proof on the left-hand side above, t1 is known in proof-steps <4>2, <4>3, ..., <4>n, while in the proof on the right-hand side, t1 is known in proof-steps <5>1, <5>2, ..., <5>n-1.   SUFFICES is mainly used to rephrase the sequent to be proved in a more perspicuous form. For example, suppose we have:

This proof is unnatural because of the nested occurrences of ASSUME … PROVE …. The point where Next needs to be expanded, in <2>3, is potentially far removed from its relevant assertion, <1>1. It would be better instead to rephrase the theorem as a conjunction and then derive the conjuncts with a SUFFICES as follows:

In this form, the definition of Next is cited right next to the assertion where it is relevant. In the rest of the proof after step <1>1, the definition of Next is irrelevant. The proof is also shallower because we change an instance of a QED step into a BY leaf proof. This kind of restatement of the current goal can make proofs much easier to read and maintain.

(Strictly speaking, the SUFFICES step was not necessary in this simple proof because the DEF Next could have been folded into the proof of <1>4. However, in more complex proofs it is better to use SUFFICES as needed to rephrase the goal up front. These steps also serve as hints to the reader about the direction of the proof.)

HAVE, TAKE and WITNESS

TLAPS provides some shortcuts for proving implications and quantifications. They can be described with their equivalent SUFFICES construct:

goal step equivalent SUFFICES step
e => f
<n>l. HAVE g
<n>l. SUFFICES ASSUME g PROVE f OBVIOUS
\A x : P(x)
<n>l. TAKE y
<n>l. SUFFICES ASSUME NEW y PROVE P(y) OBVIOUS
\A x \in S : P(x)
<n>l. TAKE y \in T
<n>l. SUFFICES ASSUME NEW y \in T PROVE P(y) OBVIOUS
\E x : P(x)
<n>l. WITNESS e
<n>l. SUFFICES P(e) OBVIOUS
\E x \in S : P(x)
<n>l. WITNESS e \in T
<n>l. SUFFICES ASSUME e \in T PROVE P(e) <n+1>1. e \in T OBVIOUS <n+1>2. QED BY <n+1>1

One important deficiency of HAVE, TAKE and WITNESS steps is that the precise form of the rephrased goal is not textually present in the proof. The (human) reader might get confused by long chains of these steps, especially if interleaved with other kinds of steps. These constructs should therefore be used sparingly, preferably only in the lowest levels of proof where there is some actual benefit in linearizing the proof.

PICK

An assumption of the form \E x : P(x) can be used by picking a fresh x for which P(x) is assumed. This is done using the step PICK x : P(x). Note that \E x : P(x) need not be present exactly in the assumptions; this step accepts a subproof that supplies the justification for \E x : P(x). Here is a somewhat contrived example: