comparison src/InductiveTypes.v @ 38:95e24b629ad9

Exercises
author Adam Chlipala <adamc@hcoop.net>
date Fri, 12 Sep 2008 16:55:37 -0400
parents c9ade53b27aa
children fd18331e5c0b
comparison
equal deleted inserted replaced
37:c9ade53b27aa 38:95e24b629ad9
731 Section nat_ind'. 731 Section nat_ind'.
732 (** First, we have the property of natural numbers that we aim to prove. *) 732 (** First, we have the property of natural numbers that we aim to prove. *)
733 Variable P : nat -> Prop. 733 Variable P : nat -> Prop.
734 734
735 (** Then we require a proof of the [O] case. *) 735 (** Then we require a proof of the [O] case. *)
736 Variable O_case : P O. 736 Hypothesis O_case : P O.
737 737
738 (** Next is a proof of the [S] case, which may assume an inductive hypothesis. *) 738 (** Next is a proof of the [S] case, which may assume an inductive hypothesis. *)
739 Variable S_case : forall n : nat, P n -> P (S n). 739 Hypothesis S_case : forall n : nat, P n -> P (S n).
740 740
741 (** Finally, we define a recursive function to tie the pieces together. *) 741 (** Finally, we define a recursive function to tie the pieces together. *)
742 Fixpoint nat_ind' (n : nat) : P n := 742 Fixpoint nat_ind' (n : nat) : P n :=
743 match n return (P n) with 743 match n return (P n) with
744 | O => O_case 744 | O => O_case
745 | S n' => S_case (nat_ind' n') 745 | S n' => S_case (nat_ind' n')
746 end. 746 end.
747 End nat_ind'. 747 End nat_ind'.
748 748
749 (** Closing the section adds the [Variable]s as new [fun]-bound arguments to [nat_ind'], and, modulo the use of [Prop] instead of [Type], we end up with the exact same definition that was generated automatically for [nat_rect]. 749 (** Closing the section adds the [Variable]s and [Hypothesis]es as new [fun]-bound arguments to [nat_ind'], and, modulo the use of [Prop] instead of [Type], we end up with the exact same definition that was generated automatically for [nat_rect].
750 750
751 %\medskip% 751 %\medskip%
752 752
753 We can also examine the definition of [even_list_mut], which we generated with [Scheme] for a mutually-recursive type. *) 753 We can also examine the definition of [even_list_mut], which we generated with [Scheme] for a mutually-recursive type. *)
754 754
782 (** First, we need the properties that we are proving. *) 782 (** First, we need the properties that we are proving. *)
783 Variable Peven : even_list -> Prop. 783 Variable Peven : even_list -> Prop.
784 Variable Podd : odd_list -> Prop. 784 Variable Podd : odd_list -> Prop.
785 785
786 (** Next, we need proofs of the three cases. *) 786 (** Next, we need proofs of the three cases. *)
787 Variable ENil_case : Peven ENil. 787 Hypothesis ENil_case : Peven ENil.
788 Variable ECons_case : forall (n : nat) (o : odd_list), Podd o -> Peven (ECons n o). 788 Hypothesis ECons_case : forall (n : nat) (o : odd_list), Podd o -> Peven (ECons n o).
789 Variable OCons_case : forall (n : nat) (e : even_list), Peven e -> Podd (OCons n e). 789 Hypothesis OCons_case : forall (n : nat) (e : even_list), Peven e -> Podd (OCons n e).
790 790
791 (** Finally, we define the recursive functions. *) 791 (** Finally, we define the recursive functions. *)
792 Fixpoint even_list_mut' (e : even_list) : Peven e := 792 Fixpoint even_list_mut' (e : even_list) : Peven e :=
793 match e return (Peven e) with 793 match e return (Peven e) with
794 | ENil => ENil_case 794 | ENil => ENil_case
802 802
803 (** Even induction principles for reflexive types are easy to implement directly. For our [formula] type, we can use a recursive definition much like those we wrote above. *) 803 (** Even induction principles for reflexive types are easy to implement directly. For our [formula] type, we can use a recursive definition much like those we wrote above. *)
804 804
805 Section formula_ind'. 805 Section formula_ind'.
806 Variable P : formula -> Prop. 806 Variable P : formula -> Prop.
807 Variable Eq_case : forall n1 n2 : nat, P (Eq n1 n2). 807 Hypothesis Eq_case : forall n1 n2 : nat, P (Eq n1 n2).
808 Variable And_case : forall f1 f2 : formula, 808 Hypothesis And_case : forall f1 f2 : formula,
809 P f1 -> P f2 -> P (And f1 f2). 809 P f1 -> P f2 -> P (And f1 f2).
810 Variable Forall_case : forall f : nat -> formula, 810 Hypothesis Forall_case : forall f : nat -> formula,
811 (forall n : nat, P (f n)) -> P (Forall f). 811 (forall n : nat, P (f n)) -> P (Forall f).
812 812
813 Fixpoint formula_ind' (f : formula) : P f := 813 Fixpoint formula_ind' (f : formula) : P f :=
814 match f return (P f) with 814 match f return (P f) with
815 | Eq n1 n2 => Eq_case n1 n2 815 | Eq n1 n2 => Eq_case n1 n2
892 Now we create a section for our induction principle, following the same basic plan as in the last section of this chapter. *) 892 Now we create a section for our induction principle, following the same basic plan as in the last section of this chapter. *)
893 893
894 Section nat_tree_ind'. 894 Section nat_tree_ind'.
895 Variable P : nat_tree -> Prop. 895 Variable P : nat_tree -> Prop.
896 896
897 Variable NLeaf'_case : P NLeaf'. 897 Hypothesis NLeaf'_case : P NLeaf'.
898 Variable NNode'_case : forall (n : nat) (ls : list nat_tree), 898 Hypothesis NNode'_case : forall (n : nat) (ls : list nat_tree),
899 All P ls -> P (NNode' n ls). 899 All P ls -> P (NNode' n ls).
900 900
901 (** A first attempt at writing the induction principle itself follows the intuition that nested inductive type definitions are expanded into mutual inductive definitions. 901 (** A first attempt at writing the induction principle itself follows the intuition that nested inductive type definitions are expanded into mutual inductive definitions.
902 902
903 [[ 903 [[
1096 1096
1097 (** %\begin{enumerate}%#<ol># 1097 (** %\begin{enumerate}%#<ol>#
1098 1098
1099 %\item%#<li># Define an inductive type [truth] with three constructors, [Yes], [No], and [Maybe]. [Yes] stands for certain truth, [False] for certain falsehood, and [Maybe] for an unknown situation. Define "not," "and," and "or" for this replacement boolean algebra. Prove that your implementation of "and" is commutative and distributes over your implementation of "or."#</li># 1099 %\item%#<li># Define an inductive type [truth] with three constructors, [Yes], [No], and [Maybe]. [Yes] stands for certain truth, [False] for certain falsehood, and [Maybe] for an unknown situation. Define "not," "and," and "or" for this replacement boolean algebra. Prove that your implementation of "and" is commutative and distributes over your implementation of "or."#</li>#
1100 1100
1101 %\item%#<li># Modify the first example language of Chapter 1 to include variables, where variables are represented with [nat]. Extend the syntax and semantics of expressions to accommodate the change. Your new [expDenote] function should take as a new extra first argument a value of type [var -> nat], where [var] is a synonym for naturals-as-variables, and the function assigns a value to each variable. Define a constant folding function which does a bottom-up pass over an expression, at each stage replacing every binary operation on constants with an equivalent constant. Prove that constant folding preserves the meaning of expressions.#</li># 1101 %\item%#<li># Modify the first example language of Chapter 1 to include variables, where variables are represented with [nat]. Extend the syntax and semantics of expressions to accommodate the change. Your new [expDenote] function should take as a new extra first argument a value of type [var -> nat], where [var] is a synonym for naturals-as-variables, and the function assigns a value to each variable. Define a constant folding function which does a bottom-up pass over an expression, at each stage replacing every binary operation on constants with an equivalent constant. Prove that constant folding preserves the meanings of expressions.#</li>#
1102
1103 %\item%#<li># Reimplement the second example language of Chapter 1 to use mutually-inductive types instead of dependent types. That is, define two separate (non-dependent) inductive types [nat_exp] and [bool_exp] for expressions of the two different types, rather than a single indexed type. To keep things simple, you may consider only the binary operators that take naturals as operands. Add natural number variables to the language, as in the last exercise, and add an "if" expression form taking as arguments one boolean expression and two natural number expressions. Define semantics and constant-folding functions for this new language. Your constant folding should simplify not just binary operations (returning naturals or booleans) with known arguments, but also "if" expressions with known values for their test expressions but possibly undetermined "then" and "else" cases. Prove that constant-folding a natural number expression preserves its meaning.#</li>#
1104
1105 %\item%#<li># Using a reflexive inductive definition, define a type [nat_tree] of infinitary trees, with natural numbers at their leaves and a countable infinity of new trees branching out of each internal node. Define a function [increment] that increments the number in every leaf of a [nat_tree]. Define a function [leapfrog] over a natural [i] and a tree [nt]. [leapfrog] should recurse into the [i]th child of [nt], the [i+1]st child of that node, the [i+2]nd child of the next node, and so on, until reaching a leaf, in which case [leapfrog] should return the number at that leaf. Prove that the result of any call to [leapfrog] is incremented by one by calling [increment] on the tree.#</li>#
1106
1107 %\item%#<li># Define a type of trees of trees of trees of (repeat to infinity). That is, define an inductive type [trexp], whose members are either base cases containing natural numbers or binary trees of [trexp]s. Base your definition on a parameterized binary tree type [btree] that you will also define, so that [trexp] is defined as a nested inductive type. Define a function [total] that sums all of the naturals at the leaves of a [trexp]. Define a function [increment] that increments every leaf of a [trexp] by one. Prove that, for all [tr], [total (increment tr) >= total tr]. On the way to finishing this proof, you will probably want to prove a lemma and add it as a hint using the syntax [Hint Resolve name_of_lemma.].#</li>#
1108
1109 %\item%#<li># Prove discrimination and injectivity theorems for the [nat_btree] type defined earlier in this chapter. In particular, without using the tactics [discriminate], [injection], or [congruence], prove that no leaf equals any node, and prove that two equal nodes carry the same natural number.#</li>#
1102 1110
1103 #</ol>#%\end{enumerate}% *) 1111 #</ol>#%\end{enumerate}% *)