comparison src/Universes.v @ 429:5744842c36a8

Pass through Universes, to incorporate new coqdoc features
author Adam Chlipala <adam@chlipala.net>
date Thu, 26 Jul 2012 11:55:52 -0400
parents 5f25705a10ea
children a54a4a2ea6e4
comparison
equal deleted inserted replaced
428:b027b39606ed 429:5744842c36a8
45 nat 45 nat
46 : Set 46 : Set
47 47
48 ]] 48 ]]
49 49
50 From a set theory perspective, it is unsurprising to consider the natural numbers as a %``%#"#set.#"#%''% *) 50 From a set theory perspective, it is unsurprising to consider the natural numbers as a "set." *)
51 51
52 Check Set. 52 Check Set.
53 (** %\vspace{-.15in}% [[ 53 (** %\vspace{-.15in}% [[
54 Set 54 Set
55 : Type 55 : Type
63 Type 63 Type
64 : Type 64 : Type
65 65
66 ]] 66 ]]
67 67
68 Strangely enough, [Type] appears to be its own type. It is known that polymorphic languages with this property are inconsistent, via %\index{Girard's paradox}%Girard's paradox%~\cite{GirardsParadox}%. That is, using such a language to encode proofs is unwise, because it is possible to %``%#"#prove#"#%''% any proposition. What is really going on here? 68 Strangely enough, [Type] appears to be its own type. It is known that polymorphic languages with this property are inconsistent, via %\index{Girard's paradox}%Girard's paradox%~\cite{GirardsParadox}%. That is, using such a language to encode proofs is unwise, because it is possible to "prove" any proposition. What is really going on here?
69 69
70 Let us repeat some of our queries after toggling a flag related to Coq's printing behavior.%\index{Vernacular commands!Set Printing Universes}% *) 70 Let us repeat some of our queries after toggling a flag related to Coq's printing behavior.%\index{Vernacular commands!Set Printing Universes}% *)
71 71
72 Set Printing Universes. 72 Set Printing Universes.
73 73
91 Type $ Top.3 ^ 91 Type $ Top.3 ^
92 : Type $ (Top.3)+1 ^ 92 : Type $ (Top.3)+1 ^
93 93
94 ]] 94 ]]
95 95
96 Occurrences of [Type] are annotated with some additional information, inside comments. These annotations have to do with the secret behind [Type]: it really stands for an infinite hierarchy of types. The type of [Set] is [Type(0)], the type of [Type(0)] is [Type(1)], the type of [Type(1)] is [Type(2)], and so on. This is how we avoid the %``%#"#[Type : Type]#"#%''% paradox. As a convenience, the universe hierarchy drives Coq's one variety of subtyping. Any term whose type is [Type] at level [i] is automatically also described by [Type] at level [j] when [j > i]. 96 Occurrences of [Type] are annotated with some additional information, inside comments. These annotations have to do with the secret behind [Type]: it really stands for an infinite hierarchy of types. The type of [Set] is [Type(0)], the type of [Type(0)] is [Type(1)], the type of [Type(1)] is [Type(2)], and so on. This is how we avoid the "[Type : Type]" paradox. As a convenience, the universe hierarchy drives Coq's one variety of subtyping. Any term whose type is [Type] at level [i] is automatically also described by [Type] at level [j] when [j > i].
97 97
98 In the outputs of our first [Check] query, we see that the type level of [Set]'s type is [(0)+1]. Here [0] stands for the level of [Set], and we increment it to arrive at the level that _classifies_ [Set]. 98 In the outputs of our first [Check] query, we see that the type level of [Set]'s type is [(0)+1]. Here [0] stands for the level of [Set], and we increment it to arrive at the level that _classifies_ [Set].
99 99
100 In the second query's output, we see that the occurrence of [Type] that we check is assigned a fresh%\index{universe variable}% _universe variable_ [Top.3]. The output type increments [Top.3] to move up a level in the universe hierarchy. As we write code that uses definitions whose types mention universe variables, unification may refine the values of those variables. Luckily, the user rarely has to worry about the details. 100 In the second query's output, we see that the occurrence of [Type] that we check is assigned a fresh%\index{universe variable}% _universe variable_ [Top.3]. The output type increments [Top.3] to move up a level in the universe hierarchy. As we write code that uses definitions whose types mention universe variables, unification may refine the values of those variables. Luckily, the user rarely has to worry about the details.
101 101
174 174
175 << 175 <<
176 Error: Universe inconsistency (cannot enforce Top.16 < Top.16). 176 Error: Universe inconsistency (cannot enforce Top.16 < Top.16).
177 >> 177 >>
178 178
179 %\index{universe inconsistency}%This error message reminds us that the universe variable for [T] still exists, even though it is usually hidden. To apply [id] to itself, that variable would need to be less than itself in the type hierarchy. Universe inconsistency error messages announce cases like this one where a term could only type-check by violating an implied constraint over universe variables. Such errors demonstrate that [Type] is _predicative_, where this word has a CIC meaning closely related to its usual mathematical meaning. A predicative system enforces the constraint that, for any object of quantified type, none of those quantifiers may ever be instantiated with the object itself. %\index{impredicativity}%Impredicativity is associated with popular paradoxes in set theory, involving inconsistent constructions like %``%#"#the set of all sets that do not contain themselves#"#%''% (%\index{Russell's paradox}%Russell's paradox). Similar paradoxes would result from uncontrolled impredicativity in Coq. *) 179 %\index{universe inconsistency}%This error message reminds us that the universe variable for [T] still exists, even though it is usually hidden. To apply [id] to itself, that variable would need to be less than itself in the type hierarchy. Universe inconsistency error messages announce cases like this one where a term could only type-check by violating an implied constraint over universe variables. Such errors demonstrate that [Type] is _predicative_, where this word has a CIC meaning closely related to its usual mathematical meaning. A predicative system enforces the constraint that, for any object of quantified type, none of those quantifiers may ever be instantiated with the object itself. %\index{impredicativity}%Impredicativity is associated with popular paradoxes in set theory, involving inconsistent constructions like "the set of all sets that do not contain themselves" (%\index{Russell's paradox}%Russell's paradox). Similar paradoxes would result from uncontrolled impredicativity in Coq. *)
180 180
181 181
182 (** ** Inductive Definitions *) 182 (** ** Inductive Definitions *)
183 183
184 (** Predicativity restrictions also apply to inductive definitions. As an example, let us consider a type of expression trees that allows injection of any native Coq value. The idea is that an [exp T] stands for a reflected expression of type [T]. 184 (** Predicativity restrictions also apply to inductive definitions. As an example, let us consider a type of expression trees that allows injection of any native Coq value. The idea is that an [exp T] stands for a reflected expression of type [T].
254 254
255 ]] 255 ]]
256 256
257 We see that the index type of [exp] has been assigned to universe level [Top.8]. In addition, each of the four occurrences of [Type] in the types of the constructors gets its own universe variable. Each of these variables appears explicitly in the type of [exp]. In particular, any type [exp T] lives at a universe level found by incrementing by one the maximum of the four argument variables. A consequence of this is that [exp] _must_ live at a higher universe level than any type which may be passed to one of its constructors. This consequence led to the universe inconsistency. 257 We see that the index type of [exp] has been assigned to universe level [Top.8]. In addition, each of the four occurrences of [Type] in the types of the constructors gets its own universe variable. Each of these variables appears explicitly in the type of [exp]. In particular, any type [exp T] lives at a universe level found by incrementing by one the maximum of the four argument variables. A consequence of this is that [exp] _must_ live at a higher universe level than any type which may be passed to one of its constructors. This consequence led to the universe inconsistency.
258 258
259 Strangely, the universe variable [Top.8] only appears in one place. Is there no restriction imposed on which types are valid arguments to [exp]? In fact, there is a restriction, but it only appears in a global set of universe constraints that are maintained %``%#"#off to the side,#"#%''% not appearing explicitly in types. We can print the current database.%\index{Vernacular commands!Print Universes}% *) 259 Strangely, the universe variable [Top.8] only appears in one place. Is there no restriction imposed on which types are valid arguments to [exp]? In fact, there is a restriction, but it only appears in a global set of universe constraints that are maintained "off to the side," not appearing explicitly in types. We can print the current database.%\index{Vernacular commands!Print Universes}% *)
260 260
261 Print Universes. 261 Print Universes.
262 (** %\vspace{-.15in}% [[ 262 (** %\vspace{-.15in}% [[
263 Top.19 < Top.9 <= Top.8 263 Top.19 < Top.9 <= Top.8
264 Top.15 < Top.9 <= Top.8 <= Coq.Init.Datatypes.38 264 Top.15 < Top.9 <= Top.8 <= Coq.Init.Datatypes.38
346 foo True 346 foo True
347 : Prop 347 : Prop
348 348
349 ]] 349 ]]
350 350
351 The basic pattern here is that Coq is willing to automatically build a %``%#"#copied-and-pasted#"#%''% version of an inductive definition, where some occurrences of [Type] have been replaced by [Set] or [Prop]. In each context, the type-checker tries to find the valid replacements that are lowest in the type hierarchy. Automatic cloning of definitions can be much more convenient than manual cloning. We have already taken advantage of the fact that we may re-use the same families of tuple and list types to form values in [Set] and [Type]. 351 The basic pattern here is that Coq is willing to automatically build a "copied-and-pasted" version of an inductive definition, where some occurrences of [Type] have been replaced by [Set] or [Prop]. In each context, the type-checker tries to find the valid replacements that are lowest in the type hierarchy. Automatic cloning of definitions can be much more convenient than manual cloning. We have already taken advantage of the fact that we may re-use the same families of tuple and list types to form values in [Set] and [Type].
352 352
353 Imitation polymorphism can be confusing in some contexts. For instance, it is what is responsible for this weird behavior. *) 353 Imitation polymorphism can be confusing in some contexts. For instance, it is what is responsible for this weird behavior. *)
354 354
355 Inductive bar : Type := Bar : bar. 355 Inductive bar : Type := Bar : bar.
356 356
445 445
446 Restart. 446 Restart.
447 destruct 1 as [x]; apply ex_intro with x; symmetry; assumption. 447 destruct 1 as [x]; apply ex_intro with x; symmetry; assumption.
448 Qed. 448 Qed.
449 449
450 (** This restriction for unification variables may seem counterintuitive, but it follows from the fact that CIC contains no concept of unification variable. Rather, to construct the final proof term, at the point in a proof where the unification variable is introduced, we replace it with the instantiation we eventually find for it. It is simply syntactically illegal to refer there to variables that are not in scope. Without such a restriction, we could trivially %``%#"#prove#"#%''% such non-theorems as [exists n : nat, forall m : nat, n = m] by [econstructor; intro; reflexivity]. *) 450 (** This restriction for unification variables may seem counterintuitive, but it follows from the fact that CIC contains no concept of unification variable. Rather, to construct the final proof term, at the point in a proof where the unification variable is introduced, we replace it with the instantiation we eventually find for it. It is simply syntactically illegal to refer there to variables that are not in scope. Without such a restriction, we could trivially "prove" such non-theorems as [exists n : nat, forall m : nat, n = m] by [econstructor; intro; reflexivity]. *)
451 451
452 452
453 (** * The [Prop] Universe *) 453 (** * The [Prop] Universe *)
454 454
455 (** In Chapter 4, we saw parallel versions of useful datatypes for %``%#"#programs#"#%''% and %``%#"#proofs.#"#%''% The convention was that programs live in [Set], and proofs live in [Prop]. We gave little explanation for why it is useful to maintain this distinction. There is certainly documentation value from separating programs from proofs; in practice, different concerns apply to building the two types of objects. It turns out, however, that these concerns motivate formal differences between the two universes in Coq. 455 (** In Chapter 4, we saw parallel versions of useful datatypes for "programs" and "proofs." The convention was that programs live in [Set], and proofs live in [Prop]. We gave little explanation for why it is useful to maintain this distinction. There is certainly documentation value from separating programs from proofs; in practice, different concerns apply to building the two types of objects. It turns out, however, that these concerns motivate formal differences between the two universes in Coq.
456 456
457 Recall the types [sig] and [ex], which are the program and proof versions of existential quantification. Their definitions differ only in one place, where [sig] uses [Type] and [ex] uses [Prop]. *) 457 Recall the types [sig] and [ex], which are the program and proof versions of existential quantification. Their definitions differ only in one place, where [sig] uses [Type] and [ex] uses [Prop]. *)
458 458
459 Print sig. 459 Print sig.
460 (** %\vspace{-.15in}% [[ 460 (** %\vspace{-.15in}% [[
473 473
474 Definition projS A (P : A -> Prop) (x : sig P) : A := 474 Definition projS A (P : A -> Prop) (x : sig P) : A :=
475 match x with 475 match x with
476 | exist v _ => v 476 | exist v _ => v
477 end. 477 end.
478
479 (* begin hide *)
480 Definition projE := O.
481 (* end hide *)
478 482
479 (** We run into trouble with a version that has been changed to work with [ex]. 483 (** We run into trouble with a version that has been changed to work with [ex].
480 [[ 484 [[
481 Definition projE A (P : A -> Prop) (x : ex P) : A := 485 Definition projE A (P : A -> Prop) (x : ex P) : A :=
482 match x with 486 match x with
491 Elimination of an inductive object of sort Prop 495 Elimination of an inductive object of sort Prop
492 is not allowed on a predicate in sort Type 496 is not allowed on a predicate in sort Type
493 because proofs can be eliminated only to build proofs. 497 because proofs can be eliminated only to build proofs.
494 >> 498 >>
495 499
496 In formal Coq parlance, %\index{elimination}``%#"#elimination#"#%''% means %``%#"#pattern-matching.#"#%''% The typing rules of Gallina forbid us from pattern-matching on a discriminee whose type belongs to [Prop], whenever the result type of the [match] has a type besides [Prop]. This is a sort of %``%#"#information flow#"#%''% policy, where the type system ensures that the details of proofs can never have any effect on parts of a development that are not also marked as proofs. 500 In formal Coq parlance, %\index{elimination}%"elimination" means "pattern-matching." The typing rules of Gallina forbid us from pattern-matching on a discriminee whose type belongs to [Prop], whenever the result type of the [match] has a type besides [Prop]. This is a sort of "information flow" policy, where the type system ensures that the details of proofs can never have any effect on parts of a development that are not also marked as proofs.
497 501
498 This restriction matches informal practice. We think of programs and proofs as clearly separated, and, outside of constructive logic, the idea of computing with proofs is ill-formed. The distinction also has practical importance in Coq, where it affects the behavior of extraction. 502 This restriction matches informal practice. We think of programs and proofs as clearly separated, and, outside of constructive logic, the idea of computing with proofs is ill-formed. The distinction also has practical importance in Coq, where it affects the behavior of extraction.
499 503
500 Recall that %\index{program extraction}%extraction is Coq's facility for translating Coq developments into programs in general-purpose programming languages like OCaml. Extraction _erases_ proofs and leaves programs intact. A simple example with [sig] and [ex] demonstrates the distinction. *) 504 Recall that %\index{program extraction}%extraction is Coq's facility for translating Coq developments into programs in general-purpose programming languages like OCaml. Extraction _erases_ proofs and leaves programs intact. A simple example with [sig] and [ex] demonstrates the distinction. *)
501 505
635 639
636 Parameter n : nat. 640 Parameter n : nat.
637 Axiom positive : n > 0. 641 Axiom positive : n > 0.
638 Reset n. 642 Reset n.
639 643
640 (** This kind of %``%#"#axiomatic presentation#"#%''% of a theory is very common outside of higher-order logic. However, in Coq, it is almost always preferable to stick to defining your objects, functions, and predicates via inductive definitions and functional programming. 644 (** This kind of "axiomatic presentation" of a theory is very common outside of higher-order logic. However, in Coq, it is almost always preferable to stick to defining your objects, functions, and predicates via inductive definitions and functional programming.
641 645
642 In general, there is a significant burden associated with any use of axioms. It is easy to assert a set of axioms that together is%\index{inconsistent axioms}% _inconsistent_. That is, a set of axioms may imply [False], which allows any theorem to be proved, which defeats the purpose of a proof assistant. For example, we could assert the following axiom, which is consistent by itself but inconsistent when combined with [classic]. *) 646 In general, there is a significant burden associated with any use of axioms. It is easy to assert a set of axioms that together is%\index{inconsistent axioms}% _inconsistent_. That is, a set of axioms may imply [False], which allows any theorem to be proved, which defeats the purpose of a proof assistant. For example, we could assert the following axiom, which is consistent by itself but inconsistent when combined with [classic]. *)
643 647
644 Axiom not_classic : ~ forall P : Prop, P \/ ~ P. 648 Axiom not_classic : ~ forall P : Prop, P \/ ~ P.
645 649
651 destruct uhoh. 655 destruct uhoh.
652 Qed. 656 Qed.
653 657
654 Reset not_classic. 658 Reset not_classic.
655 659
656 (** On the subject of the law of the excluded middle itself, this axiom is usually quite harmless, and many practical Coq developments assume it. It has been proved metatheoretically to be consistent with CIC. Here, %``%#"#proved metatheoretically#"#%''% means that someone proved on paper that excluded middle holds in a _model_ of CIC in set theory%~\cite{SetsInTypes}%. All of the other axioms that we will survey in this section hold in the same model, so they are all consistent together. 660 (** On the subject of the law of the excluded middle itself, this axiom is usually quite harmless, and many practical Coq developments assume it. It has been proved metatheoretically to be consistent with CIC. Here, "proved metatheoretically" means that someone proved on paper that excluded middle holds in a _model_ of CIC in set theory%~\cite{SetsInTypes}%. All of the other axioms that we will survey in this section hold in the same model, so they are all consistent together.
657 661
658 Recall that Coq implements%\index{constructive logic}% _constructive_ logic by default, where excluded middle is not provable. Proofs in constructive logic can be thought of as programs. A [forall] quantifier denotes a dependent function type, and a disjunction denotes a variant type. In such a setting, excluded middle could be interpreted as a decision procedure for arbitrary propositions, which computability theory tells us cannot exist. Thus, constructive logic with excluded middle can no longer be associated with our usual notion of programming. 662 Recall that Coq implements%\index{constructive logic}% _constructive_ logic by default, where excluded middle is not provable. Proofs in constructive logic can be thought of as programs. A [forall] quantifier denotes a dependent function type, and a disjunction denotes a variant type. In such a setting, excluded middle could be interpreted as a decision procedure for arbitrary propositions, which computability theory tells us cannot exist. Thus, constructive logic with excluded middle can no longer be associated with our usual notion of programming.
659 663
660 Given all this, why is it all right to assert excluded middle as an axiom? The intuitive justification is that the elimination restriction for [Prop] prevents us from treating proofs as programs. An excluded middle axiom that quantified over [Set] instead of [Prop] _would_ be problematic. If a development used that axiom, we would not be able to extract the code to OCaml (soundly) without implementing a genuine universal decision procedure. In contrast, values whose types belong to [Prop] are always erased by extraction, so we sidestep the axiom's algorithmic consequences. 664 Given all this, why is it all right to assert excluded middle as an axiom? The intuitive justification is that the elimination restriction for [Prop] prevents us from treating proofs as programs. An excluded middle axiom that quantified over [Set] instead of [Prop] _would_ be problematic. If a development used that axiom, we would not be able to extract the code to OCaml (soundly) without implementing a genuine universal decision procedure. In contrast, values whose types belong to [Prop] are always erased by extraction, so we sidestep the axiom's algorithmic consequences.
661 665
751 *** [ eq_rect_eq : 755 *** [ eq_rect_eq :
752 forall (U : Type) (p : U) (Q : U -> Type) (x : Q p) (h : p = p), 756 forall (U : Type) (p : U) (Q : U -> Type) (x : Q p) (h : p = p),
753 x = eq_rect p Q x p h ] 757 x = eq_rect p Q x p h ]
754 ]] 758 ]]
755 759
756 This axiom says that it is permissible to simplify pattern matches over proofs of equalities like [e = e]. The axiom is logically equivalent to some simpler corollaries. In the theorem names, %``%#"#UIP#"#%''% stands for %\index{unicity of identity proofs}``%#"#unicity of identity proofs#"#%''%, where %``%#"#identity#"#%''% is a synonym for %``%#"#equality.#"#%''% *) 760 This axiom says that it is permissible to simplify pattern matches over proofs of equalities like [e = e]. The axiom is logically equivalent to some simpler corollaries. In the theorem names, "UIP" stands for %\index{unicity of identity proofs}%"unicity of identity proofs", where "identity" is a synonym for "equality." *)
757 761
758 Corollary UIP_refl : forall A (x : A) (pf : x = x), pf = eq_refl x. 762 Corollary UIP_refl : forall A (x : A) (pf : x = x), pf = eq_refl x.
759 intros; replace pf with (eq_rect x (eq x) (eq_refl x) x pf); [ 763 intros; replace pf with (eq_rect x (eq x) (eq_refl x) x pf); [
760 symmetry; apply eq_rect_eq 764 symmetry; apply eq_rect_eq
761 | exact (match pf as pf' return match pf' in _ = y return x = y with 765 | exact (match pf as pf' return match pf' in _ = y return x = y with
857 Definition choice_Set (A B : Type) (R : A -> B -> Prop) (H : forall x : A, {y : B | R x y}) 861 Definition choice_Set (A B : Type) (R : A -> B -> Prop) (H : forall x : A, {y : B | R x y})
858 : {f : A -> B | forall x : A, R x (f x)} := 862 : {f : A -> B | forall x : A, R x (f x)} :=
859 exist (fun f => forall x : A, R x (f x)) 863 exist (fun f => forall x : A, R x (f x))
860 (fun x => proj1_sig (H x)) (fun x => proj2_sig (H x)). 864 (fun x => proj1_sig (H x)) (fun x => proj2_sig (H x)).
861 865
862 (** Via the Curry-Howard correspondence, this %``%#"#axiom#"#%''% can be taken to have the same meaning as the original. It is implemented trivially as a transformation not much deeper than uncurrying. Thus, we see that the utility of the axioms that we mentioned earlier comes in their usage to build programs from proofs. Normal set theory has no explicit proofs, so the meaning of the usual axiom of choice is subtlely different. In Gallina, the axioms implement a controlled relaxation of the restrictions on information flow from proofs to programs. 866 (** Via the Curry-Howard correspondence, this "axiom" can be taken to have the same meaning as the original. It is implemented trivially as a transformation not much deeper than uncurrying. Thus, we see that the utility of the axioms that we mentioned earlier comes in their usage to build programs from proofs. Normal set theory has no explicit proofs, so the meaning of the usual axiom of choice is subtlely different. In Gallina, the axioms implement a controlled relaxation of the restrictions on information flow from proofs to programs.
863 867
864 However, when we combine an axiom of choice with the law of the excluded middle, the idea of %``%#"#choice#"#%''% becomes more interesting. Excluded middle gives us a highly non-computational way of constructing proofs, but it does not change the computational nature of programs. Thus, the axiom of choice is still giving us a way of translating between two different sorts of %``%#"#programs,#"#%''% but the input programs (which are proofs) may be written in a rich language that goes beyond normal computability. This truly is more than repackaging a function with a different type. 868 However, when we combine an axiom of choice with the law of the excluded middle, the idea of "choice" becomes more interesting. Excluded middle gives us a highly non-computational way of constructing proofs, but it does not change the computational nature of programs. Thus, the axiom of choice is still giving us a way of translating between two different sorts of "programs," but the input programs (which are proofs) may be written in a rich language that goes beyond normal computability. This truly is more than repackaging a function with a different type.
865 869
866 %\bigskip% 870 %\bigskip%
867 871
868 The Coq tools support a command-line flag %\index{impredicative Set}\texttt{%#<tt>#-impredicative-set#</tt>#%}%, which modifies Gallina in a more fundamental way by making [Set] impredicative. A term like [forall T : Set, T] has type [Set], and inductive definitions in [Set] may have constructors that quantify over arguments of any types. To maintain consistency, an elimination restriction must be imposed, similarly to the restriction for [Prop]. The restriction only applies to large inductive types, where some constructor quantifies over a type of type [Type]. In such cases, a value in this inductive type may only be pattern-matched over to yield a result type whose type is [Set] or [Prop]. This contrasts with [Prop], where the restriction applies even to non-large inductive types, and where the result type may only have type [Prop]. 872 The Coq tools support a command-line flag %\index{impredicative Set}%<<-impredicative-set>>, which modifies Gallina in a more fundamental way by making [Set] impredicative. A term like [forall T : Set, T] has type [Set], and inductive definitions in [Set] may have constructors that quantify over arguments of any types. To maintain consistency, an elimination restriction must be imposed, similarly to the restriction for [Prop]. The restriction only applies to large inductive types, where some constructor quantifies over a type of type [Type]. In such cases, a value in this inductive type may only be pattern-matched over to yield a result type whose type is [Set] or [Prop]. This contrasts with [Prop], where the restriction applies even to non-large inductive types, and where the result type may only have type [Prop].
869 873
870 In old versions of Coq, [Set] was impredicative by default. Later versions make [Set] predicative to avoid inconsistency with some classical axioms. In particular, one should watch out when using impredicative [Set] with axioms of choice. In combination with excluded middle or predicate extensionality, this can lead to inconsistency. Impredicative [Set] can be useful for modeling inherently impredicative mathematical concepts, but almost all Coq developments get by fine without it. *) 874 In old versions of Coq, [Set] was impredicative by default. Later versions make [Set] predicative to avoid inconsistency with some classical axioms. In particular, one should watch out when using impredicative [Set] with axioms of choice. In combination with excluded middle or predicate extensionality, this can lead to inconsistency. Impredicative [Set] can be useful for modeling inherently impredicative mathematical concepts, but almost all Coq developments get by fine without it. *)
871 875
872 (** ** Axioms and Computation *) 876 (** ** Axioms and Computation *)
873 877
943 947
944 (** ** Methods for Avoiding Axioms *) 948 (** ** Methods for Avoiding Axioms *)
945 949
946 (** The last section demonstrated one reason to avoid axioms: they interfere with computational behavior of terms. A further reason is to reduce the philosophical commitment of a theorem. The more axioms one assumes, the harder it becomes to convince oneself that the formal system corresponds appropriately to one's intuitions. A refinement of this last point, in applications like %\index{proof-carrying code}%proof-carrying code%~\cite{PCC}% in computer security, has to do with minimizing the size of a%\index{trusted code base}% _trusted code base_. To convince ourselves that a theorem is true, we must convince ourselves of the correctness of the program that checks the theorem. Axioms effectively become new source code for the checking program, increasing the effort required to perform a correctness audit. 950 (** The last section demonstrated one reason to avoid axioms: they interfere with computational behavior of terms. A further reason is to reduce the philosophical commitment of a theorem. The more axioms one assumes, the harder it becomes to convince oneself that the formal system corresponds appropriately to one's intuitions. A refinement of this last point, in applications like %\index{proof-carrying code}%proof-carrying code%~\cite{PCC}% in computer security, has to do with minimizing the size of a%\index{trusted code base}% _trusted code base_. To convince ourselves that a theorem is true, we must convince ourselves of the correctness of the program that checks the theorem. Axioms effectively become new source code for the checking program, increasing the effort required to perform a correctness audit.
947 951
948 An earlier section gave one example of avoiding an axiom. We proved that [pred_strong1] is agnostic to details of the proofs passed to it as arguments, by unfolding the definition of the function. A %``%#"#simpler#"#%''% proof keeps the function definition opaque and instead applies a proof irrelevance axiom. By accepting a more complex proof, we reduce our philosophical commitment and trusted base. (By the way, the less-than relation that the proofs in question here prove turns out to admit proof irrelevance as a theorem provable within normal Gallina!) 952 An earlier section gave one example of avoiding an axiom. We proved that [pred_strong1] is agnostic to details of the proofs passed to it as arguments, by unfolding the definition of the function. A "simpler" proof keeps the function definition opaque and instead applies a proof irrelevance axiom. By accepting a more complex proof, we reduce our philosophical commitment and trusted base. (By the way, the less-than relation that the proofs in question here prove turns out to admit proof irrelevance as a theorem provable within normal Gallina!)
949 953
950 One dark secret of the [dep_destruct] tactic that we have used several times is reliance on an axiom. Consider this simple case analysis principle for [fin] values: *) 954 One dark secret of the [dep_destruct] tactic that we have used several times is reliance on an axiom. Consider this simple case analysis principle for [fin] values: *)
951 955
952 Theorem fin_cases : forall n (f : fin (S n)), f = First \/ exists f', f = Next f'. 956 Theorem fin_cases : forall n (f : fin (S n)), f = First \/ exists f', f = Next f'.
953 intros; dep_destruct f; eauto. 957 intros; dep_destruct f; eauto.
954 Qed. 958 Qed.
959
960 (* begin hide *)
961 Require Import JMeq.
962 Definition jme := (JMeq, JMeq_eq).
963 (* end hide *)
955 964
956 Print Assumptions fin_cases. 965 Print Assumptions fin_cases.
957 (** %\vspace{-.15in}%[[ 966 (** %\vspace{-.15in}%[[
958 Axioms: 967 Axioms:
959 JMeq.JMeq_eq : forall (A : Type) (x y : A), JMeq.JMeq x y -> x = y 968 JMeq_eq : forall (A : Type) (x y : A), JMeq x y -> x = y
960 ]] 969 ]]
961 970
962 The proof depends on the [JMeq_eq] axiom that we met in the chapter on equality proofs. However, a smarter tactic could have avoided an axiom dependence. Here is an alternate proof via a slightly strange looking lemma. *) 971 The proof depends on the [JMeq_eq] axiom that we met in the chapter on equality proofs. However, a smarter tactic could have avoided an axiom dependence. Here is an alternate proof via a slightly strange looking lemma. *)
963 972
964 (* begin thide *) 973 (* begin thide *)
986 *) 995 *)
987 996
988 (* begin thide *) 997 (* begin thide *)
989 (** As the Curry-Howard correspondence might lead us to expect, the same pattern may be applied in programming as in proving. Axioms are relevant in programming, too, because, while Coq includes useful extensions like [Program] that make dependently typed programming more straightforward, in general these extensions generate code that relies on axioms about equality. We can use clever pattern matching to write our code axiom-free. 998 (** As the Curry-Howard correspondence might lead us to expect, the same pattern may be applied in programming as in proving. Axioms are relevant in programming, too, because, while Coq includes useful extensions like [Program] that make dependently typed programming more straightforward, in general these extensions generate code that relies on axioms about equality. We can use clever pattern matching to write our code axiom-free.
990 999
991 As an example, consider a [Set] version of [fin_cases]. We use [Set] types instead of [Prop] types, so that return values have computational content and may be used to guide the behavior of algorithms. Beside that, we are essentially writing the same %``%#"#proof#"#%''% in a more explicit way. *) 1000 As an example, consider a [Set] version of [fin_cases]. We use [Set] types instead of [Prop] types, so that return values have computational content and may be used to guide the behavior of algorithms. Beside that, we are essentially writing the same "proof" in a more explicit way. *)
992 1001
993 Definition finOut n (f : fin n) : match n return fin n -> Type with 1002 Definition finOut n (f : fin n) : match n return fin n -> Type with
994 | O => fun _ => Empty_set 1003 | O => fun _ => Empty_set
995 | _ => fun f => {f' : _ | f = Next f'} + {f = First} 1004 | _ => fun f => {f' : _ | f = Next f'} + {f = First}
996 end f := 1005 end f :=
1013 1022
1014 Inductive proof : formula nil -> Prop := 1023 Inductive proof : formula nil -> Prop :=
1015 | PInject : forall (P : Prop), P -> proof (Inject nil P) 1024 | PInject : forall (P : Prop), P -> proof (Inject nil P)
1016 | PAnd : forall p q, proof p -> proof q -> proof (And p q). 1025 | PAnd : forall p q, proof p -> proof q -> proof (And p q).
1017 1026
1018 (** Let us prove a lemma showing that a %``%#"#[P /\ Q -> P]#"#%''% rule is derivable within the rules of [proof]. *) 1027 (** Let us prove a lemma showing that a "[P /\ Q -> P]" rule is derivable within the rules of [proof]. *)
1019 1028
1020 Theorem proj1 : forall p q, proof (And p q) -> proof p. 1029 Theorem proj1 : forall p q, proof (And p q) -> proof p.
1021 destruct 1. 1030 destruct 1.
1022 (** %\vspace{-.15in}%[[ 1031 (** %\vspace{-.15in}%[[
1023 p : formula nil 1032 p : formula nil
1068 1077
1069 It looks like we are almost done. Hypothesis [H1] gives [p = p0] by injectivity of constructors, and then [H] finishes the case. *) 1078 It looks like we are almost done. Hypothesis [H1] gives [p = p0] by injectivity of constructors, and then [H] finishes the case. *)
1070 1079
1071 injection H1; intros. 1080 injection H1; intros.
1072 1081
1073 (** Unfortunately, the %``%#"#equality#"#%''% that we expected between [p] and [p0] comes in a strange form: 1082 (* begin hide *)
1083 Definition existT' := existT.
1084 (* end hide *)
1085
1086 (** Unfortunately, the "equality" that we expected between [p] and [p0] comes in a strange form:
1074 1087
1075 [[ 1088 [[
1076 H3 : existT (fun Ts : list Type => formula Ts) []%list p = 1089 H3 : existT (fun Ts : list Type => formula Ts) []%list p =
1077 existT (fun Ts : list Type => formula Ts) []%list p0 1090 existT (fun Ts : list Type => formula Ts) []%list p0
1078 ============================ 1091 ============================
1236 1249
1237 Section withTypes'. 1250 Section withTypes'.
1238 Variable types : list Set. 1251 Variable types : list Set.
1239 Variable natIndex : nat. 1252 Variable natIndex : nat.
1240 1253
1241 (** Here is the trick: instead of asserting properties about the list [types], we build a %``%#"#new#"#%''% list that is _guaranteed by construction_ to have those properties. *) 1254 (** Here is the trick: instead of asserting properties about the list [types], we build a "new" list that is _guaranteed by construction_ to have those properties. *)
1242 1255
1243 Definition types' := update types natIndex nat. 1256 Definition types' := update types natIndex nat.
1244 1257
1245 Variable values : hlist (fun x : Set => x) types'. 1258 Variable values : hlist (fun x : Set => x) types'.
1246 1259