Mercurial > cpdt > repo
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. *) |