11.07.2015 Views

A Tutorial on [Co-]Inductive Types in Coq - The Flint Project

A Tutorial on [Co-]Inductive Types in Coq - The Flint Project

A Tutorial on [Co-]Inductive Types in Coq - The Flint Project

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

C<strong>on</strong>tents1 About this document 42 Introduc<strong>in</strong>g <strong>Inductive</strong> <strong>Types</strong> 52.1 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.2 Vectors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.3 <strong>The</strong> c<strong>on</strong>tradictory propositi<strong>on</strong>. . . . . . . . . . . . . . . . . 82.4 <strong>The</strong> tautological propositi<strong>on</strong>. . . . . . . . . . . . . . . . . . 82.5 Relati<strong>on</strong>s as <strong>in</strong>ductive types. . . . . . . . . . . . . . . . . . 82.6 <strong>The</strong> propositi<strong>on</strong>al equality type. . . . . . . . . . . . . . . . 102.7 Logical c<strong>on</strong>nectives. . . . . . . . . . . . . . . . . . . . . . 122.8 <strong>The</strong> existential quantifier. . . . . . . . . . . . . . . . . . . . 132.9 Mutually Dependent Def<strong>in</strong>iti<strong>on</strong>s . . . . . . . . . . . . . . . 143 Case Analysis and Pattern-match<strong>in</strong>g 143.1 N<strong>on</strong>-dependent Case Analysis . . . . . . . . . . . . . . . . 143.1.1 Example: the predecessor functi<strong>on</strong>. . . . . . . . . . 153.2 Dependent Case Analysis . . . . . . . . . . . . . . . . . . . 163.2.1 Example: str<strong>on</strong>g specificati<strong>on</strong> of the predecessor functi<strong>on</strong>.. . . . . . . . . . . . . . . . . . . . . . . . . . 163.3 Some Examples of Case Analysis . . . . . . . . . . . . . . 183.3.1 <strong>The</strong> Empty Type . . . . . . . . . . . . . . . . . . . 183.3.2 <strong>The</strong> Equality Type . . . . . . . . . . . . . . . . . . 193.3.3 <strong>The</strong> Predicate n≤m . . . . . . . . . . . . . . . . . 213.3.4 Vectors . . . . . . . . . . . . . . . . . . . . . . . . 233.4 Case Analysis and Logical Paradoxes . . . . . . . . . . . . 233.4.1 <strong>The</strong> Positivity C<strong>on</strong>diti<strong>on</strong> . . . . . . . . . . . . . . . 243.4.2 Impredicative <strong>Inductive</strong> <strong>Types</strong> . . . . . . . . . . . . 273.4.3 Extracti<strong>on</strong> C<strong>on</strong>stra<strong>in</strong>ts . . . . . . . . . . . . . . . . 283.4.4 Str<strong>on</strong>g Case Analysis <strong>on</strong> Proofs . . . . . . . . . . . 293.4.5 Summary of C<strong>on</strong>stra<strong>in</strong>ts . . . . . . . . . . . . . . . 304 Some Proof Techniques Based <strong>on</strong> Case Analysis 304.1 Discrim<strong>in</strong>ati<strong>on</strong> of <strong>in</strong>troducti<strong>on</strong> rules . . . . . . . . . . . . . 304.2 Injectiveness of <strong>in</strong>troducti<strong>on</strong> rules . . . . . . . . . . . . . . 324.3 Inversi<strong>on</strong> Techniques . . . . . . . . . . . . . . . . . . . . . 334.3.1 Interactive mode . . . . . . . . . . . . . . . . . . . 354.3.2 Static mode . . . . . . . . . . . . . . . . . . . . . . 355 <strong>Inductive</strong> <strong>Types</strong> and Structural Inducti<strong>on</strong> 375.1 Proofs by Structural Inducti<strong>on</strong> . . . . . . . . . . . . . . . . 395.2 Us<strong>in</strong>g Elim<strong>in</strong>ati<strong>on</strong> <strong>Co</strong>mb<strong>in</strong>ators. . . . . . . . . . . . . . . . 415.3 Well-founded Recursi<strong>on</strong> . . . . . . . . . . . . . . . . . . . 446 A case study <strong>in</strong> dependent elim<strong>in</strong>ati<strong>on</strong> 49


7 <strong>Co</strong>-<strong>in</strong>ductive <strong>Types</strong> and N<strong>on</strong>-end<strong>in</strong>g C<strong>on</strong>structi<strong>on</strong>s 537.1 Extensi<strong>on</strong>al Properties . . . . . . . . . . . . . . . . . . . . 557.2 About <strong>in</strong>jecti<strong>on</strong>, discrim<strong>in</strong>ate, and <strong>in</strong>versi<strong>on</strong> . . . . . . . . . 573


1 About this documentThis document is an <strong>in</strong>troducti<strong>on</strong> to the def<strong>in</strong>iti<strong>on</strong> and use of <strong>in</strong>ductive andco-<strong>in</strong>ductive types <strong>in</strong> the <strong>Co</strong>q proof envir<strong>on</strong>ment. It was born from the noteswritten for the course about the versi<strong>on</strong> V5.10 of <strong>Co</strong>q, given by EduardoGimenez at the Ecole Normale Supérieure de Ly<strong>on</strong> <strong>in</strong> March 1996. Thisarticle is a revised and improved versi<strong>on</strong> of that notes for the versi<strong>on</strong> V8.0 ofthe system.We assume that the reader has some familiarity with the proofs-as-programsparadigm of Logic [5] and the generalities of the <strong>Co</strong>q system [11]. You wouldtake a greater advantage of this document if you first read the general tutorialabout <strong>Co</strong>q and <strong>Co</strong>q’s FAQ, both available <strong>on</strong> [6]. A text book [3], accompaniedwith a lot of examples and exercises [2], presents a detailed descripti<strong>on</strong>of the <strong>Co</strong>q system and its underly<strong>in</strong>g formalism: the Calculus of <strong>Inductive</strong>C<strong>on</strong>structi<strong>on</strong>. F<strong>in</strong>ally, the complete descripti<strong>on</strong> of <strong>Co</strong>q is given <strong>in</strong> the referencemanual [11]. Most of the tactics and commands we describe haveseveral opti<strong>on</strong>s, which we do not present exhaustively. If some script here<strong>in</strong>uses a n<strong>on</strong> described fetature, please refer to the Reference Manual.If you are familiar with other proof envir<strong>on</strong>ments based <strong>on</strong> type theoryand the LCF style —like PVS, LEGO, Isabelle, etc— then you will f<strong>in</strong>d notdifficulty to guess the unexpla<strong>in</strong>ed details.<strong>The</strong> better way to read this document is to start up the <strong>Co</strong>q system, typeby yourself the examples and exercises proposed, and observe the behaviorof the system. All the examples proposed <strong>in</strong> this tutorial can be downloadedfrom the same site as the present document.<strong>The</strong> tutorial is organised as follows. <strong>The</strong> next secti<strong>on</strong> describes how <strong>in</strong>ductivetypes are def<strong>in</strong>ed <strong>in</strong> <strong>Co</strong>q, and <strong>in</strong>troduces some useful <strong>on</strong>es, like naturalnumbers, the empty type, the propositi<strong>on</strong>al equality type, and the logicalc<strong>on</strong>nectives. Secti<strong>on</strong> 3 expla<strong>in</strong>s def<strong>in</strong>iti<strong>on</strong>s by pattern-match<strong>in</strong>g and theirc<strong>on</strong>necti<strong>on</strong> with the pr<strong>in</strong>ciple of case analysis. This pr<strong>in</strong>ciple is the mostbasic elim<strong>in</strong>ati<strong>on</strong> rule associated with <strong>in</strong>ductive or co-<strong>in</strong>ductive types, andfollows a general scheme that, we illustrate for some of the types <strong>in</strong>troduced<strong>in</strong> Secti<strong>on</strong> 2. Secti<strong>on</strong> 4 illustrates the pragmatics of this pr<strong>in</strong>ciple, show<strong>in</strong>gdifferent proof techniques based <strong>on</strong> it. Secti<strong>on</strong> 5 <strong>in</strong>troduces def<strong>in</strong>iti<strong>on</strong>s bystructural recursi<strong>on</strong> and proofs by <strong>in</strong>ducti<strong>on</strong>. Secti<strong>on</strong> 6 presents some elaboratetechniques about dependent case analysis. F<strong>in</strong>ally, Secti<strong>on</strong> 7 is a brief<strong>in</strong>troducti<strong>on</strong> to co-<strong>in</strong>ductive types –i.e., types c<strong>on</strong>ta<strong>in</strong><strong>in</strong>g <strong>in</strong>f<strong>in</strong>ite objects– andthe pr<strong>in</strong>ciple of co-<strong>in</strong>ducti<strong>on</strong>.Thanks to Bruno Barras, Yves Bertot, Hugo Herbel<strong>in</strong>, Jean-FrançoisM<strong>on</strong><strong>in</strong> and Michel Lévy for their help.Lexical c<strong>on</strong>venti<strong>on</strong>s<strong>The</strong> typewriter f<strong>on</strong>t is used to represent text <strong>in</strong>put by the user, while theitalic f<strong>on</strong>t is used to represent the text output by the system as answers.4


Moreover, the mathematical symbols ≤, ≠, ∃, ∀, →, → ∨, ∧, and ⇒stand for the character str<strong>in</strong>gs , , respectively. For <strong>in</strong>stance, the <strong>Co</strong>q statementforall A:Set,(exists x : A, forall (y:A), x y) -> 2 = 3is written as follows <strong>in</strong> this tutorial:∀ A:Set,(∃ x:A, ∀ y:A, x ≠ y) → 2 = 3When a fragment of <strong>Co</strong>q <strong>in</strong>put text appears <strong>in</strong> the middle of regular text,we often place this fragment between double quotes “. . . .” <strong>The</strong>se doublequotes do not bel<strong>on</strong>g to the <strong>Co</strong>q syntax.F<strong>in</strong>ally, that any str<strong>in</strong>g enclosed between (* and *) is a comment and isignored by the <strong>Co</strong>q system.2 Introduc<strong>in</strong>g <strong>Inductive</strong> <strong>Types</strong><strong>Inductive</strong> types are types closed with respect to their <strong>in</strong>troducti<strong>on</strong> rules. <strong>The</strong>serules expla<strong>in</strong> the most basic or can<strong>on</strong>ical ways of c<strong>on</strong>struct<strong>in</strong>g an element ofthat type. In this sense, they characterize the recursive type. Different rulesmust be c<strong>on</strong>sidered as <strong>in</strong>troduc<strong>in</strong>g different objects. In order to fix ideas, letus <strong>in</strong>troduce <strong>in</strong> <strong>Co</strong>q the most well-known example of a recursive type: thetype of natural numbers.<strong>Inductive</strong> nat : Set :=| O : nat| S : nat→nat.<strong>The</strong> def<strong>in</strong>iti<strong>on</strong> of a recursive type has two ma<strong>in</strong> parts. First, we establishwhat k<strong>in</strong>d of recursive type we will characterize (a set, <strong>in</strong> this case). Sec<strong>on</strong>d,we present the <strong>in</strong>troducti<strong>on</strong> rules that def<strong>in</strong>e the type (O and S), also called itsc<strong>on</strong>structors. To say that nat is closed under these <strong>in</strong>troducti<strong>on</strong> rules meansthat O and S determ<strong>in</strong>e all the elements of this type. In other words, if n:nat,then n must have been <strong>in</strong>troduced either by the rule O or by an applicati<strong>on</strong> ofthe rule S to a previously c<strong>on</strong>structed natural number. On the c<strong>on</strong>trary, thetype Set is an open type, s<strong>in</strong>ce we do not know a priori all the possible waysof <strong>in</strong>troduc<strong>in</strong>g an object of type Set.After enter<strong>in</strong>g this command, the c<strong>on</strong>stants nat, O and S are available <strong>in</strong>the current c<strong>on</strong>text. We can see their types us<strong>in</strong>g the command Check :Check nat.nat : SetCheck O.O : natCheck S.S : nat → nat5


Moreover, <strong>Co</strong>q adds to the c<strong>on</strong>text three c<strong>on</strong>stants named nat_<strong>in</strong>d, nat_recand nat_rect, which corresp<strong>on</strong>d to different pr<strong>in</strong>ciples of structural <strong>in</strong>ducti<strong>on</strong><strong>on</strong> natural numbers that <strong>Co</strong>q <strong>in</strong>fers automatically from the def<strong>in</strong>iti<strong>on</strong>.We will come back to them <strong>in</strong> Secti<strong>on</strong> 5.In fact, the type of natural numbers as well as several useful theoremsabout them are already def<strong>in</strong>ed <strong>in</strong> the basic library of <strong>Co</strong>q, so there is no needto <strong>in</strong>troduce them. <strong>The</strong>refore, let us throw away the former (re)def<strong>in</strong>iti<strong>on</strong> ofnat, us<strong>in</strong>g the command Reset.Reset nat.Pr<strong>in</strong>t nat.<strong>Inductive</strong> nat : Set := O : nat | S : nat → natFor S: Argument scope is [nat_scope]Notice that <strong>Co</strong>q’s <strong>in</strong>terpretati<strong>on</strong> scope for natural numbers (called nat_scope)allows us to read and write natural numbers <strong>in</strong> decimal form (see [11]). For<strong>in</strong>stance, the c<strong>on</strong>structor O can be read or written as the digit 0, and the term“ S (S (S O)) ” as 3.Check O.0 : nat.Check (S (S (S O))).3 : natLet us now take a look to some other recursive types c<strong>on</strong>ta<strong>in</strong>ed <strong>in</strong> thestandard library of <strong>Co</strong>q.2.1 ListsLists are def<strong>in</strong>ed <strong>in</strong> library List:Require Import List.Pr<strong>in</strong>t list.<strong>Inductive</strong> list (A : Set) : Set :=nil : list A | c<strong>on</strong>s : A → list A → list AFor nil: Argument A is implicitFor c<strong>on</strong>s: Argument A is implicitFor list: Argument scope is [type_scope]For nil: Argument scope is [type_scope]For c<strong>on</strong>s: Argument scopes are [type_scope _ _]In this def<strong>in</strong>iti<strong>on</strong>, A is a general parameter, global to both c<strong>on</strong>structors.This k<strong>in</strong>d of def<strong>in</strong>iti<strong>on</strong> allows us to build a whole family of <strong>in</strong>ductive types,<strong>in</strong>dexed over the sort Set. This can be observed if we c<strong>on</strong>sider the typeof identifiers list, c<strong>on</strong>s and nil. Notice the notati<strong>on</strong> (A := ...) which6


must be used when <strong>Co</strong>q’s type <strong>in</strong>ference algorithm cannot <strong>in</strong>fer the implicitparameter A.Check list.list: Set → SetCheck (nil (A:=nat)).nil: list natCheck (nil (A:= nat → nat)).nil: list (nat → nat)Check (fun A: Set ⇒ (c<strong>on</strong>s (A:=A))).fun A : Set ⇒ c<strong>on</strong>s (A:=A): ∀ A : Set, A → list A → list ACheck (c<strong>on</strong>s 3 (c<strong>on</strong>s 2 nil)).3 :: 2 :: nil: list nat2.2 Vectors.Like list, vector is a polymorphic type: if A is a set, and n a naturalnumber, “ vector A n ” is the type of vectors of elements of A and size n.Require ImportBvector.Pr<strong>in</strong>t vector.<strong>Inductive</strong> vector (A : Set) : nat → Set :=Vnil : vector A 0| Vc<strong>on</strong>s : A → ∀ n : nat, vector A n → vector A (S n)For vector: Argument scopes are [type_scope nat_scope]For Vnil: Argument scope is [type_scope]For Vc<strong>on</strong>s: Argument scopes are [type_scope _ nat_scope _]Remark the difference between the two parameters A and n: <strong>The</strong> first <strong>on</strong>eis a general parameter, global to all the <strong>in</strong>troducti<strong>on</strong> rules,while the sec<strong>on</strong>d<strong>on</strong>e is an <strong>in</strong>dex, which is <strong>in</strong>stantiated differently <strong>in</strong> the <strong>in</strong>troducti<strong>on</strong> rules.Such types parameterized by regular values are called dependent types.Check (Vnil nat).Vnil nat7


