• Aucun résultat trouvé

Introduction to the Coq proof-assistant for practical software verification

N/A
N/A
Protected

Academic year: 2022

Partager "Introduction to the Coq proof-assistant for practical software verification"

Copied!
49
0
0

Texte intégral

(1)

practical software verification

Christine Paulin-Mohring

1 LRI, Univ Paris-Sud 11, CNRS, Orsay F-91405

2 INRIA Saclay - ˆIle-de-France, ProVal, Orsay, F-91893 christine.paulin@lri.fr

Abstract. This paper is a tutorial on using theCoqproof-assistant for reasoning on software correctness.

We illustrate characteristic features ofCoqlike inductive definitions and proof automation on a few examples : arithmetic, algorithms on lists, cryptographic protocols. . .

Coqis not a tool dedicated to software verification but a general purpose environment for developing mathematical proofs. However, it is based on a powerful language including basic functional programming and high- level specifications. As such it offers modern ways to literally program proofs in a structured way with advanced data-types, proofs by compu- tation, and general purpose libraries of definitions and lemmas.

Coq is well suited for software verification of programs involving ad- vanced specifications (language semantics, real numbers). TheCoqar- chitecture is also based on a small trusted kernel, making possible to use third-party libraries while being sure that proofs are not compromised.

1 Introduction

1.1 What is Coq ?

The proof assistant Coqis an environment for developing mathematical facts.

This includes defining objects (integers, sets, trees, functions, programs . . . );

making statements (using basic predicates and logical connectives); and finally writing proofs.

TheCoqcompiler automatically checks the correctness of definitions (well- formed sets, terminating functions . . . ) and of proofs.

TheCoqenvironmenthelps with: advanced notations; proof search; modular developments. It also provides program extraction towards languages like Ocaml and Haskell for efficient execution of algorithms and linking with other libraries.

Impressive examples have been done usingCoq. They cover different areas.

In pure mathematics, one can notice the Fundamental theorem of Algebra (every polynomial has a root in C) developed at Nijmegen in the team of Barendregt [21]

in 2000 and more recently the Feit-Thompson theorem on finite groups under the supervision of Gonthier in the joint INRIA-Microsoft research center [23].

Many interesting proofs combine advanced algorithms and non-trivial mathe- matics like the proof of the four-color theorem by Gonthier & Werner at INRIA

(2)

and Microsoft-Research [22], a primality checker using Pocklington and Elliptic Curve Certificates developed by Th´ery et al. at INRIA [37] and more recently the proof of a Wave Equation Resolution Scheme by Boldo et al. [9].Coqcan also be used to certify the output of external theorem provers like in the work on termination tools by Contejean and others [15], or the certification of traces issued from SAT & SMT solvers done by Gr´egoire and others [1]. Coqis also a good framework for formalizing programming environments: the Gemalto and Trusted Logic companies obtained the highest level of certification (common cri- teria EAL 7) for their formalization of the security properties of the JavaCard platform [12]; Leroy and others developed inCoqa certified optimizing compiler for C (Leroy et al.) [27]. Barthe and others usedCoqto develop Certicrypt, an environment of formal proofs for computational cryptography [5]. G. Morrisett and others also developed on top of CoqtheYnotlibrary for proving impera- tive programs using separation logic. These represent typical examples of what can be achieved usingCoq.Coqmight not be the best tool for proving your ev- eryday routine code but is definitely useful when sophisticated data-structures, algorithms and specifications are involved and also as a general framework to design special platforms for software verification.

Related Systems. Coq is a proof assistant similar to HOL systems, a family of interactive theorem provers based on Church’s higher-order logic including Isabelle/HOL [33], HOL4 [30], HOL-light [25]), PVS [32], . . .

Unlike these systems, Coqis based on an intuitionistic type theory and is consequently closer to Epigram [29], Matita [2] and also Agda [16] and NuPrl [14].

All these systems have in common that functions are programs that can be computed and not just binary relations like in mathematics.

More Informations on Coq. TheCoqweb site is located atcoq.inria.fr. It contains official distributions (multi-platforms), the reference manual and also libraries and user’s contributions.

The so-calledCoq’art book by Yves Bertot and Pierre Cast´eran [7] provides a full presentation of the Calculus of Inductive Constructions from the point of view of Interactive Theorem Proving and Program Development. The course by B. Pierce on software foundations [34] usingCoqis available on-line. The book by A. Chlipala [13] concentrates on programming withCoqand make intensive use of dependent types. We also recommend the course notesCoq in a Hurry by Y. Bertot [6] as an alternative quick introduction to theCoqsystem.

History. Information on the history of Coqcan be found in the preface of the reference manual. The origin of the language , the pure Calculus of Construc- tions and its first implementations go back to 1984 and are due to Coquand &

Huet [17].

The language and the environment were constantly extended afterward: uni- verses and tactics (Coquand, 1985), program extraction (Paulin& Werner, 1989 – Letouzey 2002), inductive definitions (Coquand & Paulin, 1989), co-inductive

(3)

definitions (Gim´enez, 1995), advanced pattern-matching (Cornes, 1995 – Her- belin, 2002), coercions (Saibi, 1997), efficient computations (Barras, 2001 – Gr´egoire, 2002), Modules (Courant, 1998 – Chrza˛szcz, 2004 – Soubiran, 2010), tactic language (Delahaye, 2000), automated tactics (Cr´egut, Boutin, Pottier, Besson, Sozeau, . . . ), type classes (Sozeau, 2009). . .

1.2 Coq architecture

It is important to understand that Coqis based on a two levels architecture.

There is a relatively small kernel based on a language with few primitive con- structions (functions, (co)-inductive definitions, product types, sorts) and a lim- ited number of rules for type-checking and computation. The same language is used to represent objects, functions, propositions and proofs.

On top of this kernel, Coq provides a rich environment to help designing theories and proofs offering mechanisms like user extensible notations, tactics for proof automation, libraries . . . This environment can be used and extended safely because ultimately any definition and proof is checked by a safe kernel.

As a Coq user, one might be interested by finding quickly the high-level constructions that will be helpful to solve a problem, but it might also be im- portant to understand the underlying low-level language in order to be able to develop new functionalities and to better control how certain constructions work in certain circumstances.

The following example illustrates the two levels structure. When dealing with integers, the user will enter the notation 5=2+3 but internally the Coq kernel will be given the term:

@eq Z (Zpos (xI (xO xH))) (Zplus (Zpos (xO xH)) (Zpos (xI xH)))

which explicits the type Z of the components and also the binary encoding of the integers.

1.3 Program verification in Coq

Coqcan be used for program verification in different ways :

– One can express the property “the programpis correct” as a mathematical statement inCoqand prove it is correct. It can can be hard but the proof is guaranteed.

– One can develop a specific program analyzer (model-checking, abstract in- terpretation,. . . ) inCoq, prove it correct and use it. It is a huge investment, but one get an automatic guaranteed result for each program instance.

– One can represent the programpby aCoqtermtand the specification by a typeT such thatt:T (which is automatically checked) impliespis correct.

It works well for functional (possibly monadic) programs.

– One can also use an external tool to generate proof obligations and then useCoqto solve obligations. It is a less safe approach (unless your gener- ator of proof obligations is certified) but it can deal with specifications in undecidable fragments where full automation will not work.

(4)

1.4 Outline

In section 2, we introduce quickly the basics Coq commands and tactics for logical reasoning. In section 3, we develop the notion of inductive definitions (both types and relations) and illustrate them on a board example, simple search algorithms and proof of cryptographic protocols. In section 4, we show examples of advanced programming usingCoq. In section 5, we discuss proof automation and in particular proofs by reflection. We conclude by a discussion on the merits of Coqwith respect to other approaches.

2 Basics of Coq system

2.1 First steps in Coq

Coqis an interactive system intended to buildlibraries of definitions and facts.

As a logical system it implements higher-order logic including arithmetic. It also includes a basic functional programming language. The environment provides additional tools such as libraries that can be quickly loaded, tools to query the environment in order to find the appropriate definitions and lemmas, and various mechanisms to simplify notations.

We recommend following the examples in this paper while experimenting with the system. A widely used interface is coqide which is part of the Coq standard distribution. An alternative is to useemacswith theproof-general[3]

