The Z/EVES 2.0 User's Guide
The Z/EVES 2.0 User's Guide
The Z/EVES 2.0 User's Guide
0 User’s Guide
TR-99-5493-06a
Mark Saaltink
ORA Canada
P.O. Box 46005, 2339 Ogilvie Rd.
Ottawa, Ontario K1J 9M7
CANADA
Contents
1 Introduction 1
2 Using Z/EVES 3
2.1 Running Z/EVES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Z/EVES Displays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2.1 The Specification window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2.2 The Proof window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2.3 The Theorems window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.4 The Proof Scripts window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.5 The Edit window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.6 The Clipboard window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.3 Composing and Checking a Specification . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4 Analysing a Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.5 LATEX Markup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3 Analysing Z Specifications 19
3.1 Checking for Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.1.1 Syntax and type errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.1.2 Domain errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.1.3 Inconsistency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.2 Exploring a Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.2.1 Schema expansion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.2.2 Preconditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.2.3 Invariants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.2.4 Refinement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.2.5 Test cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.2.6 Test theorems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
i
ii Z/EVES Project TR-99-5493-06a
5 Proving Theorems 45
5.1 Explorative Proving . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5.2 Planned Proofs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
6 Theory Development 55
6.1 Objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.1.1 Logical adequacy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.1.2 Practical adequacy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
6.1.3 Automation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
6.2 Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
6.3 A Theory Development Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6.3.1 A resource manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6.3.2 A first proof attempt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
6.3.3 Second attempt: elimination . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
6.3.4 Third attempt: developing a theory . . . . . . . . . . . . . . . . . . . . . . . 63
Chapter 1
Introduction
This user’s guide describes how and why to use Z/EVES to develop or analyse a Z specification.
This is not a tutorial on Z; there are already a number of readily available books describing Z and
its application (e.g., those by Barden et al. [2], Hayes [4], Jackey [6], Potter et al. [9], Spivey [13],
and Woodcock and Davies [15]). We assume the reader has a solid grounding in the Z language and
its use; instead, we focus on the mechanics of using Z/EVES and techniques for using Z/EVES to
analyse Z specifications.
This version of the user’s guide describes the graphical user interface to Z/EVES. Users of the
command line interface should consult the previous version [11] instead.
Detailed descriptions of the syntax used by Z/EVES, the proof commands, and the handling
of Z paragraphs can be found in the Z/EVES Reference Manual [7]. A detailed description of the
Z/EVES Mathematical Toolkit appears as a separate report [10].
Chapter 2 describes the mechanics of using Z/EVES. Chapter 3 describes several kinds of analysis
that can be applied to expose errors in Z specifications or to explore the specification. Chapter 4
describes the logical foundations and basic mechanisms of the Z/EVES theorem prover. Chapter 5
describes how to use the Z/EVES prover. The prover has an automatic mode which can prove many
simple theorems. When that fails, however, it is not always obvious how to proceed. This chapter
describes the strategies for successful application of the prover. Chapter 6 describes how to define
new concepts in a specification in a way that supports proofs.
Prover commands are shown in the text in typewriter font, e.g., rewrite.
The terms “user”, “specifier”, and “reader” all refer to Z or Z/EVES users.
1
2 Z/EVES Project TR-99-5493-06a
Chapter 2
Using Z/EVES
Z/EVES is an interactive system for composing, checking, and analysing Z specifications. Speci-
fications can be entered and checked one paragraph at a time; checked paragraphs can be revised
and rechecked; and theorems can be stated and proofs attempted at any time. Z/EVES is also able
to read entire files of specifications that have been previously prepared using LATEX markup. This
chapter describes the mechanics of using Z/EVES.
3
4 Z/EVES Project TR-99-5493-06a
The status of each paragraph is shown in two columns to the left of the paragraph. The leftmost
column shows one of three symbols:
• “Y” indicates that the paragraph has been checked and has no syntax or type errors.
• “N” indicates that the paragraph has been checked and has errors.
The next column shows the proof status for the paragraph, using one of three symbols
• “?” indicates that the paragraph has not been successfully checked (so proof status cannot be
determined).
• “N” indicates that the paragraph has an associated goal that is unproven.
• “New Paragraph” can be selected from the “Edit” menu. This exposes the Edit window
(described in Section 2.2.5), which allows the paragraph to be composed. The new paragraph
is added to the end of the specification.
• A “Paste” operation inserts the contents of the clipboard immediately before the paragraph
containing the insertion point (where the blinking cursor is) in the specification window.
Paragraphs in the specification window can be checked, modified, deleted, or moved. A paragraph
can be checked by double clicking on it, or by selecting it, right clicking, and selecting “Check” from
the pop-up menu. Selecting “Check up to here” checks all preceding paragraphs before checking the
selected paragraph. The entire specification can be checked by selecting “Check all paragraphs” from
the “Command” menu. While paragraphs are being checked, most Z/EVES functions are disabled.
However, it is still possible to select different windows and to scroll them. The “Abort” button can
be used to stop checking.
A paragraph can be modified by selecting it, right clicking, and selecting “Edit” from the pop-up
menu. This brings up the Edit window with the selected paragraph as its initial contents. When the
edit is finished, the revised paragraph replaces the original. The revised paragraph is not checked.
(Following paragraphs will also become not checked, if the original paragraph had been checked.)
Z/EVES Project TR-99-5493-06a 5
A paragraph (or group of paragraphs) can be deleted by selecting it (or them), right clicking, and
selecting “Delete” from the pop-up menu. There is no “undo” capability in the interface, so once
deleted, the paragraph cannot be recovered. If a deleted paragraph had been checked, all following
paragraphs will become not checked.
A paragraph (or group of paragraphs) can be moved by selecting it (them), right clicking, and
selecting “Move” from the pop-up menu. This changes the mode of the interface. As the mouse
pointer moves over paragraphs, they are darkened. Selecting a paragraph causes the originally
selected paragraph or paragraphs to be inserted immediately before the selected location. The move
can be canceled by right clicking, then selecting “Cancel” from the pop-up menu.
Paragraph order is important. A Z specification is a sequence of paragraphs and requires dec-
laration before use. The order in which paragraphs appear in the Specification window determines
this declaration before use order. Documents often present Z specifications with the paragraphs out
of order; if such a specification is imported into Z/EVES it is necessary to move the paragraphs into
a suitable checking order. Order is also important for theorems, as the proof of a given theorem can
only use other theorems that precede the given theorem in the specification. Thus, lemmas must
appear before the theorems whose proofs they are used in.
Z/EVES offers two modes of operation, “Eager” and “Lazy”. In “Eager” mode, the rules of
checking are strict: a paragraph can only be checked if all preceding paragraphs have been checked.
As one’s goal is to have the entire sequence of paragraphs checked, this is reasonable. “Lazy”
mode allows paragraphs to be skipped. This can be useful in experimentation; for example, the
specification might contain two alternative versions of a paragraph. In “Lazy” mode, one of these
can be checked and the other left unchecked, and the remainder of the specification can be analysed.
The status bars help a user to keep track of the experiment, by showing what has been checked and
what has not. By default, Z/EVES is in the “Lazy” mode.
When paragraphs have been checked, their phrase structure is browsable in the specification
window. When the mouse is clicked over a part of a checked paragraph, the smallest containing
phrase (i.e., name, expression, predicate, or paragraph) is highlighted. Successive clicks will cause
larger and larger containing phrases to be highlighted. Alternatively, the mouse can be moved with
the left button depressed, in which case the smallest phrase containing both the place where the
button was first depressed and the current location of the pointer is highlighted. A selected part
can be copied to the clipboard by selecting “Copy” from the “Edit” menu in the menu bar.
• “<<” moves the action point to the start of the proof, thus displaying the original goal
predicate;
The action point can also be moved by selecting it, right clicking, selecting “Move” from the pop-up
menu, then clicking on a command or just after the last command. The interstion point will be
moved to just before the selected place.
The illustrated proof window shows a proof script with two steps, both of which have been run.
The user has selected the back button and moved the action point one step back, and the Formula
area shows the goal predicate that resulted from the application of the first command.
Commands can be added to a proof script in several ways:
• “New Command” can be selected from the “Edit” menu. This exposes the Edit window, which
allows the command to be composed. The new command is added to the end of the script
when “Done” is selected from the “File” menu in the Edit window. (Alternatively, “Cancel”
can be selected from the “File” menu, in which case the edit is abandoned.)
• A “Paste” operation inserts the contents of the clipboard immediately before the insertion
point (where the blinking cursor is) in the script window, or at the end if there is no insertion
point.
• Some proof commands are available from a menus on a bar above the goal predicate display.
These commands are entered at the action point and are immediately executed. Unfortunately,
not all prover commands are available from menus, and for effective use of the prover it is
necessary to learn the syntax of commands and to use one of the other two techniques to add
them to a script.
When a proof command is running, most Z/EVES functions are disabled. However, it is still
possible to select different windows and to scroll them. A long-running proof command can be
stopped by selecting the “Abort” button.
Z/EVES Project TR-99-5493-06a 7
The Theorems window has two main parts. On the left is a list of theorem names. Double clicking
on one of these names causes the theorem to be displayed in the right part of the Theorem window.
As for checked paragraphs in the Specification window, the phrase structure of the displayed theorem
can be explored.
Theorems correspond to theorem paragraphs in a specification or are generated when a paragraph
is checked. Generated theorems can be axioms, which are facts that may be useful in later proofs,
or goals that are in need of proof. These goals are either explicit theorem paragraphs, or domain
checks generated as described in Section 3.1.2.
The Proof Scripts window contains a list of proof scripts associated with the specification. Each
proof script is sequence of proof commands for a goal. The script can be viewed (in a Proof window)
by selecting the script’s name, right clicking, and selecting “View” from the pop-up menu.
Proof scripts are retained even when the associated goal disappears, which can happen when
a paragraph is deleted or becomes not checked. The script is retained so that the proof can be
reexecuted if the paragraph is checked again and the goal exists again.
A proof script is active if its goal exists. Inactive scripts can be deleted by selecting the script’s
name, right clicking, and selecting “Delete” from the pop-up menu.
The Edit window allows new paragraphs to be composed or existing paragraphs to be modified.
The editor provides standard editing capabilities such as insertion and deletion of characters, cut
and paste, motion using cursor keys, and mouse selection. In addition, it provides a palette of Z
symbols below the edit area. Clicking on a symbol inserts it into the edit area at at the insertion
point (where the cursor is).
8 Z/EVES Project TR-99-5493-06a
Boxed paragraphs can be entered by first selecting the appropriate box type from the “Edit”
menu, which clears the editor and inserts a schema, axiomatic, or generic box. The name, decla-
rations , and predicates can then be inserted into the appropriate parts of the box. Alternatively,
boxes can be drawn by selecting the individual box characters from the palette.
Keyboard shortcuts are also available for most special characters. For all letters except j and
v, control-letter is bound to the corresponding Greek letter (control-shift-letter to the capitalized
Greek letter). The most commonly used Greek letters are in the following table.
Symbol λ µ θ ∆ Ξ
Key Ctl-l Ctl-m Ctl-q Ctl-D Ctl-X
Other symbols are available as shown in the following table:
Symbol ¬ ∧ ∨ ⇒ ⇔ ∀ ∃ •
Key Alt-! Alt-& Alt-v Alt-) Alt-= Alt-A Alt-E
S Alt-.
T
Symbol P × ∈ ∅ ⊆ ⊂
Key Alt-P Alt-x Alt-e Alt-0 Alt-z Alt-c Alt-U Alt-I
Symbol ↔ → ◦ C B −
C −
B
Key Alt-j Alt-f Alt-o Alt-r Alt-t Alt-y Alt-u
Symbol N Z < > F a
Key Alt-N Alt-Z Alt-< Alt-> Alt-F Alt-^ Alt-@
Several Z characters are similar in appearance and should be carefully distinguished.
S
• The infix union function ∪ is slightly smaller than the generalized union function .
• The
T infix intersection function ∩ is slightly smaller than the generalized intersection function
.
• The sequence concatenation function a is different from the caret ^, which is not used in Z.
• The schema operator o9 is different from the semicolon ; (which separates declarations and is
relational composition).
We will use a small example, a logging system adapted from Exercise 6.2 in Potter, Sinclair, and
Till’s book [9] to illustrate the use of Z/EVES. For the sake of brevity, we will use only the first few
paragraphs of that specification.
[User , Word ]
LogSys
password : User → 7 Word
reg, active : P User
active ⊆ reg = dom password
InitLogSys
LogSys 0
password 0 = ∅
active 0 = reg 0 = ∅
Register
∆LogSys
u? : User ; p? : Word
password 0 = password ∪ {u? 7→ p?}
active 0 = active
LogIn
∆LogSys
u? : User
p? : Word
u? ∈/ active
p? = password (u?)
password 0 = password
active 0 = active ∪ {u?}
We begin by running Z/EVES, which will eventually display an empty Specification window.
10 Z/EVES Project TR-99-5493-06a
Selecting “New Paragraph” from the “Edit” menu brings up the Edit window. After clicking the
mouse in the edit area, we can type “[User, Word]”.
After select “Done” from the “File” menu in the Edit window, the Specification window now
shows the new paragraph:
Z/EVES Project TR-99-5493-06a 11
The two status bars to the left of the paragraph show question marks, showing that it is not
known to be correct. We can check the paragraph by double clicking on it, or by right clicking on it
and selecting “Check” from the pop-up menu. When the paragraph is checked, the status bars are
updated:
(The paragraph is also selected and so is highlighted.) Both columns contain “Y”: the syntax
and type check succeeded, and there is nothing interesting to prove.
The state schema can be added similarly. Selecting “New Paragraph” from the “Edit” menu
again brings up the Edit window. The easiest way to enter the schema is to select “Schema Box”
from the “Edit” menu, which draws the schema box outlines:
We can then click in the top line, type in the schema name “LogSys”, click in the declaration part
of the box and type in the declarations, then click in the predicate part and type in the schema’s
constraints. Special characters can be entered by clicking on them in the palette below the edit area.
The results (including two typing mistakes included for illustrative purposes) appear as follows:
12 Z/EVES Project TR-99-5493-06a
Note that when a new line is started in the schema box, the box is not drawn. This does not
matter; the schema will be correctly rendered in the Specification window. Selecting “Done” from
the “File” menu adds the paragraph to the specification. Double clicking on the paragraph in the
Specification window checks it:
This time, there are errors. Right clicking on the paragraph and selecting “Show Errors” from
the pop-up menu shows the error messages:
Z/EVES Project TR-99-5493-06a 13
Evidently, active and reg do not have the correct type for the subset relation, and the two sides
of the equality have different types. On inspection we can see we omitted the P operation in the
declaration of active and reg (that is, we wrote reg, active : User instead of reg, active : P User ).
This is readily fixed; we can right click on the paragraph and select “Edit” from the pop-up menu.
When the Edit window appears, we can click on the “U” in “User”; a vertical cursor appears just
before it. Then selecting P from the palette inserts it, so that the declaration is correct. Selecting
“Done” from the “File” menu brings back the Specification window, with a revised definition of
LogSys. The status bars both hold question marks, since the revised version of LogSys has not yet
been checked. After double clicking on the revised paragraph, the check succeeds and both status
bars show “Y”.
Continuing in this way, we can add and check the remaining three paragraphs shown at the start
of this section. When schema Login is checked, the syntax status bar holds a “Y”, as there are no
syntax or type errors, but the “Proof” bar holds a “N”.
This paragraph has an associated goal that has not been proved. This is a domain check asso-
ciated with the paragraph, as explained in Section 3.1.2. We will ignore it for now.
The work done so far can be saved by selecting “Save” or “Save As ...” from the “File” menu.
Work on the specification can be continued later by opening the saved file.
14 Z/EVES Project TR-99-5493-06a
theorem CanInitLogSys
∃ LogSys 0 • InitLogSys
As for other paragraphs, this can be added by selecting “New Paragraph” from the “Edit” menu,
clicking the mouse in the edit area when the Edit window appears, and typing in the theorem using
a combination of keystrokes and selections from the palette.
When “Done” is selected from the “File” menu, this theorem is added to the specification, and
the specification window reappears. When the theorem paragraph is checked, the status bar shows
it to be free of errors but not proved:
The proof can be started by selecting the theorem in the Specification window, right clicking,
and selecting “Show proof”. This exposes the Proof window:
Z/EVES Project TR-99-5493-06a 15
The theorem’s goal predicate is shown in the bottom half of the window. An empty proof script
occupies the top half. As the proof of this theorem involves using the definitions of the schemas
mentioned, we can apply a powerful automatic proving capability by selecting “Prove by reduce”
from the “Reduction” menu appearing in the middle bar of the Proof window. This results in the
following display:
The proof script now contains the proof command we just selected; the “action point” is after
that step, so the formula window shows the result of the step. This result is the predicate false—the
conjecture is not, after all, a theorem.
We can return to the specification window by selecting “Specification” from the “Window” menu
at the top of the Proof window. Inspection of schemas Logsys and InitLogSys shows the source of the
16 Z/EVES Project TR-99-5493-06a
problem: we erroneously wrote active ⊂ reg instead of active ⊆ reg in schema Logsys. This is easily
repaired: selecting schema LogSys in the Specification window, right clicking, and selecting “Edit”
from the pop-up menu exposes the Edit window with the LogSys schema in it. The correction is
easily made. When “Done” is selected from the “File” menu, we are returned to the Specification
window, which now has the following appearance:
As the status bars show, the revised version of LogSys is not checked. Furthermore, all the
following paragraphs are not checked either. Since the modification to LogSys might have changed
the schema’s type, all these paragraphs need to be rechecked with respect to the new definition.
These paragraphs can be checked one by one, by couble clicking on them on at a time. Alternatively,
“Check all paragraphs” can be selected from the “Commands” menu; this will check all the unchecked
paragraphs. There are no syntax or type errors. We can revisit the proof of theorem CanInitLogSys
by right clicking on it and selecting “Show proof” from the pop-up menu. The old proof commands
are retained, but have not yet been executed:
Double clicking on the “prove by reduce” command in the script causes it to be run. Now, it
results in the predicate true, so the conjecture is, indeed, a theorem. If we return to the Specification
Z/EVES Project TR-99-5493-06a 17
window, by selecting “Specification” from the “Window” menu, the status bar has been updated to
show that the proof is complete.
Chapter 3 describes the various analyses supported by Z/EVES in more detail. Chapter 4
describes the Z/EVES prover; Chapter 5 describes techniques for doing proofs.
Analysing Z Specifications
The use of Z, or any other formal notation, in a specification is a great step forward: natural language
specifications are notorious for their ambiguity. Making formal statements about a system can in
itself be beneficial, as it can lead to a careful consideration of the important aspects of the system
and to the development of a consistent terminology.
However, just because a specification is expressed in a formal notation does not mean it is correct,
complete, or even meaningful. There are several different kinds of errors that might appear in a
specification, ranging from trivial spelling errors to subtle inconsistencies in meaning. These errors
are discussed in Section 3.1. Z/EVES can help specifiers avoid many of these errors.
There is a benefit to a formal specification that goes beyond its precision. Formal specifications
can be manipulated, allowing properties of the specification or the specified system to be explored.
One simple operation is the “expansion” and simplification of a schema definition, which might
help a reader better understand the meaning of a complex specification, or might help a designer
when it is not possible to structure the implementation in the way the specification is structured. A
specification is a model of the specified system, and can sometimes be used as a sort of prototype.
It might be possible, for example, to determine the effect of a certain sequence of operations by
calculation. Similarly, it may be possible to show that a system never gets into an undesirable
state by stating and proving appropriate theorems. Section 3.2 shows how Z/EVES can be used to
manipulate specifications in these and other ways.
19
20 Z/EVES Project TR-99-5493-06a
DeleteRecord
∆DataBase
k ? : Key
data 0 = k ? −
C data
When schema DeleteRecord is checked, an error is detected, and the “Syntax” status column
shows that there is an error. Selecting “Show errors” from the pop-up menu for the paragraph
displays the following message:
Error FunctionArgType (line 2) [Type checker]: in application of global ( −C ), argument 1 has
the wrong type.
Unfortunately, the line numbers in error messages are not useful; in any case we plan to replace
the line number with an exact location marked in the given paragraph. This message shows that
the error concerns the type of the first argument of − C. (The prefix global indicates that −C is a
global constant; it is not logically necessary here, but may sometimes help reveal how Z/EVES has
interpreted its input.)
that the second argument is non-zero. When type checking does not guarantee meaningfulness, a
predicate called a domain check is generated. If the domain check is true, then the original expression
is meaningful.
An example may help to clarify how domain checking works. Consider the following schema,
intended to describe a simple personnel database:
Personnel
employees : P PERSON
boss of : PERSON → 7 PERSON
salary : PERSON → 7 N
dom salary = employees
∀ e : employees • salary(e) < salary(boss of e)
When schema Personnel is checked, its status shows that it is syntactically and type correct,
but that it has an unproved goal. Selecting “Show Proof” from the pop-up menu shows the proof
script for Personnel $DomainCheck , with the following goal predicate:
employees ∈ P PERSON
∧ boss of ∈ PERSON → 7 PERSON
∧ salary ∈ PERSON → 7 N
∧ dom salary = employees
∧ e ∈ employees
⇒ e ∈ dom salary
∧ e ∈ dom boss of
∧ boss of e ∈ dom salary
There are three conjuncts in the conclusion to prove, corresponding to the three function appli-
cations in the last predicate of the schema.
We can simplify this predicate by using a rewrite or reduce command (available in the “Re-
duction” menu in the Proof window). The rewrite command produces
employees ∈ P PERSON
∧ boss of ∈ PERSON → 7 PERSON
∧ salary ∈ PERSON → 7 N
∧ dom salary = employees
∧ e ∈ employees
⇒ e ∈ dom boss of
∧ boss of e ∈ dom salary
One of the conjuncts, e ∈ dom salary, was eliminated, but the other two remain. There are
several reasons, in general, why Z/EVES might be unable to prove a predicate; in this case, these
predicates are not true. In fact, these domain checking conditions show that we have forgotten some
constraints in the schema. Both conditions concern the well-definedness of the final condition in
the schema, ∀ e : employees • salary(e) < salary(boss of e). The first, e ∈ dom boss of concerns
the expression boss of e. In this context, e is known only to be an employee. However, not every
employee has a boss (for example, the president would not). So, this quantification should, in fact,
range over only those employees having bosses. (A closer inspection of the schema shows that
boss of is some partial function, with an unspecified domain. This is probably a mistake; bosses of
non-employees should probably not be recorded.)
The second condition, boss of e ∈ dom salary, concerns the expression salary(boss of e). Does
the boss have a salary? This should be obviously true, but it is not—the specification says nothing
22 Z/EVES Project TR-99-5493-06a
about the range of function boss of , so a boss might not be an employee. Again, this was an
oversight in the schema definition.
In the light of this analysis, we can revise the definition to eliminate these flaws:
Personnel
employees : P PERSON
boss of : PERSON → 7 PERSON
salary : PERSON → 7 N
dom salary = employees
dom boss of ⊆ employees
ran boss of ⊆ employees
∀ e : dom boss of • salary(e) < salary(boss of e)
(This schema also has a nontrivial domain check condition, but this time we can show it to be
true.)
3.1.3 Inconsistency
A specification is meant to be a model of some possible system. A specification is inconsistent if
it has no models. There are two different types of inconsistency, which we call global inconsistency
and local inconsistency. Of the two, global inconsistency is the more serious, as it renders an entire
specification unsatisfiable.
Global inconsistency
An entire specification can be inconsistent if some axiom box, generic box, or predicate is too strong.
For example, any specification containing the paragraph
n:Z
n 6= n
has no models, as there is no possible value for n. In this case, the inconsistency is obvious, but in
general it can be less so. For example, there is no function f satisfying the following description:
f :N→N
∀ n, n 0 : N • n < n 0 • f (n) > f (n 0 )
An inconsistency can also arise between different paragraphs in a specification, each of which,
on its own, is consistent.
Z/EVES does not provide any specific mechanism for detecting such inconsistencies, but has
general mechanisms that can be used to detect them. For example, an axiomatic box
D
P
maxLength : N
maxLength > 80
Z/EVES Project TR-99-5493-06a 23
is satisfiable.
Unfortunately, it is not always easy to prove such conjectures; to do so, it is necessary to ex-
hibit suitable values for the declared names. The Z notation does not always provide convenient
expressions for this. For example, to show the satisfiability of the definition
exp : Z × N → Z
∀ x : Z; n : N •
exp(x , 0) = 1
∧ exp(x , n + 1) = x ∗ exp(x , n),
we need to prove
∃ exp : Z × N → Z •
∀ x : Z; n : N •
exp(x , 0) = 1
∧ exp(x , n + 1) = x ∗ exp(x , n).
There is no convenient expression to use for exp here; the most obvious candidate is defined
recursively, and Z provides no facility for recursive definitions. However, the Z/EVES Mathematical
Toolkit offers a theorem generalPrimitiveRecursion that shows that functions like exp exists:
theorem generalPrimitiveRecursion [Result, Parameter ]
∀ base : Parameter → Result; step : Result × N × Parameter → Result •
∃ f : N × Parameter → Result •
∀ p : Parameter •
f (0, p) = base(p) ∧ (∀ n : N • f (n + 1, p) = step(f (n, p), n, p))
Unfortunately (and rather typically), this theorem gives us a function that takes its arguments
the wrong way around. However, it is possible, although rather excruciating, to use this theorem
to show that exp exists. The full proof can be found in the examples directory distributed with
Z/EVES.
It is not always possible to show consistency one paragraph at a time; sometimes a group of
paragraphs need to be considered as a whole. This is often the case for a constraint paragraph. For
example, consider the two paragraphs
count : Z
count ∈ 0 . . 99
(which in a real specification might be separated by several other paragraphs). These need to
be combined before showing consistency. In general, it might be necessary to combine several
paragraphs before showing consistency.
Situations involving given types are more complex. Consider, for example, the given type
[Name]
and the assertion that Tom, Dick, and Harry are three distinct names:
Tom, Dick , Harry : Name
#{Tom, Dick , Harry} = 3.
We cannot state the relevant consistency condition (which would express the proposition that
Name :, Tom, Dick , and Harry exist). However, given a set S that could be a suitable meaning for
Name :, we can then express the proposition
24 Z/EVES Project TR-99-5493-06a
Local inconsistency
A schema can have a predicate that is not satisfiable. If such a schema is meant to describe the state
of a system, then that system is impossible; if it is meant to describe an operation, then the operation
can never be successfully invoked. In either case, the specification is probably in error. Such an
error is local , however, in that theorems proved in a specification having only local inconsistencies
are, in fact, theorems, and specifications of other components of a system may still be meaningful.
It is easy to express the satisfiability of a schema S , using the predicate ∃ S • true. Sometimes
a more impressive alternative is available: many specifications give an initialization schema of the
form Init S = b [S | P ], where the predicate P further constrains the state. In such a case, showing
∃ S • Init S not only shows that S is satisfiable, it also shows that initial states are possible.
For example, given the (corrected) schema declaration Personnel above, and the initialization
schema
InitialPersonnel
Personnel
salary = ∅,
we can show
theorem InitialPersonnelIsPossible
∃ Personnel • InitialPersonnel
as follows:
proof
invoke;
prove;
instantiate boss of == ∅;
invoke;
prove;
the specification or of the specified system to be explored. Z/EVES supports several different types
of exploration, which are described in the sections below.
NewAccount
∆Bank
users? : P1 Client
id ! : ID
id ! ∈
/ accounts
∃ Account 0 | OpenAccount • account 0 = account ⊕ {id ! 7→ θAccount 0 }
which refers to schemas ∆Bank , Account, and OpenAccount. We can begin a proof attempt, with
schema NewAccount used as a predicate, by adding a paragraph
theorem NewAccountExploration
NewAccount
and checking it. This gives a new goal. Selecting the proof for this paragraph (e.g., by right
clicking on the theorem in the specification window and selecting “Show proof”), exposes a proof
window with this predicate NewAccount as the goal.
Issuing the command prove by reduce then results in the new goal predicate
account ∈ ID → 7 Account
∧ accounts = dom account
∧ users? ∈ P Client
∧ id ! ∈ ID
∧ account 0 = account ⊕ {(id !, θAccount[balance := 0, users?/users])}
∧ accounts 0 = {id !} ∪ dom account
∧ ¬ users? = {}
∧ ¬ id ! ∈ dom account
where all the schema references have been expanded, and some simplification has occurred. In
particular, the one-point rule applied to eliminate the existential quantifier, and some redundant
conjuncts were eliminated.
After the exploration is complete, the theorem paragraph should be deleted.
3.2.2 Preconditions
The Z style of specifying operations is relational; an operation is specified (in the normal convention)
as a relation between initial and final states. This style has a number of advantages, but has the
disadvantage of leaving the precondition of an operation implicit. For example, an operation
26 Z/EVES Project TR-99-5493-06a
Op
n, n 0 : N
n0 = n − 1
describes only situations where the initial value of n is non-zero. The conventional interpretation
of this is that if Op is invoked with n = 0, there are no guarantees about what might happen—the
operation might fail catastrophically, might never terminate, or might yield some ordinary result
state (which need not even satisfy n 0 ∈ N; more generally, such an operation may result in a state
that does not satisfy the predicate part of the state schema). Clearly, the circumstances under which
this can occur are of some interest.
Z provides a reference to the precondition of an operation schema; for a schema Op = b [∆S ; in? :
IN ; out! : OUT ] the schema reference pre Op is equivalent to ∃ S 0 ; out! : OUT • Op, and describes
the initial states for which an output and a final state are possible. If the operation is total, it can be
executed in any starting state and with any inputs; thus ∀ S ; in? : IN • pre Op should be a theorem.
Trying to prove this conjecture can uncover any missing hypotheses. A correct precondition theorem,
of the form ∀ S ; in? : IN | P • pre Op, where P gives the precondition, can be a useful form of
documentation of a specification.
For example, a Canadian City Hall marriage registry might contain a record of all married
couples, using a relation wife of . This relation is, in fact, a partial injection from men to women—
partial because not all men are married; a function because a man may have at most one wife, an
injection because a woman may have at most one husband.
Registry
7 Woman
wife of : Man
Wedding
∆Registry
bride? : Woman
groom? : Man
wife of 0 = wife of ∪ {groom? 7→ bride?}
theorem WeddingPrecondition
∀ Registry; bride? : Woman; groom? : Man • pre Wedding
After checking this paragraph, we can work on its proof. The command prove by reduce results
in the predicate
wife of ∈ Man
7 Woman
∧ bride? ∈ Woman
∧ groom? ∈ Man
⇒ wife of ∪ {(groom?, bride?)} ∈ Man
7 Woman.
The various schema definitions have been expanded, the one-point rule was applied, and some
simplification was done. The predicate asserts that the updated value of wife of must be a partial
injection. We can explore this predicate further. The Z/EVES library has many rewriting rules
that are not applied automatically. If a part of the goal predicate is selected and the right mouse
Z/EVES Project TR-99-5493-06a 27
button is pressed, any of these disabled rewrite rules that apply to the selected part of the formula
can be seen in the “Apply to predicate” or “Apply to expression” submenu. In this case, selecting
wife of ∪ {(groom?, bride?)} ∈ Man 7 Woman (e.g., by sweeping the mouse across it or by clicking
inside it enough times), there is only one applicable rewrite rule, cupInPinj . This theorem describes
when a union is a partial injection, and is disabled , so that it is not normally applied automatically
by a Z/EVES step. (The Toolkit author made this choice because it seemed unwise to introduce
the rather complex replacement predicate of this rule without the user’s consent.)
Selecting this name from the “Apply to predicate” submenu results in a lengthy predicate we
will not show here. The reduce command then results in the predicate
which expresses rather concisely the precondition: if the groom is previously married, then the bride
must be his wife, and similarly, if the bride is already married, then the groom must be her husband.
We can go back to the Specification window to revise the theorem to its correct form, making
the actual precondition apparent:
theorem WeddingPrecondition
∀ Registry; bride? : Woman; groom? : Man
| bride? ∈
/ ran wife of ∧ groom? ∈
/ dom wife of
• pre Wedding
This can be rechecked and reproved. The commands used in the exploration are still in the proof
script, and can be rerun (by double clicking them in sequence) to complete the proof.
3.2.3 Invariants
Given a sequential system, defined with an initialization schema Init and a collection Op1 , . . . , Opn
of operations, a predicate I is an invariant if Init ⇒ I , and for every i ∈ 1 . . k , I is preserved by
the i th operation (that is, we have I ∧ Opi ⇒ I 0 ). Such invariants can be important for a variety
of reasons:
The conditions on an invariant are directly expressible in Z, and so no special mechanisms are
needed in Z/EVES to allow their proof.
Here is a trivial example of an invariant proof. Our system has a simple state consisting of a
number
State
n : Z,
Init
State
n = 0,
Inc
∆State
n 0 > n.
theorem SystemInvariant
(Init ⇒ n ≥ 0) ∧ (Inc ∧ n ≥ 0 ⇒ n 0 ≥ 0).
NonNegative
State
n≥0
theorem SystemInvariant
(Init ⇒ NonNegative) ∧ (Inc ∧ NonNegative ⇒ NonNegative 0 ).
3.2.4 Refinement
Z is often used to describe abstract data types. A state schema gives an abstract model of the set
of values of the type, an initialization schema describes the possible initial values, and one or more
operation schemas describe the operations on the type. In these cases, Z can also be used to express
implementations of abstract data types, by giving a second (more concrete) abstract data type and
proving that a refinement relation holds between the two types. The rules for proving a refinement
are described in detail by Woodcock and Davies [15], who give two different sets of rules (one
1 This
uses an interpretation of operation schemas that considers the precondition of a schema to be an enabling
condition, in which the operation is allowed to be invoked.
Z/EVES Project TR-99-5493-06a 29
for “forward simulation” and the other for “backward simulation”). Of the two systems, forward
simulation is the most commonly used. Given an “abstract” system with state A, initialization
schema AI , and operation AO, and given a similar “concrete” system with state C , initialization
schema CI , and operation CO, we can demonstrate a forward simulation by exhibiting some relation
R between the abstract and concrete states, proving the initialization theorem
∀ CI • ∃ AI • R,
∀ R | pre AO • pre CO
shows that the concrete operation can be invoked whenever the abstract operation can. Secondly,
∀ R; CO | pre AO • ∃ A0 • AO ∧ R 0
shows that when the abstract operation can be invoked, it can give a result consistent with the
concrete operation. (There are several equivalent ways to express these relations; the presentation
here differs from Woodcock and Davies in form but not in meaning.)
For example, here is a definition of a trivial system that dispenses numbered “tickets,” so that a
different number is issued on every call. The state thus has a component that records the numbers
that have been issued:
TicketA
given : P Z
InitA
TicketA
given = ∅
A new ticket may be requested; the resulting number has not previously been issued, and is
recorded in the set of issued tickets:
NewA
∆TicketA
t! : Z
t! ∈
/ given
given 0 = given ∪ {t!}
TicketC
next : N
InitC
TicketC
next = 0
NewC
∆TicketC
t! : Z
t! = next
next 0 = next + 1
To show that the concrete system refines the abstract system, we need the abstraction relation.
Here, the set of given numbers is the range 0 . . (next − 1):
TicketAbs
TicketA
TicketC
given = 0 . . (next − 1)
Now we can prove that corresponding operations are refinements. For initialization, we show
theorem initRefinement
∀ InitC • ∃ InitA • TicketAbs
which can be proved with a prove by reduce command. (Obviously, reduce is needed here, as the
definitions of most of the schemas must be expanded in the proof.)
For the New operation, we have two things to show. First, the preconditions are suitably related:
theorem newAbs1
∀ TicketAbs | pre NewA • pre NewC
theorem newAbs2
∀ NewC ; TicketAbs | pre NewA • (∃ TicketA0 • NewA ∧ TicketAbs 0 )
next ∈ Z
∧ next 0 = 1 + next
∧ t! = next
∧ given = 0 . . 1 + next
∧ t 0! ∈ Z
∧ given 0 = {t 0!} ∪ (0 . . 1 + next)
∧ next ≥ 0
∧ (0 ≤ t 0! ⇒ ¬ t 0! ≤ 1 + next)
⇒ {t!} ∪ (0 . . 1 + next) = 0 . . next
This is obvious, but Z/EVES is missing a trivial fact about ranges. We can add the following
lemma:
Z/EVES Project TR-99-5493-06a 31
theorem rangeExtension
∀ a, b : Z | a ≤ b • a . . b = (a . . b − 1) ∪ {b}
This is easily proved by extensionality; after the commands apply extensionality and prove,
we are left with the predicate
a∈Z
∧b∈Z
∧a≤b
∧ (y = b ∨ (a ≤ y ∧ y ≤ 1 + b))
⇒a≤y ∧y ≤b
which Z/EVES failed to prove automatically because it requires some consideration of cases. Using
any of the normalizing reduction commands (i.e., with normalization simplify, with normalization
rewrite, or with normalization reduce) which can be found under the “Normal Forms” menu
item in the proof commands menu bar, is all that is needed to complete the proof.
With this lemma in place, we can complete the refinement proof. In the specification window,
the lemma’s theorem paragraph must be moved to appear before theorem newAbs2. Then newAbs2
can be rechecked and its proof retried. The prove by reduce command gives the same result as
before; we then use an instance of the lemma and let Z/EVES finish the proof:
proof
prove by reduce;
use rangeExtension[a := 0, b := next] ;
prove;
The interface offers no handy way to enter the “use” command. It can be added by selecting
“New command” from the “Edit” menu and typing it in.
Account
balance : Z
OpenAccount
Account
balance = 0
Deposit
∆Account
amount? : N
balance 0 = balance + amount?
Withdraw
∆Account
amount? : N
balance 0 = balance − amount?
Here we have used a Z/EVES syntax extension (schema replacement) to set the values of the
inputs to the operations. This extension is not strictly necessary; for example, Deposit[amount? :=
100] could be written in Standard Z as ∃ amount? : Z | amount? = 100 • Deposit or as [Deposit |
amount? = 100] \ (amount?).
With the test cases defined, we can simply use schema expansion to see what happens. For
example, trying Test3 is possible by defining a theorem
theorem TryTest3
Test3
In the “proof” of this theorem, the command prove by reduce results in the formula
balance 0 = 520.
Some caution is advised in the use of test cases; sequential composition of operation schemas
does not exactly correspond to the sequential composition of the operations. In particular, it does
not account for cases where one operation results in a state not in the precondition of the next.
Furthermore, in a schema composition, any two outputs of different operations, if they have the
same name, must have the same value.
Ticket
given : P Z
Init
Ticket
given = ∅
Z/EVES Project TR-99-5493-06a 33
New
∆Ticket
t! : Z
t! ∈
/ given
given 0 = given ∪ {t!}
We can show that two successive invocations of the New operation will not return the same ticket
value.
TwoTickets =
b New o
9 New [t2!/t!]
theorem twoTicketsNotSame
∀ TwoTickets • t2! 6= t!
The Z/EVES prover combines automatic strategies and detailed user steps, allowing for a collabo-
rative effort in completing a proof. Z/EVES can look after mundane details such as side-conditions
on proof steps and trivial subgoals, leaving the user free to focus on the main line of argument of a
proof.
Z/EVES offers some powerful automatic commands for proving theorems (e.g., prove, or reduce).
However, these commands will only succeed in proving easy theorems, and then only when the way
has been prepared. For example, when a name is defined by an abbreviation definition, axiomatic
box, or generic box, it may be necessary for some simple theorems to be stated before the automatic
steps can succeed.
In this chapter, we will describe the Z/EVES proving mechanisms in detail; later chapters will
offer guidance on how to use these mechanisms effectively. There are two main aspects to effective
use of the prover: first, guiding the proof, and second, developing a theory in a way that supports
the prover’s capabilities.
Even with the best use of the automatic capabilities of the system, however, there will be proofs
that are not fully automatic. Indeed, this is likely to be the rule rather than the exception. In these
situations, the Z/EVES user needs to know a proof, or at least an outline of a proof; Z/EVES can
then be used to check this proof (ensuring that all side-conditions are satisfied) and, perhaps, to fill
in any missing details. This is described in Chapter 5.
the problem.
35
36 Z/EVES Project TR-99-5493-06a
example, the fact that i is an integer is expressed by the predicate i ∈ Z. Z/EVES has no special
deductive mechanism for type information; its normal rules for predicates are used.
Types appear in a variety of side-conditions, and sneak into proofs through their appearance in
generic actuals. While Z allows the generic actual parameters in a global reference to be omitted
(e.g., users write N ∪ N1 or #(1 . . 10)), the semantics of Z rely on the presence of these actuals,
and Z tools infer suitable actuals when users omit them. For example, N ∪ N1 represents the fully
explicit term ( ∪ )[Z](N, N1 ). While these generic parameters are normally uninteresting, a sound
proof system for Z must take them into account; it is easy to produce a “proof” of false in a system
that ignores implicit generic actuals.3
Z/EVES follows common practice in omitting uninteresting generic actuals in its printed rep-
resentation of a formula; however, its internal representation maintains them, and they sometimes
resurface in side conditions. For example, the Z/EVES Toolkit contains the theorem
any[X ] == X
T ::= t
if we ignore the missing generic actuals we can develop the predicate ∀ x , y : any | x = t • x = y in two ways; first,
by observing that x = t is always true (if well typed), hence the predicate is equivalent to ∀ x , y : any • x = y, which
is clearly false (e.g., for x = 0 and y = 1); and second, by observing that if x = t holds, and x and y have the same
type, then x and y are both in T , are both equal to t, and so are equal. Therefore, the predicate is true.
Z/EVES Project TR-99-5493-06a 37
inserted into the specification at a point before where it is needed. This insertion will cause any
later paragraphs to become not checked.
Each specification starts in the context of the Mathematical Toolkit [10]. There is at present no
support for sections in the Z/EVES interface.
Theorems can be stated explicitly in a specification by theorem paragraphs. Theorems are also
derived from the predicates in an axiom box or generic box. Domain-checking theorems can be
generated for paragraphs. Finally, Z/EVES may generate “implicit” theorems when a paragraph is
added, as explained in the Z/EVES Reference Manual.
Every Z/EVES theorem, whether explicit or implicit, has a name that can be used to refer to
it in a proof step. This name is provided as part of a theorem paragraph, and can be attached to
a predicate in an axiom box or generic box by means of a label (which appears in chevrons before
the predicate, e.g., hhcNonnegativeii c ≥ 0). If no name is given, Z/EVES assigns a name. Implicit
theorems always have names assigned by Z/EVES.
2 ∈ 1 .. 3
⇔ definition of . .
2 ∈ {x : Z | 1 ≤ x ≤ 3}
⇔ set theory
∃x : Z | 1 ≤ x ≤ 3 • x = 2
⇔ one-point rule
2∈Z∧1≤2≤3
⇔ arithmetic
true
In this informal proof, we have given a hint for every step in the chain. In developing a proof
with Z/EVES, we use proof commands to transform each predicate to the next.
It is possible to follow this proof plan in Z/EVES, but we seldom want to work at this level of
small details. Indeed, the rewrite, reduce, and prove commands each complete this proof in a
single step. For illustration, here is the detailed proof in Z/EVES:
We begin the proof by adding a theorem (with the “New Paragraph” function in the “Edit”
menu)
theorem SimpleTheorem
2 ∈ 1 .. 3
checking it, then selecting it in the Specification window, right clicking, and selecting “Show proof”
from the pop-up menu. The “definition of . . ” referred to above is recorded as theorem rangeDef
in the Toolkit. As it is a (disabled) rewrite rule, we can “apply” it. The simplest way to do so is
to select the expression 1 . . 3 in the formula (by clicking the left mouse button in it until it is fully
highlighted), then right clicking, and looking at the choices in the “Apply to expression” submenu
4 This is not true in two cases. First, a leading universal quantifier can be removed from a predicate, giving a
predicate that is not logically equivalent (but which is a theorem if and only if the original goal is). Second, the cases
command allows a conjunct or disjunct of a goal to become a new goal, with the other parts temporarily hidden.
38 Z/EVES Project TR-99-5493-06a
of the pop-up menu. Selecting rangeDef from this menu causes the prover rewrite with it, replacing
1 . . 3 by a set comprehensioin term and resulting in the new goal predicate
2 ∈ if 1 ∈ Z ∧ 3 ∈ Z then {k : Z | 1 ≤ k ∧ k ≤ 3} else 1 . . 3
The two side conditions did not appear in our informal proof. We can eliminate them by simpli-
fication (command “Simplify” from the “Reduction” menu):
2 ∈ {k : Z | 1 ≤ k ∧ k ≤ 3}
The next step of our informal proof referred to “set theory,” the rules of which are encoded
by a large collection or rewrite rules in Z/EVES and the Mathematical Toolkit. The rewrite
command would apply them here and complete the proof. The trivial rewrite command (in the
“Reduction” menu) applies just the most elementary rules, with no further simplification:
∃k : Z • 1 ≤ k ∧ k ≤ 3 ∧ 2 = k
The simplify command (in the “Reduction” menu) applies the one-point rule when possible:
2∈Z
For technical reasons, the application of the one-point rule often results in the “type” conditions
of the quantification remaining unsimplified. A final simplify step completes the proof, giving the
goal predicate
true
Here is an example of a more realistic proof in Z/EVES, using an explorative style, as described
in Chapter 5.
theorem SimpleTheorem2
∀ k : N • id(1 . . k ) ∈ seq N
The prove command (in the “Reduction” menu) often completes simple proofs automatically,
and otherwise usually eliminates the uninteresting parts of a conjecture, so we apply it here. It does
not complete the proof here, but results in the predicate
k ∈Z∧k ≥0
⇒ id(1 . . k ) ∈ seq N
We will appeal to the definition of seq. Clicking on the “seq” in the goal predicate highlights it;
right clicking exposes a pop-up menu. Selecting “Expand this name” directs the prover to use the
definition of seq, giving the new goal predicate
k ∈Z∧k ≥0
⇒ id(1 . . k ) ∈ {f : N →
7 N | ∃ n : N • dom[Z, N]f = 1 . . n}
k ∈Z∧k ≥0
⇒ (∃ n : N • k = n ∨ k < 1 ∧ n < 1)
Z/EVES was not able to find the right instantiation for n. We can specify the correct instance
in a proof step. There is no convenient gesture in the interface for instantiating, so it is necessary to
select “New Command” from the “Edit” menu, type in the command instantiate n == k, select
Z/EVES Project TR-99-5493-06a 39
“Done” from the “File” menu in the editor, then run the command from the proof script window
(by double clicking on it). This gives the new goal predicate
k ∈Z∧k ≥0
∧ ¬ (k ∈ N ∧ (k = k ∨ k < 1 ∧ k < 1)
⇒ (∃ n : N • k = n ∨ k < 1 ∧ n < 1)
4.2 Automation
Z/EVES has a number of automatic commands, which can drastically change the goal predicate.
It is best to have some understanding of the general effects of these commands, and how they use
theorems, before embarking on any difficult proof in Z/EVES.
• the result is, in general, P 0 ∧ Q 0 ⇒ R 0 . If one or more of the new predicates is true or false,
it can either be eliminated, or the whole predicate replaced by true or false.
The three reduction commands differ in the way they “consider” subformulas. Each of the
commands can apply certain theorems or definitions, as explained in the detailed descriptions below.
The reduction commands use only theorems and definitions that are enabled . The declaration of
a name or theorem may specify that the name should normally be disabled. A command modifier
can be used to enable or disable a theorem or definition for a single reduction command; see the
Z/EVES Reference Manual for details.
By default, Z/EVES retains the propositional structure of a predicate during traversal. In some
situations, however, consideration of cases is suggested. For example, in traversing the predicate
(P ∨ Q)
∧ (P ⇒ R)
∧ (Q ⇒ R)
⇒R
the prover is unable to infer the conclusion R.
If normalization is used, any time there is a Boolean connective nested inside another, there is
a consideration of cases. So, for example, a predicate of the form (P ∨ Q) ∧ R is converted into
if P then R else (Q ∧ R). When the if-form is traversed, R is considered twice, once with P
assumed and once with P denied and Q assumed. In the above example, normalization gives a long
formula, where R can be inferred.
Thus, normalization increases the power of the prover. However, since normalization involves
repeating parts of a formula, the current goal can become extremely large, so it is disabled by
default. The with normalization command modifier enables normalization during performance of
the specified command. Prover comands with normalization are available in the “Normal forms”
menu in the Proof window.
The extra power that normalization gives Z/EVES is especially noticeable when, for example, a
hypothesis of the current goal is a disjunction or an implication.
Sometimes the rearrange command can be used instead of normalization; rearrangement puts
simple parts of a formula ahead of complex ones, and tends to move nested Boolean connectives to
the end of the conjunction or disjunction containing them. The rearrange command appears in the
“Normal forms” menu in the Proof window.
4.2.2 Simplification
In simplification, Z/EVES performs equality and integer reasoning, propositional reasoning and
tautology checking, and applies forward rules and assumption rules where possible.
Propositional logic
The rules of propositional logic (e.g., the rules for the basic logical connectives) are encoded in the
traversal, normalization, and Boolean simplification mechanisms.
As a predicate is read and its parts considered, the context of assumptions available at each part
is determined by the propositional rules. During simplification, if a predicate is considered, and it
has already been assumed in the context, it is replaced by true. If it has been assumed false in the
context, it is replaced by false.
If a Boolean combination of predicates is considered, and some parts are true or false, the parts
can be deleted (if they are redundant, e.g., x = 1 ∧ true can be replaced by x = 1) or the Boolean
combination can be replaced by true or false (e.g., x > 2 ⇒ true can be replaced by true).
These two mechanisms (traversal and Boolean simplifications) allow the simplifier to recognize
many tautologies. For example, simplification replaces the predicate x ∈ S ⇒ x ∈ S in two steps:
first, the second occurrence of x ∈ S is replaced by true; second, x ∈ S ⇒ true is replaced by true.
When normalization is used (e.g., in the command with normalization simplify), the sim-
plifier recognizes all tautologies.
Z/EVES Project TR-99-5493-06a 41
Equality
The simplifier has a decision procedure for the facts about equality (including the substitution of
equals for equals). For example, the predicates x = x , x = y ⇒ y = x , and X = Y ⇒ P X = P Y
are all recognized as true.
Arithmetic
Simple arithmetic facts are known to the simplifier. For example, simplification turns 1 < 2 into
true, and 2 > 3 + 4 into false. The simplifier also deals with linear arithmetic (involving addition,
negation, or multiplication by a literal constant). For example, x > 1 ⇒ x > 0 is recognized as true,
as are ∀ x , y, z : Z • x ≤ y ≤ z ⇒ x ≤ z and ∀ x , y : Z | 1 ≤ x ∧ 2 + 3 ∗ x ≤ y • 5 ≤ y.
More complex terms can appear in place of the variables in these examples, so long as these terms
are known to be integer. (A term t is known to be integer if the fact t ∈ Z is in the context. As
explained below, it is sometimes useful to define assumption rules to add such facts to the context.)
Assumption rules
During traversal, any theorems labelled as “grules” (assumption rules) can be used. As explained
in the Z/EVES Reference Manual, an assumption rule has a trigger formula. If, during traversal,
an instance of a rule’s trigger is considered, the rule may be applied. If the rule’s predicate is not
an implication, it is added to the context. If the predicate is conditional, the hypotheses are looked
up. If the hypotheses are true, the conclusion is added to the context. (A hypothesis is “looked up”
by seeing if a contradiction results from assuming it to be false.)
Assumption rules are frequently used to make the type of a global reference known, or to add
inequalities concerning integer global constants. Consider, for example, the paragraph
maxLength : N1
Now, whenever the prover encounters maxLength, it will add the fact maxLength ≥ 1 to the
context. With this extra fact, the simplifier can prove simple arithmetic facts, e.g., ∀ x : Z •
x + maxLength > x or maxLength + maxLength ≥ 2.
Forward rules
As explained above, a context is maintained during traversal. This context is a set of predicates
that are assumed true. When a predicate is added to the context, it may trigger a forward rule.
A forward rule is a theorem of the form P ⇒ Q that has been labelled with the usage frule.
(There are other restrictions on the form of such a rule; see the Z/EVES Reference Manual for
details.) If an instance of P is added to the context, the forward rule fires, and the corresponding
instance of Q is also added.
When a schema is declared, a forward rule is automatically generated. For the schema S = b
[x , y : Z | x < y], this rule is S ⇒ x ∈ Z ∧ y ∈ Z. Thus, whenever S is assumed, the types of its
42 Z/EVES Project TR-99-5493-06a
components x and y are known. For the schema T = b [S , S 0 | . . .], this forward rule is T ⇒ S ∧ S 0 .
0
Thus, whenever T is assumed, so are S and S ; this then triggers the forward rule for S (twice) to
add information about x , y, x 0 , and y 0 .
The syntactic restrictions on forward rules make them somewhat limited in their usefulness. The
most common use for forward rules is to forward chain from schema references, to add equalities or
inequalities to the context. For example, suppose we have the schema
ResourceManager
owner : Resource →7 User
in use : P Resource
in use = dom owner .
Free
∆ResourceManager
r ? : Resource
u? : User
r ? ∈ in use
owner (r ?) = u?
owner 0 = {r ?} −
C owner ,
This can, of course, be proved with the reduce or prove by reduce commands. Sometimes,
however, it is undesirable to invoke the ResourceManager schema. In this simple example, it does
not matter much, but if the schema definition and the domain condition were more complex, the
use of reduction would expand the formula too much. In such a case, it might be useful to add the
forward rule
With this forward rule in place, whenever a reference to schema ResourceManager is assumed, the
simplifier will also assume in use = dom owner . Thus, in the domain condition above, by the time
r ? ∈ dom owner is considered, ∆ResourceManager and r ? ∈ in use have been assumed. Z/EVES
automatically adds a forward rule for the “above the line” material in a schema, so the assumption
∆ResourceManager triggers the automatic rule and adds ResourceManager and ResourceManager 0 .
Forward rule ResourceManagerFact is triggered by both these, so in use = dom owner and in use 0 =
dom owner 0 are added. With all these facts in the context, r ? ∈ dom owner is recognized as true.
Thus, the domain check can be proved with the rewrite or prove commands. This might be
significantly faster than proofs that expand the definition. More significantly, however, if the proof
fails, then the resulting goal will be more compact and easier to read if the schemas are not expanded.
4.2.3 Rewriting
In rewriting, Z/EVES performs simplification, and also applies rewrite rules where possible. A
rewrite rule, in general, is a theorem having the form Condition ⇒ Pattern = Replacement
(or Condition ⇒ Pattern ⇔ Replacement), where Condition is a predicate, and Pattern and
Z/EVES Project TR-99-5493-06a 43
Replacement are both expressions or are both predicates. In the rewrite command, when a sub-
formula is considered during traversal, a rewrite rule can be applied if its pattern matches the
subformula (i.e., the subformula is an instance of the pattern). In this case, the corresponding
instance of the condition is considered. If the condition is recognized as true, then the subformula is
replaced by the corresponding instance of the replacement. This new subformula is then traversed
again (so that further simplifications, rewritings, or reductions are possible).
Rewrite rules are the most easily used automation mechanisms. Unlike assumption rules and
forward rules, which have an effect only on the context, rewrite rules cause explicit changes to the
goal predicate. Furthermore, rewrite rules can be applied with the apply command, which has an
immediate effect on the goal predicate. In contrast, forward rules and assumption rules have an
indirect effect, by adding facts to the context as a goal is traversed.
The Z/EVES Mathematical Toolkit is full of rewrite rules. For example, it contains the rules
of the schema or abbreviation, and the result will again be reduced. As well, conditional rewrite
rules apply if their conditions can be shown to be true by reducing.
The reduce command is useful in proofs where it is necessary to appeal to the definitions of
the terms involved. It is very commonly used in proofs about schemas, for example, or about
abbreviations.
In proofs about complex schemas, or in theories with long chains of definitions, reduction may be
inadvisable, as the goal will be reduced to primitive terms. It is usually better to introduce enough
theorems about the defined notions (as described in Chapter 6) so that the notions can be kept in
the goal. This usually gives easier to read goals and more manageable proofs. Definitions can be
expanded selectively with the invoke command when it is appropriate to do so in a proof. A defined
name appearing in a goal predicate (in the Formula part of the Proof window) can be invoked by
selecting it, right clicking, and selecting “Expand this name” from the pop-up menu.
Proving Theorems
Z/EVES supports theorem proving in a variety of ways. In this chapter, we will describe two styles
of using the prover: explorative and planned.
In an explorative proof, a user begins with some goal to prove and does not necessarily know a
proof. Various prover commands can be used to explore the proof space, and, with some luck, the
goal can be proved. In this mode, the user hopes to make maximum use of the automatic facilities
of the prover.
In a planned proof, a user spends some time working out an informal proof of the goal before
starting to work on the proof in Z/EVES. As we describe below, an informal proof can usually be
used to guide a Z/EVES proof session.
Which of these two modes is used is a matter of personal choice. Explorative proofs are often
successful for simple goals, and we often begin a proof session with a brief period of exploration. If
that does not look promising, rather than continuing to explore we stop to think about the goal and
sketch an informal proof. This informal proof may have fairly large gaps, however, which become
new proof goals. We often deal with these exploratively, and so our Z/EVES session is an intermixing
of the two modes of proof.
45
46 Z/EVES Project TR-99-5493-06a
[X ]
dj : PX ↔ PX
hh disabled rule djDef ii
∀ A, B : P X • A dj B ⇔ A ∩ B = ∅
In trying this proof, a prove or prove by reduce command does nothing. Of course, we need
to use the definition of relation dj , as expressed by theorem djDef . As that is a disabled rule,
we can apply it. There are two ways to do so: compose a new proof command apply djDef in the
editor and add it to the proof script, or select the expression A dj [X ]{} in the goal predicate, right
click, and select djDef from the “Apply to expression” submenu of the pop-up menu. In either case,
we get the new goal
A ∈ PX
⇒ (if A ∈ P X ∧ {} ∈ P X
then A ∩ [X ]{} = ∅[X ]
else A dj [X ]{})
Now we will use the prove command to clean this up and see what results. In this case, prove
results in true and our proof is complete.
The next theorem shows that disjointness is a symmetric relation:
theorem djIsSymmetric [X ]
∀ A, B : P X • A dj B ⇔ B dj A
The symmetry of disjointness similarly needs to use the definition of dj , and is otherwise
trivial:
proof
apply djDef ;
prove;
A set is disjoint from a union only if it is disjoint from the two summands:
proof
apply djDef ;
prove;
Z/EVES Project TR-99-5493-06a 47
This time, the proof is not complete; we are left with the goal
A ∈ PX ∧ B ∈ PX ∧ C ∈ PX
⇒ (if A ∩ [X ]C = {}
then C ∩ [x ](A ∪ [x ]B ) = {} ⇔ B ∩ [X ]C = {}
else ¬ C ∩ [X ](A ∪ [X ]B ) = {})
We can try some algebraic reasoning here, using the fact C ∩(A∪B ) = (C ∩A)∪(C ∩B ) followed
by the observation that a union of two sets is empty if and only if the two sets are themselves both
empty. We could look for this theorem in the Toolkit documentation, or alternatively, can select
the subexpression C ∩ [x ](A ∪ [x ]B ) = {}, right click, and look through the “Apply to expression”
submenu. The very first choice is a theorem called distributeCapOverCupRight. Selecting this causes
both occurrences of the selected subexpression to be rewritten. Running a prove command to clean
up the formula in fact completes the proof: the goal is now true. We are in luck; the fact about
empty unions was applied automatically by the prove command.
Theprevious theorem has a symmetric counterpart (with the union in the left argument of dj
rather than the right):
We could prove this theorem in the same way we proved djCupLeft (but probably using a different
distribution law). Instead, here we will try a different line, appealing to to symmetry of disjointness
and using djCupLeft:
proof
use djIsSymmetric[X ][B := B ∪ [X ] C ];
prove;
A ∈ PX
∧ B ∈ PX
∧ C ∈ PX
∧ (if B dj [X ]A then (A dj [X ]B ∪ [X ]C ⇔ C dj [X ]A) else ¬ A dj [X ]B ∪ [X ]C )
⇒ (if A dj [X ]B then (A dj [X ]B ∪ [X ]C ⇔ A dj [X ]C ) else ¬ A dj [X ]B ∪ [X ]C )
We need to use the symmetry of disjointness again. This suggests that making djIsSymmetric a
rewrite rule might not have been a bad idea; here it would have finished the proof automatically.
proof
use djIsSymmetric[X ];
use djIsSymmetric[X ][B := C ];
prove;
This turned out to be more work than the original line of argument.
A singleton set is disjoint from second set if its sole member is not in that set:
proof
apply djDef ;
prove;
theorem djMonotone [X ]
∀ A, A0 , B , B 0 : P X | A dj B ∧ A0 ⊆ A ∧ B 0 ⊆ B • A0 dj B 0
We will start the proof of theorem djMonotone in the usual way; applying the defining axiom
for dj and running the prove command. This gives the new goal
A ∈ PX
∧ A0 ∈ P X
∧ B ∈ PX
∧ B0 ∈ P X
∧ A0 ∈ P A
∧ B0 ∈ P B
∧ A ∩ [X ]B = {}
⇒ A0 ∩ [X ]B 0 = {}
Sets can be shown equal by considering their members, and the Toolkit contains at several
different versions of the axiom of extensionality. The theorem called extensionality is a disabled
rewrite rule, and can be applied to this goal to replace the two equalities. This can be done by
selecting “New Command” from the “Edit” menu, entering the command apply extensionality,
selecting “Done” from the “File” menu, then double clicking on this command in the proof script.
Alternatively, for each equality, it can be selected with the mouse, then “extensionality” can be
selected from the “Apply to predicate” submenu of the pop-up menu exposed by right-clicking. In
either case, the result is
A ∈ PX
∧ A0 ∈ P X
∧ B ∈ PX
∧ B0 ∈ P X
∧ A0 ∈ P A
∧ B0 ∈ P B
∧ (∀ x : A ∩ [X ]B • x ∈ {})
∧ (∀ y : {} • y ∈ A ∩ [X ]B )
⇒ (∀ x 0 : A0 ∩ [X ]B 0 • x 0 ∈ {})
∧ (∀ y 0 : {} • y 0 ∈ A0 ∩ [X ]B 0 )
As usual in an exploration, we immediately try the prove command and hope for the best. In
this case, the result is
A ∈ PX
∧ A0 ∈ P X
∧ B ∈ PX
∧ B0 ∈ P X
∧ A0 ∈ P A
∧ B0 ∈ P B
∧ x ∈ A0
∧ ¬ (∃ x 0 : A ∩ [X ]B • true)
⇒ ¬ x ∈ B0
Z/EVES Project TR-99-5493-06a 49
Z/EVES eliminated several quantifiers and simplified somewhat. At this stage, we need to think
a bit. We can argue as follows: suppose x ∈ B 0 held, given the hypotheses of the goal. Then we
would have x ∈ A and x ∈ B as well, because A ⊆ A0 and B ⊆ B 0 . This contradicts the hypothesis
¬ (∃ x 0 : A ∩ [X ]B • true).
We could proceed in several different ways. Here, we start with the hardest step (for Z/EVES):
dealing with quantifiers. We argued that x is a “witness” value that contradicts the existentially
quantified hypothesis, so willtype in an instantiation command instantiate x 0 == x, execute
it, then clean up the formula, as usual, by a prove command. This results in the goal
A ∈ PX
∧ A0 ∈ P X
∧ B ∈ PX
∧ B0 ∈ P X
∧ A0 ∈ P A
∧ B0 ∈ P B
∧ x ∈ A0
∧¬x ∈B
∧ ¬ (∃ x 0 : A ∩ [X ]B • true)
⇒ ¬ x ∈ B0
Such a proof can be presented to Z/EVES as a series of use commands, one for each line of the
proof, possibly after some theorems are stated. A theorem is introduced for each step that deduces
a predicate from some prior predicates; this theorem asserts that the earlier predicates imply the
conclusion. Where a step brings in a prior theorem, the use command does so as well. Where
a step deduces a new predicate from prior predicates, the use command brings in the associated
theorem. Finally, a simplify or prove command completes the proof. Of course, the theorems that
50 Z/EVES Project TR-99-5493-06a
are introduced are themselves in need of proof. However, each of these lemmas is usually simpler
than the original theorem.
In practice, it is not always necessary to have a theorem for every line of the proof; some steps are
so simple that the final prove command can make them automatically. This is an advantage that
the prove command has over the simplify command in completing a proof: it is more powerful in
filling in gaps in the proof.
For the example above, we need no theorems; all the steps except for the two marked “Leibniz’
Law” are references to theorems of the Toolkit, and Z/EVES can do simple equality reasoning. So,
the proof can be presented to Z/EVES as follows:
theorem example [X , Y , Z ]
∀ Q : X ↔ Y ; R : Y ↔ Z ; S : P Y • (Q B S ) o9 R = Q o9 (S C R)
proof
use compIdRight[X , Y ][R := Q];
use compAssociates[X , Y , Y , Z ][P := Q, Q := id S ];
use compIdLeft[Y , Z ];
prove;
Interestingly, a final simplify command will not complete the proof, because the instance of
theorem compAssociates has the side condition id S ∈ Y ↔ Y , which is not immediately obvious.
We could flesh out the proof with a detail of how to derive this, but it is simpler to use the prove
command and let Z/EVES fill in the details itself.
Our next example is to prove that the domain and range a finite injection are of the same size:
theorem injSizeDomRan [X , Y ]
∀g : X
7 7 Y • #(dom g) = #(ran g)
(Recall that X 7 7 Y is the set of finite injections (that is, finite one-to-one mappings) from X
to Y , and X →7 7 Y is the set of finite partial functions from X to Y .)
Before starting an informal proof, it is worth checking the Toolkit to see what is already known.
The section on finiteness contains something likely:
6. Since #(ran g) ≤ #(dom g) (by step 3) and #(dom g) ≤ #(ran g) (by step 5), we have
#(dom g) = #(ran g).
There are just three steps in this argument that need further justification:
7 7 Y ⇒ g∼ ∈ Y →
• g ∈X 7 7 X , which we will state as a lemma, and
• the arithmetic reasoning in the conclusion, which Z/EVES can complete automatically.
theorem step4Lemma [X , Y ]
7 7 Y • g∼ ∈ Y →
∀g : X 77 Y
Now the main theorem can be proved following the argument outlined above:
theorem injSizeDomRan [X , Y ]
∀g : X
7 7 Y • #(dom g) = #(ran g)
proof
use finiteFunction[X , Y ][f := g];
use step4Lemma[X , Y ];
use finiteFunction[Y , X ][f := g ∼ [X , Y ]];
prove;
The lemma still needs to be proved, but we will not show that proof here.
A more complex informal proof uses quantifier reasoning. For example, in trying to prove a
universally quantified conclusion, it is common to eliminate the quantifier, stating something like
“let x be arbitrary.” Alternatively, having proved an existentially quantified predicate of the form
∃ x : X • P (x ), it is common to again “let x : X | P (x ) be given”, and assume P (x ). Both these
steps can be presented to Z/EVES as a prenex operation, using the prenex command. Existentially
quantified conclusions are proved by proving some instance; such an instance can be provided in a
Z/EVES proof with the instantiate command.
For example, we can show (∃ x : S • x ∈/ T ) ⇒ ¬ S ⊆ T using the following argument:
1. Assume ∃ x : S • x ∈
/ T.
3. S ⊆ T ⇔ (∀ e : S • e ∈ T ), by theorem subDef .
theorem example2
∀ S , T : P Z • (∃ x : S • x ∈
/ T) ⇒ ¬ S ⊆ T
The choice of x in step 2 can be presented as a prenex command, which results in the goal
S ∈ PZ ∧ T ∈ PZ ∧ x ∈ S ∧ x ∈
/T
⇒¬S ⊆T
52 Z/EVES Project TR-99-5493-06a
We can now bring in the instance of theorem subDef needed for step 3, with the command
use subDef[\num][A := S, B := T]. This gives the goal
(S ∈ P Z ∧ T ∈ P Z ⇒ (S ⊆ T ⇔ (∀ x 0:S •x 0 ∈ T )))
∧ S ∈ PZ
∧ T ∈ PZ
∧x ∈S
∧x ∈/T
⇒¬S ⊆T
Theorem subDef actually uses x as its bound variable, instead of the e we used in the informal
proof sketch. When the theorem is used, Z/EVES renames the bound variable to avoid conflict with
the x aleady appearing in the goal. So, our subsequent instantiation needs to use the new name.
The command instantiate x__0 == x can be followed by prove and the proof is complete. In
summary, the proof script is
proof
prenex ;
use subDef [Z][A := S , B := T ];
instantiate x 0 == x ;
prove;
theorem relationInDomCrossRan [X , Y ]
∀ R : X ↔ Y • R ∈ (dom R) ↔ (ran R)
7. Similarly, y ∈ ran R.
8. Thus, (x , y) ∈ (dom R) × (ran R), and, since e = (x , y), the proof is complete.
Three steps in this chain (4, 6, and 7) need filling in, and we will make a lemma for each of them:
theorem thm1 [X , Y ]
∀R : X ↔ Y • e ∈ R ⇒ e ∈ X × Y
theorem thm2 [X , Y ]
∀ R : X ↔ Y • (x , y) ∈ R ⇒ x ∈ dom R
Z/EVES Project TR-99-5493-06a 53
theorem thm3 [X , Y ]
∀ R : X ↔ Y • (x , y) ∈ R ⇒ y ∈ ran R
With these three lemmas in place, we can turn to the main theorem.
theorem relationInDomCrossRan [X , Y ]
∀ R : X ↔ Y • R ∈ (dom R) ↔ (ran R)
The first step in our argument used the definition of ↔ . There are two occurrences in the goal,
so we direct Z/EVES to expand the one we want by the command invoke \dom[X, Y] R \rel \ran[X, Y] R
which gives the goal
The second step was to use theorem inPower . As this is a disabled rewrite rule, it can be “applied”
by selecting the predicate, right clicking, and selection “inPower” from the “Apply to predicate”
submenu of the pop-up menu. This results in the goal
R∈X ↔Y
∧e∈R
⇒ e ∈ dom[X , Y ]R × ran[X , Y ]R.
Step 4 was captured in lemma thm1, which we will bring in with the command use thm1[X, Y],
which must be added as a new command and typed in to the editor. This results in the goal
(R ∈ X ↔ Y ∧ e ∈ R ⇒ e ∈ X × Y )
∧R∈X ↔Y
∧e∈R
⇒ e ∈ dom[X , Y ]R × ran[X , Y ]R
Normally, after a use command we apply a prove command to clean up the goal. If we try that
here, the added lemma is eliminated and we are left with the goal we had before the use command.
So, before cleaning up, we will move on to step 5, where e ∈ X × Y is used.1 This step is to infer
∃ x : X ; y : Y • e = (x , y) from e ∈ X × Y . This is the gist of theorem InCross2 in the Toolkit.
We can apply the theorem, as it is a rewrite rule, by selecting X × Y in the goal predicate, right
clicking, and selecting “InCross2” from the “Apply to expression” submenu. This results in the goal
(R ∈ X ↔ Y ∧ e ∈ R ⇒ (∃ x : X ; y : Y • e = (x , y)))
∧R∈X ↔Y
∧e∈R
⇒ e ∈ dom[X , Y ]R × ran[X , Y ]R
1 It seems strange that even though this fact is so obvious to Z/EVES, we need to bring it in. There is, in fact, a
good reason to add e ∈ X × Y ; once it is explicitly in the formula, other commands can be applied to it, as seen the
the remainder of this proof.
We might also have made a different lemma:
theorem thm1a [X , Y ]
∀ R : X ↔ Y • e ∈ R ⇒ (∃ x : X ; y : Y • e = (x , y))
which has a less trivial proof than the original form; which adds a fact that is not immediately obvious to Z/EVES
(and so which is not eliminated in a following prove step; and which saves a step in the main proof. This is easier to
see in hindsight than when first planning the proof!
54 Z/EVES Project TR-99-5493-06a
which can be cleaned up with the prove command. The resulting goal is
R∈X ↔Y
∧x ∈X
∧y ∈Y
∧ e = (x , y)
∧ (x , y) ∈ R
⇒ x ∈ dom[X , Y ]R ∧ y ∈ ran[X , Y ]R
Z/EVES has jumped ahead a bit in the argument, applying the argument of step 8, but has left us
with the remaining two interesting steps. We bring in the two lemmas defined for these steps, and
clean up with a prove command
proof
use thm2[X , Y ];
use thm3[X , Y ];
prove;
proof
with enabled (inDom) rewrite;
instantiate y 0 == y;
prove;
use thm1[X , Y ][e := (x , y)];
prove;
Theorem thm3 can be proved by using theorem thm2 on the inverse relation:
proof
use thm2[Y , X ][R := R ∼ [X , Y ], x := y, y := x ] ;
prove;
Chapter 6
Theory Development
Many specifications need to introduce new concepts. When some new name is introduced, one or
more theorems are added (usually in the axiom of generic box introducing the name, but sometimes
as separate theorem or predicate paragraphs). This collection of theorems forms the “theory” of the
new name.
In order to be successful in getting proofs through Z/EVES, it is necessary to have a sufficient
stock of theorems. Numerous simple facts are needed in even the easiest of proofs, and the power of
the reduction commands depends critically on the available theorems. The Toolkit defines a fairly
rich set of theorems about its functions, so that rewriting and reduction can automatically prove
many simple facts.
When a specification introduces new functions, the automatic commands will be unable to prove
anything nontrivial unless some theorems about these functions are added. Even worse, proofs of
simple facts involving references to the new functions might fail as well, because some simple subgoal
about the new function cannot be discharged.
In this chapter, we will describe some of the approaches we use in developing a theory.
6.1 Objectives
The goal of theory development is threefold:
• logical adequacy: The given theorems should determine the meaning of the new name.
• practical adequacy: There should be enough “support” theorems about a concept to make it
possible to prove typical theorems arising from the analysis of specifications using that concept.
• automation: When practical, there should be enough rewrite rules, forward rules, and assump-
tion rules so that trivial facts can be proved automatically.
f :Z→N
∀ x : N • f (x ) = 2 ∗ x
∀ x : Z | x ≤ 0 • f (x ) = −x ,
55
56 Z/EVES Project TR-99-5493-06a
6.1.3 Automation
A good collection of rewrite rules, forward rules, and assumption rules for a basic theory makes it
easier to prove theorems involving its concepts.
New notions are introduced because they are needed in a specification, and these notions will
appear in the theorems generated while analysing the specification. While proving a domain con-
dition, the satisfiability of some schema, or some other fact about a specification, it can be an
annoyance and a distraction to spend time working on a trivial fact about the basic concepts used.
A well-automated theory allows Z/EVES to prove these trivial facts by itself, freeing the specifier
to concentrate on the more interesting and illuminating aspects of the proof.
We certainly do not advise a huge investment in setting up a theory so that all the interesting
proofs are fully automatic. This is an ambitious undertaking, and likely not worth the effort. It is
worthwhile, however, spending enough time to make the trivial steps automatic.
6.2 Guidelines
Several guidelines can be applied in the development of a theory. We can illustrate some of them
using the following definition of the complement of a set with respect to its type:
Z/EVES Project TR-99-5493-06a 57
[X ]
∼ : PX → PX
∀S : PX • ∼ S = X \ S
1. Use plain facts. There can be a temptation to express properties in a compact form, using
various notions from the Toolkit. A theory is more likely to be practically adequate if its
facts are stated in a simple and direct form. For example, instead of a theorem asserting
disjoint hS , ∼ S i, it is probably more useful to assert x ∈ ∼ S ⇒ ¬ x ∈ S .
2. Look for rewrite rules. Rewriting is by far the easiest of the prover’s mechanisms to understand
and control, and many mathematical facts make natural rewrite rules if they are expressed
properly. Rewrite rules that help reduce the size and complexity of a goal are particularly
valuable, as are rules that apply to predicates that commonly occur as side conditions in a
proof.
A common type of rewrite rule replaces an expression or predicate by something simpler. For
example, the fact ∀ S : P X • ∼ ( ∼ S ) = S is an obvious candidate for a rewrite rule; the
replacement expression S is always simpler than the pattern ∼ ( ∼ S ). Similarly, the fact
∼ [X ]{} = X is suitable as a rule.
3. Not all theorems make good rules. While it is useful to identify theorems that can be rewrite
rules, one should be judicious. For example, the Z/EVES mathematical Toolkit contains a
number of distribution laws, including A ∪ (B ∩ C ) = (A ∪ B ) ∩ (A ∪ C ). This could possibly
be a rewrite rule, but it is not obvious which form of expression is superior. Similarly, the
equality R ∼ ∗ = R ∗ ∼ is a possible rewrite rule, but it is not obvious that one form should be
preferred to the other. These facts are disabled rewrite rules in the Toolkit, so they can be
applied if desired but are not normally applied.
A fact might be a poor rewrite rule because it introduces complexity. For example, p ∈
X × Y ⇔ (∃ x : X ; y : Y • p = (x , y) can be added as a rewrite rule, but doing so makes
rewriting introduce many quantifiers into a predicate. Again, it is better to state such facts as
disabled rules, so they can be applied when, and if, they are appropriate in a proof.
4. Make theorems strong. Suppose we have defined the notion of increasing and decreasing
sequences. We could then state a theorem
This can be made into a rewrite rule, so that if a predicate rev (t) ∈ decreasing is encountered
for some sequence t, Z/EVES will consider the predicate t ∈ increasing. If this subgoal can
be proved, the original predicate will be replaced by true. But suppose Z/EVES fails to prove
the subgoal in some case where a user expected it to succeed. In this case, it is not so easy to
find out what happened.
A stronger fact can be stated:
Now, whenever a predicate rev (t) ∈ decreasing is encountered, it is replaced with t ∈ increasing
(which might then be further rewritten or simplified).
58 Z/EVES Project TR-99-5493-06a
This stronger rule has another advantage: it can be used to refute predicates of the form
rev (s) ∈ decreasing as well as to prove them. For example, the predicate
x∈
/ increasing ∧ rev (x ) ∈ decreasing
can be reduced to false using the strong rule, but is unaffected by the weak rule.
A simple fact about complementation is x ∈ ∼ S ⇒ ¬ x ∈ S . This could be stated as a
theorem, but the equivalence
∀S : PX; x : X • x ∈ ∼ S ⇔ ¬ x ∈ S
∀ S : P X • x ∈ ∼ S ⇔ x ∈ X ∧ ¬ x ∈ S.
This last form is useful in those (hopefully rare) cases where non-maximal sets are used as
generic actuals, and allows us to show, for example, ¬ S [N] given the definition
b [A : P X | −1 ∈ ∼ A]
S [X ] =
In this case, the generic actual for ∼ is N (rather than the maximal set Z).1
Even in those cases where the theorem is not suitable as a rewrite rule, a strong form of the
theorem can be more powerful, and thus more useful, than a weaker form.
5. Avoid complex conditions. Generally, it is advisable to ensure that any conditions or a rewrite
rule are not more complex than the pattern. In particular, it is probably not a good idea to
have a rule that introduces some new concept in its conditions. For example, a rule
is silly; any time a predicate n ∈ Odd is rewritten, the primality of n will be considered. This
is likely to be a complete waste of time.
6. Make rules work together. It is wise to have some overall strategy in mind when writing rewrite
rules. For example, a good strategy for complementation might be to push complementation
inside other set connectives—that is, to rewrite ∼ (A ∪ B ) to ( ∼ A) ∩ ( ∼ B ) and so on. A
collection of such rules expressing defines a kind of “normal form” for set expressions.
In the absence of a coherent strategy for the rules about complementation, it is easy to run
into trouble. For example, if we have the three rules
to associate with the type of generic formal parameters. The approach taken in Z/EVES is to use generic formal
parameters as though they are maximal. Thus, for example, in the definition n[X ] == X ∪ X , the generic actual
inferred for ∪ is simply X .
Z/EVES Project TR-99-5493-06a 59
(where in the third rule we chose the opposite direction of rewriting than that suggested by
the “push in” strategy), then there is a possibility of conflict between the rules. For example,
if a term of the form ∼ (A ∩ B ) is rewritten, it is transformed by rule complementCap to
( ∼ A) ∪ ( ∼ B ). This can be rewritten by rule complementSetminus to ∼ (A \ ∼ B ). Rule
diffSetminus then applies to the parenthesised term, resulting in ∼ (A ∩ B ), which is exactly
where we started. Such rule loops should be avoided.
7. Work with the Toolkit. The Z/EVES Mathematical Toolkit [10] contains many facts about
the concepts introduced in the standard Z Mathematical Toolkit, and most of these facts are
expressed as rewrite rules. Any rules added in a theory need to work together with these
existing rules.2 For example, to avoid an ordering conflict with rule emptyDefinition, a rule’s
pattern should contain {} instead of ∅.
8. Add assumption rules (grules) for abbreviation definitions, as directed by the Z/EVES Refer-
ence Manual. This is really part of working with the Toolkit, but deserves special emphasis.
The logical adequacy of this definition is obvious; the predicate determines the truth of A dj B
for every pair A, B in the domain of the disjointness relation.
We will use this concept in the specification of a simple resource management system. This gives
us several simple conjectures involving disjointness that are used to analyse the specification.
As explained in Section 3.1.3, it is useful to ensure that this initial state is satisfiable:
theorem InitManagerIsOK
∃ Manager • InitManager
AddResource
∆Manager
r ? : Resource
r? ∈/ free ∪ used
used 0 = used
free 0 = free ∪ {r ?}
theorem AddResourceIsHonest
∀ Manager ; r ? : Resource | r ? ∈
/ free ∪ used • pre AddResource
Alloc
∆Manager
r ! : Resource
r ! ∈ free
free 0 = free \ {r !}
used 0 = used ∪ {r !}
theorem AllocIsHonest
∀ Manager | free 6= {} • pre Alloc
Obviously, we need more operations to make a realistic specification; however, the three conjec-
tures above are all we need to illustrate the issues in theory development.
theorem axiom$4 [X ]
A ∈ P X ∧ B ∈ P X ⇒ (A dj [X ]B ⇔ A ∩ [X ]B = ∅[X ]
(As we will see, it is possible to attach a chosen name to this theorem, by labelling the predicate.)
We can appeal to a suitable instance of this fact, and see where that gets us.
Z/EVES Project TR-99-5493-06a 61
proof
use axiom$4[Resource][A := {}, B := {}];
Z/EVES rejects this command.3 We will leave this unfinished and move on to the next theorem,
AddResourceIsHonest. The command prove by reduce results in a goal
used ∈ P Resource
∧ free ∈ P Resource
∧ r ? ∈ Resource
∧ used dj free
∧ ¬ r ? ∈ free
∧ ¬ r ? ∈ used
⇒ used dj free ∪ {r ?}.
proof
use axiom$4[Resource][A := used , B := free ];
use axiom$4[Resource][A := used , B := free ∪ { r ? }];
prove;
used ∈ P Resource
∧ free ∈ P Resource
∧ r ? ∈ Resource
∧ used dj free
∧ ¬ r ? ∈ free
∧ ¬ r ? ∈ used
∧ (used dj free ∪ {r ?} ⇔ used ∩ (free ∪ {r ?}) = {})
∧ free ∩ used = {}
⇒ used ∩ (free ∪ {r ?}) = {}
This looks pretty messy, and seem to have little to do with our original problem of the resource
manager! We will turn to the third goal, AllocIsHonest. Command prove by reduce produces the
goal
used ∈ P Resource
∧ free ∈ P Resource
∧ used dj free
∧ ¬ free = {}
⇒ (∃ r ! : Resource • r ! ∈ free ∧ used ∪ {r !} dj free \ {r !})
Since free is nonempty, it has a member which could be used for r !. The Toolkit contains the
theorem
theorem nonEmptySetHasMember
S = {} ∨ (∃ x : S • true)
3 There is a slight flaw in the way that the current version of Z/EVES checks use commands, so, in this version, it
is simply impossible to bring in the needed instance of the axiom.
62 Z/EVES Project TR-99-5493-06a
This theorem lets us bring in the fact ∃ x : free • true; prenexing eliminates the quantifier on x ;
then r ! can be instantiated. Following this, we use the prove command to clean up the goal:
proof
use nonEmptySetHasMember [S := free];
prove;
instantiate r ! == x ;
prove;
used ∈ P Resource
∧ free ∈ P Resource
∧ x ∈ free
∧ used dj free
∧ ¬ free = {}
∧ ¬ used ∪ {x } dj free \ {x }
⇒ (∃ r ! : Resource • r ! ∈ free ∧ used ∪ {r !} dj free \ {r !})
in which the two disjointness hypotheses are contradictory. We can eliminate function dj , clean
up, and see where we are:
proof
use axiom$4[Resource][A := used ∪ {x }, B := free \ {x }];
use axiom$4[Resource][A := used , B := free];
prove;
used ∈ P Resource
∧ free ∈ P Resource
∧ x ∈ free
∧ used dj free
∧ ¬ free = {}
∧ ¬ used ∪ {x } dj free \ {x }
∧ free ∩ used = {}
∧ ¬ (used ∪ {x }) ∩ (free \ {x }) = {}
⇒ (∃ r ! : Resource • r ! ∈ free ∧ used ∪ {r !} dj free \ {r !})
The hypotheses are still contradictory, but further proof steps are required to show it.
As can be seen from these three proof attempts, it is rather awkward to work with disjointness.
The following two sections show how the theory can be developed to improve the situation.
[X ]
dj : PX ↔ PX
hh rule djDef ii
∀ A, B : P X • A dj B ⇔ A ∩ B = ∅
With this revised definition, we can recheck the specification and try the example theorems again.
For InitManagerIsOK , the command prove by reduce completes the proof.
For AddResourceIsHonest, the prove by reduce command results in the goal
used ∈ P Resource
∧ free ∈ P Resource
∧ r ? ∈ Resource
∧ free ∩ used = {}
∧ ¬ r ? ∈ free
∧ ¬ r ? ∈ used
⇒ used ∩ (free ∪ {r ?}) = {}
which we saw in our earlier proof attempt. We can complete the proof using some set theory:
rule distributeCapOverCupRight transforms the conclusion to (user ∩ free) ∪ (used ∩ {r ?}) = {}),
which can be proved automatically by rewriting. The complete proof is then
proof
prove by reduce;
apply distributeCapOverCupRight;
prove;
The proof has been successful. However, the proof is still not as simple as we might like; an
obvious fact like this should be proved immediately.
The proof for AllocIsHonest is not much different from the previous attempt; the appeals to
axiom$4 are gone, but nothing else has changed.
This approach has not been a big improvement. We could follow two paths. One is to stick with
the elimination idea, and prove some additional facts about intersection, so that the above proofs
can be completed more easily. The second path, which we explore in the next section, is to abandon
the elimination approach and add some useful facts about disjointness.
From the proof of theorem InitSIsOK , we know that the fact ∅ dj ∅ is needed. In fact, any set
is disjoint from the empty set, so we will prove the more general fact ∀ A : P X • A dj ∅. This fact
can be a rewrite rule, and it looks like a good one: the replacement (in this case true) is far simpler
than the pattern A dj ∅.
To make this a useful rewrite rule, one other small detail needs to be observed. The Toolkit rules
replace ∅ by {}. Thus, it is better to use {} in the rule’s pattern.
The above rule is fine, but it will not apply to a predicate of the form {} dj A, which is also
true. In fact, disjointness is a symmetric relation: if A dj B then B dj A. We can easily state
and prove this fact, but it is not so easily automated. The equivalence A dj B ⇔ B dj A can be
made a rewrite rule. Instead of leading to an infinite sequence of rewrite steps, a rule like this is
recognized by Z/EVES and is treated specially. Z/EVES applies it at most once (to a given instance)
and determines heuristically which permutation of the arguments is preferred. However, there is no
guarantee that {} dj A would be permuted into A dj {} so that rule djNullRight would apply.
It seems we have no option but to state two versions of every interesting rewrite rule, so that is
what we will do.
Although it does not help us in stating our main theorems here, the symmetry of the disjointness
relation is a useful fact.
theorem djIsSymmetric [X ]
∀ A, B : P X • A dj B ⇔ B dj A
Our attempt to prove theorem AddResourceIsHonest without eliminating the disjointness pred-
icate resulted in the goal
used ∈ P Resource
∧ free ∈ P Resource
∧ r ? ∈ Resource
∧ used dj free
∧ ¬ r ? ∈ free
∧ ¬ r ? ∈ used
⇒ used dj free ∪ {r ?}
Two general facts about disjointness are applicable here. First, a set is disjoint with the union
of two others if and only if it is disjoint with each of the two other sets.
Secondly, a set A is disjoint with a unit set {x } if and only if x is not a member of A.
Finally, when we tried to prove AllocIsHonest, we had the contradictory hypothesesused dj free
and ¬ used dj free \ {x }. That these are contradictory is a consequence of the general fact that
subsets of disjoint sets are also disjoint:
theorem djMonotone [X ]
∀ A, A0 , B , B 0 : P X | A dj B ∧ A0 ⊆ A ∧ B 0 ⊆ B • A0 dj B 0
There seems to be no straightforward way to automate the use of this theorem, so we leave it as
a plain fact.
With these theorems in hand, we can retry the three proofs. Both InitManagerIsOK and
AddResourceIsHonest are proved by the prove by reduce command. For AllocIsHonest, more
work is required:
proof
prove by reduce;
use nonEmptySetHasMember [S := free];
prenex ;
instantiate r ! == x ;
prove;
used ∈ P Resource
∧ free ∈ P Resource
∧ x ∈ free
∧ used dj free
∧ ¬ free = {}
∧ ¬ used dj free \ {x }
⇒ (∃ r ! : Resource • r ! ∈ free ∧ used dj free \ {r !})
proof
use djMonotone[Resource][A := used , A0 := used , B := free, B 0 := free \ {x }];
prove;
These proof scripts seem reasonable; the obvious facts about disjointness were proved automati-
cally, and little of the proof of AllocIsHonest had to do with disjointness.
Of course, this single “test drive” of the theory of disjointness does not show that it is finished,
and it is quite likely that a more realistic resource manager would require additional properties.
Another way to test the theory is with small examples. In this case, the rules we have defined
so far are enough to let rewriting show {1, 2, 3} dj {4} and {1, 2, 3} dj 10 . . 20 are true, and
{1, 2, 3} dj 2 . . 20 is false. So, the theory seems to be reasonably well developed.
There is a danger in developing a theory like this—what if the axioms are incorrect? It is easy
to overlook some small detail in stating such theorems, and a missing detail can make a supposed
theorem unsound. So, these theorems should all be proved. In fact, we already proved most of these
theorems in Section 5.1, and the remainder are similar; we will therefore not show the proofs here.
66 Z/EVES Project TR-99-5493-06a
Bibliography
67