: vector nat 0Check (fun (A:Set)(a:A)⇒ Vc<strong>on</strong>s _ a _ (Vnil _)).fun (A : Set) (a : A) ⇒ Vc<strong>on</strong>s A a 0 (Vnil A): ∀ A : Set, A → vector A 1Check (Vc<strong>on</strong>s _ 5 _ (Vc<strong>on</strong>s _ 3 _ (Vnil _))).Vc<strong>on</strong>s nat 5 1 (Vc<strong>on</strong>s nat 3 0 (Vnil nat)): vector nat 22.3 <strong>The</strong> c<strong>on</strong>tradictory propositi<strong>on</strong>.Another example of an <strong>in</strong>ductive type is the c<strong>on</strong>tradictory propositi<strong>on</strong>. Thistype <strong>in</strong>habits the universe of propositi<strong>on</strong>s, and has no element at all.Pr<strong>in</strong>t False.<strong>Inductive</strong> False : Prop :=Notice that no c<strong>on</strong>structor is given <strong>in</strong> this def<strong>in</strong>iti<strong>on</strong>.2.4 <strong>The</strong> tautological propositi<strong>on</strong>.Similarly, the tautological propositi<strong>on</strong> True is def<strong>in</strong>ed as an <strong>in</strong>ductive typewith <strong>on</strong>ly <strong>on</strong>e element I:Pr<strong>in</strong>t True.<strong>Inductive</strong> True : Prop := I : True2.5 Relati<strong>on</strong>s as <strong>in</strong>ductive types.Some relati<strong>on</strong>s can be also <strong>in</strong>troduced <strong>in</strong> a smart way as an <strong>in</strong>ductive familyof propositi<strong>on</strong>s. Let us take as example the order n ≤ m <strong>on</strong> natural numbers,called le <strong>in</strong> <strong>Co</strong>q. This relati<strong>on</strong> is <strong>in</strong>troduced through the follow<strong>in</strong>g def<strong>in</strong>iti<strong>on</strong>,quoted from the standard library 2 :Pr<strong>in</strong>t le.<strong>Inductive</strong> le (n:nat) : nat→Prop :=| le_n: n ≤ n| le_S: ∀ m, n ≤ m → n ≤ S m.Notice that <strong>in</strong> this def<strong>in</strong>iti<strong>on</strong> n is a general parameter, while the sec<strong>on</strong>dargument of le is an <strong>in</strong>dex (see secti<strong>on</strong> 2.2). This def<strong>in</strong>iti<strong>on</strong> <strong>in</strong>troduces the2 In the <strong>in</strong>terpretati<strong>on</strong> scope for Peano arithmetic: nat_scope, “ n


<strong>in</strong>ary relati<strong>on</strong> n≤m as the family of unary predicates “to be greater or equalthan a given n”, parameterized by n.<strong>The</strong> <strong>in</strong>troducti<strong>on</strong> rules of this type can be seen as a sort of Prolog rulesfor prov<strong>in</strong>g that a given <strong>in</strong>teger n is less or equal than another <strong>on</strong>e. In fact,an object of type n≤m is noth<strong>in</strong>g but a proof built up us<strong>in</strong>g the c<strong>on</strong>structorsle_n and le_S of this type. As an example, let us c<strong>on</strong>struct a proof that zerois less or equal than three us<strong>in</strong>g <strong>Co</strong>q’s <strong>in</strong>teractive proof mode. Such an objectcan be obta<strong>in</strong>ed apply<strong>in</strong>g three times the sec<strong>on</strong>d <strong>in</strong>troducti<strong>on</strong> rule of le, toa proof that zero is less or equal than itself, which is provided by the firstc<strong>on</strong>structor of le:<strong>The</strong>orem zero_leq_three: 0 ≤ 3.Proof.1 subgoal============================0 ≤ 3Proof.c<strong>on</strong>structor 2.1 subgoal============================0 ≤ 2c<strong>on</strong>structor 2.1 subgoal============================0 ≤ 1c<strong>on</strong>structor 21 subgoal============================0 ≤ 0c<strong>on</strong>structor 1.Proof completedQed.When the current goal is an <strong>in</strong>ductive type, the tactic “ c<strong>on</strong>structor i ”applies the i-th c<strong>on</strong>structor <strong>in</strong> the def<strong>in</strong>iti<strong>on</strong> of the type. We can take a lookat the proof c<strong>on</strong>structed us<strong>in</strong>g the command Pr<strong>in</strong>t:Pr<strong>in</strong>t Pr<strong>in</strong>t zero_leq_three.zero_leq_three =9


zero_leq_three = le_S 0 2 (le_S 0 1 (le_S 0 0 (le_n 0))): 0 ≤ 3When the parameter i is not supplied, the tactic c<strong>on</strong>structor tries toapply “ c<strong>on</strong>structor 1 ”, “ c<strong>on</strong>structor 2 ”,. . . , “ c<strong>on</strong>structor n ”where n is the number of c<strong>on</strong>structors of the <strong>in</strong>ductive type (2 <strong>in</strong> our example)of the c<strong>on</strong>clusi<strong>on</strong> of the goal. Our little proof can thus be obta<strong>in</strong>ed iterat<strong>in</strong>gthe tactic c<strong>on</strong>structor until it fails:Lemma zero_leq_three': 0 ≤ 3.repeat c<strong>on</strong>structor.Qed.Notice that the strict order <strong>on</strong> nat, called lt is not <strong>in</strong>ductively def<strong>in</strong>ed:Pr<strong>in</strong>t lt.lt = fun n m : nat ⇒ S n ≤ m: nat → nat → PropLemma zero_lt_three : 0 < 3.Proof.unfold lt.====================1 ≤ 3repeat c<strong>on</strong>structor.Qed.2.6 <strong>The</strong> propositi<strong>on</strong>al equality type.In <strong>Co</strong>q, the propositi<strong>on</strong>al equality between two <strong>in</strong>habitants a and b of thesame type A , noted a = b, is <strong>in</strong>troduced as a family of recursive predicates“ to be equal to a ”, parameterised by both a and its type A. This familyof types has <strong>on</strong>ly <strong>on</strong>e <strong>in</strong>troducti<strong>on</strong> rule, which corresp<strong>on</strong>ds to reflexivity.Notice that the syntax “a = b ” is an abbreviati<strong>on</strong> for “eq a b ”, and thatthe parameter A is implicit, as it can be <strong>in</strong>fered from a.Pr<strong>in</strong>t eq.<strong>Inductive</strong> eq (A : Type) (x : A) : A → Prop :=refl_equal : x = xFor eq: Argument A is implicitFor refl_equal: Argument A is implicitFor eq: Argument scopes are [type_scope _ _]For refl_equal: Argument scopes are [type_scope _]10


Notice also that the first parameter A of eq has type Type. <strong>The</strong> typesystem of <strong>Co</strong>q allows us to c<strong>on</strong>sider equality between various k<strong>in</strong>d of terms:elements of a set, proofs, propositi<strong>on</strong>s, types, and so <strong>on</strong>. Look at [11, 3]to get more details <strong>on</strong> <strong>Co</strong>q’s type system, as well as implicit arguments andargument scopes.Lemma eq_3_3 : 2 + 1 = 3.Proof.reflexivity.Qed.Lemma eq_proof_proof : refl_equal (2*6) = refl_equal (3*4).Proof.reflexivity.Qed.Pr<strong>in</strong>t eq_proof_proof.eq_proof_proof =refl_equal (refl_equal (3 * 4)): refl_equal (2 * 6) = refl_equal (3 * 4)Lemma eq_lt_le : ( 2 < 4) = (3 ≤ 4).Proof.reflexivity.Qed.Lemma eq_nat_nat : nat = nat.Proof.reflexivity.Qed.Lemma eq_Set_Set : Set = Set.Proof.reflexivity.Qed.Lemma eq_Type_Type : Type = Type.Proof.reflexivity.Qed.11


2.7 Logical c<strong>on</strong>nectives.<strong>The</strong> c<strong>on</strong>juncti<strong>on</strong> and disjuncti<strong>on</strong> of two propositi<strong>on</strong>s are also examples ofrecursive types:<strong>Inductive</strong> or (A B : Prop) : Prop :=or_<strong>in</strong>trol : A → A ∨ B | or_<strong>in</strong>tror : B → A ∨ B<strong>Inductive</strong> and (A B : Prop) : Prop :=c<strong>on</strong>j : A → B → A ∧ B<strong>The</strong> propositi<strong>on</strong>s A and B are general parameters of these c<strong>on</strong>nectives.Choos<strong>in</strong>g different universes for A and B and for the <strong>in</strong>ductive type itselfgives rise to different type c<strong>on</strong>structors. For example, the type sumbool is adisjuncti<strong>on</strong> but with computati<strong>on</strong>al c<strong>on</strong>tents.<strong>Inductive</strong> sumbool (A B : Prop) : Set :=left : A → {A} + {B} | right : B → {A} + {B}This type –noted {A}+{B} <strong>in</strong> <strong>Co</strong>q– can be used <strong>in</strong> <strong>Co</strong>q programs as asort of boolean type, to check whether it is A or B that is true. <strong>The</strong> values“ left p ” and “ right q ” replace the boolean values true and false, respectively.<strong>The</strong> advantage of this type over bool is that it makes available theproofs p of A or q of B, that could be necessary to c<strong>on</strong>struct a verificati<strong>on</strong>proof about the program. For <strong>in</strong>stance, let us c<strong>on</strong>sider the certified programle_lt_dec of the Standard Library.Require Import <strong>Co</strong>mpare_dec.Check le_lt_dec.le_lt_dec: ∀ n m : nat, {n ≤ m} + {m < n}We use le_lt_dec to build a functi<strong>on</strong> for comput<strong>in</strong>g the max of tw<strong>on</strong>atural numbers:Def<strong>in</strong>iti<strong>on</strong> max (n p :nat) := match le_lt_dec n p with| left _ ⇒ p| right _ ⇒ nend.In the follow<strong>in</strong>g proof, the case analysis <strong>on</strong> the term “ le_lt_dec n p ”gives us an access to proofs of n ≤ p <strong>in</strong> the first case, p < n <strong>in</strong> the other.<strong>The</strong>orem le_max : ∀ n p, n ≤ p → max n p = p.Proof.12


<strong>in</strong>tros n p ; unfold max ; case (le_lt_dec n p); simpl.2 subgoalsn : natp : nat============================n ≤ p → n ≤ p → p = psubgoal 2 is:p < n → n ≤ p → n = ptrivial.<strong>in</strong>tros; absurd (p < p); eauto with arith.Qed.Once the program verified, the proofs are erased by the extracti<strong>on</strong> procedure:Extracti<strong>on</strong> max.(** val max : nat → nat → nat **)let max n p =match le_lt_dec n p with| Left → p| Right → nAnother example of use of sumbool is given <strong>in</strong> Secti<strong>on</strong> 5.3.2.8 <strong>The</strong> existential quantifier.<strong>The</strong> existential quantifier is yet another example of a logical c<strong>on</strong>nective <strong>in</strong>troducedas an <strong>in</strong>ductive type.<strong>Inductive</strong> ex (A : Type) (P : A → Prop) : Prop :=ex_<strong>in</strong>tro : ∀ x : A, P x → ex PNotice that <strong>Co</strong>q uses the abreviati<strong>on</strong> “ ∃ x:A, B ” for“ ex (fun x:A ⇒ B) ”.<strong>The</strong> former quantifier <strong>in</strong>habits the universe of propositi<strong>on</strong>s. As for c<strong>on</strong>juncti<strong>on</strong>and disjuncti<strong>on</strong> c<strong>on</strong>nectives, there is also another versi<strong>on</strong> of existentialquantificati<strong>on</strong> <strong>in</strong>habit<strong>in</strong>g the universe Set, which is noted sig P . <strong>The</strong> syntax“ {x:A | B} ” is an abreviati<strong>on</strong> for “ sig (fun x:A ⇒ B) ”.13


3.1.1 Example: the predecessor functi<strong>on</strong>.An example of a def<strong>in</strong>iti<strong>on</strong> by case analysis is the functi<strong>on</strong> which computesthe predecessor of any given natural number:Def<strong>in</strong>iti<strong>on</strong> pred (n:nat) := match n with| O ⇒ O| S m ⇒ mend.Eval simpl <strong>in</strong> pred 56.= 55: natEval simpl <strong>in</strong> pred 0.= 0: natEval simpl <strong>in</strong> fun p ⇒ pred (S p).= fun p : nat ⇒ p: nat → natAs <strong>in</strong> functi<strong>on</strong>al programm<strong>in</strong>g, tuples and wild-cards can be used <strong>in</strong> patterns. Such def<strong>in</strong>iti<strong>on</strong>s are automatically compiled by <strong>Co</strong>q <strong>in</strong>to an expressi<strong>on</strong>which may c<strong>on</strong>ta<strong>in</strong> several nested case expressi<strong>on</strong>s. For example, the exclusiveor <strong>on</strong> booleans can be def<strong>in</strong>ed as follows:Def<strong>in</strong>iti<strong>on</strong> xorb (b1 b2:bool) :=match b1, b2 with| false, true ⇒ true| true, false ⇒ true| _ , _ ⇒ falseend.This k<strong>in</strong>d of def<strong>in</strong>iti<strong>on</strong> is compiled <strong>in</strong> <strong>Co</strong>q as follows 3 :Pr<strong>in</strong>t xorb.xorb =fun b1 b2 : bool ⇒if b1 then if b2 then false else trueelse if b2 then true else false: bool → bool → bool3 <strong>Co</strong>q uses the c<strong>on</strong>diti<strong>on</strong>al “ if b then a else b ” as an abreviati<strong>on</strong> to“ match b with true ⇒ a | false ⇒ b end ”.15


3.2 Dependent Case AnalysisA more general typ<strong>in</strong>g rule for case expressi<strong>on</strong>s is obta<strong>in</strong>ed c<strong>on</strong>sider<strong>in</strong>g thatnot <strong>on</strong>ly the object def<strong>in</strong>ed may depend <strong>on</strong> n, but also its type. For <strong>in</strong>stance,let us c<strong>on</strong>sider some functi<strong>on</strong> Q : nat→Set, and n : nat. In order to build aterm of type Q n, we can associate to the c<strong>on</strong>structor O some term t O : Q Oand to the pattern “ S p ” some term t S : Q (S p). Notice that the terms t Oand t S do not have the same type.<strong>The</strong> syntax of the dependent case analysis and its associated typ<strong>in</strong>g rulemake precise how the result<strong>in</strong>g type depends <strong>on</strong> the argument of the patternmatch<strong>in</strong>g, and which c<strong>on</strong>stra<strong>in</strong>t holds <strong>on</strong> the branches of the pattern match<strong>in</strong>g:Q : nat→Set t O : Q O p : nat ⊢ t p : Q (S p) n : natmatch n as n 0 return Q n 0 with | O ⇒t O | S p ⇒t S end : Q n<strong>The</strong> <strong>in</strong>terest of this rule of dependent pattern-match<strong>in</strong>g is that it can bealso read as the follow<strong>in</strong>g logical pr<strong>in</strong>ciple (replac<strong>in</strong>g Set by Prop <strong>in</strong> thetype of Q): <strong>in</strong> order to prove that a property Q holds for all n, it is sufficientto prove that Q holds for O and that for all p : nat, Q holds for (S p). <strong>The</strong>former, n<strong>on</strong>-dependent versi<strong>on</strong> of case analysis can be obta<strong>in</strong>ed from thislatter rule just tak<strong>in</strong>g Q as a c<strong>on</strong>stant functi<strong>on</strong> <strong>on</strong> n.Notice that destructur<strong>in</strong>g n <strong>in</strong>to O or “ S p ” doesn’t make appear <strong>in</strong> thegoal the equalities “ n = O ” and “ n = S p ”. <strong>The</strong>y are “<strong>in</strong>ternalized” <strong>in</strong> therules above (see secti<strong>on</strong> 4.3.)3.2.1 Example: str<strong>on</strong>g specificati<strong>on</strong> of the predecessor functi<strong>on</strong>.In Secti<strong>on</strong> 3.1.1, the predecessor functi<strong>on</strong> was def<strong>in</strong>ed directly as a functi<strong>on</strong>from nat to nat. It rema<strong>in</strong>s to prove that this functi<strong>on</strong> has some desiredproperties. Another way to proceed is to, first <strong>in</strong>troduce a specificati<strong>on</strong> ofwhat is the predecessor of a natural number, under the form of a <strong>Co</strong>q type,then build an <strong>in</strong>habitant of this type: <strong>in</strong> other words, a realizati<strong>on</strong> of thisspecificati<strong>on</strong>. This way, the correctness of this realizati<strong>on</strong> is ensured by <strong>Co</strong>q’stype system.A reas<strong>on</strong>able specificati<strong>on</strong> for pred is to say that for all n there existsanother m such that either m = n = 0, or (S m) is equal to n. <strong>The</strong> functi<strong>on</strong>pred should be just the way to compute such an m.Def<strong>in</strong>iti<strong>on</strong> pred_spec (n:nat) :={m:nat | n=0∧ m=0 ∨ n = S m}.Def<strong>in</strong>iti<strong>on</strong> predecessor : ∀ n:nat, pred_spec n.<strong>in</strong>tro n; case n.16


n : nat============================pred_spec 0unfold pred_spec;exists 0;auto.=========================================∀ n0 : nat, pred_spec (S n0)unfold pred_spec; <strong>in</strong>tro n0; exists n0; auto.Def<strong>in</strong>ed.If we pr<strong>in</strong>t the term built by <strong>Co</strong>q, we can observe its dependent patternmatch<strong>in</strong>gstructure:predecessor = fun n : nat ⇒match n as n0 return (pred_spec n0) with| O ⇒exist (fun m : nat ⇒ 0 = 0 ∧ m = 0 ∨ 0 = S m) 0(or_<strong>in</strong>trol (0 = 1) (c<strong>on</strong>j (refl_equal 0) (refl_equal 0)))| S n0 ⇒exist (fun m : nat ⇒ S n0 = 0 ∧ m = 0 ∨ S n0 = S m) n0(or_<strong>in</strong>tror (S n0 = 0 ∧ n0 = 0) (refl_equal (S n0)))end : ∀ n : nat, pred_spec nNotice that there are many variants to the pattern “ <strong>in</strong>tros ...; case... ”. Look at the reference manual and/or the book: tactics destruct,“ <strong>in</strong>tro pattern ”, etc.<strong>The</strong> command Extracti<strong>on</strong> can be used to see the computati<strong>on</strong>al c<strong>on</strong>tentsassociated to the certified functi<strong>on</strong> predecessor:Extracti<strong>on</strong> predecessor.(** val predecessor : nat → pred_spec **)let predecessor = functi<strong>on</strong>| O → O| S n0 → n0Exercise 3.1 Prove the follow<strong>in</strong>g theorem:<strong>The</strong>orem nat_expand : ∀ n:nat,n = match n with| 0 ⇒ 0| S p ⇒ S pend.17