library. Both environments offer similar functionalities. A main window contains Coq commands and is sequentially interpreted. When entering proof mode, another window displays the current status of the proof (unsolved goals). Finally, a window displays Coqoutput messages (including errors). coqidehas also a specialQueries window to display result of various printing commands.

Fig. 1.Graphical interfaces forCoq:coqide(left),Proof General(right)

AllCoqcommands end with a dot. Comments are written between (* ..

*). This document has been prepared usingCoqV8.3pl3. The lines correspond- ing toCoqinputs are starting withCoq <. TheCoqcode corresponding to the examples presented in this paper are available from the author web page.

(5)

2.2 Basic terms

A Coq object in the environment has a name and a type. The Check term command takes a name (or more generally a term) as an argument; it checks it is well-formed and displays its type.

Coq < Check nat . nat : Set

Coq < Check 0.

0 : nat

The object nat is a predefined type for natural numbers, its type is a special constant Set called a sort. The constant 0 has type nat. The object S is the successor function, it has type nat→ nat. The binary function plus has type nat→nat→natwhich should be read asnat→(nat→nat).

The termfunx→t(orfun(x:T)→tto indicate the typeT of variablex) represents a function f such that f(a)≡t[x←a].

A function f can be applied to a term t using the notation f t. The term f t1t2 stands for (f t1)t2. The natural number 10 is just a notation for the successor function applied 10 times to0and the usual infix notationt1+t2can be used instead ofplust1t2.

Coq < Check ( 3 + 2 ) . 3 + 2 : nat

The standard library defines the type of booleans bool with two inhabitants true andfalse. A choice on a boolean termb is writtenifbthent1 elset2. Propositions. In Coq, logical propositions are also seen as terms. The type of propositions is the sort Prop will be the type of propositions. We present a summary of Coq syntax for logical propositions (first line presents paper notation and second line the correspondingCoqinput).

⊥ > t=u t6=u¬P P∧Q P∨Q P →Q P ⇔Q False True t=u t<>u ~P P /\ Q P \/ Q P -> Q P <-> Q

The arrow represents implication, it associates to the right and T1->T2->T3 is interpreted asT1->(T2->T3)

Quantifiers. Syntax for universal and existential quantifiers is given below with possible variants:

∀x, P forall x, P forall x:T, P forall T (x y:T) (z:nat),P

∃x, P exists x, P exists x:T, Pno multiple bindings

The commandCheckverifies a proposition is well-formed but does not say if it is true or not.

Coq < Check ( 1 + 2 = 3 ) . 1 + 2 = 3 : P r op

Coq < Check (f o r a l l x : nat , e x i s t s y , x = y + y ).

f o r a l l x : nat , e x i s t s y : nat , x = y + y : P r o p

(6)

In the following, term will denote any Coq term, name or id represents an identifier, type represents a so-called “type” which is a term with type Type, Set or Prop. We useprop instead oftype when we expect a term of typeProp, however the same commands will usually also work with a more general type.

2.3 Logical rules and tactics

In order to establish a proposition is true, we need to produce a proof. Following the approach introduced by R. Milner for the LCF system, we use backward reasoning withtactics. Atactictransforms a goal into a set ofsubgoalssuch that solving these subgoals issufficient to solve the original goal. The proof succeeds whenno subgoals are left.

In practice, we introduce a new goal inCoqusing one of the following com- mands with prop representing a logical proposition (a well-formed term of type Prop).

Lemmaid:prop. Theoremid:prop. Goalprop.

Coq implements a natural deduction logical system. Following Curry-Howard isomorphism, a proof of a proposition A is represented by a term of type A.

So there is only one form of judgment Γ ` p : A. The environment Γ is a list of names associated with types x : T. When A is a type of objects, it is interpreted as “the termpis well-formed in the environmentΓ and has typeA”.

For instancex:nat`x+ 1 :nat. WhenAis a proposition, it is interpreted as

“Ais provable under the assumption ofΓ andpis a witness of that proof”. For instancex:nat, h:x= 1`. . .:x6= 0

Axiom. The basic rule of natural deduction is the axiom rule when the goal to be proven is directly an hypothesis. The logical rule and corresponding tactics are:

h:A∈Γ

Γ `h:A exacthorassumption

Connectives. The rules for a connective are separated between introduction rule(s) giving a mean to prove a proposition formed with that connective if we can prove simpler propositions, and a rule ofeliminationwhich explains how we can use a proof of a proposition with that connective. In the figure 2, we give the logical rule and the corresponding tactics. A tactic will work with a still unresolved goal, that we indicate using?in place of the proof-term.

It would be painful to apply only atomic rules as given in the figure. Tactics usually combine in one step several introductions or elimination rules. The tactic intros does multiple introductions and infer names when none are given. The tacticapplytakes as an argument a proofhof a proposition

∀x1. . . xn, A1→ · · ·Ap→B.

(7)

introduction elimination

Γ`?:False

Γ`?:C exfalso

¬ Γ,h:A`False

Γ`?:¬A introh Γ`h:¬A Γ`?:A

Γ`?:C destructh

Γ,h:A`?:B

Γ`?:A→B introh Γ`h:A→B Γ`?:A

Γ`?:B applyh

Γ,y:A`?:B[x←y]

Γ`?:∀x:A,B introy Γ`h:∀x:A,B Γ`t:A

Γ`?:B[x←t] applyywith(x:=t)

Γ`?:A Γ`?:B

Γ`?:A∧B split Γ`h:A∧B Γ,l:A,m:B`?:C

Γ`?:C destructhas(l, m)

Γ`?:A Γ`?:A∨B

Γ`?:B Γ`?:A∨B

left right

Γ`h:A∨B Γ,l:A`?:C Γ,l:B`?:C

Γ`?:C destructhas[l|l]

Γ`t:A Γ`?:B[x←t]

Γ`?:∃x:A,B existst Γ`h:∃x:A,B Γ,x:A,l:B`?:C

Γ`?:C destructhas(x, l)

= t≡u

Γ`?:t=u reflexivity Γ`h:t=u Γ`?:C[x←u]

Γ`?:C[x←t] rewriteh Fig. 2.Logical rules and corresponding tactics

It tries to find termstisuch that the current goal is equivalent toB[xi←ti]i=1...n

and generates subgoals corresponding toAj[xi←ti]i=1...n. If some of thexi are not infered by the system, it is always possible to use the variantwith(xi:=ti).

Tactics associated with logical rules implement backward reasoning, but it is often useful to do forward reasoning, adding new facts in the goal to be proven.

This is done using theasserttactic:

Γ `?:B Γ, h:B`?:A

Γ `?:A assert(h:B)

As an exercise, you may try to prove the following simple logical properties.

Coq < Lemma ex1 : f o r a l l A B C :Prop,

( A - > B - > C ) - > ( A - > B ) - > A - > C . Coq < Lemma ex2 : f o r a l l A , ~~~ A - > ~ A .

Coq < Lemma ex3 : f o r a l l A B , A \/ B - > ~ (~ A /\ ~ B ).

Coq < Lemma ex4 : f o r a l l T ( P : T - > P r o p) ,

(~ e x i s t s x , P x ) - > f o r a l l x , ~ P x . Tactics can be combined using what is called atactical:

t1 ; t2 applies tactict1 then tactict2on generated subgoals t1 || t2 applies tactict1, when it fails, appliest2

try t applies tactict, does nothing whentfails repeat trepeats tactictuntil it fails

Some tactics are doing proof search to help solve a goal:

(8)

contradictionsolves the goal whenFalse, orAand¬Aappear in the hypotheses tauto solves propositional tautologies

trivial tries very simple lemmas to solve the goal

auto searches in a database of lemmas to solve the goal intuition removes the propositional structure of the goal then auto omega solves goals in linear arithmetic

Proving Equalities. The introduction rule of equality is reflexivity. InCoq, two terms t and u are convertible (written t ≡ u) when they represent the same value after computation. The elimination rule allows to replace a term by an equal in any context. As a consequence, we have the following derived rules and corresponding tactics:

Γ`?:u=t

Γ`?:t=u symmetry

Γ`?:t=v Γ`?:v=u

