comparison src/InductiveTypes.v @ 30:4887ddb1ad23

Parameterized inductives
author Adam Chlipala <adamc@hcoop.net>
date Mon, 08 Sep 2008 15:38:34 -0400
parents add8215ec72a
children 1a82839f83b7
comparison
equal deleted inserted replaced
29:add8215ec72a 30:4887ddb1ad23
355 P NLeaf -> 355 P NLeaf ->
356 (forall n : nat_btree, 356 (forall n : nat_btree,
357 P n -> forall (n0 : nat) (n1 : nat_btree), P n1 -> P (NNode n n0 n1)) -> 357 P n -> forall (n0 : nat) (n1 : nat_btree), P n1 -> P (NNode n n0 n1)) ->
358 forall n : nat_btree, P n 358 forall n : nat_btree, P n
359 ]] *) 359 ]] *)
360
361
362 (** * Parameterized Types *)
363
364 (** We can also define polymorphic inductive types, as with algebraic datatypes in Haskell and ML. *)
365
366 Inductive list (T : Set) : Set :=
367 | Nil : list T
368 | Cons : T -> list T -> list T.
369
370 Fixpoint length T (ls : list T) : nat :=
371 match ls with
372 | Nil => O
373 | Cons _ ls' => S (length ls')
374 end.
375
376 Fixpoint app T (ls1 ls2 : list T) {struct ls1} : list T :=
377 match ls1 with
378 | Nil => ls2
379 | Cons x ls1' => Cons x (app ls1' ls2)
380 end.
381
382 Theorem length_app : forall T (ls1 ls2 : list T), length (app ls1 ls2)
383 = plus (length ls1) (length ls2).
384 induction ls1; crush.
385 Qed.
386
387 (** There is a useful shorthand for writing many definitions that share the same parameter, based on Coq's %\textit{%#<i>#section#</i>#%}% mechanism. The following block of code is equivalent to the above: *)
388
389 (* begin hide *)
390 Reset list.
391 (* end hide *)
392
393 Section list.
394 Variable T : Set.
395
396 Inductive list : Set :=
397 | Nil : list
398 | Cons : T -> list -> list.
399
400 Fixpoint length (ls : list) : nat :=
401 match ls with
402 | Nil => O
403 | Cons _ ls' => S (length ls')
404 end.
405
406 Fixpoint app (ls1 ls2 : list) {struct ls1} : list :=
407 match ls1 with
408 | Nil => ls2
409 | Cons x ls1' => Cons x (app ls1' ls2)
410 end.
411
412 Theorem length_app : forall ls1 ls2 : list, length (app ls1 ls2)
413 = plus (length ls1) (length ls2).
414 induction ls1; crush.
415 Qed.
416 End list.
417
418 (** After we end the section, the [Variable]s we used are added as extra function parameters for each defined identifier, as needed. *)
419
420 Check list.
421 (** [[
422
423 list
424 : Set -> Set
425 ]] *)
426
427 Check Cons.
428 (** [[
429
430 Cons
431 : forall T : Set, T -> list T -> list T
432 ]] *)
433
434 Check length.
435 (** [[
436
437 length
438 : forall T : Set, list T -> nat
439 ]]
440
441 The extra parameter [T] is treated as a new argument to the induction principle, too. *)
442
443 Check list_ind.
444 (** [[
445
446 list_ind
447 : forall (T : Set) (P : list T -> Prop),
448 P (Nil T) ->
449 (forall (t : T) (l : list T), P l -> P (Cons t l)) ->
450 forall l : list T, P l
451 ]]
452
453 Thus, even though we just saw that [T] is added as an extra argument to the constructor [Cons], there is no quantifier for [T] in the type of the inductive case like there is for each of the other arguments. *)