comparison src/Large.v @ 462:d7a73ab1df7b

Proofreading pass through Chapter 16
author Adam Chlipala <adam@chlipala.net>
date Wed, 29 Aug 2012 16:33:59 -0400
parents 980962258b49
children 1fd4109f7b31
comparison
equal deleted inserted replaced
461:b6c47e6d43dc 462:d7a73ab1df7b
154 induction e as [ | ? IHe1 ? IHe2 ]; [ 154 induction e as [ | ? IHe1 ? IHe2 ]; [
155 trivial 155 trivial
156 | simpl; rewrite IHe1; rewrite IHe2; rewrite mult_plus_distr_l; trivial ]. 156 | simpl; rewrite IHe1; rewrite IHe2; rewrite mult_plus_distr_l; trivial ].
157 Qed. 157 Qed.
158 158
159 (** We use the form of the semicolon operator that allows a different tactic to be specified for each generated subgoal. This is an improvement in robustness of the script. We no longer need to worry about tactics from one case being applied to a different case. Still, the proof script is not especially readable. Probably most readers would not find it helpful in explaining why the theorem is true. 159 (** We use the form of the semicolon operator that allows a different tactic to be specified for each generated subgoal. This is an improvement in robustness of the script. We no longer need to worry about tactics from one case being applied to a different case. Still, the proof script is not especially readable. Probably most readers would not find it helpful in explaining why the theorem is true. The same could be said for scripts which use the%\index{bullets}% _bullets_ or curly braces provided by Coq 8.4, which allow code like the above to be stepped through interactively, with periods in place of the semicolons, while representing proof structure in a way that is enforced by Coq. Interactive replay of scripts becomes easier, but readability is not really helped.
160 160
161 The situation gets worse in considering extensions to the theorem we want to prove. Let us add multiplication nodes to our [exp] type and see how the proof fares. *) 161 The situation gets worse in considering extensions to the theorem we want to prove. Let us add multiplication nodes to our [exp] type and see how the proof fares. *)
162 162
163 Reset exp. 163 Reset exp.
164 164
639 The %\index{tactics!abstract}%[abstract] tactical helps us force thunks by proving some subgoals as their own lemmas. For instance, a proof [induction x; crush] can in many cases be made to use significantly less peak memory by changing it to [induction x; abstract crush]. The main limitation of [abstract] is that it can only be applied to subgoals that are proved completely, with no undetermined unification variables in their initial states. Still, many large automated proofs can realize vast memory savings via [abstract]. *) 639 The %\index{tactics!abstract}%[abstract] tactical helps us force thunks by proving some subgoals as their own lemmas. For instance, a proof [induction x; crush] can in many cases be made to use significantly less peak memory by changing it to [induction x; abstract crush]. The main limitation of [abstract] is that it can only be applied to subgoals that are proved completely, with no undetermined unification variables in their initial states. Still, many large automated proofs can realize vast memory savings via [abstract]. *)
640 640
641 641
642 (** * Modules *) 642 (** * Modules *)
643 643
644 (** Last chapter's examples of proof by reflection demonstrate opportunities for implementing abstract proof strategies with stronger formal guarantees than can be had with Ltac scripting. Coq's _module system_ provides another tool for more rigorous development of generic theorems. This feature is inspired by the module systems found in Standard ML%~\cite{modules}% and Objective Caml, and the discussion that follows assumes familiarity with the basics of one of those systems. 644 (** Last chapter's examples of proof by reflection demonstrate opportunities for implementing abstract proof strategies with stronger formal guarantees than can be had with Ltac scripting. Coq's _module system_ provides another tool for more rigorous development of generic theorems. This feature is inspired by the module systems found in Standard ML%~\cite{modules}% and OCaml, and the discussion that follows assumes familiarity with the basics of one of those systems.
645 645
646 ML modules facilitate the grouping of %\index{abstract type}%abstract types with operations over those types. Moreover, there is support for%\index{functor}% _functors_, which are functions from modules to modules. A canonical example of a functor is one that builds a data structure implementation from a module that describes a domain of keys and its associated comparison operations. 646 ML modules facilitate the grouping of %\index{abstract type}%abstract types with operations over those types. Moreover, there is support for%\index{functor}% _functors_, which are functions from modules to modules. A canonical example of a functor is one that builds a data structure implementation from a module that describes a domain of keys and its associated comparison operations.
647 647
648 When we add modules to a base language with dependent types, it becomes possible to use modules and functors to formalize kinds of reasoning that are common in algebra. For instance, this module signature captures the essence of the algebraic structure known as a group. A group consists of a carrier set [G], an associative binary operation [f], a left identity element [e] for [f], and an operation [i] that is a left inverse for [f].%\index{Vernacular commands!Module Type}% *) 648 When we add modules to a base language with dependent types, it becomes possible to use modules and functors to formalize kinds of reasoning that are common in algebra. For instance, the following module signature captures the essence of the algebraic structure known as a group. A group consists of a carrier set [G], an associative binary operation [f], a left identity element [id] for [f], and an operation [i] that is a left inverse for [f].%\index{Vernacular commands!Module Type}% *)
649 649
650 Module Type GROUP. 650 Module Type GROUP.
651 Parameter G : Set. 651 Parameter G : Set.
652 Parameter f : G -> G -> G. 652 Parameter f : G -> G -> G.
653 Parameter e : G. 653 Parameter id : G.
654 Parameter i : G -> G. 654 Parameter i : G -> G.
655 655
656 Axiom assoc : forall a b c, f (f a b) c = f a (f b c). 656 Axiom assoc : forall a b c, f (f a b) c = f a (f b c).
657 Axiom ident : forall a, f e a = a. 657 Axiom ident : forall a, f id a = a.
658 Axiom inverse : forall a, f (i a) a = e. 658 Axiom inverse : forall a, f (i a) a = id.
659 End GROUP. 659 End GROUP.
660 660
661 (** Many useful theorems hold of arbitrary groups. We capture some such theorem statements in another module signature.%\index{Vernacular commands!Declare Module}% *) 661 (** Many useful theorems hold of arbitrary groups. We capture some such theorem statements in another module signature.%\index{Vernacular commands!Declare Module}% *)
662 662
663 Module Type GROUP_THEOREMS. 663 Module Type GROUP_THEOREMS.
664 Declare Module M : GROUP. 664 Declare Module M : GROUP.
665 665
666 Axiom ident' : forall a, M.f a M.e = a. 666 Axiom ident' : forall a, M.f a M.id = a.
667 667
668 Axiom inverse' : forall a, M.f a (M.i a) = M.e. 668 Axiom inverse' : forall a, M.f a (M.i a) = M.id.
669 669
670 Axiom unique_ident : forall e', (forall a, M.f e' a = a) -> e' = M.e. 670 Axiom unique_ident : forall id', (forall a, M.f id' a = a) -> id' = M.id.
671 End GROUP_THEOREMS. 671 End GROUP_THEOREMS.
672 672
673 (** We implement generic proofs of these theorems with a functor, whose input is an arbitrary group [M]. %\index{Vernacular commands!Module}% *) 673 (** We implement generic proofs of these theorems with a functor, whose input is an arbitrary group [M]. %\index{Vernacular commands!Module}% *)
674 674
675 Module GroupProofs (M : GROUP) : GROUP_THEOREMS with Module M := M. 675 Module GroupProofs (M : GROUP) : GROUP_THEOREMS with Module M := M.
681 Import M. 681 Import M.
682 (** It would be inconvenient to repeat the prefix [M.] everywhere in our theorem statements and proofs, so we bring all the identifiers of [M] into the local scope unqualified. 682 (** It would be inconvenient to repeat the prefix [M.] everywhere in our theorem statements and proofs, so we bring all the identifiers of [M] into the local scope unqualified.
683 683
684 Now we are ready to prove the three theorems. The proofs are completely manual, which may seem ironic given the content of the previous sections! This illustrates another lesson, which is that short proof scripts that change infrequently may be worth leaving unautomated. It would take some effort to build suitable generic automation for these theorems about groups, so I stick with manual proof scripts to avoid distracting us from the main message of the section. We take the proofs from the Wikipedia page on elementary group theory. *) 684 Now we are ready to prove the three theorems. The proofs are completely manual, which may seem ironic given the content of the previous sections! This illustrates another lesson, which is that short proof scripts that change infrequently may be worth leaving unautomated. It would take some effort to build suitable generic automation for these theorems about groups, so I stick with manual proof scripts to avoid distracting us from the main message of the section. We take the proofs from the Wikipedia page on elementary group theory. *)
685 685
686 Theorem inverse' : forall a, f a (i a) = e. 686 Theorem inverse' : forall a, f a (i a) = id.
687 intro. 687 intro.
688 rewrite <- (ident (f a (i a))). 688 rewrite <- (ident (f a (i a))).
689 rewrite <- (inverse (f a (i a))) at 1. 689 rewrite <- (inverse (f a (i a))) at 1.
690 rewrite assoc. 690 rewrite assoc.
691 rewrite assoc. 691 rewrite assoc.
693 rewrite inverse. 693 rewrite inverse.
694 rewrite ident. 694 rewrite ident.
695 apply inverse. 695 apply inverse.
696 Qed. 696 Qed.
697 697
698 Theorem ident' : forall a, f a e = a. 698 Theorem ident' : forall a, f a id = a.
699 intro. 699 intro.
700 rewrite <- (inverse a). 700 rewrite <- (inverse a).
701 rewrite <- assoc. 701 rewrite <- assoc.
702 rewrite inverse'. 702 rewrite inverse'.
703 apply ident. 703 apply ident.
704 Qed. 704 Qed.
705 705
706 Theorem unique_ident : forall e', (forall a, M.f e' a = a) -> e' = M.e. 706 Theorem unique_ident : forall id', (forall a, M.f id' a = a) -> id' = M.id.
707 intros. 707 intros.
708 rewrite <- (H e). 708 rewrite <- (H id).
709 symmetry. 709 symmetry.
710 apply ident'. 710 apply ident'.
711 Qed. 711 Qed.
712 End GroupProofs. 712 End GroupProofs.
713 713
717 Open Scope Z_scope. 717 Open Scope Z_scope.
718 718
719 Module Int. 719 Module Int.
720 Definition G := Z. 720 Definition G := Z.
721 Definition f x y := x + y. 721 Definition f x y := x + y.
722 Definition e := 0. 722 Definition id := 0.
723 Definition i x := -x. 723 Definition i x := -x.
724 724
725 Theorem assoc : forall a b c, f (f a b) c = f a (f b c). 725 Theorem assoc : forall a b c, f (f a b) c = f a (f b c).
726 unfold f; crush. 726 unfold f; crush.
727 Qed. 727 Qed.
728 Theorem ident : forall a, f e a = a. 728 Theorem ident : forall a, f id a = a.
729 unfold f, e; crush. 729 unfold f, id; crush.
730 Qed. 730 Qed.
731 Theorem inverse : forall a, f (i a) a = e. 731 Theorem inverse : forall a, f (i a) a = id.
732 unfold f, i, e; crush. 732 unfold f, i, id; crush.
733 Qed. 733 Qed.
734 End Int. 734 End Int.
735 735
736 (** Next, we can produce integer-specific versions of the generic group theorems. *) 736 (** Next, we can produce integer-specific versions of the generic group theorems. *)
737 737
743 : forall e' : Int.G, (forall a : Int.G, Int.f e' a = a) -> e' = Int.e 743 : forall e' : Int.G, (forall a : Int.G, Int.f e' a = a) -> e' = Int.e
744 ]] 744 ]]
745 745
746 Projections like [Int.G] are known to be definitionally equal to the concrete values we have assigned to them, so the above theorem yields as a trivial corollary the following more natural restatement: *) 746 Projections like [Int.G] are known to be definitionally equal to the concrete values we have assigned to them, so the above theorem yields as a trivial corollary the following more natural restatement: *)
747 747
748 Theorem unique_ident : forall e', (forall a, e' + a = a) -> e' = 0. 748 Theorem unique_ident : forall id', (forall a, id' + a = a) -> id' = 0.
749 (* begin thide *) 749 (* begin thide *)
750 exact IntProofs.unique_ident. 750 exact IntProofs.unique_ident.
751 Qed. 751 Qed.
752 (* end thide *) 752 (* end thide *)
753 753
754 (** As in ML, the module system provides an effective way to structure large developments. Unlike in ML, Coq modules add no expressiveness; we can implement any module as an inhabitant of a dependent record type. It is the second-class nature of modules that makes them easier to use than dependent records in many case. Because modules may only be used in quite restricted ways, it is easier to support convenient module coding through special commands and editing modes, as the above example demonstrates. An isomorphic implementation with records would have suffered from lack of such conveniences as module subtyping and importation of the fields of a module. On the other hand, all module values must be determined statically, so modules may not be computed, e.g., within the defintions of normal functions, based on particular function parameters. *) 754 (** As in ML, the module system provides an effective way to structure large developments. Unlike in ML, Coq modules add no expressiveness; we can implement any module as an inhabitant of a dependent record type. It is the second-class nature of modules that makes them easier to use than dependent records in many case. Because modules may only be used in quite restricted ways, it is easier to support convenient module coding through special commands and editing modes, as the above example demonstrates. An isomorphic implementation with records would have suffered from lack of such conveniences as module subtyping and importation of the fields of a module. On the other hand, all module values must be determined statically, so modules may not be computed, e.g., within the definitions of normal functions, based on particular function parameters. *)
755 755
756 756
757 (** * Build Processes *) 757 (** * Build Processes *)
758 758
759 (* begin hide *) 759 (* begin hide *)