Γ`?:t=u transitivityv

Γ`?:f=g Γ`?:t1=u1...Γ`?:tn=un Γ`?:f t1...tn=g u1...un

f equal

Variants of therewriterule includesrewrite <- HwhenH is a proof oft=u (or a generalization of it) which replacesubytand the tacticreplace u with t which does the replacement but also generates the goalt=u.

Therewritetactics by default replace all the occurrences ofuin P(u). To rewrite selected occurrences, there is a variant: rewriteH atoccs.

Another useful tactic for dealing with equalities issubst. Whenxis a variable and the context contains an hypothesis x=t (or t =x) withxnot occurring in t, then the tactic subst x will substitute t for x and remove both x and the hypothesis from the context. The tactic subst without argument do the substitution on all possible variables in the context.

Finishing Proofs. The commandsTheorem andLemma, given a name name and a property A, enter the interactive proof mode in which tactics are used to transform the goal. Hopefully, after some effort there will be no remaining subgoals : the proof ofAis finished. Actually,Coqis doing one more check before accepting the proof. From the tactics used, the system extracts a term p and the trusted kernel has to check thatΓ `p:Ais a valid judgment, which is done by elementary rules for type-checking p. This step is done with the commands Qed or Save. The proof is recorded in the environment and given the name name with type A. It can be used in other proofs like any hypothesis in the environment. It might seem useless to check again the proof, however, this choice of architecture allows to freely extend the set of tactics without compromising the safety of the proofs. Actually, some correctness checking (universes, well- formed definition of recursive functions) are not done during interactive proof mode and consequently, it might be the case (in rare occasions) that a “finished proof” is actually not a correct proof.

(9)

If a proof is not finished, it is possible to admit an intermediate goal using the tacticadmit. It will introduce an axiom corresponding to the current goal, it uses this axiom to solve the goal and continue with the next unproven goal.

Using the commandAdmittedinstead ofQedgives the possibility to finish the proof, introducing the original goalAas an axiom. It is convenient to postpone a proof but it is also potentially dangerous. Assuming a false property might result in being able to prove⊥and, consequently, everything becomes provable.

Safety inCoqis only guaranteed if there are no axioms left in the proof. The commandPrint Assumptionsname can be used to display all axioms used in the theoremname.

Definitions. A new definition is introduced by:

Definitionname args: type := term.

The identifiername is then an abbreviation for the termterm. The typetype is optional as well as the arguments which are a list of identifiers possibly associated with types. For instance, the square function can be defined as follows:

Coq < D e f i n i t i o n s q u a r e ( x : nat ) : nat := x * x . s q u a r e is d e f i n e d

A Coq definition name can be unfolded in a goal by using the tactic unfold name (in the conclusion) or unfoldname inH (in hypothesisH).

Variables and axioms. It is often convenient to introduce a local context of vari- ables and properties, which are shared between several definitions. It is done with a section mechanism. A section name is opened using the command Section name. Then objects can be introduced using the syntax:

Variablename:type or Hypothesisname:prop

Several variables with the same type can be introduced with a single command, using the variantVariablesand a blank-separated list of names. The following definitions can refer to the objects in the context of the section. The section is ended by the command Endname; then all definitions are automatically ab- stracted with respect to the variables they depend on.

For instance, we can introduce a typeAand two variables of this type using the commands:

Coq < Section t e s t . Coq < Variable A : T y p e. Coq < Variables x y : A .

Coq < D e f i n i t i o n d o u b l e : A * A := ( x , x ).

Coq < D e f i n i t i o n t r i p l e : A * A * A := ( x , y , x ).

Coq < End t e s t .

After ending the section, the objectsA,xandy are not accessible anymore and one can observe the new types of doubleandtriple.

(10)

Coq < Print d o u b l e .

d o u b l e = fun ( A : T y p e) ( x : A ) = > ( x , x ) : f o r a l l A : Type, A - > A * A

Coq < Print t r i p l e .

t r i p l e = fun ( A : T y p e) ( x y : A ) = > ( x , y , x ) : f o r a l l A : Type, A - > A - > A * A * A

2.4 Libraries in Coq

TheCoqenvironment is organized in a modular way. Some libraries are already loaded when starting the system. They can be displayed using the command:

Coq < Print L i b r a r i e s .

Searching the environment The following interactive commands are useful to find information in libraries when doing proofs. They can be executed from the coqide Queriesmenu.

– SearchAbout name: displays all declarations id : type in the environment such thatname appears intype.

Coq < SearchAbout p l u s .

p l u s _ n _ O : f o r a l l n : nat , n = n + 0 p l u s _ O _ n : f o r a l l n : nat , 0 + n = n

p l u s _ n _ S m : f o r a l l n m : nat , S ( n + m ) = n + S m p l u s _ S n _ m : f o r a l l n m : nat , S n + m = S ( n + m ) m u l t _ n _ S m : f o r a l l n m : nat , n * m + n = n * S m n a t _ i t e r _ p l u s :

f o r a l l ( n m : nat ) ( A : T y p e) ( f : A - > A ) ( x : A ) , n a t _ i t e r ( n + m ) f x = n a t _ i t e r n f ( n a t _ i t e r m f x ) Useful variants areSearchAbout[name1· · ·namen] to find objects with types mentioning all the names namei and alsoSearchAbout pattern to find ob- jects with types mentioning an instance of thepattern which is a term pos- sibly using the special symbol “ ” to represent an arbitrary term.

Coq < SearchAbout [ p l u s 0].

p l u s _ n _ O : f o r a l l n : nat , n = n + 0 p l u s _ O _ n : f o r a l l n : nat , 0 + n = n Coq < SearchAbout ( ~ _ < - > _ ).

n e g _ f a l s e : f o r a l l A : Prop, ~ A < - > ( A < - > F a l s e ) – Checkterm: checks ifterm can be typed and displays its type.

– Printname: prints the definition ofname together with its type.

– About id: displays the type of the object id (plus other informations like qualified name or implicit arguments).

Coq < A b o u t p a i r .

p a i r : f o r a l l A B : Type, A - > B - > A * B

A r g u m e n t s A , B are i m p l i c i t and m a x i m a l l y i n s e r t e d

<... >

E x p a n d s to : C o n s t r u c t o r Coq . I n i t . D a t a t y p e s . p a i r

(11)

Loading New Libraries. The commandRequire Importname checks if module name is already present in the environment. If not, and if a filename.vo occurs in the load-path, then it is loaded and opened (its contents is revealed).

The set of loaded modules and the load-path can be displayed with commands Print LibrariesandPrint LoadPath. The default load-path is the set of all sub-directories of theCoqstandard library.

The libraries related to natural numbers arithmetic are gathered in a single moduleArithin such a way that the commandRequire ImportArith loads and opens all these modules.

As usual in programming languages, the module names are used to organize the name space. The same “short name” can be used to represent different objects in different modules.

The commandRequirename (withoutImport) only loads the library, the objects inside are refered to by a qualified name:dir.name.id. This long name is also useful when the same identifier exists in different libraries. The command Locateid helps find all occurrence ofid in loaded libraries.

2.5 Examples

After all these generalities, we can try to do our first program verifications.

One of the challenges proposed by the LASER summer school was to define an absolute value function on machine integers and prove the result is positive.

We first prove a much simpler result on mathematical integers. Mathematical integers inCoqare defined as a typeZ. Their representation is based on a binary representation of positive numbers (typepositive).

Definition and properties of integers are defined in the library ZAriththat needs to be loaded first. In order to use the standard arithmetical notations for Z, we have to tell Coq to use them (otherwise Coq will interpret 0 or + as objects innat).

Coq < Require Import Z A r i t h . Coq < Open Scope Z _ s c o p e .

The absolute value function is part ofCoqstandard arithmetic library (function Zabs), and the expected result is a theorem namedZabs pos).

However, we may want to do it naively. We need to test the sign of an integer so we need a boolean function for that. The commandSearchAbout(Z->bool) shows their is a functionZle bool: Z -> Z -> bool, then the commandSearch- AboutZle boolgives us several properties of this function , including:

Z l e _ c a s e s : f o r a l l n m , if Z l e _ b o o l n m t h e n n <= m e l s e n > m which links the boolean result of theZle boolfunction with the mathematical property. The proof goes as follows:

Coq < D e f i n i t i o n abs ( n : Z ) : Z := if Z l e _ b o o l 0 n t h e n n e l s e - n . abs is d e f i n e d

Coq < Lemma a b s _ p o s : f o r a l l n , 0 <= abs n .

(12)

Coq < i n t r o n ; u n f o l d abs . 1 s u b g o a l

