A Tool For Helping Teach A Programming Method Isabelle Dony
Baudouin Le Charlier
Universite´ catholique de Louvain Place Sainte-Barbe 2 B-1348 Louvain-la-Neuve
Universite´ catholique de Louvain Place Sainte-Barbe 2 B-1348 Louvain-la-Neuve
[email protected]
[email protected]
ABSTRACT We present and discuss a tool that checks the correctness of simple programs constructed according to the structured programming method. The tool is intended to provide interesting feedback to students learning the programming method: it detects programming and/or reasoning errors and it provides typical counter-examples. We argue that our system is better adapted to our pedagogical context than other verification tools and we report on preliminary experiments with the tool in a third year programming course.
Categories and Subject Descriptors D.2.4 [Software]: Software Engineering—Software/Program Verification; F.3 [Theory of computation]: Logic and Meaning of Programs
Obviously, building such a system is far from an easy task. It may even be thought completely unfeasible to experts in the field. Our approach is to restrict our ambition to a very simple programming language with simple types (limited to finite domains) and arrays, and to address (relatively) small examples such as searching and sorting algorithms. In this context, it is possible to specify problems and subproblems, both clearly and formally, using a specific assertion language based on mathematical logic. The rest of the paper is organised as follows. In Section 2, we recall the main lines of the structured method of Dijkstra and others, and we explain why teaching this method is difficult; we also consider the use of existing verifying tools in our context. In Section 3, we present our tool based on a typical example. In Section 4, we report on experiments of using the tool with students in a programming course. Section 5 contains the conclusion.
General Terms Algorithms, Documentation, Experimentation, Verification
2. A PROGRAMMING METHOD
Keywords
2.1 Description of the method
Formal specification, Invariant, Program construction, Program verification, Programming errors, Programming course
1.
INTRODUCTION
In this paper, we present a tool we have specifically designed to help our students to understand the structured programming method developed by Dijkstra and others (see e.g., [4, 7, 8, 11]). Our motivation to build this tool is twofold. On the one hand, existing verification tools (e.g., [14, 3, 6, 1]) are too complex to be used in a pedagogical context ; moreover they often lack completeness (and, sometimes, even soundness [6]). On the other hand, teaching “formal” (i.e., rigorous) program construction with pen and paper does not motivate students at all. Thus, since students love to use tools, providing them with a tool that checks not only their programs but also their specifications and the structure of their reasoning seemed appealing to us.
The programming method we teach is based on specifications, invariants, and decomposition into subproblems, as advocated by Dijkstra, Gries, and Hoare, just to mention a few famous computer scientists [13, 10, 7]. The steps to construct an iterative algorithm are the following: we first define the set of variables of the program, then we formally specify the problem by means of a precondition (Pre) and a postcondition (Post), then we choose a invariant (Inv), and finally, we derive the statements: the initialisation (Init), the iteration (Iter), the closing (Clos), and the halting condition (H) so that the following propositions are true: • { Pre } Init { Inv } • { Inv and not H } Iter { Inv } • { Inv and H } Clos { Post }
We use Hoare’s notation [13], i.e., { P } S { Q }, to mean that if the assertion P holds, then it is guaranteed that • S terminates and does not generate any run-time error • after executing S, the assertion Q also holds.
Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. To copy otherwise, to republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. ITiCSE’06, June 26–28, 2006, Bologna, Italy. Copyright 2006 ACM 1-59593-055-8/06/0006 ...$5.00.
(Notice that we use Hoare’s notation to express total correctness, not only partial correctness as in Hoare’s original proposal [13].) If a problem is too complex to be solved by a single loop, it can be decomposed into several subproblems, which must be specified and constructed independently. Finally, to prove the termination of a loop, a variant (i.e., a positive integer function of the program variables, which strictly decreases) must be provided.
2.2 Teaching the method: some issues The programming method is taught in two programming courses at two different formality levels. In the first (introductory) course [15], it is used very informally to help construct (simple) programs more systematically. In the second (more advanced) course, we expect the students to get a deeper understanding of the method. The benefit of the method stems from the divide-andconquer approach: problems are broken into subproblems until only very simple problems are obtained. Moreover, the construction of a loop is also broken into independent subproblems through the use of an invariant and a variant. However, such an approach can be successful only if students are able to write specifications (and invariants) that are both sound and complete. If the method is not supported by a formal specification language, it is very hard to explain to the students what a good specification (or invariant) is. This is partly due to the lack of mathematical maturity of the students, and partly due to the fact that students tend to prefer a global approach of “understanding” a complex algorithm as a whole, in an operational way, without any attempt to make a declarative reasoning. Thus, we concluded that a helping tool should enforce the use of the method: decomposition into subproblems and complete specification of the subproblems. Moreover the tool should provide an informative feedback to the students when they make specification or reasoning errors.
2.3 Usability of existing verification tools Nowadays a number of verification tools exist but they have not been designed to be used in a genuine pedagogical context. We have tried to use them in our context to solve some simple problems according to the structured programming method. The Extended Static Checker ESC [6] uses a theorem prover to check the correctness of classes annotated with JML specifications [5]; it has been used to check the absence of errors such as null pointer dereferencing, array bound violation, and division by zero. In our context, ESC is not precise enough: it reports many false warnings and may report correctness when there are bugs. Besides, the success of a verification may heavily depend on the way an assertion is written (noted by trying to verify the binary search algorithm). Similar problems have been found with an algorithm computing the next permutation (see [9]). Additionally, JML is not expressive enough to give a complete formal specification for most algorithms (e.g., the next permutation algorithm). The Blast tool [1, 12] focuses on checking sequential C code, using well-engineered predicate abstraction and abstraction refinement tools. The assertion language is restricted to the C syntax and, up to now, Blast does not handle arrays precisely. We tried to use it for algorithms that do not use arrays like Indian exponentiation, simple integer division, and squaring using the relation (x+1)2 = x2 +2x+1. Problems appear probably because the theorem prover used by Blast does not handle full arithmetic. The theorem prover PVS [3] can be used to formally prove program correctness. The disadvantage of PVS is that, even when the teacher has provided the axioms and deductions rules, the verification is not yet fully automated. Hence, the system is not really usable in our pedagogical context. SPARK (a subset of Ada) and its tools have been used in an academic context [14]. Since this system uses a theorem
Data: const n