A Proof Environment for Concurrent Programs Nama BROWN and Dominique MERY? CRIN-CNRS & INRIA Lorraine, BP 239 54506 Vanduvre-les-Nancy, France. email:
[email protected],
[email protected]
Abstract. Unity [CM88, Mer92, Kna90], as action systems approach
[BS91], is a formal method that attempts to decouple a program from its implementation. Therefore, Unity separates logical behaviour from implementation, it provides predicates for speci cations, and proof rules for deriving speci cations directly from the program text. This type of proof strategy is often clearer and more succinct than argument about a program's operational behaviour. Our research ts into Unity's methodology. Its aims to develop a proof environment suitable for mechanical proof of concurrent programs. This proof is based on Unity [CM88], and may be used to specify and verify both safety and liveness properties. Our veri cation method is based on theorem proving, so that an axiomatization of the operational semantics is needed. We use Dijkstra's wp-calculus to formalize the Unity logic, so we can always derive a sound relationship between the operational semantics of a given Unity speci cation and the axiomatic one from which theorems in our logic will be derived.
Automated theorem proving, concurrency, program veri cation, formal speci cations, Unity, B
1 Introduction In a mechanically veri ed proof, all proof steps are validated by a computer program called a theorem prover. Hence, whether a mechanically veri ed proof is correct is really a question of whether the theorem prover is sound. The theorem prover used in our research is B-Tool [BT91a, BT91b, BT91c]. B provides a platform for solving the problem speci cation and correct construction of software systems. It is a exible inference engine which forms the basis of a computeraided system for the formal construction of provably correct software. Using a mechanized theorem prover to validate a proof presents an additional burden for the user, since machine validated proofs are longer and more dicult to produce. However, if one trusts the theorem prover, one may then focus attention on the speci cation that was proved. This analysis may be facilitated by ?
on sabbatical leave at the Department of Computing Science University of Stirling under the European Science Exchange Programme Royal Society - CNRS
consulting the mechanized proof script. The proof environment for concurrent programs presented in this paper is based on Unity, which has two important characteristics: } Unity provides predicates for speci cations, and proof rules to derive speci cations directly from the program text. This type of proof strategy is often clearer and more succinct than argument about a program's operational behaviour. David Goldschlag in [Gol90] described how to mechanically verify a Unity program with the Boyer-Moore prover[BM88]. } Unity separates the concern of algorithm from that of architecture. It de nes a general semantics for concurrent programs that encourage the re nement of architecture-independent programs to architecture-speci c ones. In a paper presented at the European Workshops on Parallel Computing [BM92], we have already described a systematic method for mapping (implementing) a Unity speci cation into the programming language Occam.
2 Unity
This section is a brief discussion of the Unity notation and programming logic. The section described the logic de ned by Chandy and Misra together with the modi cation suggested by Sanders to incorporate the notion of strongest stable predicate and weakest stable predicate.
2.1 A Programming Notation A Unity program consists of a declaration of variables, a speci cation of their initial values, and a set of multiple-assignment statements. A program execution starts from a state satisfying the initial condition and loops forever; in each step of execution some assignment statement is selected non-deterministically and executed (Fig.1). Non-deterministic selection is constrained by the rule of fairness. A state of a program is called a xed point if and only if execution of any statement of the program, in this state, leaves the state unchanged. Proofs trans 1
trans 2
init
state 0
state 1
trans n fixed point state n
Fig. 1. Execution of a Unity progam in Unity are based on assertions of the type fpgsfqg, where s represents the Unity assignment statement, p the precondition that must be validated before the execution of s, and q the post-condition that results from the execution of
s. Our proof system is designed to reason about a set of Unity actions. A Unity action represents a Unity assignment statement. So, to apply our proof method to a Unity program, we must rst compute, using the algorithm given next, the set of Unity actions associated to this program.
input: { U , the Unity program output: { SA, set of actions of the Unity program U algorithm SA ; While S = 6 ; (S represents the set of statements of the program U ) do Take s 2 S CASE s == (x := E ) then SA s == (x; y := E1 ; E2 ) then SA s == (x; y := E1 ; E2 if b) then SA s == (x := E ) if g then SA s == (x := E1 if g1 E2 if g2 .. .
En if gn )
then SA
SA SA SA SA
[ [ [ [
fx := E g fx; y := E ; E g fx; y := E ; E if bg fx := E if gg 1
2
1
2
SA [ fx := E1 if g1 ; x := E2 if g2 ; .. .
x := En if gn g
2.2 A Programming Logic Interesting properties of concurrent programs are safety and liveness (progress) [Lam77]. Safety properties state that something bad will never happen; examples are invariance properties such as mutual exclusion and deadlock-freedom [GT90]. Liveness properties guarantee that something good will eventually happen; examples are termination and freedom from starvation. Unity de nes predicates that permit the speci cation of subsets of these properties. Stable properties, a subset of safety properties, are speci ed using the predicate unless; progress properties, a subset of liveness properties, are speci ed using the predicates ensures and leads-to.
p unless q = fdefinition of unless in Unity; PRG stands for a Unity program:g < 8 s : s in PRG :: fp ^ : qg s fp _ qg > fby using the definition of wlp; wlp stands for weakest liberal precondition[Dij76]g < 8 s : s in PRG :: fp ^ : qg ! wlp (s; p _ q) > fall statements in a Unity program are guaranteed to terminateg < 8 s : s in PRG :: fp ^ :qg ! wp (s; p _ q) > : The reader may have noticed that the properties one can specify the operator unless are limited to Safety properties, i.e, properties that disallow certain transition between program states. When specifying concurrent programs, however, we are often interested in stating that a certain predicate holds at some point in the future. In Unity, this requirement is expressed using the operators ensures and leads-to. p ensures q def = fdefinition of ensures in Unityg p unless q & < 9 s : s in PRG :: fp ^ : qg s fqg > fby using the definition of wlpg p unless q & < 9 s : s in PRG :: fp ^ : qg ! wlp (s; q) > fall statements in a Unity program are guaranteed to terminateg p unless q & < 9 s : s in PRG :: fp ^ :qg ! wp (s; q) > : def
P leads-to Q states that if P holds in some state of the program, then a state is eventually reached where Q holds. The leads-to predicate is transitive. Formally, leads-to is de ned by the following rules (see [CM88]: ensures q (1) ppleads ? to q to q; q leads ? to r (2) p leads ? p leads ? to r q); (r leads ? to q) (3) (p leads(p ?_ to r) leads ? to q (4) All p leads ? to q are obtained by finite use of the above rules: The complete Unity programming logic is based on the temporal operators unless, ensures and leads-to, plus the substitution axiom. Combining the substitution axiom with the de ned temporal operators gives an unsound proof system [San91, Mis90]. A. Sanders in [San91] modi es the Unity logic by eliminating the substitution axiom from this logic and by giving a new de nition of the operator unless, ensures and leads-to using the predicate transformers sst and wst, standing respectively for strongest stable predicate and weakest stable predicate. Instead of changing the Unity logic, as Sanders did in [San91], and in order to capture the semantic completeness of the Unity logic, we can be guided by the
feps [Mer86] system that has been proved correct and semantically complete, by
adding the two following rules: p ensures q; I nv(i); r ^ i ) p; p ) r ^ i r ensures q p leads ? to q; I nv(i); r ^ i ) p r leads ? to q
However, we must be able to encode the feps system in the obtained logic, to provide a full proof of the semantic completeness.
3 The Implementation of Unity in B This section is a presentation of the Proof Environment. Proof in this Proof Environment resemble Unity hand proofs, except that every concept must be de ned and every theorem proved in order to have the proof mechanically veri ed by the B prover.
3.1 A brief introduction to B First, we present the syntax of some symbols representing the main logical operators of the Unity logic into B. formal operator :p p^q p_q p!q p=q 8x 9x
Implementation in B :p p&q pjq p)q p == q !x #x
Meaning negation conjunction disjunction implication equality universal existence
B is a rule-based inference engine with rule-rewriting and pattern matching facilities. Its behaviour is controlled by rule bases known as theories. The application of theories is guided by tactics. Speci c proof strategies may be prescribed using appropriate combinations of theories and tactics, a proof can be completely automated. B has no pre-de ned encoding of any logical laws; these are supplied in the form of theories and tactics wherever appropriate. As a result, B can be con gured to support a large variety of dierent logics. However, B does have a number of basic built-in mechanisms which are common to most formal proofs regardless of the underlying logic. These mechanisms support the idea of carrying out a proof under certain hypotheses, the notion of variables and their scopes and freeness, quanti ers, substitution, equality, : : : The addition of these mechanisms greatly facilitates the practice of proving theorems encountered in the formal software development process without sacri cing B's generality and exibility.
When building a proof, B constructs its proof tree dynamically; as a consequence, the state of a proof in construction is characterized by an incomplete proof tree. There are two modes for building proofs: one is called the normal mode and the other is called the forward mode. The forward mode is only used when a new hypothesis is generated. It consists of generating other hypotheses that are derived not only from the one just generated, but also from the ones that are already visible and from some rule. The visible hypotheses are simply those which are members of the sets of hypotheses of the ascending nodes of the current node. Let's now present some useful B tactics which we will use for the proofs of Unity programs. } Proof that construct hypothesis DED:
f1 &f2 & : : : &fn ) g Application of DED New goal to prove : g Hypothesis : ff1 ; f2 ; : : : ; fn g
Goal to prove :
} Proof using hypothesis INHYP:
Goal to prove : P visible hypothesis : f: : : ; P; : : :g Application of INHY P New goal to prove : Nothing
} Proof by Generalization GEN:
Goal to prove :
8x:P
x has no free occurrence in the visible hypothesis:
Application of GEN New goal to prove : P
} Proof by Generalization GEN:
Goal to prove :
8x:P
x has some free occurrences in the visible hypothesis:
Application of GEN New goal to prove : [x := y]P; where y is not free in the visible hypothesis nor in formula P:
3.2 De ning the Proof Environment under Centaur
CENTAUR is used mainly for two purposes: rstly, to develop a programming environment for Unity, secondly to consolidate the new development environment with a proof method (Fig.2). The CENTAUR system [Cen91, Cen92] may be used to design a programming language, experiment with syntax, types, and semantics or to construct a specialized language environment. CENTAUR features several speci cation formalisms with which one de nes various aspects of programming languages, and compilers that transform speci cations in these formalisms into part of a generated environment:
Unity Program
CENTAUR
Set of Unity Actions
theorems Unity.metal
Proof Environment.
B-TOOL Syntactic Editor
Unity.ppml
Fig.2. The Proof Environment METAL is a meta-language for de ning concrete and abstract syntax. The distinguishing feature of METAL is the great exibility that it allows for mapping between concrete and abstract syntax. SDF (Syntax De nition Formalism) is also a formalism for de ning concrete and abstract syntax. SDF establishes a xed mapping between concrete and abstract syntax. PPML a pretty printing meta-language used for de ning the mapping from abstract syntax trees to a textual (pretty printed) representation. TYPOL is a speci cation language based on inference rules used for the de nition of static and dynamic semantics of programming languages. The design of the programming environment consists of several steps that are either automatic, or semi-automatic.A rst step consists of writing a METAL speci cation of the Unity language. This speci cation de nes the concrete syntax, the abstract syntax and the rules of trees formation that express the correspondence between abstract and concrete syntax. The METAL-PPML generates tables and programs used for parser generation from this speci cation. The generation of a parser is not completely automatic and the user has to supply some les along with those generated by METAL-PPML. The semantics of the language is treated by the TYPOL environment. A second step consists of writing the PPML speci cation of the rules of textual representation (or unparsing) for the Unity formalism from its abstract syntax. The unparser for the Unity formalism is generated using the compile command of the METAL-PPML environment. The Unity environment comprises two kinds of editors: textual and structural. The user can easily write a Unity program in a textual form. A parser checks it. If the program is syntactically correct, the parser generates the internal representation.
The user can run an interface to the theorem prover that allows him to prove the correctness of Unity program using the set of its actions (statements). The interface ensures the interaction between the Unity environment and the proof system implemented under B. The interface operates on the internal representation. The prover is designed according to the enrichment principle (Fig.3).
leads-to_thy
leads-to_thy: B theory defining the predicate leads-to.
Ensures_thy
Ensures_thy: B Theory defining the predicate ensures.
Unless_thy
Unless_thy: B Theory defining the predicate unless.
wp_theory
wp_theory: B Theory defining wp_calculus.
Fig. 3. Structure of the Proof System A basic layer represents the Dijkstra's wp-calculus [Dij76]. This is successively enriched with other theories for reasoning about Unity programs. To wp-theory, we have supplied another layer for deriving safety properties which we denote by unless-thy. ensures-thy and leads-to-thy, de nes the most interesting progress properties.
3.3 Implementation of Wp-Calculus into B prover The rst level of the proof system formalizes the de nitions of wp-calculus for the assignment statements in the B prover. Let x denote a list of program variables, and E a list of expressions, possibly depending on x and matching the variables in x in number and type. An assignment statement is of the form x := E if b, where x:=E is a multiple assignment satement and B is a boolean expression. With wp standing for Dijkstra's weakest precondition[Dij76], we de ne the predicate transformer semantics of such a statement as follows: wp(x := E if b; Q) (b ) wp(x := E; Q)) ^ (:b ) Q) (b ) [x := E]Q) ^ (:b ) Q)
where [x:=E]Q stands for Q with all occurrences of variables in x simultaneously replaced by the matching expressions in E. The second part of the de nition above could be omitted when we are dealing with invariant properties. B-de nition
} THEORY wp ? theory IS
END
? ? ? ?
wp(x := E; p) == [x := E]p; wp((x := E if b); p) == (b ) wp(x := E; p)&(:b ) p)); wp((x; y := E; F); p) == [x; y := E; F]p; wp((x; y := E; Fifb); p) == (b ) wp((x; y := E; F); p))&(:b ) p)
3.4 Implementation of the predicate unless in the B prover unless(PRG, p, q) states that every statement in the program PRG executed in states, where p holds but q does not, will lead to states where p or q holds. Intuitively, this means that once p holds in a computation, it continues to hold, at least until q (this may occur immediately). Notice that if unless(PRG, p, False) is true for program PRG and p holds on the initial state, then p is an invariant of PRG. The predicate unless is de ned as follows:
} Hypothesis
PRG is a Unity program, wp weakest precondition[Dij76, Lam90, DS90] unless-thy, the name of the B theory that contains the de nition of unless. PRG def = B Cons(a1 ; Cons(a2 ; : : : ; Cons(an?1 ; an ) : : :)); where ai(nio) 2 SA. SA, set of actions of the program PRG.
} B-de nition
THEORY unless-thy IS unless(a,p,q) == ((p & :(q)) ) wp(a,p j q)) unless(Cons(a,l), p, q) == unless(a,p,q) & unless(l,p,q) END
} comment
We implement the predicate unless in a recursive manner.
3.5 Implementation of the predicate ensures in the B prover The ensures relation (over predicates) de nes the most basic progress properties of programs. p ensures q states that if p is true at some point in the computation, p remains true as long as q is false, and q eventually becomes true. For a given program PRG, ensures(PRG, p, q) is de ned as follows: } Hypothesis PRG is a Unity program. ensures-thy, the name of the B theory that contains the de nition of ensures.
} B-de nition THEORY ensures-thy IS ensures(a,p,q) == exists-test(a,p,q) & unless(a,p,q) ensures(Cons(a,l),p,q) == exists-test(Cons(a,l),p,q) & unless(Cons(a,l),p,q) exists-test(a,p,q) == ((p & :(q)) ) wp(a,q)); exists-test(Cons(a,l),p,q) == Or-Else(((p & :(q)) ) wp(a,q)),exist-test(l,p,q)) END
} comment
The predicate ensures is de ned in a recursive manner. exists-test(PRG,p,q) == 9s 2 PRG: (p ^ :q) ) wp(s; q), this predicate is also de ned recursively. Or-Else(a,b) = ajb.
To complete the de nition of ensures, we de ne the predicate Or-Else as follows: } Hypothesis bcall, dynamic change of tactics and backtracking in B. a,b: B formulae. t,r: tactics.
} B-de nition Or-Else(a,b) == bcall(t:a j r:b) Or-Else(a,Or-Else(b,c)) == a j Or-Else(b,c)
} comment
The interpretation of bcall(t1 : f1 j t2 : f2 ) goes as follows: we start proving the goal f1 using the tactic t1, if this proof fails, then B backtracks to the bcall node, and f2 becomes the formula to prove using the tactic t2. If this proof does not succeed, B backtracks to the previous ascending bcall, if any, etc.
3.6 Implementation of the predicate leads-to in the B prover Informally, p leads-to q means that if p becomes true q is or will be true. However, we cannot assert that p will remain true as long as q is not. This is the major dierence between ensures and leads-to. } B-de nition THEORY leads-to-thy IS ensures(s,P,Q) ) leadsto(s,P,Q); leadsto(s,P,Q) & leadsto(s,Q,R) ) leadsto(s,P,R); leadsto(s,P,Q) & leadsto(s,R,Q) ) leadsto(s,(PjR),Q) END
4 Derived Rules Unity's unless, ensures and leads-to predicates provide a simple and powerful vocabulary to specify and reason about the behaviour of concurrent programs. Proof rules facilitates the proof of program properties in much that some way that lemmas aid a mathematical proof. In fact, the proof rules presented in this section are theorems about computation. The theorems presented below have been proved correct in our Proof System, by using, both the de nition of unless and ensures given in the previous section, and the assertion theory. Hence, these theorems can be used to prove the correctness of any unity program, if necessary. Consequence Weakening SimpleDisjunction Disjunction ensures(p; q) unless(p; q) ensures(p; q) q ) r unless(p0; q0) ensures (p _ r; q _ r) ensures(p; r) unless(p _ p0; q _ q0) Simple Conjunction Cancellation unless(p; q) unless(p; q) unless(p0; q0) unless(q; r) unless(p ^ p0; q _ q0) unless(p _ q; r)
Impossibility ensures(p; false) :(p)
4.1 Proof of the Consequence Weakening rule The proof of the consequence weakening for the predicate ensures necessitates the use of the de nition of unless and ensures. From p unless q, we have for all statements s in the program, fp ^ :qg s fp _ qg, and from q ) r we can deduce :r ) :q. Hence, we have p ^ :r ) p ^ :q and p _ q ) p _ r. Therefore, we deduce fp ^ :rg s fp _ rg from which the results follow for the predicate unless. We must now show that there exists a statement s such that fp ^ :qg s fqg implies fp ^ :rg s fqg. The proof follows from p ^ :r ) p ^ :q, because :r ) :q. B is able to print a proof tree by decorating and traversing its nodes in post- xed mode, that is from left to right, from the leaves upward. The B proof of the theorem of consequence weakening described above is pretty-printed as follows: PROOF 1 2 3 4 5 6 7 8 9 10 11
p and not(q) => wp(s,(p | q)) p and not(q) => wp(s,q) q => r p and not(q) => wp(s,(p | q)) p and not(r) p and not(r) q => r not(r) => not(q) p and not(q) p and not(r) => p and not(q) q => r
HYP HYP HYP INHYP HYP INHYP INHYP 7 proposition.33 6 8 proposition.34 DED INHYP
12 13 14 15 16 17 18 19 20 21 22 23 24 25
26
27
28 29
(p | q) => (p | r) p and not(r) => wp(s,(p | r)) p and not(q) => wp(s,(p | q)) p and not(r) p and not(r) q => r not(r) => not(q) p and not(q) p and not(r) => p and not(q) q => r (p | q) => r p and not(r) => wp(s,r) (p and not(r) => wp(s,(p | r))) & (p and not(r) => wp(s,r)) (p and not(q) => wp(s,(p | q))) & (p and not(q) => wp(s,q)) & (q => r) => (p and not (r) => wp(s,(p | r))) & (p and not(r) => wp (s,r)) (p and not(q) => wp(s,(p | q))) & (p and not(q) => wp(s,q)) & (q => r) => unless(s,p ,r) & (p and not(r) => wp(s,r)) (p and not(q) => wp(s,(p | q))) & (p and not(q) => wp(s,q)) & (q => r) => ensures(s, p,r) unless(s,p,q) & (p and not(q) => wp(s,q)) & (q => r) => ensures(s,p,r) ensures(s,p,q) & (q => r) => ensures(s,p,r)
11 proposition.32 4 10 12 Unity_logic.1 INHYP HYP INHYP INHYP 17 proposition.33 16 18 proposition.34 DED INHYP 21 proposition.31 14 20 22 Unity_logic.1 13 23 AND
DED
25 Forall_test.2
26 Forall_test.1 27 Forall_test.2 28 Forall_test.1
END OF PROOF
5 An Example The purpose of this section is to describe, by means of an example, how to mechanically verify a concurrent program using our Proof System.
5.1 Proof Format
Most of our proofs are purely computational in the sense that they consist of a number of syntactic transformations instead of semantic reasoning steps. We use a proof format that was rst proposed by Feijen, Dijkstra, and others, and that greatly facilitate this kind of proof. For example, a proof that A D may be rendered in our format as
A
fhint why A B g B
fhint why B C g C
fhint why C Dg D
5.2 A simple program
The goal of this program [CM88] is to divide M by N, where M and N are integers. M0 and N>0; the quotient is stored in x, and the remainder in y. The speci cation of the program is that the predicate x N + y = M ^ 0 y < N holds at any xed point, and that a xed point is reached eventually. Program
Division
declare x; y; z; k : integer initially x; y; z; k = 0; M; N; 1 assign z;k := 2 z; 2 k if y 2 z N; 1 if y < 2 z []x;y := x + k; y ? z if y z
Proof of an Invariant:
We prove that (I (y 0) ^ (k 1) ^ (z = N k) ^ (x N + y = M )) is an invariant for the Unity program described above. Therefore, we prove that: { (init ) I), i.e: x = 0 & y = M & z = N & k = 1 & M 0 & N > 0 ) y 0 & k 1 & z =N k & xN +y = M . { I is stable, i.e: fI g z; k := 2 z; 2 k if y 2 z fI g fI g z; k := N; 1 if y < 2 z fI g fI g x; y := x + k; y ? z if y z fI g The complete B proof for all statements of the program is summarized in the Appendix A. In the following, we comment the proof for the rst statement of the program.
fI g z; k := 2 z; 2 k if y 2 z fI g fI invariant of the program P : invariant(P; I) def = stable(P; I) & init(P) ) Ig Goals : step 39 x = 0 & y = M & z = N & k = 1 & M 0 & N > 0 ) y 0 & k 1 & z = N k & x N + y = M: step 19 stable(z; k := 2 z; 2 k if y 2 z; y 0 & k 1 & z = N k & x N + y = M ): fProof of the rst subgoal init ) I; we apply the B atomic tactic DEDg Hypothesis : fx = 0; y = M; z = N; k = 1; M 0; N > 0g fsteps : 20; 21; : : : ; 25g Goal : y 0 & k 1 & z = N k & x N + y = M:
fstep : 38g fWe apply the B atomic tactic ANDg Goals : step 27 y 0 step 29 k 1 step 33 z = N k step 37 x N + y = M
fProof of y 0g From the hypothesis y = M and M 0; we deduce that y 0:
fProof of k 1g From the hypothesis k = 1; we deduce k 1; step 28
fProof of z = N kg From the hypothesis z = N and k = 1; we deduce z = N k; step 32; 31; 30
fProof of x N + y = Mg From the hypothesis x = 0 and y = M; we deduce x N + y = M; step 36; 35; 34 fProof of the subgoal stable( z; k := 2 z; 2 k if y 2 z; I) Recall that we implement a program in B as a sequence of actions: stable(PRG; I) def = I ) wp(PRG; I)g (y ? 0 & k 1 & z = N k & x N + y = M) ) wp z;k := 2 z; 2 k if y 2 z; (y 0 & k 1 & z = N k & x N + y = M ) ; step 18
fde nition of wp; step 17g (y 0 & k 1 & z = N k & x N + y = M ) ) (y 2 z ) [z;k := 2 z; 2 k](y 0 & k 1 & z = N k & x N + y = M )
fWe apply the B atomic tactic DEDg Goal (step 16) (y 2 z ) [z;k := 2 z; 2 k](y 0&k 1&z = N k&x N + y = M ) Hypothesis : step 1; y 0 step 2; k 1 step 3; z = N k step 4; x N + y = M fWe apply the B atomic tactic SUB; step 15g y 2 z ) y 0 & 2 k 1 &2 z = N (2 k) &x N + y = M
fWe apply the B atomic tactic DEDg Goal (step 14) y 0 & 2 k 1 &2 z = N (2 k) &x N + y = M Hypothesis : step 5 y 2 z:
fWe apply the B atomic tactic ANDg Goals : step 6 y 0 step 8 2 k 1 step 11 2 z = N (2 k) step 12 x N + y = M
fFor the proof of the subgoals y 0 and x N + y = M; we apply the B atomic tactic INHYP because y 0 and x N + y = M are hypothesis: Proof of the subgoal 2 z = N (2 k):g From the hypothesis z = N k; we must then prove that 2 (N k) = N (2 k); which is true by applying the B atomic tactic EQL: steps 10; 9
fProof of the subgoal 2 k 1g From the hypothesis k 1; we deduce that 2 k 1; step 7 B is able to print a proof tree by decorating and traversing its nodes in post- xed mode, that is from left to right, from the leaves upward. The B proof of the theorem of consequence weakening described above is pretty-printed as follows: PROOF 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
17
y>=0 k>=1 z = N*k x*N+y = M y>=2*z y>=0 k>=1 2*k>=1 2*(N*k) = 2*(N*k) 2*z = 2*(N*k) 2*z = N*(2*k) x*N+y = M y>=0 & 2*k>=1 & 2*z = N*(2*k) M y>=2*z => y>=0 & 2*k>=1 & 2*z = x*N+y = M y>=2*z => [z,k:=2*z,2*k](y>=0 & = N*k & x*N+y = M) y>=0 & k>=1 & z = N*k & x*N+y = M z => [z,k:=2*z,2*k](y>=0 & k>=1 & x*N+y = M)) y>=0 & k>=1 & z = N*k & x*N+y = M
HYP HYP HYP HYP HYP INHYP INHYP 7 proposition.16 EQL 9 HYP.3 10 proposition.20 INHYP & x*N+y = 6 8 11 12 AND N*(2*k) & DED k>=1 & z 14 SUB => (y>=2* z = N*k & DED => (y>=2*
18
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 nv.1
z => wp((z,k:=2*z,2*k),(y>=0 & k>=1 & z = N *k & x*N+y = M))) y>=0 & k>=1 & z = N*k & x*N+y = M => wp( Cond_ass((z,k:=2*z,2*k),y>=2*z),(y>=0 & k>= 1 & z = N*k & x*N+y = M)) stable(Cond_ass((z,k:=2*z,2*k),y>=2*z),(y>= 0 & k>=1 & z = N*k & x*N+y = M)) x = 0 y = M z = N k = 1 M>=0 N>0 M>=0 y>=0 k = 1 k>=1 N = N N = N*1 N = N*k z = N*k y = M 0+y = M 0*N+y = M x*N+y = M y>=0 & k>=1 & z = N*k & x*N+y = M x = 0 & y = M & z = N & k = 1 & M>=0 & N>0 => y>=0 & k>=1 & z = N*k & x*N+y = M Inv(y>=0 & k>=1 & z = N*k & x*N+y = M)
16 wp_theory.4
17 wp_theory.5 18 Stable_theory.1 HYP HYP HYP HYP HYP HYP INHYP 26 HYP.21 INHYP 28 proposition.23 EQL 30 proposition.24 31 HYP.23 32 HYP.22 INHYP 34 proposition.26 35 proposition.25 36 HYP.20 27 29 33 37 AND DED 19 39 lect_param_i
END OF PROOF
6 Conclusion The Proof Environment presented in this paper is based on Unity and has been implemented in B. Proofs in this Proof Environment resemble Unity hand proofs, except that every concept must be de ned and every theorem proved in order to have the proof mechanically veri ed by the B prover. This process of mechanical veri cation allows us to place greater trust in the correction of a proof. This trust comes at the expense of the extra work required to mechanically check a proof. However, if the theorem prover is sound, then one can simply believe the mechanically veri ed proof and focus attention on the more dicult issue of analysing whether the speci cation that was proved is appropriate for the problem being solved, refering to the validated proof script, when appropriate. The Proof Environment is the second step of our project. The rst was the study of mapping Unity programs to Occam programs but it requires a sound Unity program. The correctness can be veri ed using our implementation but we need to integrate it into a general tool for manipulating formal texts and re ning speci cations to programs. This tool will be useful to experiment speci c case studies. We
have de ned a mapping to Occam but we can explore other programming languages. Further investigations will use the B toolkit environment to model the re nement of concurrent programs.
References [BM88] R.S. Boyer and J.S. Moore. A Computational Logic Handbook. Academic Press, 1988. [BM92] N. Brown and D. Mery. Deriving Occam Programs through the Re nement of Unity-like Speci cations . In W. Joosen and E. Milgrom, editors, Proceedings European Workshop on Parallel Computing. IOS PRESS, 1992. [BS91] R.J.R. Back and K. Sere. Deriving an occam implementation of action systems. In C. Morgan and J.C.P. Woodcock, editors, 4rd Re nement Workshop. Springer-Verlag, January 1991. BCS-FACS, Workshops in Computing. [BT91a] BP Innovation Centre and Edinburgh Portable Compilers Ltd. B-Tool Version1.1, Reference Manual, 1991. [BT91b] BP Innovation Centre and Edinburgh Portable Compilers Ltd. B-Tool Version1.1, Tutorial, 1991. [BT91c] BP Innovation Centre and Edinburgh Portable Compilers Ltd. B-Tool Version1.1, User Manual, 1991. [Cen91] Centaur. Version1.1, Reference Manual, 1991. [Cen92] Centaur. Version1.2, Reference Manual, 1992. [CM88] K.M. Chandy and J. Misra. Parallel Program Design A Foundation. AddisonWesley Publishing Company, 1988. ISBN 0-201-05866-9. [Dij76] E.W. Dijkstra. A Discipline of Programming. Prentice-Hall, 1976. [DS90] E.W. Dijkstra and C.S. Scholten. Predicate Calculus and Program Semantics. Texts and Monographs in Computer Science. Springer Verlag, 1990. [Gol90] D.M. Goldschlag. Mechanically verifying concurrent programs with the boyermoore prover. IEEE Transactions on Software Engineering, 16(9):1005{1023, september 1990. [GT90] A.J.M. Van Gasteren and G. Tel. Comments on "on the proof of a distributed algorithm": always true is not invariant. Information Processing Letters, 35:277{279, 1990. [Kna90] E. Knapp. An exercise in the formal derivation of parallel programs: Maximum ows in graphs. Transactions On Programming Languages and Systems, 12(2):203{223, 1990. [Lam77] L. Lamport. Proving the correctness of multiprocess programs. Trans. on Software Engineering 1, 1977. [Lam90] L. Lamport. A temporal logic of actions. Technical Report 57, DEC Palo Alto, april 1990. [Mer86] D. Mery. A proof system to derive eventuality properties under justice hypothesis. In LNCS, number 233. Mathematical Foundations of Computer Science, 1986. Bratislava, Tchecoslovaquie. [Mer92] D. Mery. The NU system as a development system for concurrent programs: NU . Theoretical Computer Science, 94(2):311 { 334, march 1992. [Mis90] J. Misra. Soundness of the substitution axiom. Notes on Unity, pages 14{90, 1990.
[San91] B.A. Sanders. Eliminating the substitution axiom from unity logic. Formal Aspects of Computing, 3:189{205, 1991.
A APPENDIX A: Proof of Invariance ------------------------------------------------------------------------------PROOF 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
19 20 21 22 23 24 25 26 27 28 29 30 31 32
y>=0 k>=1 z = N*k x*N+y = M y>=2*z y>=0 k>=1 2*k>=1 2*(N*k) = 2*(N*k) 2*z = 2*(N*k) 2*z = N*(2*k) x*N+y = M y>=0 & 2*k>=1 & 2*z = N*(2*k) & x*N+y = M [z,k:=2*z,2*k](y>=0 & k>=1 & z = N*k & x*N+y = M) wp((z,k:=2*z,2*k),(y>=0 & k>=1 & z = N* k & x*N+y = M)) y>=2*z => wp((z,k:=2*z,2*k),(y>=0 & k>=1 & z = N*k & x*N+y = M)) wp(Cond_ass((z,k:=2*z,2*k),y>=2*z),(y>=0 & k>=1 & z = N*k & x*N+y = M)) y>=0 & k>=1 & z = N*k & x*N+y = M => wp( Cond_ass((z,k:=2*z,2*k),y>=2*z),(y>=0 & k>= 1 & z = N*k & x*N+y = M)) stable(Cond_ass((z,k:=2*z,2*k),y>=2*z),(y>= 0 & k>=1 & z = N*k & x*N+y = M)) y>=0 k>=1 z = N*k x*N+y = M y=0 1 = 1 1>=1 N = N N = N*1 x*N+y = M y>=0 & 1>=1 & N = N*1 & x*N+y = M [z,k:=N,1](y>=0 & k>=1 & z = N*k & x*N+ y = M)
HYP HYP HYP HYP HYP INHYP INHYP 7 proposition.16 EQL 9 HYP.3 10 proposition.20 INHYP 6 8 11 12 AND 13 SUB 14 wp_theory.4 DED 16 wp_theory.5
DED 18 Stable_theory.1 HYP HYP HYP HYP HYP INHYP EQL 26 proposition.23 EQL 28 proposition.24 INHYP 25 27 29 30 AND 31 SUB
33 34 35 36
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
59 60
y.2 61
wp((z,k:=N,1),(y>=0 & k>=1 & z = N*k & x*N+y = M)) y wp((z,k:=N,1),(y>=0 & k>=1 & z = N*k & x*N+y = M)) wp(Cond_ass((z,k:=N,1),y=0 & k>= 1 & z = N*k & x*N+y = M)) y>=0 & k>=1 & z = N*k & x*N+y = M => wp( Cond_ass((z,k:=N,1),y=0 & k>=1 & z = N*k & x*N+y = M)) stable(Cond_ass((z,k:=N,1),y=0 & k >=1 & z = N*k & x*N+y = M)) y>=0 k>=1 z = N*k x*N+y = M y>=z y>=z y-z>=0 k>=1 z = N*k x*N+y = M x*N+N*k-N*k+y = M x*N+N*k-z+y = M x*N+k*N-z+y = M x*N+k*N+(y-z) = M (x+k)*N+(y-z) = M y-z>=0 & k>=1 & z = N*k & (x+k)*N+(y-z) = M [x,y:=x+k,y-z](y>=0 & k>=1 & z = N*k & x*N+y = M) wp((x,y:=x+k,y-z),(y>=0 & k>=1 & z = N* k & x*N+y = M)) y>=z => wp((x,y:=x+k,y-z),(y>=0 & k>=1 & z = N*k & x*N+y = M)) wp(Cond_ass((x,y:=x+k,y-z),y>=z),(y>=0 & k>=1 & z = N*k & x*N+y = M)) y>=0 & k>=1 & z = N*k & x*N+y = M => wp( Cond_ass((x,y:=x+k,y-z),y>=z),(y>=0 & k>=1 & z = N*k & x*N+y = M))
32 wp_theory.4 DED 34 wp_theory.5
DED 36 Stable_theory.1 HYP HYP HYP HYP HYP INHYP 43 arithmetique.14 INHYP INHYP INHYP 47 arithmetique.11 48 HYP.40 49 arithmetique.1 50 arithmetique.4 51 arithmetique.5 44 45 46 52 AND 53 SUB 54 wp_theory.4 DED 56 wp_theory.5
DED
stable(Cond_ass((x,y:=x+k,y-z),y>=z),(y>=0 & k>=1 & z = N*k & x*N+y = M)) 58 Stable_theory.1 stable(Cons(Cond_ass((z,k:=N,1),y=z)),(y>=0 & k>=1 & z = N*k & x*N+y = M)) 37 59 Stable_theor stable(Cons(Cond_ass((z,k:=2*z,2*k),y>=2*z) ,Cons(Cond_ass((z,k:=N,1),y=z))),(y>=0 & k>=1 & z = N* k & x*N+y = M)) 19 60 Stable_theor y.2 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 nv.1
x = 0 y = M z = N k = 1 M>=0 N>0 M>=0 y>=0 k = 1 k>=1 N = N N = N*1 N = N*k z = N*k y = M 0+y = M 0*N+y = M x*N+y = M y>=0 & k>=1 & z = N*k & x*N+y = M x = 0 & y = M & z = N & k = 1 & M>=0 & N>0 => y>=0 & k>=1 & z = N*k & x*N+y = M Inv(P)
HYP HYP HYP HYP HYP HYP INHYP 68 HYP.63 INHYP 70 proposition.23 EQL 72 proposition.24 73 HYP.65 74 HYP.64 INHYP 76 proposition.26 77 proposition.25 78 HYP.62 69 71 75 79 AND DED 61 81 lect_param_i
END OF PROOF -------------------------------------------------------------------------------
This article was processed using the LaTEX macro package with LLNCS style