3.3 Some Examples of Case Analysis<strong>The</strong> reader will f<strong>in</strong>d <strong>in</strong> the Reference manual all details about typ<strong>in</strong>g caseanalysis (chapter 4: Calculus of <strong>Inductive</strong> C<strong>on</strong>structi<strong>on</strong>s, and chapter 15:Extended Pattern-Match<strong>in</strong>g).<strong>The</strong> follow<strong>in</strong>g commented examples will show the different situati<strong>on</strong>s toc<strong>on</strong>sider.3.3.1 <strong>The</strong> Empty TypeIn a def<strong>in</strong>iti<strong>on</strong> by case analysis, there is <strong>on</strong>e branch for each <strong>in</strong>troducti<strong>on</strong> ruleof the type. Hence, <strong>in</strong> a def<strong>in</strong>iti<strong>on</strong> by case analysis <strong>on</strong> p : False there areno cases to be c<strong>on</strong>sidered. In other words, the rule of (n<strong>on</strong>-dependent) caseanalysis for the type False is (for s <strong>in</strong> Prop, Set or Type):Q : s p : Falsematch p return Q with end : QAs a corollary, if we could c<strong>on</strong>struct an object <strong>in</strong> False, then it couldbe possible to def<strong>in</strong>e an object <strong>in</strong> any type. <strong>The</strong> tactic c<strong>on</strong>tradicti<strong>on</strong> corresp<strong>on</strong>dsto the applicati<strong>on</strong> of the elim<strong>in</strong>ati<strong>on</strong> rule above. It searches <strong>in</strong> thec<strong>on</strong>text for an absurd hypothesis (this is, a hypothesis whose type is False)and then proves the goal by a case analysis of it.<strong>The</strong>orem fromFalse : False → 0=1.<strong>in</strong>tro H.c<strong>on</strong>tradicti<strong>on</strong>.Qed.In <strong>Co</strong>q the negati<strong>on</strong> is def<strong>in</strong>ed as follows :Def<strong>in</strong>iti<strong>on</strong> not (P:Prop) := P → False<strong>The</strong> propositi<strong>on</strong> “ not A ” is also written “ ∼ A ”.If A and B are propositi<strong>on</strong>s, a is a proof of A and H is a proof of ∼A, the term “ match H a return B with end ” is a proof term of B.Thus, if your goal is B and you have some hypothesis H :∼ A, the tactic“ case H ” generates a new subgoal with statement A, as shown by thefollow<strong>in</strong>g example 4 .Fact Nosense : 0 ≠ 0 → 2 = 3.Proof.<strong>in</strong>tro H; case H.===========================0 = 04 Notice that a≠b is just an abreviati<strong>on</strong> for “ ∼a= b ”18


eflexivity.Qed.<strong>The</strong> tactic “ absurd A ” (where A is any propositi<strong>on</strong>), is based <strong>on</strong> thesame pr<strong>in</strong>ciple, but generates two subgoals: A and ∼ A, for solv<strong>in</strong>g B.3.3.2 <strong>The</strong> Equality TypeLet A : Type, a, b of type A, and π a proof of a = b. N<strong>on</strong> dependent caseanalysis of π allows us to associate to any proof of “ Q a ” a proof of “ Q b ”,where Q : A→s (where s ∈ {Prop, Set, Type}). <strong>The</strong> follow<strong>in</strong>g term is aproof of “ Q a→Q b ”.fun H : Q a ⇒match π <strong>in</strong> (_ = y) return Q y withrefl_equal ⇒ HendNotice the header of the match c<strong>on</strong>struct. It expresses how the result<strong>in</strong>g type“ Q y ” depends <strong>on</strong> the type of p. Notice also that <strong>in</strong> the pattern <strong>in</strong>troducedby the keyword <strong>in</strong>, the parameter a <strong>in</strong> the type “ a = y ” must be implicit,and replaced by a wildcard ’_’.<strong>The</strong>refore, do<strong>in</strong>g case analysis <strong>on</strong> a proof of the equality a = b amountsto replace all the occurrences of the term b with the term a <strong>in</strong> the goal to beproven. Let us illustrate this through an example: the transitivity property ofthis equality.<strong>The</strong>orem trans : ∀ n m p:nat, n=m → m=p → n=p.Proof.<strong>in</strong>tros n m p eqnm.n : natm : natp : nateqnm : n = m============================m = p → n = pcase eqnm.n : natm : natp : nateqnm : n = m============================n = p → n = p19


trivial.Qed.Exercise 3.2 Prove the symmetry property of equality.Instead of us<strong>in</strong>g case, we can use the tactic rewrite . If H is a proof ofa = b, then “ rewrite H ” performs a case analysis <strong>on</strong> a proof of b = a, obta<strong>in</strong>edby apply<strong>in</strong>g a symmetry theorem to H. This applicati<strong>on</strong> of symmetryallows us to rewrite the equality from left to right, which looks more natural.An opti<strong>on</strong>al parameter (either → or ←) can be used to precise <strong>in</strong> which sensethe equality must be rewritten. By default, “ rewrite H ” corresp<strong>on</strong>ds to“ rewrite → H ”Lemma Rw : ∀ x y: nat, y = y * x → y * x * x = y.<strong>in</strong>tros x y e; do 2 rewrite


Proof.<strong>in</strong>tro n;rewrite


match H <strong>in</strong> (_ ≤ q) return (Q q) with| le_n ⇒ H0| le_S m Hm ⇒ HS m Hmendis a proof term of “ Q p ”.<strong>The</strong> two patterns of this match c<strong>on</strong>struct describe all possibles forms ofproofs of “ n ≤ m ” (notice aga<strong>in</strong> that the general parameter n is implicit <strong>in</strong>the “ <strong>in</strong> ... ” clause and is absent from the match patterns.Notice that the choice of <strong>in</strong>troduc<strong>in</strong>g some of the arguments of the predicateas be<strong>in</strong>g general parameters <strong>in</strong> its def<strong>in</strong>iti<strong>on</strong> has c<strong>on</strong>sequences <strong>on</strong> therule of case analysis that is derived. In particular, the type Q of the objectdef<strong>in</strong>ed by the case expressi<strong>on</strong> <strong>on</strong>ly depends <strong>on</strong> the <strong>in</strong>dexes of the predicate,and not <strong>on</strong> the general parameters. In the def<strong>in</strong>iti<strong>on</strong> of the predicate ≤, thefirst argument of this relati<strong>on</strong> is a general parameter of the def<strong>in</strong>iti<strong>on</strong>. Hence,the predicate Q to be proven <strong>on</strong>ly depends <strong>on</strong> the sec<strong>on</strong>d argument of therelati<strong>on</strong>. In other words, the <strong>in</strong>teger n is also a general parameter of the ruleof case analysis.An example of an applicati<strong>on</strong> of this rule is the follow<strong>in</strong>g theorem, show<strong>in</strong>gthat any <strong>in</strong>teger greater or equal than 1 is the successor of another naturalnumber:Lemma predecessor_of_positive :∀ n, 1 ≤ n → ∃ p:nat, n = S p.Proof.<strong>in</strong>tros n H;case H.n : natH : 1 ≤ n============================∃ p : nat, 1 = S pexists 0; trivial.n : natH : 1 ≤ n============================∀ m : nat, 0 ≤ m → ∃ p : nat, S m = S p<strong>in</strong>tros m _ .exists m.trivial.Qed.22


3.3.4 Vectors<strong>The</strong> vector polymorphic and dependent family of types will give an idea ofthe most general scheme of pattern-match<strong>in</strong>g.For <strong>in</strong>stance, let us def<strong>in</strong>e a functi<strong>on</strong> for comput<strong>in</strong>g the tail of any vector.Notice that we shall build a total functi<strong>on</strong>, by c<strong>on</strong>sider<strong>in</strong>g that the tail of anempty vector is this vector itself. In that sense, it will be slightly differentfrom the Vtail functi<strong>on</strong> of the Standard Library, which is def<strong>in</strong>ed <strong>on</strong>ly forvectors of type “ vector A (S n) ”.<strong>The</strong> header of the functi<strong>on</strong> we want to build is the follow<strong>in</strong>g:Def<strong>in</strong>iti<strong>on</strong> Vtail_total(A : Set) (n : nat) (v : vector A n) : vector A (pred n):=S<strong>in</strong>ce the branches will not have the same type (depend<strong>in</strong>g <strong>on</strong> the parametern), the body of this functi<strong>on</strong> is a dependent pattern match<strong>in</strong>g <strong>on</strong> v. Sowe will have :match v <strong>in</strong> (vector _ n0) return (vector A (pred n0)) with<strong>The</strong> first branch deals with the c<strong>on</strong>structor Vnil and must return a value<strong>in</strong> “ vector A (pred 0) ”, c<strong>on</strong>vertible to “ vector A 0 ”. So, we propose:| Vnil ⇒ Vnil A<strong>The</strong> sec<strong>on</strong>d branch c<strong>on</strong>siders a vector <strong>in</strong> “ vector A (S n0) ” of theform “ Vc<strong>on</strong>s A n0 v0 ”, with “ v0:vector A n0 ”, and must return avalue <strong>in</strong> “ vector A (pred (S n0)) ”, c<strong>on</strong>vertible to “ v0:vector A n0 ”.This sec<strong>on</strong>d branch is thus :| Vc<strong>on</strong>s _ n0 v0 ⇒ v0Here is the full def<strong>in</strong>iti<strong>on</strong>:Def<strong>in</strong>iti<strong>on</strong> Vtail_total(A : Set) (n : nat) (v : vector A n) : vector A (pred n):=match v <strong>in</strong> (vector _ n0) return (vector A (pred n0)) with| Vnil ⇒ Vnil A| Vc<strong>on</strong>s _ n0 v0 ⇒ v0end.3.4 Case Analysis and Logical ParadoxesIn the previous secti<strong>on</strong> we have illustrated the general scheme for generat<strong>in</strong>gthe rule of case analysis associated to some recursive type from the def<strong>in</strong>iti<strong>on</strong>of the type. However, if the logical soundness is to be preserved, certa<strong>in</strong>restricti<strong>on</strong>s to this schema are necessary. This secti<strong>on</strong> provides a brief explanati<strong>on</strong>of these restricti<strong>on</strong>s.23


3.4.1 <strong>The</strong> Positivity C<strong>on</strong>diti<strong>on</strong>In order to make sense of recursive types as types closed under their <strong>in</strong>troducti<strong>on</strong>rules, a c<strong>on</strong>stra<strong>in</strong>t has to be imposed <strong>on</strong> the possible forms of such rules.This c<strong>on</strong>stra<strong>in</strong>t, known as the positivity c<strong>on</strong>diti<strong>on</strong>, is necessary to prevent theuser from naively <strong>in</strong>troduc<strong>in</strong>g some recursive types which would open thedoor to logical paradoxes. An example of such a dangerous type is the “<strong>in</strong>ductivetype” Lambda, whose <strong>on</strong>ly c<strong>on</strong>structor is lambda :(Lambda→False)→Lambda.Follow<strong>in</strong>g the pattern given <strong>in</strong> Secti<strong>on</strong> 3.3, the rule of (n<strong>on</strong> dependent) caseanalysis for Lambda would be the follow<strong>in</strong>g:Q : Prop p : Lambda h : Lambda→False ⊢ t : Qmatch p return Q with lambda h ⇒ t end : QIn order to avoid paradoxes, it is impossible to c<strong>on</strong>struct the type Lambda<strong>in</strong> <strong>Co</strong>q:<strong>Inductive</strong> Lambda : Set :=lambda : (Lambda → False) → Lambda.Error: N<strong>on</strong> strictly positive occurrence of "Lambda" <strong>in</strong>"(Lambda → False) → Lambda"In order to expla<strong>in</strong> this danger, we will declare some c<strong>on</strong>stants for simulat<strong>in</strong>gthe c<strong>on</strong>structi<strong>on</strong> of Lambda as an <strong>in</strong>ductive type.Let us open some secti<strong>on</strong>, and declare two variables, the first <strong>on</strong>e forLambda, the other for the c<strong>on</strong>structor lambda.Secti<strong>on</strong> Paradox.Variable Lambda : Set.Variable lambda : (Lambda → False) →Lambda.S<strong>in</strong>ce Lambda is not a truely <strong>in</strong>ductive type, we can’t use the matchc<strong>on</strong>struct. Nevertheless, we can simulate it by a variable matchL such that“ matchL l Q (fun h : Lambda → False ⇒ t) ” should be understoodas “ match l return Q with | lambda h ⇒ t) ”Variable matchL : Lambda →∀ Q:Prop, ((Lambda →False) → Q) →Q.From these c<strong>on</strong>stants, it is possible to def<strong>in</strong>e applicati<strong>on</strong> by case analysis.<strong>The</strong>n, through auto-applicati<strong>on</strong>, the well-known loop<strong>in</strong>g term (λx.(x x) λx.(x x))provides a proof of falsehood.Def<strong>in</strong>iti<strong>on</strong> applicati<strong>on</strong> (f x: Lambda) :False :=matchL f False (fun h ⇒ h x).24


Def<strong>in</strong>iti<strong>on</strong> Delta : Lambda :=lambda (fun x : Lambda ⇒ applicati<strong>on</strong> x x).Def<strong>in</strong>iti<strong>on</strong> loop : False := applicati<strong>on</strong> Delta Delta.<strong>The</strong>orem two_is_three : 2 = 3.Proof.elim loop.Qed.End Paradox.This example can be seen as a formulati<strong>on</strong> of Russell’s paradox <strong>in</strong> type theoryassociat<strong>in</strong>g (applicati<strong>on</strong> x x) to the formula x ∉ x, and Delta to the set{x | x ∉ x}. If matchL would satisfy the reducti<strong>on</strong> rule associated to caseanalysis, that is,matchL (lambda f) Q h =⇒ h fthen the term loop would compute <strong>in</strong>to itself. This is not actually surpris<strong>in</strong>g,s<strong>in</strong>ce the proof of the logical soundness of <strong>Co</strong>q str<strong>on</strong>gly lays <strong>on</strong> the propertythat any well-typed term must term<strong>in</strong>ate. Hence, n<strong>on</strong>-term<strong>in</strong>ati<strong>on</strong> is usuallya syn<strong>on</strong>ymous of <strong>in</strong>c<strong>on</strong>sistency.3.4.1.1 In this case, the c<strong>on</strong>structi<strong>on</strong> of a n<strong>on</strong>-term<strong>in</strong>at<strong>in</strong>g program comesfrom the so-called negative occurrence of Lambda <strong>in</strong> the argument of the c<strong>on</strong>structorlambda.<strong>The</strong> reader will f<strong>in</strong>d <strong>in</strong> the Reference Manual a complete formal def<strong>in</strong>iti<strong>on</strong>of the noti<strong>on</strong>s of positivity c<strong>on</strong>diti<strong>on</strong> and strict positivity that an <strong>in</strong>ductivedef<strong>in</strong>iti<strong>on</strong> must satisfy.Notice that the positivity c<strong>on</strong>diti<strong>on</strong> does not forbid us to put functi<strong>on</strong>alrecursive arguments <strong>in</strong> the c<strong>on</strong>structors.For <strong>in</strong>stance, let us c<strong>on</strong>sider the type of <strong>in</strong>f<strong>in</strong>itely branch<strong>in</strong>g trees, withlabels <strong>in</strong> Z.Require Import ZArith.<strong>Inductive</strong> itree : Set :=| ileaf : itree| <strong>in</strong>ode : Z → (nat → itree) → itree.In this representati<strong>on</strong>, the i-th child of a tree represented by “ <strong>in</strong>ode zs ” is obta<strong>in</strong>ed by apply<strong>in</strong>g the functi<strong>on</strong> s to i. <strong>The</strong> follow<strong>in</strong>g def<strong>in</strong>iti<strong>on</strong>sshow how to c<strong>on</strong>struct a tree with a s<strong>in</strong>gle node, a tree of height 1 and a treeof height 2:Def<strong>in</strong>iti<strong>on</strong> is<strong>in</strong>gle l := <strong>in</strong>ode l (fun i ⇒ ileaf).25