n : Z

= = = = = = = = = = = = = = = = = = = = = = = = = = = =

0 <= ( if Z l e _ b o o l 0 n t h e n n e l s e - n )

Coq < a s s e r t ( if Z l e _ b o o l 0 n t h e n 0 <= n e l s e 0 > n ).

2 s u b g o a l s n : Z

= = = = = = = = = = = = = = = = = = = = = = = = = = = =

if Z l e _ b o o l 0 n t h e n 0 <= n e l s e 0 > n s u b g o a l 2 is :

0 <= ( if Z l e _ b o o l 0 n t h e n n e l s e - n ) Coq < a p p l y Z l e _ c a s e s .

1 s u b g o a l n : Z

H : if Z l e _ b o o l 0 n t h e n 0 <= n e l s e 0 > n

= = = = = = = = = = = = = = = = = = = = = = = = = = = =

0 <= ( if Z l e _ b o o l 0 n t h e n n e l s e - n )

Coq < d e s t r u c t ( Z l e _ b o o l 0 n ); a u t o w i t h z a r i t h . Proof c o m p l e t e d .

Coq < Qed.

a b s _ p o s is d e f i n e d

If we want to reason on machine integers, one can use theInt31library inCoq which represents 31-bit cyclic arithmetic, but because it is interpreted as positive integers between0and231−1, some work is needed before solving the problem and we shall not detail the proof here. The Compcert project[27] also provides a library http://compcert.inria.fr/src/lib/Integers.v defining machine integers as mathematical numbers modulo 2N.

A second challenge was to implement a class for a bank account with a bal- ance represented as an IEEE floating point number and to specify a deposit method. Of course the difficulty comes from the interpretation of theplus op- eration which will be a floating point number operation with rounding in the program ans possibly a mathematical operation in the specification.

InCoq, it is possible to manipulate real numbers (libraryReals, with arith- metic notations) and there are also external libraries dealing with IEEE floating point real numbers, the most recent one being Flocq [10] (we use here version 2.0).

Coq < Require Import R e a l s F a p p l i _ I E E E F a p p l i _ I E E E _ b i t s . Coq < Open L o c a l Scope R _ s c o p e .

The typebinary32represents a single precision (normalized) floating point num- ber with its sign (a boolean), its mantissa (a positive binary number between 0 and 223−1) and its exponent (between−126 and 126).Coqis able to compute with these numbers. We can also choose the rounding mode of the addition.

Coq < Print b i n a r y 3 2 .

b i n a r y 3 2 = b i n a r y _ f l o a t 24 128 : Set

(13)

Coq < Check b 3 2 _ p l u s . b 3 2 _ p l u s : m o d e - >

b i n a r y _ f l o a t 24 128 - >

b i n a r y _ f l o a t 24 128 - > b i n a r y _ f l o a t 24 128 Coq < Print m o d e .

Inductive m o d e : T y p e :=

m o d e _ N E | m o d e _ Z R | m o d e _ D N | m o d e _ U P | m o d e _ N A

The functionB2Rtransforms a floating point into the corresponding real number.

We introduce convenient notations for the numbers 1, 2−23 and 2−24. Coq < Notation b i n 3 2 b m e :=

Coq < ( b i n a r y _ n o r m a l i z e 24 128 g t 0 _ 2 4 g t _ 2 4 _ 1 2 8 m o d e _ N E m e b ).

Coq < D e f i n i t i o n b 3 2 _ o n e := b i n 3 2 f a l s e (1) ( 0 ) .

Coq < D e f i n i t i o n b 3 2 _ 2 _ m i n u s 2 3 := b i n 3 2 f a l s e (1) ( -23).

Coq < D e f i n i t i o n b 3 2 _ 2 _ m i n u s 2 4 := b i n 3 2 f a l s e (1) ( -24).

We can now implement the deposit function and introduce the property corre- sponding to its correctness.

Coq < D e f i n i t i o n d e p o s i t ( o l d a a m o u n t : b i n a r y 3 2 ) : b i n a r y 3 2 Coq < := b 3 2 _ p l u s m o d e _ N E o l d a a m o u n t .

Coq < D e f i n i t i o n d e p o s i t _ c o r r e c t o l da a m o u n t : P r o p :=

Coq < B2R ( d e p o s i t o l d a a m o u n t ) = ( B2R o l d a + B2R a m o u n t )% R . We can now show correct and incorrect behaviors.

Coq < Lemma ex1 : d e p o s i t _ c o r r e c t b 3 2 _ o n e b 3 2 _ 2 _ m i n u s 2 3 . Coq < c o m p u t e .

1 s u b g o a l

= = = = = = = = = = = = = = = = = = = = = = = = = = = = 8 3 8 8 6 0 9 * / 8 3 8 8 6 0 8 =

8 3 8 8 6 0 8 * / 8 3 8 8 6 0 8 + 8 3 8 8 6 0 8 * / 7 0 3 6 8 7 4 4 1 7 7 6 6 4

The proof can be finished using thefieldtactic to reason on real numbers. The following case can be proved to be incorrect:

Coq < Lemma ex2 : ~ ( d e p o s i t _ c o r r e c t b 3 2 _ o n e b 3 2 _ 2 _ m i n u s 2 4 ).

Coq < c o m p u t e ; i n t r o . 1 s u b g o a l

H : 8 3 8 8 6 0 8 * / 8 3 8 8 6 0 8 =

8 3 8 8 6 0 8 * / 8 3 8 8 6 0 8 + 8 3 8 8 6 0 8 * / 1 4 0 7 3 7 4 8 8 3 5 5 3 2 8

= = = = = = = = = = = = = = = = = = = = = = = = = = = = F a l s e

The proof comes from the fact that we have an hypothesis (x = x+y) with y 6= 0 but unfortunately it is not fully automated inCoq(automation on real numbers is still rudimentary); we do not give the details here.

These examples show that Coq provides advanced libraries to reason on complex mathematical and algorithmic notions such as real and floating point numbers.

(14)

2.6 About classical logic

Coq implements an intuitionistic logic. Which means that A∨ ¬A is not an axiom. Actually, bothA∨Band∃x:A, Bhave a strong constructive meaning.

