comparison src/InductiveTypes.v @ 28:0543bbd62843

nat
author Adam Chlipala <adamc@hcoop.net>
date Mon, 08 Sep 2008 15:02:18 -0400
parents 8788249c7d3a
children add8215ec72a
comparison
equal deleted inserted replaced
27:8788249c7d3a 28:0543bbd62843
169 Check bool_ind. 169 Check bool_ind.
170 (** [[ 170 (** [[
171 171
172 bool_ind : forall P : bool -> Prop, P true -> P false -> forall b : bool, P b 172 bool_ind : forall P : bool -> Prop, P true -> P false -> forall b : bool, P b
173 ]] *) 173 ]] *)
174
175
176 (** * Simple Recursive Types *)
177
178 (** The natural numbers are the simplest common example of an inductive type that actually deserves the name. *)
179
180 Inductive nat : Set :=
181 | O : nat
182 | S : nat -> nat.
183
184 (** [O] is zero, and [S] is the successor function, so that [0] is syntactic sugar for [O], [1] for [S O], [2] for [S (S O)], and so on.
185
186 Pattern matching works as we demonstrated in the last chapter: *)
187
188 Definition isZero (n : nat) : bool :=
189 match n with
190 | O => true
191 | S _ => false
192 end.
193
194 Definition pred (n : nat) : nat :=
195 match n with
196 | O => O
197 | S n' => n'
198 end.
199
200 (** We can prove theorems by case analysis: *)
201
202 Theorem S_isZero : forall n : nat, isZero (pred (S (S n))) = false.
203 destruct n; reflexivity.
204 Qed.
205
206 (** We can also now get into genuine inductive theorems. First, we will need a recursive function, to make things interesting. *)
207
208 Fixpoint plus (n m : nat) {struct n} : nat :=
209 match n with
210 | O => m
211 | S n' => S (plus n' m)
212 end.
213
214 (** Recall that [Fixpoint] is Coq's mechanism for recursive function definitions, and that the [{struct n}] annotation is noting which function argument decreases structurally at recursive calls.
215
216 Some theorems about [plus] can be proved without induction. *)
217
218 Theorem O_plus_n : forall n : nat, plus O n = n.
219 intro; reflexivity.
220 Qed.
221
222 (** Coq's computation rules automatically simplify the application of [plus]. If we just reverse the order of the arguments, though, this no longer works, and we need induction. *)
223
224 Theorem n_plus_O : forall n : nat, plus n O = n.
225 induction n.
226
227 (** Our first subgoal is [plus O O = O], which %\textit{%#<i>#is#</i>#%}% trivial by computation. *)
228
229 reflexivity.
230
231 (** Our second subgoal is more work and also demonstrates our first inductive hypothesis.
232
233 [[
234
235 n : nat
236 IHn : plus n O = n
237 ============================
238 plus (S n) O = S n
239 ]]
240
241 We can start out by using computation to simplify the goal as far as we can. *)
242
243 simpl.
244
245 (** Now the conclusion is [S (plus n O) = S n]. Using our inductive hypothesis: *)
246
247 rewrite IHn.
248
249 (** ...we get a trivial conclusion [S n = S n]. *)
250
251 reflexivity.
252
253 (** Not much really went on in this proof, so the [crush] tactic from the [Tactics] module can prove this theorem automatically. *)
254
255 Restart.
256 induction n; crush.
257 Qed.
258
259 (** We can check out the induction principle at work here: *)
260
261 Check nat_ind.
262 (** [[
263
264 nat_ind : forall P : nat -> Prop,
265 P O -> (forall n : nat, P n -> P (S n)) -> forall n : nat, P n
266 ]]
267
268 Each of the two cases of our last proof came from the type of one of the arguments to [nat_ind]. We chose [P] to be [(fun n : nat => plus n O = n)]. The first proof case corresponded to [P O], and the second case to [(forall n : nat, P n -> P (S n))]. The free variable [n] and inductive hypothesis [IHn] came from the argument types given here.
269
270 Since [nat] has a constructor that takes an argument, we may sometimes need to know that that constructor is injective. *)
271
272 Theorem S_inj : forall n m : nat, S n = S m -> n = m.
273 injection 1; trivial.
274 Qed.
275
276 (** [injection] refers to a premise by number, adding new equalities between the corresponding arguments of equated terms that are formed with the same constructor. We end up needing to prove [n = m -> n = m], so it is unsurprising that a tactic named [trivial] is able to finish the proof.
277
278 There is also a very useful tactic called [congruence] that can prove this theorem immediately. [congruence] generalizes [discriminate] and [injection], and it also adds reasoning about the general properties of equality, such as that a function returns equal results on equal arguments. That is, [congruence] is a %\textit{%#<i>#complete decision procedure for the theory of equality and uninterpreted functions#</i>#%}%, plus some smarts about inductive types. *)