Def<strong>in</strong>iti<strong>on</strong> t1 := <strong>in</strong>ode 0 (fun n ⇒ is<strong>in</strong>gle (Z_of_nat n)).Def<strong>in</strong>iti<strong>on</strong> t2 :=<strong>in</strong>ode 0(fun n : nat ⇒<strong>in</strong>ode (Z_of_nat n)(fun p ⇒ is<strong>in</strong>gle (Z_of_nat (n*p)))).Let us def<strong>in</strong>e a preorder <strong>on</strong> <strong>in</strong>f<strong>in</strong>itely branch<strong>in</strong>g trees. In order to comparetwo n<strong>on</strong>-leaf trees, it is necessary to compare each of their children withouttak<strong>in</strong>g care of the order <strong>in</strong> which they appear:<strong>Inductive</strong> itree_le : itree→ itree → Prop :=| le_leaf : ∀ t, itree_le ileaf t| le_node : ∀ l l' s s',Zle l l' →(∀ i, ∃ j:nat, itree_le (s i) (s' j))→itree_le (<strong>in</strong>ode l s) (<strong>in</strong>ode l' s').Notice that a call to the predicate itree_le appears as a general parameterof the <strong>in</strong>ductive type ex (see Sect.2.8). This k<strong>in</strong>d of def<strong>in</strong>iti<strong>on</strong> is acceptedby <strong>Co</strong>q, but may lead to some difficulties, s<strong>in</strong>ce the <strong>in</strong>ducti<strong>on</strong> pr<strong>in</strong>ciple automaticallygenerated by the system is not the most appropriate (see chapter14 of [3] for a detailed explanati<strong>on</strong>).<strong>The</strong> follow<strong>in</strong>g def<strong>in</strong>iti<strong>on</strong>, obta<strong>in</strong>ed by skolemis<strong>in</strong>g the propositi<strong>on</strong>∀ i, ∃ j, (itree_le (s i) (s ′ j)) <strong>in</strong> the type of itree_le, does not presentthis problem:<strong>Inductive</strong> itree_le' : itree→ itree → Prop :=| le_leaf' : ∀ t, itree_le' ileaf t| le_node' : ∀ l l' s s' g,Zle l l' →(∀ i, itree_le' (s i) (s' (g i))) →itree_le' (<strong>in</strong>ode l s) (<strong>in</strong>ode l' s').Another example is the type of trees of unbounded width, <strong>in</strong> which arecursive subterm (ltree A) <strong>in</strong>stantiates the type of polymorphic lists:Require Import List.<strong>Inductive</strong> ltree (A:Set) : Set :=lnode : A → list (ltree A) → ltree A.This declarati<strong>on</strong> can be transformed add<strong>in</strong>g an extra type to the def<strong>in</strong>iti<strong>on</strong>,as was d<strong>on</strong>e <strong>in</strong> Secti<strong>on</strong> 2.9.26


3.4.2 Impredicative <strong>Inductive</strong> <strong>Types</strong>An <strong>in</strong>ductive type R <strong>in</strong>habit<strong>in</strong>g a universe S is predicative if the <strong>in</strong>troducti<strong>on</strong>rules of R do not make a universal quantificati<strong>on</strong> <strong>on</strong> a universe c<strong>on</strong>ta<strong>in</strong><strong>in</strong>gS. All the recursive types previously <strong>in</strong>troduced are examples of predicativetypes. An example of an impredicative <strong>on</strong>e is the follow<strong>in</strong>g type:<strong>Inductive</strong> prop : Prop :=prop_<strong>in</strong>tro : Prop → prop.Notice that the c<strong>on</strong>structor of this type can be used to <strong>in</strong>ject any propositi<strong>on</strong>–even itself!– <strong>in</strong>to the type. A careless use of such a self-c<strong>on</strong>ta<strong>in</strong>edobjects may lead to a variant of Burali-Forti’s paradox. <strong>The</strong> c<strong>on</strong>structi<strong>on</strong> ofBurali-Forti’s paradox is more complicated than Russel’s <strong>on</strong>e, so we will notdescribe it here, and po<strong>in</strong>t the reader <strong>in</strong>terested <strong>in</strong> it to [1, 4].Lemma prop_<strong>in</strong>ject: prop.Proof prop_<strong>in</strong>tro prop.Another example is the sec<strong>on</strong>d order existential quantifier for propositi<strong>on</strong>s:<strong>Inductive</strong> ex_Prop (P : Prop → Prop) : Prop :=exP_<strong>in</strong>tro : ∀ X : Prop, P X → ex_Prop P.Notice that predicativity <strong>on</strong> sort Set forbids us to build the follow<strong>in</strong>gdef<strong>in</strong>iti<strong>on</strong>s.<strong>Inductive</strong> aSet : Set :=aSet_<strong>in</strong>tro: Set → aSet.User error: Large n<strong>on</strong>-propositi<strong>on</strong>al <strong>in</strong>ductive types must be <strong>in</strong> Type<strong>Inductive</strong> ex_Set (P : Set → Prop) : Set :=exS_<strong>in</strong>tro : ∀ X : Set, P X → ex_Set P.User error: Large n<strong>on</strong>-propositi<strong>on</strong>al <strong>in</strong>ductive types must be <strong>in</strong> TypeNevertheless, <strong>on</strong>e can def<strong>in</strong>e types like aSet and ex_Set, as <strong>in</strong>habitantsof Type.<strong>Inductive</strong> ex_Set (P : Set → Prop) : Type :=exS_<strong>in</strong>tro : ∀ X : Set, P X → ex_Set P.In the follow<strong>in</strong>g example, the <strong>in</strong>ductive type typ can be def<strong>in</strong>ed, but theterm associated with the <strong>in</strong>teractive Def<strong>in</strong>iti<strong>on</strong> of typ_<strong>in</strong>ject is <strong>in</strong>compatiblewith <strong>Co</strong>q’s hierarchy of universes:27


<strong>Inductive</strong> typ : Type :=typ_<strong>in</strong>tro : Type → typ.Def<strong>in</strong>iti<strong>on</strong> typ_<strong>in</strong>ject: typ.split; exact typ.Proof completedDef<strong>in</strong>ed.Error: Universe Inc<strong>on</strong>sistency.Abort.One possible way of avoid<strong>in</strong>g this new source of paradoxes is to restrictthe k<strong>in</strong>d of elim<strong>in</strong>ati<strong>on</strong>s by case analysis that can be d<strong>on</strong>e <strong>on</strong> impredicativetypes. In particular, projecti<strong>on</strong>s <strong>on</strong> those universes equal or bigger than the<strong>on</strong>e <strong>in</strong>habited by the impredicative type must be forbidden [4]. A c<strong>on</strong>sequenceof this restricti<strong>on</strong> is that it is not possible to def<strong>in</strong>e the first projecti<strong>on</strong>of the type “ ex_Prop P ”:Check (fun (P:Prop→Prop)(p: ex_Prop P) ⇒match p with exP_<strong>in</strong>tro X HX ⇒ X end).Error:Incorrect elim<strong>in</strong>ati<strong>on</strong> of "p" <strong>in</strong> the <strong>in</strong>ductive type"ex_Prop", the return type has sort "Type" while it should be"Prop"Elim<strong>in</strong>ati<strong>on</strong> of an <strong>in</strong>ductive object of sort "Prop"is not allowed <strong>on</strong> a predicate <strong>in</strong> sort "Type"because proofs can be elim<strong>in</strong>ated <strong>on</strong>ly to build proofs.3.4.3 Extracti<strong>on</strong> C<strong>on</strong>stra<strong>in</strong>ts<strong>The</strong>re is a f<strong>in</strong>al c<strong>on</strong>stra<strong>in</strong>t <strong>on</strong> case analysis that is not motivated by the potential<strong>in</strong>troducti<strong>on</strong> of paradoxes, but for compatibility reas<strong>on</strong>s with <strong>Co</strong>q’s extracti<strong>on</strong>mechanism . This mechanism is based <strong>on</strong> the classificati<strong>on</strong> of basictypes <strong>in</strong>to the universe Set of sets and the universe Prop of propositi<strong>on</strong>s. <strong>The</strong>objects of a type <strong>in</strong> the universe Set are c<strong>on</strong>sidered as relevant for computati<strong>on</strong>purposes. <strong>The</strong> objects of a type <strong>in</strong> Prop are c<strong>on</strong>sidered just as formalisedcomments, not necessary for executi<strong>on</strong>. <strong>The</strong> extracti<strong>on</strong> mechanism c<strong>on</strong>sists<strong>in</strong> eras<strong>in</strong>g such formal comments <strong>in</strong> order to obta<strong>in</strong> an executable program.Hence, <strong>in</strong> general, it is not possible to def<strong>in</strong>e an object <strong>in</strong> a set (that shouldbe kept by the extracti<strong>on</strong> mechanism) by case analysis of a proof (which willbe thrown away).Nevertheless, this general rule has an excepti<strong>on</strong> which is important <strong>in</strong>practice: if the def<strong>in</strong>iti<strong>on</strong> proceeds by case analysis <strong>on</strong> a proof of a s<strong>in</strong>glet<strong>on</strong>28


propositi<strong>on</strong> or an empty type (e.g. False), then it is allowed. A s<strong>in</strong>glet<strong>on</strong>propositi<strong>on</strong> is a n<strong>on</strong>-recursive propositi<strong>on</strong> with a s<strong>in</strong>gle c<strong>on</strong>structor c, allwhose arguments are proofs. For example, the propositi<strong>on</strong>al equality and thec<strong>on</strong>juncti<strong>on</strong> of two propositi<strong>on</strong>s are examples of s<strong>in</strong>glet<strong>on</strong> propositi<strong>on</strong>s.3.4.4 Str<strong>on</strong>g Case Analysis <strong>on</strong> Proofs<strong>The</strong> pla<strong>in</strong> Calculus of <strong>Inductive</strong> C<strong>on</strong>structi<strong>on</strong>s allows us to def<strong>in</strong>e a propositi<strong>on</strong>Q by case analysis <strong>on</strong> the proofs of another recursive propositi<strong>on</strong> R. Aswe will see <strong>in</strong> Secti<strong>on</strong> 4.1, this enables <strong>on</strong>e to prove that different <strong>in</strong>troducti<strong>on</strong>rules of R c<strong>on</strong>struct different objects. However, this property is <strong>in</strong> c<strong>on</strong>tradicti<strong>on</strong>with the pr<strong>in</strong>ciple of excluded middle of classical logic, becausethis pr<strong>in</strong>ciple entails that the proofs of a propositi<strong>on</strong> cannot be dist<strong>in</strong>guished.This pr<strong>in</strong>ciple is not provable <strong>in</strong> <strong>Co</strong>q, but it is frequently <strong>in</strong>troduced by theusers as an axiom, for reas<strong>on</strong><strong>in</strong>g <strong>in</strong> classical logic. For this reas<strong>on</strong>, the def<strong>in</strong>iti<strong>on</strong>of propositi<strong>on</strong>s by case analysis <strong>on</strong> proofs is currently not allowed <strong>in</strong><strong>Co</strong>q.Def<strong>in</strong>iti<strong>on</strong> comes_from_the_left (P Q:Prop)(H:P ∨ Q): Prop :=match H with| or_<strong>in</strong>trol p ⇒ True| or_<strong>in</strong>tror q ⇒ Falseend.Error:Incorrect elim<strong>in</strong>ati<strong>on</strong> of "H" <strong>in</strong> the <strong>in</strong>ductive type"or", the return type has sort "Type" while it should be"Prop"Elim<strong>in</strong>ati<strong>on</strong> of an <strong>in</strong>ductive object of sort "Prop"is not allowed <strong>on</strong> a predicate <strong>in</strong> sort "Type"because proofs can be elim<strong>in</strong>ated <strong>on</strong>ly to build proofs.On the other hand, if we replace the propositi<strong>on</strong> P ∨Q with the <strong>in</strong>formativetype {P } + {Q}, the elim<strong>in</strong>ati<strong>on</strong> is accepted:Def<strong>in</strong>iti<strong>on</strong> comes_from_the_left_sumbool(P Q:Prop)(x:{P} + {Q}): Prop :=match x with| left p ⇒ True| right q ⇒ Falseend.29


3.4.5 Summary of C<strong>on</strong>stra<strong>in</strong>tsTo end with this secti<strong>on</strong>, the follow<strong>in</strong>g table summarizes which universe U 1may <strong>in</strong>habit an object of type Q def<strong>in</strong>ed by case analysis <strong>on</strong> x : R, depend<strong>in</strong>g<strong>on</strong> the universe U 2 <strong>in</strong>habited by the <strong>in</strong>ductive types R. 5Q : U 1Set Prop Typex : R :Set yes yes yesU 2Prop if R s<strong>in</strong>glet<strong>on</strong> yes noType yes yes yes4 Some Proof Techniques Based <strong>on</strong> Case AnalysisIn this secti<strong>on</strong> we illustrate the use of case analysis as a proof pr<strong>in</strong>ciple,expla<strong>in</strong><strong>in</strong>g the proof techniques beh<strong>in</strong>d three very useful <strong>Co</strong>q tactics, calleddiscrim<strong>in</strong>ate, <strong>in</strong>ject and <strong>in</strong>versi<strong>on</strong>.4.1 Discrim<strong>in</strong>ati<strong>on</strong> of <strong>in</strong>troducti<strong>on</strong> rulesIn the <strong>in</strong>formal semantics of recursive types described <strong>in</strong> Secti<strong>on</strong> 2 it wassaid that each of the <strong>in</strong>troducti<strong>on</strong> rules of a recursive type is c<strong>on</strong>sidered asbe<strong>in</strong>g different from all the others. It is possible to capture this fact <strong>in</strong>sidethe logical system us<strong>in</strong>g the propositi<strong>on</strong>al equality. We take as example thefollow<strong>in</strong>g theorem, stat<strong>in</strong>g that O c<strong>on</strong>structs a natural number different fromany of those c<strong>on</strong>structed with S.<strong>The</strong>orem S_is_not_O : ∀ n, S n ≠ 0.In order to prove this theorem, we first def<strong>in</strong>e a propositi<strong>on</strong> by case analysis<strong>on</strong> natural numbers, so that the propositi<strong>on</strong> is true for O and false for anynatural number c<strong>on</strong>structed with S. This uses the empty and s<strong>in</strong>glet<strong>on</strong> type<strong>in</strong>troduced <strong>in</strong> Secti<strong>on</strong>s 2.Def<strong>in</strong>iti<strong>on</strong> Is_zero (x:nat):= match x with| 0 ⇒ True| _ ⇒ Falseend.<strong>The</strong>n, we prove the follow<strong>in</strong>g lemma:5 In the box <strong>in</strong>dexed by U 1 = Type and U 2 = Set, the answer “yes” takes <strong>in</strong>to account thepredicativity of sort Set. If you are work<strong>in</strong>g with the opti<strong>on</strong> “impredicative-set”, you must put <strong>in</strong>this box the c<strong>on</strong>diti<strong>on</strong> “if R is predicative”.30


Lemma O_is_zero : ∀ m, m = 0 → Is_zero m.Proof.<strong>in</strong>tros m H; subst m.================Is_zero 0simpl;trivial.Qed.F<strong>in</strong>ally, the proof of S_is_not_O follows by the applicati<strong>on</strong> of the previouslemma to S n.red; <strong>in</strong>tros n Hn.n : natHn : S n = 0============================Falseapply O_is_zero with (m := S n).assumpti<strong>on</strong>.Qed.<strong>The</strong> tactic discrim<strong>in</strong>ate is a special-purpose tactic for prov<strong>in</strong>g disequalitiesbetween two elements of a recursive type <strong>in</strong>troduced by differentc<strong>on</strong>structors. It generalizes the proof method described here for natural numbersto any [co]-<strong>in</strong>ductive. This tactic is also capable of prov<strong>in</strong>g disequalitieswhere the difference is not <strong>in</strong> the c<strong>on</strong>structors at the head of the terms, butdeeper <strong>in</strong>side them. For example, it can be used to prove the follow<strong>in</strong>g theorem:<strong>The</strong>orem disc2 : ∀ n, S (S n) ≠ 1.Proof.<strong>in</strong>tros n Hn; discrim<strong>in</strong>ate.Qed.When there is an assumpti<strong>on</strong> H <strong>in</strong> the c<strong>on</strong>text stat<strong>in</strong>g a false equalityt 1 = t 2 , discrim<strong>in</strong>ate solves the goal by first prov<strong>in</strong>g (t 1 ≠ t 2 ) and thenreas<strong>on</strong><strong>in</strong>g by absurdity with respect to H:<strong>The</strong>orem disc3 : ∀ n, S (S n) = 0 → ∀ Q:Prop, Q.Proof.<strong>in</strong>tros n Hn Q.discrim<strong>in</strong>ate.Qed.31


In this case, the proof proceeds by absurdity with respect to the false equalityassumed, whose negati<strong>on</strong> is proved by discrim<strong>in</strong>ati<strong>on</strong>.4.2 Injectiveness of <strong>in</strong>troducti<strong>on</strong> rulesAnother useful property about recursive types is the <strong>in</strong>jectiveness of <strong>in</strong>troducti<strong>on</strong>rules, i.e., that whenever two objects were built us<strong>in</strong>g the same <strong>in</strong>troducti<strong>on</strong>rule, then this rule should have been applied to the same element.This can be stated formally us<strong>in</strong>g the propositi<strong>on</strong>al equality:<strong>The</strong>orem <strong>in</strong>j : ∀ n m, S n = S m → n = m.Proof.This theorem is just a corollary of a lemma about the predecessor functi<strong>on</strong>:Lemma <strong>in</strong>j_pred : ∀ n m, n = m → pred n = pred m.Proof.<strong>in</strong>tros n m eq_n_m.rewrite eq_n_m.trivial.Qed.Once this lemma is proven, the theorem follows directly from it:<strong>in</strong>tros n m eq_Sn_Sm.apply <strong>in</strong>j_pred with (n:= S n) (m := S m); assumpti<strong>on</strong>.Qed.This proof method is implemented by the tactic <strong>in</strong>jecti<strong>on</strong> . This tacticis applied to a term t of type “ c t 1 . . . t n = c t ′ 1 . . . t ′ n ”, where c is somec<strong>on</strong>structor of an <strong>in</strong>ductive type. <strong>The</strong> tactic <strong>in</strong>jecti<strong>on</strong> is applied as deep aspossible to derive the equality of all pairs of subterms of t i and t ′ i placed <strong>in</strong>the same positi<strong>on</strong>. All these equalities are put as antecedents of the currentgoal.Like discrim<strong>in</strong>ate, the tactic <strong>in</strong>jecti<strong>on</strong> can be also applied if x doesnot occur <strong>in</strong> a direct sub-term, but somewhere deeper <strong>in</strong>side it. Its applicati<strong>on</strong>may leave some trivial goals that can be easily solved us<strong>in</strong>g the tactictrivial.Lemma list_<strong>in</strong>ject : ∀ (A:Set)(a b :A)(l l':list A),a :: b :: l = b :: a :: l' → a = b ∧ l = l'.Proof.<strong>in</strong>tros A a b l l' e.e : a :: b :: l = b :: a :: l’32


============================a = b ∧ l = l’<strong>in</strong>jecti<strong>on</strong> e.============================l = l’ → b = a → a = b → a = b ∧ l = l’auto.Qed.4.3 Inversi<strong>on</strong> TechniquesIn secti<strong>on</strong> 3.2, we motivated the rule of dependent case analysis as a wayof <strong>in</strong>ternaliz<strong>in</strong>g the <strong>in</strong>formal equalities n = O and n = (S p) associatedto each case. This <strong>in</strong>ternalisati<strong>on</strong> c<strong>on</strong>sisted <strong>in</strong> <strong>in</strong>stantiat<strong>in</strong>g n with the corresp<strong>on</strong>d<strong>in</strong>gterm <strong>in</strong> the type of each branch. However, sometimes it couldbe better to <strong>in</strong>ternalise these equalities as extra hypotheses –for example, <strong>in</strong>order to use the tactics rewrite, discrim<strong>in</strong>ate or <strong>in</strong>jecti<strong>on</strong> presented<strong>in</strong> the previous secti<strong>on</strong>s. This is frequently the case when the element analysedis denoted by a term which is not a variable, or when it is an object ofa particular <strong>in</strong>stance of a recursive family of types. C<strong>on</strong>sider for example thefollow<strong>in</strong>g theorem:<strong>The</strong>orem not_le_Sn_0 : ∀ n:nat, ~ (S n ≤ 0).Intuitively, this theorem should follow by case analysis <strong>on</strong> the hypothesisH : (S n ≤ O), because no <strong>in</strong>troducti<strong>on</strong> rule allows to <strong>in</strong>stantiate thearguments of le with respectively a successor and zero. However, there isno way of captur<strong>in</strong>g this with the typ<strong>in</strong>g rule for case analysis presented <strong>in</strong>secti<strong>on</strong> 2, because it does not take <strong>in</strong>to account what particular <strong>in</strong>stance ofthe family the type of H is. Let us try it:Proof.red; <strong>in</strong>tros n H; case H.2 subgoalsn : natH : S n ≤ 0============================Falsesubgoal 2 is:∀ m : nat, S n ≤ m → FalseUndo.33


What is necessary here is to make available the equalities “ S n = O ” and“ S m = O ” as extra hypotheses of the branches, so that the goal can besolved us<strong>in</strong>g the Discrim<strong>in</strong>ate tactic. In order to obta<strong>in</strong> the desired equalitiesas hypotheses, let us prove an auxiliary lemma, that our theorem is acorollary of:Lemma not_le_Sn_0_with_c<strong>on</strong>stra<strong>in</strong>ts :∀ n p , S n ≤ p → p = 0 → False.Proof.<strong>in</strong>tros n p H; case H .2 subgoalsn : natp : natH : S n ≤ p============================S n = 0 → Falsesubgoal 2 is:∀ m : nat, S n ≤ m → S m = 0 → False<strong>in</strong>tros;discrim<strong>in</strong>ate.<strong>in</strong>tros;discrim<strong>in</strong>ate.Qed.Our ma<strong>in</strong> theorem can be now solved by an applicati<strong>on</strong> of this lemma:Show.2 subgoalsn : natp : natH : S n ≤ p============================S n = 0 → Falsesubgoal 2 is:∀ m : nat, S n ≤ m → S m = 0 → Falseeapply not_le_Sn_0_with_c<strong>on</strong>stra<strong>in</strong>ts; eauto.Qed.<strong>The</strong> general method to address such situati<strong>on</strong>s c<strong>on</strong>sists <strong>in</strong> chang<strong>in</strong>g thegoal to be proven <strong>in</strong>to an implicati<strong>on</strong>, <strong>in</strong>troduc<strong>in</strong>g as prec<strong>on</strong>diti<strong>on</strong>s the equalitiesneeded to elim<strong>in</strong>ate those cases that make no sense. This proof tech-34


nique is implemented by the tactic <strong>in</strong>versi<strong>on</strong> . In order to prove a goalG ⃗q from an object of type R ⃗t, this tactic automatically generates a lemma∀, ⃗x.(R ⃗x) → ⃗x = ⃗t → ⃗ B → (G ⃗q), where the list of propositi<strong>on</strong>s ⃗ B corresp<strong>on</strong>dto those sub-goals that cannot be directly proven us<strong>in</strong>g discrim<strong>in</strong>ate.This lemma can be either saved for further use, or generated <strong>in</strong>teractively. Inthis latter case, the subgoals yield by the tactic are the hypotheses ⃗ B of thelemma. If the lemma has been stocked, then the tactic“ <strong>in</strong>versi<strong>on</strong> ...us<strong>in</strong>g ... ” can be used to apply it.Let us show both techniques <strong>on</strong> our previous example:4.3.1 Interactive mode<strong>The</strong>orem not_le_Sn_0' : ∀ n:nat, ~ (S n ≤ 0).Proof.red; <strong>in</strong>tros n H ; <strong>in</strong>versi<strong>on</strong> H.Qed.4.3.2 Static modeDerive Inversi<strong>on</strong> le_Sn_0_<strong>in</strong>v with (∀ n :nat, S n ≤ 0).<strong>The</strong>orem le_Sn_0'' : ∀ n p : nat, ~ S n ≤ 0 .Proof.<strong>in</strong>tros n p H;<strong>in</strong>versi<strong>on</strong> H us<strong>in</strong>g le_Sn_0_<strong>in</strong>v.Qed.In the example above, all the cases are solved us<strong>in</strong>g discrim<strong>in</strong>ate, so itrema<strong>in</strong>s no sub-goal to be proven (i.e. the list ⃗ B is empty). Let us present asec<strong>on</strong>d example, where this list is not empty:T<strong>The</strong>orem le_reverse_rules :∀ n m:nat, n ≤ m →n = m ∨∃ p, n ≤ p ∧ m = S p.Proof.<strong>in</strong>tros n m H; <strong>in</strong>versi<strong>on</strong> H.2 subgoalsn : natm : natH : n ≤ m35


H0 : n = m============================m = m ∨ (∃ p : nat, m ≤ p ∧ m = S p)subgoal 2 is:n = S m0 ∨ (∃ p : nat, n ≤ p ∧ S m0 = S p)left;trivial.right; exists m0; split; trivial.Proof completedThis example shows how this tactic can be used to “reverse” the <strong>in</strong>troducti<strong>on</strong>rules of a recursive type, deriv<strong>in</strong>g the possible premises that couldlead to prove a given <strong>in</strong>stance of the predicate. This is why these tactics arecalled <strong>in</strong>versi<strong>on</strong> tactics: they go back from c<strong>on</strong>clusi<strong>on</strong>s to premises.<strong>The</strong> hypothesis corresp<strong>on</strong>d<strong>in</strong>g to the propositi<strong>on</strong>al equalities are not needed<strong>in</strong> this example, s<strong>in</strong>ce the tactic does the rewrit<strong>in</strong>g necessary to solve the subgoals.When the equalities are no l<strong>on</strong>ger needed after the <strong>in</strong>versi<strong>on</strong>, it is betterto use the tactic Inversi<strong>on</strong>_clear. This variant of the tactic clears from thec<strong>on</strong>text all the equalities <strong>in</strong>troduced.Restart.<strong>in</strong>tros n m H; <strong>in</strong>versi<strong>on</strong>_clear H.n : natm : nat============================m = m ∨ (∃ p : nat, m ≤ p ∧ m = S p)left;trivial.n : natm : natm0 : natH0 : n ≤ m0============================n = S m0 ∨ (∃ p : nat, n ≤ p ∧ S m0 = S p)right; exists m0; split; trivial.Qed.Exercise 4.1 C<strong>on</strong>sider the follow<strong>in</strong>g language of arithmetic expressi<strong>on</strong>, andits operati<strong>on</strong>al semantics, described by a set of rewrit<strong>in</strong>g rules.36


<strong>Inductive</strong> ArithExp : Set :=| Zero : ArithExp| Succ : ArithExp → ArithExp| Plus : ArithExp → ArithExp → ArithExp.<strong>Inductive</strong> RewriteRel : ArithExp → ArithExp → Prop :=| RewSucc : ∀ e1 e2 :ArithExp,RewriteRel e1 e2 → RewriteRel (Succ e1) (Succ e2)| RewPlus0 : ∀ e:ArithExp,RewriteRel (Plus Zero e) e| RewPlusS : ∀ e1 e2:ArithExp,RewriteRel e1 e2 →RewriteRel (Plus (Succ e1) e2) (Succ (Plus e1 e2)).1. Prove that Zero cannot be rewritten any further.2. Prove that an expressi<strong>on</strong> of the form “ Succ e ” is always rewritten<strong>in</strong>to an expressi<strong>on</strong> of the same form.5 <strong>Inductive</strong> <strong>Types</strong> and Structural Inducti<strong>on</strong>Elements of <strong>in</strong>ductive types are well-founded with respect to the structuralorder <strong>in</strong>duced by the c<strong>on</strong>structors of the type. In additi<strong>on</strong> to case analysis,this extra hypothesis about well-foundness justifies a str<strong>on</strong>ger elim<strong>in</strong>ati<strong>on</strong>rule for them, called structural <strong>in</strong>ducti<strong>on</strong>. This form of elim<strong>in</strong>ati<strong>on</strong> c<strong>on</strong>sists<strong>in</strong> def<strong>in</strong><strong>in</strong>g a value “ f x ” from some element x of the <strong>in</strong>ductive type I,assum<strong>in</strong>g that values have been already associated <strong>in</strong> the same way to thesub-parts of x of type I.Def<strong>in</strong>iti<strong>on</strong>s by structural <strong>in</strong>ducti<strong>on</strong> are expressed through the Fixpo<strong>in</strong>tcommand . This command is quite close to the let-rec c<strong>on</strong>structi<strong>on</strong> offuncti<strong>on</strong>al programm<strong>in</strong>g languages. For example, the follow<strong>in</strong>g def<strong>in</strong>iti<strong>on</strong><strong>in</strong>troduces the additi<strong>on</strong> of two natural numbers (already def<strong>in</strong>ed <strong>in</strong> the StandardLibrary:)Fixpo<strong>in</strong>t plus (n p:nat) {struct n} : nat :=match n with| 0 ⇒ p| S m ⇒ S (plus m p)end.<strong>The</strong> def<strong>in</strong>iti<strong>on</strong> is by structural <strong>in</strong>ducti<strong>on</strong> <strong>on</strong> the first argument of the functi<strong>on</strong>.This is <strong>in</strong>dicated enclos<strong>in</strong>g by the “ struct n ” directive <strong>in</strong> the functi<strong>on</strong>’sheader 6 . In order to be accepted, the def<strong>in</strong>iti<strong>on</strong> must satisfy a syntacticalc<strong>on</strong>diti<strong>on</strong>, called the guardedness c<strong>on</strong>diti<strong>on</strong>. Roughly speak<strong>in</strong>g, this6 This directive is opti<strong>on</strong>al <strong>in</strong> the case of a functi<strong>on</strong> of a s<strong>in</strong>gle argument37


c<strong>on</strong>diti<strong>on</strong> c<strong>on</strong>stra<strong>in</strong>s the arguments of a recursive call to be pattern variables,issued from a case analysis of the formal argument of the functi<strong>on</strong> po<strong>in</strong>tedby the struct directive. In the case of the functi<strong>on</strong> plus, the argument m<strong>in</strong> the recursive call is a pattern variable issued from a case analysis of n.<strong>The</strong>refore, the def<strong>in</strong>iti<strong>on</strong> is accepted.Notice that we could have def<strong>in</strong>ed the additi<strong>on</strong> with structural <strong>in</strong>ducti<strong>on</strong><strong>on</strong> its sec<strong>on</strong>d argument:Fixpo<strong>in</strong>t plus' (n p:nat) {struct p} : nat :=match p with| 0 ⇒ n| S q ⇒ S (plus' n q)end.In the follow<strong>in</strong>g def<strong>in</strong>iti<strong>on</strong> of additi<strong>on</strong>, the sec<strong>on</strong>d argument of plusgrows at each recursive call. However, as the first <strong>on</strong>e always decreases, thedef<strong>in</strong>iti<strong>on</strong> is sound.Fixpo<strong>in</strong>t plus'' (n p:nat) {struct n} : nat :=match n with| 0 ⇒ p| S m ⇒ plus'' m (S p)end.Moreover, the argument <strong>in</strong> the recursive call could be a deeper comp<strong>on</strong>entof n. This is the case <strong>in</strong> the follow<strong>in</strong>g def<strong>in</strong>iti<strong>on</strong> of a boolean functi<strong>on</strong>determ<strong>in</strong><strong>in</strong>g whether a number is even or odd:Fixpo<strong>in</strong>t even_test (n:nat) : bool :=match nwith 0 ⇒ true| 1 ⇒ false| S (S p) ⇒ even_test pend.Mutually dependent def<strong>in</strong>iti<strong>on</strong>s by structural <strong>in</strong>ducti<strong>on</strong> are also allowed.For example, the previous functi<strong>on</strong> even could be alternatively def<strong>in</strong>ed us<strong>in</strong>gan auxiliary functi<strong>on</strong> odd:Reset even_test.Fixpo<strong>in</strong>t even_test (n:nat) : bool :=match nwith| 0 ⇒ true| S p ⇒ odd_test pendwith odd_test (n:nat) : bool :=match n38


with| 0 ⇒ false| S p ⇒ even_test pend.Def<strong>in</strong>iti<strong>on</strong>s by structural <strong>in</strong>ducti<strong>on</strong> are computed lazily, i.e. they are expanded<strong>on</strong>ly when they are applied, and the decreas<strong>in</strong>g argument is a termhav<strong>in</strong>g a c<strong>on</strong>structor at the head. We can check this us<strong>in</strong>g the Eval command,which computes the normal form of a well typed term.Eval simpl <strong>in</strong> even_test.= even_test: nat → boolEval simpl <strong>in</strong> (fun x : nat ⇒ even x).= fun x : nat ⇒ even x: nat → PropEval simpl <strong>in</strong> (fun x : nat ⇒ even_test (plus 5 x)).= fun x : nat ⇒ odd_test x: nat → boolEval simpl <strong>in</strong> (fun x : nat ⇒ even_test (plus x 5)).= fun x : nat ⇒ even_test (x + 5): nat → bool5.1 Proofs by Structural Inducti<strong>on</strong><strong>The</strong> pr<strong>in</strong>ciple of structural <strong>in</strong>ducti<strong>on</strong> can be also used <strong>in</strong> order to def<strong>in</strong>eproofs, that is, to prove theorems. Let us call an elim<strong>in</strong>ati<strong>on</strong> comb<strong>in</strong>atorany functi<strong>on</strong> that, given a predicate P , def<strong>in</strong>es a proof of “ P x ” by structural<strong>in</strong>ducti<strong>on</strong> <strong>on</strong> x. In <strong>Co</strong>q, the pr<strong>in</strong>ciple of proof by <strong>in</strong>ducti<strong>on</strong> <strong>on</strong> naturalnumbers is a particular case of an elim<strong>in</strong>ati<strong>on</strong> comb<strong>in</strong>ator. <strong>The</strong> def<strong>in</strong>iti<strong>on</strong>of this comb<strong>in</strong>ator depends <strong>on</strong> three general parameters: the predicate to beproven, the base case, and <strong>in</strong>ductive hypothesis:Secti<strong>on</strong> Pr<strong>in</strong>ciple_of_Inducti<strong>on</strong>.Variable P : nat → Prop.Hypothesis base_case : P 0.Hypothesis <strong>in</strong>ductive_hyp : ∀ n:nat, P n → P (S n).Fixpo<strong>in</strong>t nat_<strong>in</strong>d (n:nat) : (P n) :=match n return P n with39


end.| 0 ⇒ base_case| S m ⇒ <strong>in</strong>ductive_hyp m (nat_<strong>in</strong>d m)End Pr<strong>in</strong>ciple_of_Inducti<strong>on</strong>.As this proof pr<strong>in</strong>ciple is used very often, <strong>Co</strong>q automatically generatesit when an <strong>in</strong>ductive type is <strong>in</strong>troduced. Similar pr<strong>in</strong>ciples nat_rec andnat_rect for def<strong>in</strong><strong>in</strong>g objects <strong>in</strong> the universes Set and Type are also automaticallygenerated 7 . <strong>The</strong> command Scheme can be used to generate anelim<strong>in</strong>ati<strong>on</strong> comb<strong>in</strong>ators from certa<strong>in</strong> parameters, like the universe that must<strong>in</strong>habit the object def<strong>in</strong>ed, whether the case analysis <strong>in</strong> the def<strong>in</strong>iti<strong>on</strong>s must bedependent or not, etc. For example, it can be used to generate an elim<strong>in</strong>ati<strong>on</strong>comb<strong>in</strong>ator for reas<strong>on</strong><strong>in</strong>g <strong>on</strong> even natural numbers from the mutually dependentpredicates <strong>in</strong>troduced <strong>in</strong> page 14. We do not display the comb<strong>in</strong>atorshere by lack of space, but you can see them us<strong>in</strong>g the Pr<strong>in</strong>t command.Scheme Even_<strong>in</strong>ducti<strong>on</strong> := M<strong>in</strong>imality for even Sort Propwith Odd_<strong>in</strong>ducti<strong>on</strong> := M<strong>in</strong>imality for odd Sort Prop.<strong>The</strong>orem even_plus_four : ∀ n:nat, even n → even (4+n).Proof.<strong>in</strong>tros n H.elim H us<strong>in</strong>g Even_<strong>in</strong>ducti<strong>on</strong> with (P0 := fun n ⇒ odd (4+n));simpl;repeat c<strong>on</strong>structor;assumpti<strong>on</strong>.Qed.Another example of an elim<strong>in</strong>ati<strong>on</strong> comb<strong>in</strong>ator is the pr<strong>in</strong>ciple of double<strong>in</strong>ducti<strong>on</strong> <strong>on</strong> natural numbers, <strong>in</strong>troduced by the follow<strong>in</strong>g def<strong>in</strong>iti<strong>on</strong>:Secti<strong>on</strong> Pr<strong>in</strong>ciple_of_Double_Inducti<strong>on</strong>.Variable P : nat → nat →Prop.Hypothesis base_case1 : ∀ m:nat, P 0 m.Hypothesis base_case2 : ∀ n:nat, P (S n) 0.Hypothesis <strong>in</strong>ductive_hyp : ∀ n m:nat, P n m → P (S n) (S m).Fixpo<strong>in</strong>t nat_double_<strong>in</strong>d (n m:nat){struct n} : P n m :=match n, m return P n m with0 , x ⇒ base_case1 x| (S x), 0 ⇒ base_case2 x| (S x), (S y) ⇒ <strong>in</strong>ductive_hyp x y (nat_double_<strong>in</strong>d x y)end.End Pr<strong>in</strong>ciple_of_Double_Inducti<strong>on</strong>.7 In fact, whenever possible, <strong>Co</strong>q generates the pr<strong>in</strong>ciple I_rect, then derives from it the weakerpr<strong>in</strong>ciples I_<strong>in</strong>d and I_rec. If some pr<strong>in</strong>ciple has to be def<strong>in</strong>ed by hand, the user may try to buildI_rect (if possible). Thanks to <strong>Co</strong>q’s c<strong>on</strong>versi<strong>on</strong> rule, this pr<strong>in</strong>ciple can be used directly to buildproofs and/or programs.40


Chang<strong>in</strong>g the type of P <strong>in</strong>to nat → nat → Set, another comb<strong>in</strong>atornat_double_rec for c<strong>on</strong>struct<strong>in</strong>g (certified) programs can be def<strong>in</strong>ed <strong>in</strong> exactlythe same way. This def<strong>in</strong>iti<strong>on</strong> is left as an exercise.For <strong>in</strong>stance the functi<strong>on</strong> comput<strong>in</strong>g the m<strong>in</strong>imum of two natural numberscan be def<strong>in</strong>ed <strong>in</strong> the follow<strong>in</strong>g way:Def<strong>in</strong>iti<strong>on</strong> m<strong>in</strong> : nat → nat → nat :=nat_double_rec (fun (x y:nat) ⇒ nat)(fun (x:nat) ⇒ 0)(fun (y:nat) ⇒ 0)(fun (x y r:nat) ⇒ S r).Eval compute <strong>in</strong> (m<strong>in</strong> 5 8).= 5 : nat5.2 Us<strong>in</strong>g Elim<strong>in</strong>ati<strong>on</strong> <strong>Co</strong>mb<strong>in</strong>ators.<strong>The</strong> tactic apply can be used to apply <strong>on</strong>e of these proof pr<strong>in</strong>ciples dur<strong>in</strong>g thedevelopment of a proof. C<strong>on</strong>sider for example the propositi<strong>on</strong> “ ∀ n:nat, n ≠ S n ”.Lemma not_circular : ∀ n:nat, n ≠ S n.Proof.<strong>in</strong>tro n.apply nat_<strong>in</strong>d with (P:= fun n ⇒ n ≠ S n).2 subgoalsn : nat============================0 ≠ 1subgoal 2 is:∀ n0 : nat, n0 ≠ S n0 → S n0 ≠ S (S n0)discrim<strong>in</strong>ate.red; <strong>in</strong>tros n0 Hn0 eqn0Sn0;<strong>in</strong>jecti<strong>on</strong> eqn0Sn0;trivial.Qed.<strong>The</strong> tactic elim is a ref<strong>in</strong>ement of apply, specially c<strong>on</strong>ceived for theapplicati<strong>on</strong> of elim<strong>in</strong>ati<strong>on</strong> comb<strong>in</strong>ators. If t is an object of an <strong>in</strong>ductive typeI, then “ elim t ” tries to f<strong>in</strong>d an abstracti<strong>on</strong> P of the current goal G suchthat (P t) ≡ G. <strong>The</strong>n it solves the goal apply<strong>in</strong>g “ I_<strong>in</strong>d P ”, where I_<strong>in</strong>dis the comb<strong>in</strong>ator associated to I. <strong>The</strong> different cases of the <strong>in</strong>ducti<strong>on</strong> appearsthen as sub-goals that rema<strong>in</strong> to be solved. In the preced<strong>in</strong>g proof, the tactic41


call “ apply nat_<strong>in</strong>d with (P:= fun n ⇒ n ≠ S n) ” can be simplyreplaced with “ elim n ”.<strong>The</strong> opti<strong>on</strong> “ elim t us<strong>in</strong>g C ” allows to use a derived comb<strong>in</strong>atorC <strong>in</strong>stead of the default <strong>on</strong>e. C<strong>on</strong>sider the follow<strong>in</strong>g theorem, stat<strong>in</strong>g thatequality is decidable <strong>on</strong> natural numbers:Lemma eq_nat_dec : ∀ n p:nat, {n=p}+{n ≠ p}.Proof.<strong>in</strong>tros n p.Let us prove this theorem us<strong>in</strong>g the comb<strong>in</strong>ator nat_double_rec of secti<strong>on</strong>5.1. <strong>The</strong> example also illustrates how elim may sometimes fail <strong>in</strong> f<strong>in</strong>d<strong>in</strong>ga suitable abstracti<strong>on</strong> P of the goal. Note that if “ elim n ” is useddirectly <strong>on</strong> the goal, the result is not the expected <strong>on</strong>e.elim n us<strong>in</strong>g nat_double_rec.4 subgoalsn : natp : nat============================∀ x : nat, {x = p} + {x ≠ p}subgoal 2 is:nat → {0 = p} + {0 ≠ p}subgoal 3 is:nat → ∀ m : nat, {m = p} + {m ≠ p} → {S m = p} + {S m ≠ p}subgoal 4 is:nat<strong>The</strong> four sub-goals obta<strong>in</strong>ed do not corresp<strong>on</strong>d to the premises that wouldbe expected for the pr<strong>in</strong>ciple nat_double_rec. <strong>The</strong> problem comes fromthe fact that this pr<strong>in</strong>ciple for elim<strong>in</strong>at<strong>in</strong>g n has a universally quantified formulaas c<strong>on</strong>clusi<strong>on</strong>, which c<strong>on</strong>fuses elim about the right way of abstract<strong>in</strong>gthe goal.<strong>The</strong>refore, <strong>in</strong> this case the abstracti<strong>on</strong> must be explicited us<strong>in</strong>g the tacticpattern. Once the right abstracti<strong>on</strong> is provided, the rest of the proof isimmediate:Undo.pattern p,n.42


n : natp : nat============================(fun n0 n1 : nat ⇒ {n1 = n0} + {n1 ≠ n0}) p nelim n us<strong>in</strong>g nat_double_rec.3 subgoalsn : natp : nat============================∀ x : nat, {x = 0} + {x ≠ 0}subgoal 2 is:∀ x : nat, {0 = S x} + {0 ≠ S x}subgoal 3 is:∀ n0 m : nat, {m = n0} + {m ≠ n0} → {S m = S n0} + {S m ≠ S n0}destruct x; auto.destruct x; auto.<strong>in</strong>tros n0 m H; case H.<strong>in</strong>tro eq; rewrite eq ; auto.<strong>in</strong>tro neg; right; red ; <strong>in</strong>jecti<strong>on</strong> 1; auto.Def<strong>in</strong>ed.Notice that the tactic “ decide equality ” generalises the proof aboveto a large class of <strong>in</strong>ductive types. It can be used for prov<strong>in</strong>g a propositi<strong>on</strong> ofthe form ∀ (x, y : R), {x = y}+{x≠y}, where R is an <strong>in</strong>ductive datatype allwhose c<strong>on</strong>structors take <strong>in</strong>formative arguments —like for example the typenat:Def<strong>in</strong>iti<strong>on</strong> eq_nat_dec' : ∀ n p:nat, {n=p} + {n≠p}.decide equality.Def<strong>in</strong>ed.Exercise 5.1 1. Def<strong>in</strong>e a recursive functi<strong>on</strong> nat2itree mapp<strong>in</strong>g any naturalnumber n <strong>in</strong>to an <strong>in</strong>f<strong>in</strong>itely branch<strong>in</strong>g tree of height n.2. Provide an elim<strong>in</strong>ati<strong>on</strong> comb<strong>in</strong>ator for these trees.3. Prove that the relati<strong>on</strong> itree_le is a preorder (i.e. reflexive and transitive).Exercise 5.2 Def<strong>in</strong>e the type of lists, and a predicate “be<strong>in</strong>g an orderedlist” us<strong>in</strong>g an <strong>in</strong>ductive family. <strong>The</strong>n, def<strong>in</strong>e the functi<strong>on</strong> (from n) = 0 ::1 . . . n :: nil and prove that it always generates an ordered list.43


5.3 Well-founded Recursi<strong>on</strong>Structural <strong>in</strong>ducti<strong>on</strong> is a str<strong>on</strong>g elim<strong>in</strong>ati<strong>on</strong> rule for <strong>in</strong>ductive types. Thismethod can be used to def<strong>in</strong>e any functi<strong>on</strong> whose term<strong>in</strong>ati<strong>on</strong> is based <strong>on</strong>the well-foundedness of certa<strong>in</strong> order relati<strong>on</strong> R decreas<strong>in</strong>g at each recursivecall. What makes this pr<strong>in</strong>ciple so str<strong>on</strong>g is the possibility of reas<strong>on</strong><strong>in</strong>g bystructural <strong>in</strong>ducti<strong>on</strong> <strong>on</strong> the proof that certa<strong>in</strong> R is well-founded. In order toillustrate this we have first to <strong>in</strong>troduce the predicate of accessibility.Pr<strong>in</strong>t Acc.<strong>Inductive</strong> Acc (A : Set) (R : A → A → Prop) : A → Prop :=Acc_<strong>in</strong>tro : ∀ x : A, (∀ y : A, R y x → Acc R y) → Acc R xFor Acc: Argument A is implicitFor Acc_<strong>in</strong>tro: Arguments A, R are implicit. . .This <strong>in</strong>ductive predicate characterize those elements x of A such that anydescend<strong>in</strong>g R-cha<strong>in</strong> . . . x 2 R x 1 R x start<strong>in</strong>g from x is f<strong>in</strong>ite. A wellfoundedrelati<strong>on</strong> is a relati<strong>on</strong> such that all the elements of A are accessible.44


C<strong>on</strong>sider now the problem of represent<strong>in</strong>g <strong>in</strong> <strong>Co</strong>q the follow<strong>in</strong>g ML functi<strong>on</strong>div(x, y) <strong>on</strong> natural numbers, which computes ⌈ x y⌉ if y > 0 and yieldsx otherwise.let rec div x y =if x = 0 then 0else if y = 0 then xelse (div (x-y) y)+1;;<strong>The</strong> equality test <strong>on</strong> natural numbers can be represented as the functi<strong>on</strong>eq_nat_dec def<strong>in</strong>ed page 42. Giv<strong>in</strong>g x and y, this functi<strong>on</strong> yields either thevalue (left p) if there exists a proof p : x = y, or the value (right q) if thereexists q : a ≠ b. <strong>The</strong> subtracti<strong>on</strong> functi<strong>on</strong> is already def<strong>in</strong>ed <strong>in</strong> the libraryM<strong>in</strong>us.Hence, direct translati<strong>on</strong> of the ML functi<strong>on</strong> div would be:Require Import M<strong>in</strong>us.Fixpo<strong>in</strong>t div (x y:nat){struct x}: nat :=if eq_nat_dec x 0then 0else if eq_nat_dec y 0then xelse S (div (x-y) y).Error:Recursive def<strong>in</strong>iti<strong>on</strong> of div is ill-formed.In envir<strong>on</strong>mentdiv : nat → nat → natx : naty : nat_ : x ≠ 0_ : y ≠ 0Recursive call to div has pr<strong>in</strong>cipal argument equal to"x - y"<strong>in</strong>stead of a subterm of x<strong>The</strong> program div is rejected by <strong>Co</strong>q because it does not verify the syntacticalc<strong>on</strong>diti<strong>on</strong> to ensure term<strong>in</strong>ati<strong>on</strong>. In particular, the argument of therecursive call is not a pattern variable issued from a case analysis <strong>on</strong> x. Wewould have the same problem if we had the directive “ {struct y} ” <strong>in</strong>steadof “ {struct x} ”. However, we know that this program always stops. Oneway to justify its term<strong>in</strong>ati<strong>on</strong> is to def<strong>in</strong>e it by structural <strong>in</strong>ducti<strong>on</strong> <strong>on</strong> a proofthat x is accessible trough the relati<strong>on</strong>


some auxiliary lemmas, justify<strong>in</strong>g that the first argument of div decreases ateach recursive call.Lemma m<strong>in</strong>us_smaller_S : ∀ x y:nat, x - y < S x.Proof.<strong>in</strong>tros x y; pattern y, x;elim x us<strong>in</strong>g nat_double_<strong>in</strong>d.destruct x0; auto with arith.simpl; auto with arith.simpl; auto with arith.Qed.Lemma m<strong>in</strong>us_smaller_positive :∀ x y:nat, x ≠0 → y ≠ 0 → x - y < x.Proof.destruct x; destruct y;( simpl;<strong>in</strong>tros; apply m<strong>in</strong>us_smaller ||<strong>in</strong>tros; absurd (0=0); auto).Qed.<strong>The</strong> last two lemmas are necessary to prove that for any pair of positive naturalnumbers x and y, if x is accessible with respect to lt, then so is x − y.Def<strong>in</strong>iti<strong>on</strong> m<strong>in</strong>us_decrease : ∀ x y:nat, Acc lt x →x ≠ 0 →y ≠ 0 →Acc lt (x-y).Proof.<strong>in</strong>tros x y H; case H.<strong>in</strong>tros z Hz posz posy.apply Hz; apply m<strong>in</strong>us_smaller_positive; assumpti<strong>on</strong>.Def<strong>in</strong>ed.Let us take a look at the proof of the lemma m<strong>in</strong>us_decrease, s<strong>in</strong>ce theway <strong>in</strong> which it has been proven is crucial for what follows.Pr<strong>in</strong>t m<strong>in</strong>us_decrease.m<strong>in</strong>us_decrease =fun (x y : nat) (H : Acc lt x) ⇒match H <strong>in</strong> (Acc _ y0) return (y0 ≠ 0 → y ≠ 0 → Acc lt (y0 - y)) with| Acc_<strong>in</strong>tro z Hz ⇒fun (posz : z ≠ 0) (posy : y ≠ 0) ⇒Hz (z - y) (m<strong>in</strong>us_smaller_positive z y posz posy)end: ∀ x y : nat, Acc lt x → x ≠ 0 → y ≠ 0 → Acc lt (x - y)46


Remark that the functi<strong>on</strong> call (m<strong>in</strong>us_decrease n m H) <strong>in</strong>deed yields anaccessibility proof that is structurally smaller than its argument H, becauseit is (an applicati<strong>on</strong> of) its recursive comp<strong>on</strong>ent Hz. This enables to justifythe follow<strong>in</strong>g def<strong>in</strong>iti<strong>on</strong> of div_aux:Def<strong>in</strong>iti<strong>on</strong> div_aux (x y:nat)(H: Acc lt x):nat.fix 3.<strong>in</strong>tros.ref<strong>in</strong>e (if eq_nat_dec x 0then 0else if eq_nat_dec y 0then yelse div_aux (x-y) y _).div_aux : ∀ x : nat, nat → Acc lt x → natx : naty : natH : Acc lt x_ : x ≠ 0_0 : y ≠ 0============================Acc lt (x - y)apply (m<strong>in</strong>us_decrease x y H);auto.Def<strong>in</strong>ed.<strong>The</strong> ma<strong>in</strong> divisi<strong>on</strong> functi<strong>on</strong> is easily def<strong>in</strong>ed, us<strong>in</strong>g the theorem lt_wf ofthe library Wf_nat. This theorem asserts that nat is well founded w.r.t. lt,thus any natural number is accessible.Def<strong>in</strong>iti<strong>on</strong> div x y := div_aux x y (lt_wf x).Let us expla<strong>in</strong> the proof above. In the def<strong>in</strong>iti<strong>on</strong> of div_aux, what decreasesis not x but the proof of the accessibility of x. <strong>The</strong> tactic “ fix 3 ”is used to <strong>in</strong>dicate that the proof proceeds by structural <strong>in</strong>ducti<strong>on</strong> <strong>on</strong> the thirdargument of the theorem –that is, <strong>on</strong> the accessibility proof. It also <strong>in</strong>troducesa new hypothesis <strong>in</strong> the c<strong>on</strong>text, named as the current theorem, and with thesame type as the goal. <strong>The</strong>n, the proof is ref<strong>in</strong>ed with an <strong>in</strong>complete proofterm, c<strong>on</strong>ta<strong>in</strong><strong>in</strong>g a hole _. This hole corresp<strong>on</strong>ds to the proof of accessibilityfor x − y, and is filled up with the (smaller!) accessibility proof provided bythe functi<strong>on</strong> m<strong>in</strong>us_decrease.47


Lets take a look to the term div_aux def<strong>in</strong>ed:Pr<strong>in</strong>t div_aux.div_aux =(fix div_aux (x y : nat) (H : Acc lt x) {struct H} : nat :=match eq_nat_dec x 0 with| left _ ⇒ 0| right _ ⇒match eq_nat_dec y 0 with| left _ ⇒ y| right _0 ⇒ div_aux (x - y) y (m<strong>in</strong>us_decrease x y H _ _0)endend): ∀ x : nat, nat → Acc lt x → natIf the n<strong>on</strong>-<strong>in</strong>formative parts from this proof –that is, the accessibilityproof– are erased, then we obta<strong>in</strong> exactly the program that we were look<strong>in</strong>gfor.Extracti<strong>on</strong> div.let div x y =div_aux x yExtracti<strong>on</strong> div_aux.let rec div_aux x y =match eq_nat_dec x O with| Left → O| Right →(match eq_nat_dec y O with| Left → y| Right → div_aux (m<strong>in</strong>us x y) y)This methodology enables the representati<strong>on</strong> of any program whose term<strong>in</strong>ati<strong>on</strong>can be proved <strong>in</strong> <strong>Co</strong>q. Once the expected properties from this programhave been verified, the justificati<strong>on</strong> of its term<strong>in</strong>ati<strong>on</strong> can be thrownaway, keep<strong>in</strong>g just the desired computati<strong>on</strong>al behavior for it.48


6 A case study <strong>in</strong> dependent elim<strong>in</strong>ati<strong>on</strong>Dependent types are very expressive, but ignor<strong>in</strong>g some useful techniquescan cause some problems to the beg<strong>in</strong>ner. Let us c<strong>on</strong>sider aga<strong>in</strong> the type ofvectors (see secti<strong>on</strong> 2.2). We want to prove a quite trivial property: the <strong>on</strong>lyvalue of type “ vector A 0 ” is “ Vnil A ”.Our first naive attempt leads to a cul-de-sac.Lemma vector0_is_vnil :∀ (A:Set)(v:vector A 0), v = Vnil A.Proof.<strong>in</strong>tros A v;<strong>in</strong>versi<strong>on</strong> v.1 subgoalA : Setv : vector A 0============================v = Vnil AAbort.Another attempt is to do a case analysis <strong>on</strong> a vector of any length n, underan explicit hypothesis n = 0. <strong>The</strong> tactic discrim<strong>in</strong>ate will help us to getrid of the case n = S p. Unfortunately, even the statement of our lemma isrefused!Lemma vector0_is_vnil_aux :∀ (A:Set)(n:nat)(v:vector A n), n = 0 → v = Vnil A.Error: In envir<strong>on</strong>mentA : Setn : natv : vector A ne : n = 0<strong>The</strong> term "Vnil A" has type "vector A 0" while it is expected to have type"vector A n"In effect, the equality “ v = Vnil A ” is ill typed, because the type“ vector A n ” is not c<strong>on</strong>vertible with “ vector A 0 ”.This problem can be solved if we c<strong>on</strong>sider the heterogeneous equalityJMeq [10] which allows us to c<strong>on</strong>sider terms of different types, even if thisequality can <strong>on</strong>ly be proven for terms <strong>in</strong> the same type. <strong>The</strong> axiom JMeq_eq,from the library JMeq allows us to c<strong>on</strong>vert a heterogeneous equality to astandard <strong>on</strong>e.49


Lemma vector0_is_vnil_aux :∀ (A:Set)(n:nat)(v:vector A n),n= 0 → JMeq v (Vnil A).Proof.destruct v.auto.<strong>in</strong>tro; discrim<strong>in</strong>ate.Qed.Our property of vectors of null length can be easily proven:Lemma vector0_is_vnil : ∀ (A:Set)(v:vector A 0), v = Vnil A.<strong>in</strong>tros a v;apply JMeq_eq.apply vector0_is_vnil_aux.trivial.Qed.It is <strong>in</strong>terest<strong>in</strong>g to look at another proof of vector0_is_vnil, whichillustrates a technique developed and used by various people (c<strong>on</strong>sult <strong>in</strong>the <strong>Co</strong>q-club mail<strong>in</strong>g list archive the c<strong>on</strong>tributi<strong>on</strong>s by Yves Bertot, PierreLetouzey, Laurent Théry, Jean Duprat, and Nicolas Magaud, Venanzio Caprettaand C<strong>on</strong>or McBride). This technique is also used for unfold<strong>in</strong>g <strong>in</strong>f<strong>in</strong>ite listdef<strong>in</strong>iti<strong>on</strong>s (see chapter13 of [3]). Notice that this def<strong>in</strong>iti<strong>on</strong> does not rely <strong>on</strong>any axiom (e.g. JMeq_eq).We first give a new def<strong>in</strong>iti<strong>on</strong> of the identity <strong>on</strong> vectors. Before that,we make lighter the use of c<strong>on</strong>structors and selectors thanks to the implicitarguments feature:Implicit Arguments Vc<strong>on</strong>s [A n].Implicit Arguments Vnil [A].Implicit Arguments Vhead [A n].Implicit Arguments Vtail [A n].Def<strong>in</strong>iti<strong>on</strong> Vid : ∀ (A : Set)(n:nat), vector A n → vector A n.Proof.destruct n; <strong>in</strong>tro v.exact Vnil.exact (Vc<strong>on</strong>s (Vhead v) (Vtail v)).Def<strong>in</strong>ed.<strong>The</strong>n we prove that Vid is the identity <strong>on</strong> vectors:Lemma Vid_eq : ∀ (n:nat) (A:Set)(v:vector A n), v=(Vid _ n v).Proof.destruct v.A : Set50


============================Vnil = Vid A 0 Vnilsubgoal 2 is:Vc<strong>on</strong>s a v = Vid A (S n) (Vc<strong>on</strong>s a v)reflexivity.reflexivity.Def<strong>in</strong>ed.Why def<strong>in</strong><strong>in</strong>g a new identity functi<strong>on</strong> <strong>on</strong> vectors ? <strong>The</strong> follow<strong>in</strong>g dialogueshows that Vid has some <strong>in</strong>terest<strong>in</strong>g computati<strong>on</strong>al properties:Eval simpl <strong>in</strong> (fun (A:Set)(v:vector A 0) ⇒ (Vid _ _ v)).= fun (A : Set) (_ : vector A 0) ⇒ Vnil: ∀ A : Set, vector A 0 → vector A 0Notice that the pla<strong>in</strong> identity <strong>on</strong> vectors doesn’t c<strong>on</strong>vert v <strong>in</strong>to Vnil.Eval simpl <strong>in</strong> (fun (A:Set)(v:vector A 0) ⇒ v).= fun (A : Set) (v : vector A 0) ⇒ v: ∀ A : Set, vector A 0 → vector A 0<strong>The</strong>n we prove easily that any vector of length 0 is Vnil:<strong>The</strong>orem zero_nil : ∀ A (v:vector A 0), v = Vnil.Proof.<strong>in</strong>tros.change (Vnil (A:=A)) with (Vid _ 0 v).1 subgoalA : Setv : vector A 0============================v = Vid A 0 vapply Vid_eq.Def<strong>in</strong>ed.A similar result can be proven about vectors of strictly positive lenght 8 .<strong>The</strong>orem decomp :∀ (A : Set) (n : nat) (v : vector A (S n)),v = Vc<strong>on</strong>s (Vhead v) (Vtail v).8 As for Vid,Vid_eq, this def<strong>in</strong>iti<strong>on</strong> is from Jean Duprat.51


Proof.<strong>in</strong>tros.change (Vc<strong>on</strong>s (Vhead v) (Vtail v)) with (Vid _(S n) v).1 subgoalA : Setn : natv : vector A (S n)============================v = Vid A (S n) vapply Vid_eq.Def<strong>in</strong>ed.Both lemmas: zero_nil and decomp, can be used to derive easily adouble recursi<strong>on</strong> pr<strong>in</strong>ciple <strong>on</strong> vectors of same length:Def<strong>in</strong>iti<strong>on</strong> vector_double_rect :∀ (A:Set) (P: ∀ (n:nat),(vector A n)→(vector A n) → Type),P 0 Vnil Vnil →(∀ n (v1 v2 : vector A n) a b, P n v1 v2 →P (S n) (Vc<strong>on</strong>s a v1) (Vc<strong>on</strong>s b v2)) →∀ n (v1 v2 : vector A n), P n v1 v2.<strong>in</strong>ducti<strong>on</strong> n.<strong>in</strong>tros; rewrite (zero_nil _ v1); rewrite (zero_nil _ v2).auto.<strong>in</strong>tros v1 v2; rewrite (decomp _ _ v1);rewrite (decomp _ _ v2).apply X0; auto.Def<strong>in</strong>ed.Notice that, due to the c<strong>on</strong>versi<strong>on</strong> rule of <strong>Co</strong>q’s type system, this functi<strong>on</strong>can be used directly with Prop or Set <strong>in</strong>stead of type (thus it is useless tobuild from scratch vector_double_<strong>in</strong>d and vector_double_rec).We f<strong>in</strong>ish this example with show<strong>in</strong>g how to def<strong>in</strong>e the bitwise or <strong>on</strong>boolean vectors of the same length, and prov<strong>in</strong>g a little property about thisoperati<strong>on</strong>.Def<strong>in</strong>iti<strong>on</strong> bitwise_or n v1 v2 : vector bool n :=vector_double_rect bool(fun n v1 v2 ⇒ vector bool n)Vnil(fun n v1 v2 a b r ⇒ Vc<strong>on</strong>s (orb a b) r) n v1 v2.Let us def<strong>in</strong>e recursively the n-th element of a vector. Notice that it mustbe a partial functi<strong>on</strong>, <strong>in</strong> case n is greater or equal than the length of the vector.52


S<strong>in</strong>ce <strong>Co</strong>q <strong>on</strong>ly c<strong>on</strong>siders total functi<strong>on</strong>s, the functi<strong>on</strong> returns a value <strong>in</strong> anopti<strong>on</strong> type.Fixpo<strong>in</strong>t vector_nth (A:Set)(n:nat)(p:nat)(v:vector A p){struct v}: opti<strong>on</strong> A :=match n,v with_ , Vnil ⇒ N<strong>on</strong>e| 0 , Vc<strong>on</strong>s b _ _ ⇒ Some b| S n', Vc<strong>on</strong>s _ p' v' ⇒ vector_nth A n' p' v'end.Implicit Arguments vector_nth [A p].We can now prove — us<strong>in</strong>g the double <strong>in</strong>ducti<strong>on</strong> comb<strong>in</strong>ator — a simpleproperty rely<strong>in</strong>g vector_nth and bitwise_or:Lemma nth_bitwise : ∀ (n:nat) (v1 v2: vector bool n) i a b,vector_nth i v1 = Some a →vector_nth i v2 = Some b →vector_nth i (bitwise_or _ v1 v2) = Some (orb a b).Proof.<strong>in</strong>tros n v1 v2; pattern n,v1,v2.apply vector_double_rect.simpl.destruct i; discrim<strong>in</strong>ate 1.destruct i; simpl;auto.<strong>in</strong>jecti<strong>on</strong> 1; <strong>in</strong>jecti<strong>on</strong> 2;<strong>in</strong>tros; subst a; subst b; auto.Qed.7 <strong>Co</strong>-<strong>in</strong>ductive <strong>Types</strong> and N<strong>on</strong>-end<strong>in</strong>g C<strong>on</strong>structi<strong>on</strong>s<strong>The</strong> objects of an <strong>in</strong>ductive type are well-founded with respect to the c<strong>on</strong>structorsof the type. In other words, such objects are built by apply<strong>in</strong>g af<strong>in</strong>ite number of times the c<strong>on</strong>structors of the type. <strong>Co</strong>-<strong>in</strong>ductive types areobta<strong>in</strong>ed by relax<strong>in</strong>g this c<strong>on</strong>diti<strong>on</strong>, and may c<strong>on</strong>ta<strong>in</strong> n<strong>on</strong>-well-founded objects[9, 8]. An example of a co-<strong>in</strong>ductive type is the type of <strong>in</strong>f<strong>in</strong>ite sequencesformed with elements of type A, also called streams. This type canbe <strong>in</strong>troduced through the follow<strong>in</strong>g def<strong>in</strong>iti<strong>on</strong>:<strong>Co</strong><strong>Inductive</strong> Stream (A: Set) :Set :=| C<strong>on</strong>s : A→Stream A→Stream A.If we are <strong>in</strong>terested <strong>in</strong> f<strong>in</strong>ite or <strong>in</strong>f<strong>in</strong>ite sequences, we c<strong>on</strong>sider the type oflazy lists:53


<strong>Co</strong><strong>Inductive</strong> LList (A: Set) : Set :=| LNil : LList A| LC<strong>on</strong>s : A → LList A → LList A.It is also possible to def<strong>in</strong>e co-<strong>in</strong>ductive types for the trees with <strong>in</strong>f<strong>in</strong>itebranches (see Chapter 13 of [3]).Structural <strong>in</strong>ducti<strong>on</strong> is the way of express<strong>in</strong>g that <strong>in</strong>ductive types <strong>on</strong>lyc<strong>on</strong>ta<strong>in</strong> well-founded objects. Hence, this elim<strong>in</strong>ati<strong>on</strong> pr<strong>in</strong>ciple is not validfor co-<strong>in</strong>ductive types, and the <strong>on</strong>ly elim<strong>in</strong>ati<strong>on</strong> rule for streams is case analysis.This pr<strong>in</strong>ciple can be used, for example, to def<strong>in</strong>e the destructors headand tail.Def<strong>in</strong>iti<strong>on</strong> head (A:Set)(s : Stream A) :=match s with C<strong>on</strong>s a s' ⇒ a end.Def<strong>in</strong>iti<strong>on</strong> tail (A : Set)(s : Stream A) :=match s with C<strong>on</strong>s a s' ⇒ s' end.Inf<strong>in</strong>ite objects are def<strong>in</strong>ed by means of (n<strong>on</strong>-end<strong>in</strong>g) methods of c<strong>on</strong>structi<strong>on</strong>,like <strong>in</strong> lazy functi<strong>on</strong>al programm<strong>in</strong>g languages. Such methods canbe def<strong>in</strong>ed us<strong>in</strong>g the <strong>Co</strong>Fixpo<strong>in</strong>t command . For example, the follow<strong>in</strong>gdef<strong>in</strong>iti<strong>on</strong> <strong>in</strong>troduces the <strong>in</strong>f<strong>in</strong>ite list [a, a, a, . . .]:<strong>Co</strong>Fixpo<strong>in</strong>t repeat (A:Set)(a:A) : Stream A :=C<strong>on</strong>s a (repeat a).However, not any co-recursive def<strong>in</strong>iti<strong>on</strong> is an admissible method of c<strong>on</strong>structi<strong>on</strong>.Similarly to the case of structural <strong>in</strong>ducti<strong>on</strong>, the def<strong>in</strong>iti<strong>on</strong> mustverify a guardedness c<strong>on</strong>diti<strong>on</strong> to be accepted. This c<strong>on</strong>diti<strong>on</strong> states that anyrecursive call <strong>in</strong> the def<strong>in</strong>iti<strong>on</strong> must be protected –i.e, be an argument of–some c<strong>on</strong>structor, and <strong>on</strong>ly an argument of c<strong>on</strong>structors [7]. <strong>The</strong> follow<strong>in</strong>gdef<strong>in</strong>iti<strong>on</strong>s are examples of valid methods of c<strong>on</strong>structi<strong>on</strong>:<strong>Co</strong>Fixpo<strong>in</strong>t iterate (A: Set)(f: A → A)(a : A) : Stream A:=C<strong>on</strong>s a (iterate f (f a)).<strong>Co</strong>Fixpo<strong>in</strong>t map(A B:Set)(f: A → B)(s : Stream A) : Stream B:=match s with C<strong>on</strong>s a tl ⇒ C<strong>on</strong>s (f a) (map f tl) end.Exercise 7.1 Def<strong>in</strong>e two different methods for c<strong>on</strong>struct<strong>in</strong>g the stream which<strong>in</strong>f<strong>in</strong>itely alternates the values true and false.Exercise 7.2 Us<strong>in</strong>g the destructors head and tail, def<strong>in</strong>e a functi<strong>on</strong> whichtakes the n-th element of an <strong>in</strong>f<strong>in</strong>ite stream.54


A n<strong>on</strong>-end<strong>in</strong>g method of c<strong>on</strong>structi<strong>on</strong> is computed lazily. This means thatits def<strong>in</strong>iti<strong>on</strong> is unfolded <strong>on</strong>ly when the object that it <strong>in</strong>troduces is elim<strong>in</strong>ated,that is, when it appears as the argument of a case expressi<strong>on</strong>. We can checkthis us<strong>in</strong>g the command Eval.Eval simpl <strong>in</strong> (fun (A:Set)(a:A) ⇒ repeat a).= fun (A : Set) (a : A) ⇒ repeat a: ∀ A : Set, A → Stream AEval simpl <strong>in</strong> (fun (A:Set)(a:A) ⇒ head (repeat a)).= fun (A : Set) (a : A) ⇒ a: ∀ A : Set, A → A7.1 Extensi<strong>on</strong>al PropertiesCase analysis is also a valid proof pr<strong>in</strong>ciple for <strong>in</strong>f<strong>in</strong>ite objects. However, thispr<strong>in</strong>ciple is not sufficient to prove extensi<strong>on</strong>al properties, that is, propertiesc<strong>on</strong>cern<strong>in</strong>g the whole <strong>in</strong>f<strong>in</strong>ite object [8]. A typical example of an extensi<strong>on</strong>alproperty is the predicate express<strong>in</strong>g that two streams have the same elements.In many cases, the m<strong>in</strong>imal reflexive relati<strong>on</strong> a = b that is used as equality for<strong>in</strong>ductive types is too small to capture equality between streams. C<strong>on</strong>siderfor example the streams iterate f (f x) and (map f (iterate f x)).Even though these two streams have the same elements, no f<strong>in</strong>ite expansi<strong>on</strong>of their def<strong>in</strong>iti<strong>on</strong>s lead to equal terms. In other words, <strong>in</strong> order to deal withextensi<strong>on</strong>al properties, it is necessary to c<strong>on</strong>struct <strong>in</strong>f<strong>in</strong>ite proofs. <strong>The</strong> typeof <strong>in</strong>f<strong>in</strong>ite proofs of equality can be <strong>in</strong>troduced as a co-<strong>in</strong>ductive predicate,as follows:<strong>Co</strong><strong>Inductive</strong> EqSt (A: Set) : Stream A → Stream A → Prop :=eqst : ∀ s1 s2: Stream A,head s1 = head s2 →EqSt (tail s1) (tail s2) →EqSt s1 s2.It is possible to <strong>in</strong>troduce proof pr<strong>in</strong>ciples for reas<strong>on</strong><strong>in</strong>g about <strong>in</strong>f<strong>in</strong>iteobjects as comb<strong>in</strong>ators def<strong>in</strong>ed through <strong>Co</strong>Fixpo<strong>in</strong>t. However, oppositelyto the case of <strong>in</strong>ductive types, proof pr<strong>in</strong>ciples associated to co-<strong>in</strong>ductivetypes are not elim<strong>in</strong>ati<strong>on</strong> but <strong>in</strong>troducti<strong>on</strong> comb<strong>in</strong>ators. An example of sucha comb<strong>in</strong>ator is Park’s pr<strong>in</strong>ciple for prov<strong>in</strong>g the equality of two streams, usuallycalled the pr<strong>in</strong>ciple of co-<strong>in</strong>ducti<strong>on</strong>. It states that two streams are equalif they satisfy a bisimulati<strong>on</strong>. A bisimulati<strong>on</strong> is a b<strong>in</strong>ary relati<strong>on</strong> R such thatany pair of streams s 1 ad s 2 satisfy<strong>in</strong>g R have equal heads, and tails alsosatisfy<strong>in</strong>g R. This pr<strong>in</strong>ciple is <strong>in</strong> fact a method for c<strong>on</strong>struct<strong>in</strong>g an <strong>in</strong>f<strong>in</strong>iteproof:Secti<strong>on</strong> Parks_Pr<strong>in</strong>ciple.Variable A : Set.55


Variable R : Stream A → Stream A → Prop.Hypothesis bisim1 : ∀ s1 s2:Stream A, R s1 s2 →head s1 = head s2.Hypothesisbisim2 : ∀ s1 s2:Stream A, R s1 s2 →R (tail s1) (tail s2).<strong>Co</strong>Fixpo<strong>in</strong>t park_ppl :∀ s1 s2:Stream A, R s1 s2 → EqSt s1 s2 :=fun s1 s2 (p : R s1 s2) ⇒eqst s1 s2 (bisim1 s1 s2 p)(park_ppl (tail s1) (tail s2) (bisim2 s1 s2 p)).End Parks_Pr<strong>in</strong>ciple.Let us use the pr<strong>in</strong>ciple of co-<strong>in</strong>ducti<strong>on</strong> to prove the extensi<strong>on</strong>al equalitymenti<strong>on</strong>ed above.<strong>The</strong>orem map_iterate : ∀ (a:Set)(f:A→A)(x:A),EqSt (iterate f (f x)) (map f (iterate f x)).Proof.<strong>in</strong>tros A f x.apply park_ppl with(R:= fun s1 s2 ⇒∃ x: A, s1 = iterate f (f x) ∧s2 = map f (iterate f x)).<strong>in</strong>tros s1 s2 (x0,(eqs1,eqs2));rewrite eqs1;rewrite eqs2;reflexivity.<strong>in</strong>tros s1 s2 (x0,(eqs1,eqs2)).exists (f x0);split;[rewrite eqs1|rewrite eqs2]; reflexivity.exists x;split; reflexivity.Qed.<strong>The</strong> use of Park’s pr<strong>in</strong>ciple is sometimes annoy<strong>in</strong>g, because it requiresto f<strong>in</strong>d an <strong>in</strong>variant relati<strong>on</strong> and prove that it is <strong>in</strong>deed a bisimulati<strong>on</strong>. Inmany cases, a shorter proof can be obta<strong>in</strong>ed try<strong>in</strong>g to c<strong>on</strong>struct an ad-hoc<strong>in</strong>f<strong>in</strong>ite proof, def<strong>in</strong>ed by a guarded declarati<strong>on</strong>. <strong>The</strong> tactic “ “<strong>Co</strong>fix f ” canbe used to do that. Similarly to the tactic fix <strong>in</strong>dicated <strong>in</strong> Secti<strong>on</strong> 5.3, thistactic <strong>in</strong>troduces an extra hypothesis f <strong>in</strong>to the c<strong>on</strong>text, whose type is thesame as the current goal. Note that the applicati<strong>on</strong>s of f <strong>in</strong> the proof must beguarded. In order to prevent us from do<strong>in</strong>g unguarded calls, we can def<strong>in</strong>e atactic that always apply a c<strong>on</strong>structor before us<strong>in</strong>g f :Ltac <strong>in</strong>f<strong>in</strong>iteproof f :=cofix f; c<strong>on</strong>structor; [clear f| simpl; try (apply f; clear f)].In the example above, this tactic produces a much simpler proof that theformer <strong>on</strong>e:56


<strong>The</strong>orem map_iterate' : ∀ ((A:Set)f:A→A)(x:A),EqSt (iterate f (f x)) (map f (iterate f x)).Proof.<strong>in</strong>f<strong>in</strong>iteproof map_iterate'.reflexivity.Qed.Exercise 7.3 Def<strong>in</strong>e a co-<strong>in</strong>ductive type Nat c<strong>on</strong>ta<strong>in</strong><strong>in</strong>g n<strong>on</strong>-standard naturalnumbers –this is, verify<strong>in</strong>g.∃m ∈ Nat, ∀ n ∈ Nat, n < mExercise 7.4 Prove that the extensi<strong>on</strong>al equality of streams is an equivalencerelati<strong>on</strong> us<strong>in</strong>g Park’s co-<strong>in</strong>ducti<strong>on</strong> pr<strong>in</strong>ciple.Exercise 7.5 Provide a suitable def<strong>in</strong>iti<strong>on</strong> of “be<strong>in</strong>g an ordered list” for <strong>in</strong>f<strong>in</strong>itelists and def<strong>in</strong>e a pr<strong>in</strong>ciple for prov<strong>in</strong>g that an <strong>in</strong>f<strong>in</strong>ite list is ordered.Apply this method to the list [0, 1, . . .]. <strong>Co</strong>mpare the result with exercise 5.2.7.2 About <strong>in</strong>jecti<strong>on</strong>, discrim<strong>in</strong>ate, and <strong>in</strong>versi<strong>on</strong>S<strong>in</strong>ce co-<strong>in</strong>ductive types are closed w.r.t. their c<strong>on</strong>structors, the techniquesshown <strong>in</strong> Secti<strong>on</strong> 4 work also with these types.Let us c<strong>on</strong>sider the type of lazy lists, <strong>in</strong>troduced <strong>on</strong> page 53. <strong>The</strong> follow<strong>in</strong>glemmas are straightforward applicati<strong>on</strong>s of discrim<strong>in</strong>ate and <strong>in</strong>jecti<strong>on</strong>:Lemma Lnil_not_Lc<strong>on</strong>s : ∀ (A:Set)(a:A)(l:LList A),LNil ≠ (LC<strong>on</strong>s a l).Proof.<strong>in</strong>tros;discrim<strong>in</strong>ate.Qed.Lemma <strong>in</strong>jecti<strong>on</strong>_demo : ∀ (A:Set)(a b : A)(l l': LList A),LC<strong>on</strong>s a (LC<strong>on</strong>s b l) = LC<strong>on</strong>s b (LC<strong>on</strong>s a l') →a = b ∧ l = l'.Proof.<strong>in</strong>tros A a b l l' e; <strong>in</strong>jecti<strong>on</strong> e; auto.Qed.In order to show <strong>in</strong>versi<strong>on</strong> at work, let us def<strong>in</strong>e two predicates <strong>on</strong> lazylists:57


<strong>Inductive</strong> F<strong>in</strong>ite (A:Set) : LList A → Prop :=| Lnil_f<strong>in</strong> : F<strong>in</strong>ite (LNil (A:=A))| Lc<strong>on</strong>s_f<strong>in</strong> : ∀ a l, F<strong>in</strong>ite l → F<strong>in</strong>ite (LC<strong>on</strong>s a l).<strong>Co</strong><strong>Inductive</strong> Inf<strong>in</strong>ite (A:Set) : LList A → Prop :=| LC<strong>on</strong>s_<strong>in</strong>f : ∀ a l, Inf<strong>in</strong>ite l → Inf<strong>in</strong>ite (LC<strong>on</strong>s a l).First, two easy theorems:Lemma LNil_not_Inf<strong>in</strong>ite : ∀ (A:Set), ~ Inf<strong>in</strong>ite (LNil (A:=A)).Proof.<strong>in</strong>tros A H;<strong>in</strong>versi<strong>on</strong> H.Qed.Lemma F<strong>in</strong>ite_not_Inf<strong>in</strong>ite : ∀ (A:Set)(l:LList A),F<strong>in</strong>ite l → ~ Inf<strong>in</strong>ite l.Proof.<strong>in</strong>tros A l H; elim H.apply LNil_not_Inf<strong>in</strong>ite.<strong>in</strong>tros a l0 F0 I0' I1.case I0'; <strong>in</strong>versi<strong>on</strong>_clear I1.trivial.Qed.On the other hand, the next proof uses the cofix tactic. Notice the destructurati<strong>on</strong>of l, which allows us to apply the c<strong>on</strong>structor LC<strong>on</strong>s_<strong>in</strong>f, thussatisfy<strong>in</strong>g the guard c<strong>on</strong>diti<strong>on</strong>:Lemma Not_F<strong>in</strong>ite_Inf<strong>in</strong>ite : ∀ (A:Set)(l:LList A),~ F<strong>in</strong>ite l → Inf<strong>in</strong>ite l.Proof.cofix H.destruct l.<strong>in</strong>tro; absurd (F<strong>in</strong>ite (LNil (A:=A)));[auto|c<strong>on</strong>structor].1 subgoalH : forall (A : Set) (l : LList A), ~ F<strong>in</strong>ite l -> Inf<strong>in</strong>ite lA : Seta : Al : LList AH0 : ~ F<strong>in</strong>ite (LC<strong>on</strong>s a l)============================Inf<strong>in</strong>ite lAt this po<strong>in</strong>t, <strong>on</strong>e must not apply H! . It would be possible to solve thecurrent goal by an <strong>in</strong>versi<strong>on</strong> of “ F<strong>in</strong>ite (LC<strong>on</strong>s a l) ”, but, s<strong>in</strong>ce the58


guard c<strong>on</strong>diti<strong>on</strong> would be violated, the user would get an error message aftertype<strong>in</strong>g Qed. In order to satisfy the guard c<strong>on</strong>diti<strong>on</strong>, we apply the c<strong>on</strong>structorof Inf<strong>in</strong>ite, then apply H.c<strong>on</strong>structor.apply H.red; <strong>in</strong>tro H1;case H0.c<strong>on</strong>structor.trivial.Qed.<strong>The</strong> reader is <strong>in</strong>vited to replay this proof and understand each of its steps.References[1] B. Barras. A formalisati<strong>on</strong> of Burali-Forti’s paradox <strong>in</strong> coq. Distributedwith<strong>in</strong> the bunch of c<strong>on</strong>tributi<strong>on</strong> to the <strong>Co</strong>q system, March1998. http://pauillac.<strong>in</strong>ria.fr/coq.[2] Y. Bertot and P. Castéran. <strong>Co</strong>q’Art: examples and exercises. http://www.labri.fr/Perso/~casteran/<strong>Co</strong>qArt.[3] Y. Bertot and P. Castéran. Interactive <strong>The</strong>orem Prov<strong>in</strong>g and ProgramDevelopment. <strong>Co</strong>q’Art: <strong>The</strong> Calculus of <strong>Inductive</strong> C<strong>on</strong>structi<strong>on</strong>s. Texts<strong>in</strong> <strong>The</strong>oretical <strong>Co</strong>mputer Science. An EATCS series. Spr<strong>in</strong>ger Verlag,2004.[4] T. <strong>Co</strong>quand. An Analysis of Girard’s Paradox. In Symposium <strong>on</strong> Logic<strong>in</strong> <strong>Co</strong>mputer Science, Cambridge, MA, 1986. IEEE <strong>Co</strong>mputer SocietyPress.[5] T. <strong>Co</strong>quand. Metamathematical <strong>in</strong>vestigati<strong>on</strong>s <strong>on</strong> a calculus of c<strong>on</strong>structi<strong>on</strong>s.In P. Odifreddi, editor, Logic and <strong>Co</strong>mputer Science. AcademicPress, 1990.[6] Development team. <strong>The</strong> <strong>Co</strong>q proof assistant. Documentati<strong>on</strong>, systemdownload. C<strong>on</strong>tact: http://coq.<strong>in</strong>ria.fr/.[7] E. Giménez. <strong>Co</strong>dify<strong>in</strong>g guarded def<strong>in</strong>iti<strong>on</strong>s with recursive schemes. InWorkshop <strong>on</strong> <strong>Types</strong> for Proofs and Programs, number 996 <strong>in</strong> LNCS,pages 39–59. Spr<strong>in</strong>ger-Verlag, 1994.[8] E. Giménez. An applicati<strong>on</strong> of co-<strong>in</strong>ductive types <strong>in</strong> coq: verificati<strong>on</strong> ofthe alternat<strong>in</strong>g bit protocol. In Workshop <strong>on</strong> <strong>Types</strong> for Proofs and Programs,number 1158 <strong>in</strong> LNCS, pages 135–152. Spr<strong>in</strong>ger-Verlag, 1995.[9] E. Giménez. A Calculus of Inf<strong>in</strong>ite C<strong>on</strong>structi<strong>on</strong>s and its applicati<strong>on</strong> tothe verificati<strong>on</strong> of communicat<strong>in</strong>g systems. PhD thesis, Ecole NormaleSupérieure de Ly<strong>on</strong>, 1996.[10] C. McBride. Elim<strong>in</strong>ati<strong>on</strong> with a motive. In <strong>Types</strong> for Proofs and Programs’2000,volume 2277, pages 197–217, 2002.59


[11] C. D. Team. <strong>The</strong> <strong>Co</strong>q reference manual. LogiCal <strong>Project</strong>,http://coq.<strong>in</strong>ria.fr/.60

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!