Mercurial > cpdt > repo
comparison src/Universes.v @ 345:518c8994a715
One more axiom avoidance example
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Wed, 19 Oct 2011 10:00:07 -0400 |
parents | 7466ac31f162 |
children | ad315efc3b6b |
comparison
equal
deleted
inserted
replaced
344:7466ac31f162 | 345:518c8994a715 |
---|---|
880 (** %\vspace{-.15in}% | 880 (** %\vspace{-.15in}% |
881 << | 881 << |
882 Closed under the global context | 882 Closed under the global context |
883 >> | 883 >> |
884 | 884 |
885 As another example, consider the following type of formulas in first-order logic. The intent of the type definition will not be important in what follows, but we give a quick intuition for the curious reader. Our formulas may include [forall] quantification over arbitrary [Type]s, and we index formulas by environments telling which variables are in scope and what their types are; such an environment is a [list Type]. A constructor [Inject] lets us include any Coq [Prop] as a formula, and [VarEq] and [Lift] can be used for variable references, in what is essentially the de Bruijn index convention. (Again, the detail in this paragraph is not important to understand the discussion that follows!) *) | 885 *) |
886 | |
887 (* begin thide *) | |
888 (** 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. | |
889 | |
890 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. *) | |
891 | |
892 Definition finOut n (f : fin n) : match n return fin n -> Type with | |
893 | O => fun _ => Empty_set | |
894 | _ => fun f => {f' : _ | f = Next f'} + {f = First} | |
895 end f := | |
896 match f with | |
897 | First _ => inright _ (refl_equal _) | |
898 | Next _ f' => inleft _ (exist _ f' (refl_equal _)) | |
899 end. | |
900 (* end thide *) | |
901 | |
902 (** As another example, consider the following type of formulas in first-order logic. The intent of the type definition will not be important in what follows, but we give a quick intuition for the curious reader. Our formulas may include [forall] quantification over arbitrary [Type]s, and we index formulas by environments telling which variables are in scope and what their types are; such an environment is a [list Type]. A constructor [Inject] lets us include any Coq [Prop] as a formula, and [VarEq] and [Lift] can be used for variable references, in what is essentially the de Bruijn index convention. (Again, the detail in this paragraph is not important to understand the discussion that follows!) *) | |
886 | 903 |
887 Inductive formula : list Type -> Type := | 904 Inductive formula : list Type -> Type := |
888 | Inject : forall Ts, Prop -> formula Ts | 905 | Inject : forall Ts, Prop -> formula Ts |
889 | VarEq : forall T Ts, T -> formula (T :: Ts) | 906 | VarEq : forall T Ts, T -> formula (T :: Ts) |
890 | Lift : forall T Ts, formula Ts -> formula (T :: Ts) | 907 | Lift : forall T Ts, formula Ts -> formula (T :: Ts) |
959 existT (fun Ts : list Type => formula Ts) []%list p0 | 976 existT (fun Ts : list Type => formula Ts) []%list p0 |
960 ============================ | 977 ============================ |
961 proof p0 | 978 proof p0 |
962 ]] | 979 ]] |
963 | 980 |
964 It may take a bit of tinkering, but, reviewing Chapter 3's discussion of writing injection principles manually, it makes sense that an [existT] type is the most direct way to express the output of [inversion] on a dependently typed constructor. The constructor [And] is dependently typed, since it takes a parameter [Ts] upon which the types of [p] and [q] depend. Let us not dwell further here on why this goal appears; the reader may like to attempt the (impossible) exercise of building a better injection lemma for [And], without using axioms. | 981 It may take a bit of tinkering, but, reviewing Chapter 3's discussion of writing injection principles manually, it makes sense that an [existT] type is the most direct way to express the output of [injection] on a dependently typed constructor. The constructor [And] is dependently typed, since it takes a parameter [Ts] upon which the types of [p] and [q] depend. Let us not dwell further here on why this goal appears; the reader may like to attempt the (impossible) exercise of building a better injection lemma for [And], without using axioms. |
965 | 982 |
966 How exactly does an axiom come into the picture here? Let us ask [crush] to finish the proof. *) | 983 How exactly does an axiom come into the picture here? Let us ask [crush] to finish the proof. *) |
967 | 984 |
968 crush. | 985 crush. |
969 Qed. | 986 Qed. |