Indeed, from a proof of ` ∃x:A, B, one can compute t such that B[x←t] is provable and from a proof ofA∨B one can compute a booleanb and proofs of b=true→Aandb=false→A.

Classical reasoning is often not needed, manual proofs of A∨ ¬A can be built for many simple formulas. It is also possible to use classical versions of logical connectives (negative formulas are classical). But if we really want to use classical logic, a libraryClassicalintroduces the excluded middle as an axiom.

3 Inductive Declarations

Inductive definitions are another main ingredient ofCoqlanguage. It is a generic mechanism which captures different notions such as data-types, logical connec- tives, primitive relations. We illustrate the use of inductive definitions on an example, modeling a game on a board containing bi-color tokens. We also study simple algorithms on lists and a cryptographic protocol.

3.1 Inductive Data Types

A data-type name can be declared by specifying a set of constructors. Each constructor ci is given a type Ci which declares the type of its expected argu- ments. A constructor possibly accepts arguments (which can be recursively of typename), and when applied to all its arguments, a constructor has type the inductive definition name itself. There are some syntactic restrictions over the type of constructors to make sure that the definition is well-founded.

The syntax for declaring an inductively defined type is:

Inductivename :sort:= c1:C1| . . . |cn :Cn.

where name is the name of the type to be defined; sort is one of Set or Type (or even Prop); ci are the names of the constructors and Ci is the type of the constructorci.

The declaration of an inductive definition introduces new primitive objects for the type itself and its constructors; it also generates theorems which are abbreviations for more complex terms expressing thatname is the smallest set containing the terms build with constructors. These theorems provide induction principles to reason on objects in inductive types.

Examples. The data types of booleans and natural numbers are defined induc- tively as follows:

Coq < Print b o o l .

Inductive b o o l : Set := t r u e : b o o l | f a l s e : b o o l

(15)

Coq < Check b o o l _ i n d .

b o o l _ i n d : f o r a l l P : b o o l - > Prop,

P t r u e - > P f a l s e - > f o r a l l b : bool , P b Coq < Print nat .

Inductive nat : Set := O : nat | S : nat - > nat Coq < Check n a t _ i n d .

n a t _ i n d : f o r a l l P : nat - > Prop,

P 0 - > (f o r a l l n : nat , P n - > P ( S n )) - > f o r a l l n : nat , P n

The type of booleans has only two constant constructors. The type of natural numbers has a constantOand a unary constructor Sfor the successor function.

The product type is also inductively defined.

Coq < Print p r o d .

Inductive p r o d ( A B : T y p e) : T y p e := p a i r : A - > B - > A * B For p a i r : A r g u m e n t s A , B are i m p l i c i t and m a x i m a l l y i n s e r t e d We remark two things on this definition. First it is a polymorphic definition, parametrized by two type A and B. Second the constructor pair takes two arguments and pairs them in an object of typeA∗B, which is what is expected for a product representation.

Inductive Types and Equality. The constructors of an inductive type are injective and distinct. For instance one can provetrue6=falseand for natural numbers, Sn=Sm→n=m and Sn6= 0. These lemmas are part of the stan- dard library for natural numbers but have to be proved for new inductive types.

There are tactics to automate this process.

– discriminateH will prove any goal ifH is a proof oft1=t2witht1andt2

starting with different constructors. With no argument discriminate will try to find such a contradiction in the context.

– injectionH assumesH is a proof of t1=t2 with t1 and t2 starting with the same constructor. It will deduce equalitiesu1=u2, v1=v2, . . .between corresponding subterms and add these equalities as new hypotheses.

Coq < Goal (f o r a l l n , S ( S n ) = 1 - > 0 = 1 ) . Coq < i n t r o s n H .

1 s u b g o a l n : nat

H : S ( S n ) = 1

= = = = = = = = = = = = = = = = = = = = = = = = = = = = 0 = 1

Coq < d i s c r i m i n a t e H . Proof c o m p l e t e d .

Coq < Goal (f o r a l l n m , S n = S ( S m ) - > 0 < n ).

Coq < i n t r o s n m H .

(16)

1 s u b g o a l n : nat m : nat

H : S n = S ( S m )

= = = = = = = = = = = = = = = = = = = = = = = = = = = = 0 < n

Coq < i n j e c t i o n H . 1 s u b g o a l

n : nat m : nat

H : S n = S ( S m )

= = = = = = = = = = = = = = = = = = = = = = = = = = = = n = S m - > 0 < n

Remark on Inductive Propositions. Thesort in an inductive definition can also bePropallowing the inductive declaration of logical propositions. Following the Curry-Howard correspondence between proposition and types, all proposi- tional connectives except for negation, implication and universal quantifier are declared using inductive definitions.Falseis a degenerated case where there are no constructors. True is the proposition with only one proof I (corresponding to the unit type with only one constructor). Conjunction of two propositions corresponds to the product type and disjunction to an inductive proposition with two constructors. Existential quantifiers and equality are also inductively defined.

Coq < Print F a l s e .

Inductive F a l s e : Pr o p :=

Coq < Check F a l s e _ i n d .

F a l s e _ i n d : f o r a l l P : Prop, F a l s e - > P Coq < Print or .

Inductive or ( A B : P r o p) : P r o p :=

o r _ i n t r o l : A - > A \/ B | o r _ i n t r o r : B - > A \/ B Coq < Check o r _ i n d .

o r _ i n d : f o r a l l A B P : Prop,

( A - > P ) - > ( B - > P ) - > A \/ B - > P

The Board Example. The game we want to study involves nine bicolor tokens (one side black and one side white) which are placed on a 3×3 board.

A B C

A B C

At each step it is possible to choose one line or one column and to inverse the color of each token on that line or column. We want to study when a configuration is reachable from a starting configuration.

(17)

The data types involved in that example are the state of each token (black or white) which can be represented by a boolean or a special inductive type with two values. We need to identify a column and a line by a position (three possible values).

Coq < Inductive c o l o r : T y p e := W h i t e | B l a c k . Coq < Inductive pos : T y p e := A | B | C .

Finally we need to represent the board. It is convenient to represent it as three lines, each line being composed of three colors. In order to reuse functions, one can introduce a polymorphic type of triples of elements in an arbitrary typeM (the definition is very similar to the definition of the product type).

Coq < Inductive t r i p l e M := T r i p l e : M - > M - > M - > t r i p l e M . A line White/Black/White will be represented by the termTriple White Black White. TheCoqkernel requires the type argumentM to be explicitly given, so theCoqinternal term isTriple color White Black White. However, the type colorcan be easily deduced from the type of Whiteand can be systematically omitted in the input, thanks to the Coqdeclaration:

Coq < Set I m p l i c i t A r g u m e n t s .

which tells Coq to infer type arguments whenever possible. Alternatively, the command Implicit Argumentsname [args] can be used to force the implicit arguments of a given objectname. On can also introduce a special notation for triples:

Coq < Notation "[ x | y | z ]" := ( T r i p l e x y z ).

and define a function which given an elementm in M builds a triple with the valuemin the three positions.

Coq < D e f i n i t i o n t r i p l e _ x M ( m : M ) : t r i p l e M := [ m | m | m ].

3.2 Definitions by pattern-matching

The Pattern-Matching Operator. When a termtbelongs to some inductive type, it is possible to build a new term by case analysis over the various constructors which may occur as the head oftwhen it is evaluated. Such definitions are known in functional programming languages as pattern-matching. TheCoq syntax is the following:

matchterm withc1args1⇒term1 . . . cn argsn⇒termn end In this construction, the expressionterm has an inductive type withnconstruc- tors c1, ..., cn. The term termi is the term to build when the evaluation of t produces the constructorci.

(18)

Example. If nhas typenat, the function checking whethernisOcan be defined as follows:

Coq < D e f i n i t i o n i s z e r o n :=

m a t c h n wi t h | O = > t r u e | S x = > f a l s e end. The board example. On can simply define a function which inverses a color:

Coq < D e f i n i t i o n t u r n _ c o l o r ( c : c o l o r ) : c o l o r :=

m a t c h c w i t h | W h i t e = > B l a c k | B l a c k = > W h i t e end. On our board example, given a function f of type M →M, one can define a functiontriple map which given a triple(a, b, c), appliesf to all components, and a functiontriple map selectwhich also expects a position and applies the functionf at that position.

Coq < D e f i n i t i o n t r i p l e _ m a p M f ( t : t r i p l e M ) : t r i p l e M :=

m a t c h t w i t h ( T r i p l e a b c ) = > [( f a )|( f b )|( f c )] end. Coq < D e f i n i t i o n t r i p l e _ m a p _ s e l e c t M f p t : t r i p l e M :=

m a t c h t wi t h ( T r i p l e a b c ) = >

m a t c h p w i t h | A = > [ ( f a ) | b | c ]

| B = > [ a | ( f b ) | c ]

| C = > [ a | b | ( f c ) ] end

end.

Generalized Pattern-Matching Definitions. More generally, patterns can match several terms at the same time, they may be nested and they may contain the universal pattern which filters any expression. Patterns are examined in a sequential way (as in functional programming languages) and they must cover the whole domain of the inductive type. Thus one may write for instance Coq < D e f i n i t i o n n o z e r o n m :=

m a t c h n , m w i t h

| O , _ = > f a l s e | _ , O = > f a l s e | _ , _ = > t r u e end.

However, the generalized pattern-matching is not considered as a primitive con- struct and is actuallycompiled into a sequence of primitive patterns.

Some Equivalent Notations. In the case of an inductive type with a single con- structorC:

let(x1, .., xn):=t inu

can be used as an equivalent tomatcht withCx1..xn⇒uend.

In the case of an inductive type with two constructors (like booleans)c1and c2 (such as the type of booleans for instance) the construct

iftthenu1 elseu2

can be used as an equivalent tomatcht withc1⇒u1|c2⇒u2 end.

(19)

3.3 Fixpoint Definitions

To define interesting functions over recursive data types, we use recursive func- tions. General fixpoints are not allowed since they lead to an unsound logic.

Only structural recursion is allowed. It means that a function can be defined by fixpoint if one of its formal arguments, sayx, has an inductive type and if each recursive call is performed on a term which can be checked to be structurally smaller than x. The basic idea is that x will usually be the main argument of a match and then recursive calls can be performed in each branch on some variables of the corresponding pattern.

The FixpointConstruct. The syntax for a fixpoint definition is the following:

Fixpointname (x1:type1) . . . (xp:typep){structxi}:type :=term The variable xi following the struct keyword is the recursive argument. Its typetypei must be an instance of an inductive type. If the clause{structxi} is omitted, the system will try to infer an appropriate argument.

The type ofname isforall (x1:type1). . .(xp:typep), type. Occurrences of name in term must be applied to at least i arguments and theith must be structurally smaller thanxi.

Examples. The following two definitions of plusby recursion over the first and the second argument respectively are correct:

Coq < Fixpoint p l u s 1 ( n m : nat ) : nat :=

Coq < m a t c h n w i t h | O = > m | S p = > S ( p l u s 1 p m ) end. p l u s 1 is r e c u r s i v e l y d e f i n e d ( d e c r e a s i n g on 1 st a r g u m e n t ) Coq < Fixpoint p l u s 2 ( n m : nat ) : nat :=

Coq < m a t c h m w i t h | O = > n | S p = > S ( p l u s 2 n p ) end. p l u s 2 is r e c u r s i v e l y d e f i n e d ( d e c r e a s i n g on 2 nd a r g u m e n t )

Restrictions on Fixpoint Declarations. There are strong syntactic restrictions on the kind of definitions that are accepted, there should be one decreasing argument for each fixpoint, the following definition will not be accepted:

Coq < Fixpoint t e s t ( b : b o o l ) ( n m : nat ) : b o o l Coq < := m a t c h ( n , m ) w i t h

Coq < | ( O , _ ) = > t r u e | ( _ ,0) = > f a l s e

Coq < | ( S p , S q ) = > if b t h e n t e s t b p m e l s e t e s t b n q Coq < end.

E r r o r : C a n n o t g u e s s d e c r e a s i n g a r g u m e n t of fix .

However, it is possible to define functions with more elaborated recursive schemes using higher order functions like the Ackermann function:

Coq < Fixpoint ack ( n m : nat ) { s t r u c t n } : nat Coq < := m a t c h n w i t h

(20)

Coq < | 0 = > S m

Coq < | S p = > let fix a c k n ( m : nat ) { s t r u c t m } :=

Coq < m a t c h m w i t h 0 = > ack p 1

| S q = > ack p ( a c k n q ) end

Coq < in a c k n m

Coq < end.

ack is r e c u r s i v e l y d e f i n e d ( d e c r e a s i n g on 1 st a r g u m e n t )

We may remark the internal definition of fixpoint using thelet fixconstruction which defines the value of ack n as a new function ackn with one argument and a structurally smaller recursive call. As an exercise, you may prove that the following equations are solved usingreflexivity.

Coq < Goal f o r a l l n , ack ( S n ) 0 = ack n 1.

Coq < Goal f o r a l l n m , ack ( S n ) ( S m ) = ack n ( ack ( S n ) m ).

Computation. A fixpoint can be computed when the recursive argument starts with a constructor. So plus1 0 n and n are convertible but plus1 n 0 is in normal form when nis a variable. The equation corresponding to the fixpoint definition is not just proven by reflexivity but requires a simple case analysis over the recursive argument.

Coq < Lemma p l u s 1 _ e q : f o r a l l n m ,

Coq < p l u s 1 n m = m a t c h n w i t h O = > m | S p = > S ( p l u s 1 p m ) end. Coq < d e s t r u c t n ; t r i v i a l .

Proof c o m p l e t e d .

The tactic simpl name when name is a fixpoint definition will simplify the expression whenever it is applied to a constructor. The tactic simpl simplifies all fixpoint definitions in the goal (which is sometimes too much, in which case it is recommended to prove the relevant equations as theorems and use them in a controled way with therewritetactic).

Remark. Coqdoes not prevent to define empty inductive data-types such as:

Coq < Inductive E : Set := Ei : E - > E . E is d e f i n e d

But of course, there are no way to build a value (term without variable) of type Eand furthermore, one can build a function which given an argument inEbuild an element in any typeA:

Coq < Fixpoint E a n y A x : A :=

m a t c h x wi t h ( Ei y ) = > E a n y A y end.

E a n y is r e c u r s i v e l y d e f i n e d ( d e c r e a s i n g on 2 nd a r g u m e n t ) In particular one can proveFalsefrom an hypothesisx:E.

(21)

Computing. One can reduce a term and prints its normal form withEvalcomputein term. For instance:

Coq < Eval c o m p u t e in (2 + 3)% nat .

= 5% nat : nat

Coq < Eval c o m p u t e in ( t u r n _ c o l o r W h i t e ).

= B l a c k : c o l o r

Coq < Eval c o m p u t e in ( t r i p l e _ m a p t u r n _ c o l o r [ B l a c k | W h i t e | W h i t e ]).

= [ W h i t e | B l a c k | B l a c k ] : t r i p l e c o l o r

3.4 Algorithms on lists

Another LASER challenge was proving algorithms on arrays. We choose to rep- resent arrays by functional lists. We import theList and ZArithlibraries and use the predefined notations. Notations for lists include a::l for the operator cons andl1++l2 for the concatenation of two lists.

Coq < Require Import L i s t Z A r i t h . Coq < Open Scope Z _ s c o p e .

Coq < Open Scope l i s t _ s c o p e . Coq < Print l i s t .

Inductive l i s t ( A : T y p e) : T y p e :=

nil : l i s t A | c o n s : A - > l i s t A - > l i s t A

Sum and maximum Computing the sum and the maximum value of a list is done by a simple fixpoint definition.

Coq < Fixpoint sum ( l : l i s t Z ) : Z :=

Coq < m a t c h l w i t h nil = > 0 | a :: m = > a + sum m end. Coq < Fixpoint max ( l : l i s t Z ) : Z :=

Coq < m a t c h l w i t h nil = > 0

Coq < | a :: nil = > a

Coq < | a :: m = > let b := max m in

Coq < if Z l e _ b o o l a b t h e n b e l s e a

Coq < end.

Because the pattern-matching for defining maxis not elementary, it is useful to prove the corresponding equation to be used for rewriting.

Lemma m a x _ c o n s : f o r a l l a m , m < > nil

- > max ( a :: m ) = let b := max m in if a <=? b t h e n b e l s e a . i n t r o a ; d e s t r u c t m ; t r i v i a l ; i n t r o H .

d e s t r u c t H ; t r i v i a l . Qed.

We can after that enunciate the correctness property we want to prove:

Lemma s u m _ m a x _ p r o p : f o r a l l l , sum l <= Z _ o f _ n a t ( l e n g t h l ) * max l . It is proved by induction onl(see section 3.6), then using the tacticsimplto do

some of the simplifications onsumandlengthand then arithmetical reasoning.

(22)

Correctness of maxand sum. To specify the behavior of max, we could use the predicateInof theListlibrary and say that wheneverlis non empty thenmaxl is inland it is not less than all elements inl. Our functionsumsatisfies the two following equations which can be considered as a valid functional specification.

sum nil= 0 sum(a::l) =a+suml Termination. All functions in Coqterminate.

3.5 Inductive Relations

Inductive definitions can also be used to introduce relations specified by a set of closure properties (like inference rules or Prolog clauses). Each clause is given a name, seen as a constructor of the relation. The type of this constructor is the logical formula associated to the clause. The syntax of such a definition is:

Inductivename:arity:=c1:C1| . . . |cn :Cn

wherename is the name of the relation to be defined,arityits type (for instance nat->nat->Prop for a binary relation over natural numbers) and, as for data types,ci andCi are the names and types of constructors respectively.

Example. The definition of the order relation over natural numbers can be de- fined as the smallest relation verifying:

∀n:nat,0≤n ∀nm:nat, n≤m⇒(Sn)≤(Sm) which is sometimes presented as a set of inference rules

0≤n

n≤m (Sn)≤(Sm) InCoq, such a relation is defined as follows:

Coq < Inductive LE : nat - > nat - > P r o p :=

Coq < | L E _ O : f o r a l l n : nat , LE 0 n

Coq < | L E _ S : f o r a l l n m : nat , LE n m - > LE ( S n ) ( S m ).

LE is d e f i n e d L E _ i n d is d e f i n e d

This declaration introduces identifiers LE,LE O andLE S, each having the type specified in the declaration. The LE indtheorem is introduced which captures the minimality of the relation.

Coq < Check L E _ i n d . L E _ i n d

: f o r a l l P : nat - > nat - > Prop, (f o r a l l n : nat , P 0 n ) - >

(f o r a l l n m : nat , LE n m - > P n m - > P ( S n ) ( S m )) - >

f o r a l l n n0 : nat , LE n n0 - > P n n0

(23)

Actually, the definition of the order relation on natural numbers inCoqstandard library is slightly different:

Coq < Print le .

Inductive le ( n : nat ) : nat - > P r o p :=

l e _ n : ( n <= n )

| l e _ S : f o r a l l m : nat , ( n <= m ) - > ( n <= S m )

The parameter(n:nat)after leis used to factor out nin the whole inductive definition. As a counterpart, the first argument oflemust benin the conclusion of each type of constructor. In particular, n could not have been a parameter in the definition of LE since LE must be applied to (S n) in the conclusion of the second clause. Both definitions of the order can be proved equivalent.

For technical reasons, having more arguments as parameters in an inductive definition makes usually proofs easier. In general there are multiple ways to define the same relation by inductive declarations (or possibly recursive functions). One has to keep in mind that they are differentimplementations of the same notion and that like in programming, some of the choices will have consequences on the easiness of doing subsequent proofs with these notions.

Examples

The Board Example. We have defined functions on triples and colors. We can now introduce the type of boards that will be a triple of lines, a line being a triple of colors. We also define two specific boards start and target. And we can define the functionsturn colandturn rowwhich inverse the colors.

Coq < D e f i n i t i o n b o a r d := t r i p l e ( t r i p l e c o l o r ).

Coq < D e f i n i t i o n s t a r t : b o a r d

Coq < := [ [ W h i t e | W h i t e | B l a c k ] | Coq < [ B l a c k | W h i t e | W h i t e ] | Coq < [ B l a c k | B l a c k | B l a c k ] ].

Coq < D e f i n i t i o n t a r g e t : b o a r d

Coq < := [ [ B l a c k | B l a c k | W h i t e ] | Coq < [ W h i t e | B l a c k | B l a c k ] | Coq < [ B l a c k | B l a c k | B l a c k ] ].

Coq < D e f i n i t i o n t u r n _ r o w ( p : pos ) : b o a r d - > b o a r d :=

Coq < t r i p l e _ m a p _ s e l e c t ( t r i p l e _ m a p t u r n _ c o l o r ) p . Coq < D e f i n i t i o n t u r n _ c o l ( p : pos ) : b o a r d - > b o a r d :=

Coq < t r i p l e _ m a p ( t r i p l e _ m a p _ s e l e c t t u r n _ c o l o r p ).

Now if we want to define the relation between two boards corresponding to one step (inversing one line or one column), we can use predefined logical connectives:

Coq < D e f i n i t i o n m o v e 1 ( b1 b2 : b o a r d ) : P r o p :=

Coq < (e x i s t s p : pos , b2 = t u r n _ r o w p b1 ) Coq < \/ (e x i s t s p : pos , b2 = t u r n _ c o l p b1 ).

(24)

or alternatively a direct inductive definition:

Coq < Inductive m o v e ( b1 : b o a r d ) : b o a r d - > P r o p :=

Coq < m o v e _ r o w : f o r a l l ( p : pos ) , m o v e b1 ( t u r n _ r o w p b1 ) Coq < | m o v e _ c o l : f o r a l l ( p : pos ) , m o v e b1 ( t u r n _ c o l p b1 ).

If we want to define reachability, we need to consider the reflexive-transitive closure of themoverelation. This is done easily with an inductive definition:

Coq < Inductive m o v e s ( b1 : b o a r d ): b o a r d - > P r o p :=

Coq < m o v e s _ i n i t : m o v e s b1 b1 Coq < | m o v e s _ s t e p : f o r a l l b2 b3 ,

Coq < m o v e s b1 b2 - > m o v e b2 b3 - > m o v e s b1 b3 . One can prove simple properties like:

Coq < Lemma m o v e _ m o v e s : f o r a l l b1 b2 , m o v e b1 b2 - > m o v e s b1 b2 . Coq < i n t r o s ; a p p l y m o v e s _ s t e p w i t h b1 ; t r i v i a l .

1 s u b g o a l b1 : b o a r d b2 : b o a r d H : m o v e b1 b2

= = = = = = = = = = = = = = = = = = = = = = = = = = = = m o v e s b1 b1

Coq < a p p l y m o v e s _ i n i t . Proof c o m p l e t e d .

We can prove that the board targetis accessible from the boardstart.

Lemma r e a c h a b l e : m o v e s s t a r t t a r g e t .

a p p l y m o v e s _ s t e p w i t h ( t u r n _ r o w A s t a r t ); a u t o .

r e p l a c e t a r g e t w i t h ( t u r n _ r o w B ( t u r n _ r o w A s t a r t )); a u t o . Qed.

Linear Search. With linear search of a zero in an array of non-negative integers, we go back to natural numbers.

Open Scope n a t _ s c o p e .

In order to capture the special case where there is no 0 in the list, we prefer to use an option type with none or one value.

Coq < Print o p t i o n .

Inductive o p t i o n ( A : T y p e) : T y p e :=

S o m e : A - > o p t i o n A | N o n e : o p t i o n A We use a terminal recursive definition:

Coq < Fixpoint l i n e a r ( n : nat ) ( l : l i s t nat ) : o p t i o n nat :=

Coq < m a t c h l w i t h nil = > N o n e

Coq < | a :: m = > if z e r o p a t h e n S o m e n e l s e l i n e a r ( S n ) m Coq < end.

Coq < D e f i n i t i o n l i n e a r _ s e a r c h := l i n e a r 0.

(25)

In order to specify this function, it is convenient to introduce an inductive predi- catecorrectsuch thatcorrectk lis true whenlstarts withknon-zero elements and then contains a zero.

Coq < Inductive c o r r e c t : nat - > l i s t nat - > P r o p :=

Coq < c o r r e c t _ h d : f o r a l l a l , a =0 - > c o r r e c t 0 ( a :: l ) Coq < | c o r r e c t _ t l : f o r a l l a l n ,

Coq < a < >0 - > c o r r e c t n l - > c o r r e c t ( S n ) ( a :: l ).

Coq < Hint Constructors c o r r e c t .

TheHint Constructorscommand adds the constructors of the inductive defi- nition in the hints database to be used by theautotactic.

3.6 Elimination of Inductive Definitions

Proof by Case Analysis: the destruct tactic. An object in an inductive definition I, when fully instantiated and evaluated will be formed after one of the constructors of I. When we have an arbitrary term t in I, we can reason by case on the constructors the term t can be evaluated to. The destruct t tactic generates a new subgoal for each constructor and introduces new vari- ables and hypothesis corresponding to the arguments of the constructor. Coq generates automatically names for these variables. It is recommended to use destructtaspat; withpat a pattern for naming variables.pat will be written [p1|. . .|pn] withnthe number of constructors ofI. The patternpiwill be written (x1, . . . , xk) if the constructor ci expectskarguments.

If the goal has the form ∀x: I, P, then the tactic intros pat, will do the introduction of x and will immediately after destruct this variable using the pattern as in the following example:

Coq < Goal f o r a l l A B : Prop, ( A /\ ~ B ) \/ B - > ~ A - > B . Coq < i n t r o s A B [ ( Ha , Hnb ) | Hb ] Hna .

2 s u b g o a l s A : Pr o p B : Pr o p Ha : A Hnb : ~ B Hna : ~ A

= = = = = = = = = = = = = = = = = = = = = = = = = = = = B

s u b g o a l 2 is : B

Coq < c o n t r a d i c t i o n . 1 s u b g o a l

A : P ro p B : P ro p Hb : B Hna : ~ A

= = = = = = = = = = = = = = = = = = = = = = = = = = = =

(26)

B

Coq < a u t o . Proof c o m p l e t e d .

For instance, the equivalence between the two definitions of one-step move in the board example can be easily done using thedestructtactic.

Coq < Lemma e x b o a r d : f o r a l l b1 b2 , m o v e 1 b1 b2 < - > m o v e b1 b2 . The destructtactic, when applied to an hypothesis will clear this hypothesis from the goal. Thecasetactic is a more elementary tactic corresponding to the logical elimination rule when more control is needed.

Proof by induction. The tactic to perform proofs by induction isinductionterm whereterm is an expression in an inductive type. It can be an induction over a natural number or a list but also an elimination rule for a logical connective or a minimality principle for an inductive relation. More precisely, an induction is the application of one of the principles which are automatically generated when the inductive definition is declared.

Theinductiontactic can also be applied to variables or hypotheses bound in the goal. To refer to some unnamed hypothesis from the conclusion (i.e.the left hand-side of an implication), one has to useinductionnumwhere num is thenum-th unnamed hypothesis in the conclusion.

Theinductiontactic generalizes the dependent hypotheses of the expression on which the induction applies.

Induction over Data Types. For an inductive type I, the induction scheme is given by the theorem I ind; it generalizes the standard induction over natural numbers. The main difficulty is to tell the system what is the property to be proved by induction. The default (inferred) property for the tacticinductionterm is the abstraction of the goal w.r.t. all occurrences ofterm. If only some occur- rences must be abstracted (but not all) then the tactic “patternterm atoccs”

can be applied first.

It is sometimes necessary to generalize the goal before performing induction.

This can be done using the cut prop tactic, which changes the goal G into prop→Gand generates a new subgoalprop. If the generalization involves some hypotheses, one may use the generalise tactic first (if xis a variable of type A, thengeneralise xchanges the goalGinto the new goalforall x:A, G).

The correctness of thelinearfunction introduced earlier can be expressed by the following lemma:

Coq < Lemma l i n e a r _ c o r r e c t : f o r a l l l n k ,

Coq < l i n e a r n l = S o m e k < - > ( n <= k /\ c o r r e c t ( k - n ) l ).

which is proved by induction onl. The special case is a simple consequence when n= 0:

Coq < Lemma l i n e a r _ s e a r c h _ c o r r e c t :

Coq < f o r a l l l k , l i n e a r _ s e a r c h l = S o m e k < - > c o r r e c t k l .

(27)

Induction over Proofs. Ifterm belongs to an inductive relation then the induc- tion tactic corresponds to the use of the minimality principle for this relation.

Generally speaking, the property to be proved is (I x1. . . xn)⇒GwhereIis the inductive relation. The goalGis abstracted w.r.t.x1. . . xn to build the relation used in the induction. It works well when x1. . . xn are either parameters of the inductive relation or variables. If some of thexi are complex terms, the system may fail to find a well-typed abstraction or may infer a non-provable property.

If no recursion is necessary then the tacticinversionterm is to be preferred (it exploits all informations inx1. . . xn). If recursion is needed then one can try to first change the goal into the equivalent one (assuming xi is a non-variable, non-parameter argument):

∀y,(I x1. . . y . . . xn)⇒xi =y⇒G and then do the induction on the proof of (I x1. . . y . . . xn).

For the board example, the transitivity of themoves relation (an arbitrary number of simple moves) is easily done by an induction on the proof of (movesb2b3).

Coq < Lemma m o v e s _ t r a n s

Coq < : f o r a l l ( b1 b2 b3 : b o a r d ) ,

Coq < m o v e s b1 b2 - > m o v e s b2 b3 - > m o v e s b1 b3 . Coq < i n d u c t i o n 2.

A more complex proof will be to prove that there are no possible moves from the board startto the board with only white tokens (called wboard). So we have to prove:

Coq < Lemma n o t _ r e a c h a b l e : ~ m o v e s s t a r t w b o a r d . Coq < i n t r o .

1 s u b g o a l

H : m o v e s s t a r t w b o a r d

= = = = = = = = = = = = = = = = = = = = = = = = = = = = F a l s e

After an introduction, we end up proving⊥from the assumption(moves start wboard). If we try an induction on this proof, the first goal will be to prove⊥ without any assumption, this is hopeless. A solution is to find an appropriate invariant of the game and to derive a contradiction from the assumption that wboardsatisfies this invariant. The hint is to look at the number of white tokens at the 4 corners.

3.7 Advanced inductive definitions

The inductive definition mechanism ofCoqis quite general and allows to model more than just algebraic data-types.

For instance, it is possible to represent trees with infinite branching, like in this type of ordinal notations.

(28)

Coq < Inductive ord := z e r o : ord | s u c c : ord - > ord Coq < | lim : ( nat - > ord ) - > ord .

The constructor limtakes a function as argument, for each natural number, it gives a new object of typeordwhich is a subterm.

Another important inductive definition is the accessibility property. Given a binary relation R on a type A, an element x : A is accessible if there are no infinite chain (xi)i∈IN such that x0 = xand ∀i, R(xi+1, xi). Inductively, it is possible to define x to be accessible when all y such that R(x, y) are also accessible. This is captured in the following definition:

Coq < Print Acc .

Inductive Acc ( A : T y p e) ( R : A - > A - > P r o p) ( x : A ) : P r o p :=

A c c _ i n t r o : (f o r a l l y : A , R y x - > Acc R y ) - > Acc R x This inductive definition is the key for the definition of general fixpoints (see section 4.2)

Dependent types. It is also possible to introduce types indexed by other objects (also called dependent types) like in the type of vectors of sizen:

Coq < Inductive v e c t ( A :T y p e) : nat - > T y p e :=

Coq < v0 : v e c t 0

Coq < | v1 : f o r a l l n , A - > v e c t n - > v e c t ( S n ).

This definition looks like the definition of lists but with an extra argument which will correspond to the size of the vector. Dependent types can also be defined in a recursive way:

Coq < Fixpoint p r o d n A ( n : nat ) : T y p e :=

Coq < m a t c h n w i t h O = > A | S n = > A * p r o d n n end.

In that definition, the type (prodn 2) is convertible with the typeA∗(A∗A).

3.8 Needham-Schroeder Public Key protocol

The formalization of Needham-Schroeder Public Key protocol inCoqwas first experimented by D. Bolignano [11]. Inductive definitions are used to model the exchanges. We have three agentsA,B,I for Alice, Bob and the Intruder.

Coq < Inductive a g e n t : Set := A | B | I .

A nonce is a secret that is generated by one agent to be shared with another; in our formalization, nonces have two agents as parameters. The atomic messages are names of the agents, nonces, secret keys. A message can be encoded or combined with another.

Coq < Inductive m e s s a g e : Set :=

Coq < N a m e : a g e n t - > m e s s a g e

Coq < | N o n c e : a g e n t * a g e n t - > m e s s a g e Coq < | SK : a g e n t - > m e s s a g e

Coq < | Enc : m e s s a g e - > a g e n t - > m e s s a g e Coq < | P : m e s s a g e - > m e s s a g e - > m e s s a g e .

Références

Documents relatifs

ﺢﺼﻧ و ﻰﻠﺻ ﺪﻤﳏ ﺎﻧﺪﻴﺳ ﲔﳌﺎﻌﻟا رﻮﻧ و ﺔﲪﺮﻟا ﱯﻧ ﻰﻠﻋ ﺔﻣﻷا ا ﻢﻠﺳ و ﻪﻴﻠﻋ ﷲا ﺮﻈﺘﻨﻧ ﻦﳓ و ،ﺎﻨﻟ ةوﺪﻗ ﻞﻀﻓأ ﺖﻨﻛ ﻚﻧﻷ ﷲ ﺪﻤﳊ ﺔﻣﺎﻴﻘﻟا مﻮﻳ ﻚﺘﻋﺎﻔﺷ تﺎﻣﻮﻠﻌﳌﺎﺑ ﺎﻧدوز و ةﺪﻋﺎﺴﳌا

distribution of mH2A1.1 to control of gene expression in human breast cancer

The primary reasons for remodeling are: a change of the building's function, a need for additional space, to reduce building energy costs, to comply with current

Ainsi le tumulus d’Ahiga, où l’ancienne cou- tume paienne de l’offrande monétaire se mêle a la tradition protohistorique de l’incinération, pourrait bien

In order for a reflexive tactic based on a SAT solver to deal with the full propositional fragment of Coq’s logic, it needs to be able to take any arbi- trary formula in input

the Fer2 2 flies, despite the fact that Fer2 expression is restricted to several clusters of cells in the brain (Fig. Thus, loss of Fer2 expression leads to both cell-autonomous

• The ripple tactic makes use of all equational cached lemmas when performing rippling proof steps (see §3.6.1).. Rippling is able to productively use any rule that can

In an annotated inductive types, the universe where the inductive type is defined is no longer a simple sort, but what is called an arity, which is a type whose conclusion is a