Mercurial > cpdt > repo
comparison src/Subset.v @ 442:89c67796754e
Undo some overzealous vspace tweaks
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Wed, 01 Aug 2012 16:09:37 -0400 |
parents | f923024bd284 |
children | 2740b8a23cce |
comparison
equal
deleted
inserted
replaced
441:cbfd23b4364d | 442:89c67796754e |
---|---|
83 (** %\vspace{-.15in}% [[ | 83 (** %\vspace{-.15in}% [[ |
84 = 1 | 84 = 1 |
85 : nat | 85 : nat |
86 ]] | 86 ]] |
87 | 87 |
88 %\smallskip{}%One aspect in particular of the definition of [pred_strong1] may be surprising. We took advantage of [Definition]'s syntactic sugar for defining function arguments in the case of [n], but we bound the proofs later with explicit [fun] expressions. Let us see what happens if we write this function in the way that at first seems most natural. | 88 One aspect in particular of the definition of [pred_strong1] may be surprising. We took advantage of [Definition]'s syntactic sugar for defining function arguments in the case of [n], but we bound the proofs later with explicit [fun] expressions. Let us see what happens if we write this function in the way that at first seems most natural. |
89 | 89 |
90 %\vspace{-.15in}%[[ | 90 %\vspace{-.15in}%[[ |
91 Definition pred_strong1' (n : nat) (pf : n > 0) : nat := | 91 Definition pred_strong1' (n : nat) (pf : n > 0) : nat := |
92 match n with | 92 match n with |
93 | O => match zgtz pf with end | 93 | O => match zgtz pf with end |
151 (** %\vspace{-.15in}% [[ | 151 (** %\vspace{-.15in}% [[ |
152 Inductive sig (A : Type) (P : A -> Prop) : Type := | 152 Inductive sig (A : Type) (P : A -> Prop) : Type := |
153 exist : forall x : A, P x -> sig P | 153 exist : forall x : A, P x -> sig P |
154 ]] | 154 ]] |
155 | 155 |
156 %\smallskip{}%The family [sig] is a Curry-Howard twin of [ex], except that [sig] is in [Type], while [ex] is in [Prop]. That means that [sig] values can survive extraction, while [ex] proofs will always be erased. The actual details of extraction of [sig]s are more subtle, as we will see shortly. | 156 The family [sig] is a Curry-Howard twin of [ex], except that [sig] is in [Type], while [ex] is in [Prop]. That means that [sig] values can survive extraction, while [ex] proofs will always be erased. The actual details of extraction of [sig]s are more subtle, as we will see shortly. |
157 | 157 |
158 We rewrite [pred_strong1], using some syntactic sugar for subset types. *) | 158 We rewrite [pred_strong1], using some syntactic sugar for subset types. *) |
159 | 159 |
160 Locate "{ _ : _ | _ }". | 160 Locate "{ _ : _ | _ }". |
161 (** %\vspace{-.15in}% [[ | 161 (** %\vspace{-.15in}% [[ |
299 exist (fun m : nat => S n' = S m) n' (eq_refl (S n')) | 299 exist (fun m : nat => S n' = S m) n' (eq_refl (S n')) |
300 end | 300 end |
301 : forall n : nat, n > 0 -> {m : nat | n = S m} | 301 : forall n : nat, n > 0 -> {m : nat | n = S m} |
302 ]] | 302 ]] |
303 | 303 |
304 %\smallskip{}%We see the code we entered, with some proofs filled in. The first proof obligation, the second argument to [False_rec], is filled in with a nasty-looking proof term that we can be glad we did not enter by hand. The second proof obligation is a simple reflexivity proof. *) | 304 We see the code we entered, with some proofs filled in. The first proof obligation, the second argument to [False_rec], is filled in with a nasty-looking proof term that we can be glad we did not enter by hand. The second proof obligation is a simple reflexivity proof. *) |
305 | 305 |
306 Eval compute in pred_strong4 two_gt0. | 306 Eval compute in pred_strong4 two_gt0. |
307 (** %\vspace{-.15in}% [[ | 307 (** %\vspace{-.15in}% [[ |
308 = exist (fun m : nat => 2 = S m) 1 (eq_refl 2) | 308 = exist (fun m : nat => 2 = S m) 1 (eq_refl 2) |
309 : {m : nat | 2 = S m} | 309 : {m : nat | 2 = S m} |
310 ]] | 310 ]] |
311 | 311 |
312 %\smallskip{}%A tactic modifier called %\index{tactics!abstract}%[abstract] can be helpful for producing shorter terms, by automatically abstracting subgoals into named lemmas. *) | 312 A tactic modifier called %\index{tactics!abstract}%[abstract] can be helpful for producing shorter terms, by automatically abstracting subgoals into named lemmas. *) |
313 | 313 |
314 (* begin thide *) | 314 (* begin thide *) |
315 Definition pred_strong4' : forall n : nat, n > 0 -> {m : nat | n = S m}. | 315 Definition pred_strong4' : forall n : nat, n > 0 -> {m : nat | n = S m}. |
316 refine (fun n => | 316 refine (fun n => |
317 match n with | 317 match n with |
356 (** %\vspace{-.15in}% [[ | 356 (** %\vspace{-.15in}% [[ |
357 = [1] | 357 = [1] |
358 : {m : nat | 2 = S m} | 358 : {m : nat | 2 = S m} |
359 ]] | 359 ]] |
360 | 360 |
361 %\smallskip{}%One other alternative is worth demonstrating. Recent Coq versions include a facility called %\index{Program}%[Program] that streamlines this style of definition. Here is a complete implementation using [Program].%\index{Vernacular commands!Obligation Tactic}\index{Vernacular commands!Program Definition}% *) | 361 One other alternative is worth demonstrating. Recent Coq versions include a facility called %\index{Program}%[Program] that streamlines this style of definition. Here is a complete implementation using [Program].%\index{Vernacular commands!Obligation Tactic}\index{Vernacular commands!Program Definition}% *) |
362 | 362 |
363 Obligation Tactic := crush. | 363 Obligation Tactic := crush. |
364 | 364 |
365 Program Definition pred_strong6 (n : nat) (_ : n > 0) : {m : nat | n = S m} := | 365 Program Definition pred_strong6 (n : nat) (_ : n > 0) : {m : nat | n = S m} := |
366 match n with | 366 match n with |
374 (** %\vspace{-.15in}% [[ | 374 (** %\vspace{-.15in}% [[ |
375 = [1] | 375 = [1] |
376 : {m : nat | 2 = S m} | 376 : {m : nat | 2 = S m} |
377 ]] | 377 ]] |
378 | 378 |
379 %\smallskip{}%In this case, we see that the new definition yields the same computational behavior as before. *) | 379 In this case, we see that the new definition yields the same computational behavior as before. *) |
380 | 380 |
381 | 381 |
382 (** * Decidable Proposition Types *) | 382 (** * Decidable Proposition Types *) |
383 | 383 |
384 (** There is another type in the standard library which captures the idea of program values that indicate which of two propositions is true.%\index{Gallina terms!sumbool}% *) | 384 (** There is another type in the standard library which captures the idea of program values that indicate which of two propositions is true.%\index{Gallina terms!sumbool}% *) |
419 (** %\vspace{-.15in}% [[ | 419 (** %\vspace{-.15in}% [[ |
420 = No | 420 = No |
421 : {2 = 3} + {2 <> 3} | 421 : {2 = 3} + {2 <> 3} |
422 ]] | 422 ]] |
423 | 423 |
424 %\smallskip{}%Note that the %\coqdocnotation{%#<tt>#Yes#</tt>#%}% and %\coqdocnotation{%#<tt>#No#</tt>#%}% notations are hiding proofs establishing the correctness of the outputs. | 424 Note that the %\coqdocnotation{%#<tt>#Yes#</tt>#%}% and %\coqdocnotation{%#<tt>#No#</tt>#%}% notations are hiding proofs establishing the correctness of the outputs. |
425 | 425 |
426 Our definition extracts to reasonable OCaml code. *) | 426 Our definition extracts to reasonable OCaml code. *) |
427 | 427 |
428 Extraction eq_nat_dec. | 428 Extraction eq_nat_dec. |
429 | 429 |
527 (** %\vspace{-.15in}% [[ | 527 (** %\vspace{-.15in}% [[ |
528 = No | 528 = No |
529 : {In 3 (1 :: 2 :: nil)} + {~ In 3 (1 :: 2 :: nil)} | 529 : {In 3 (1 :: 2 :: nil)} + {~ In 3 (1 :: 2 :: nil)} |
530 ]] | 530 ]] |
531 | 531 |
532 %\smallskip{}%[In_dec] has a reasonable extraction to OCaml. *) | 532 [In_dec] has a reasonable extraction to OCaml. *) |
533 | 533 |
534 Extraction In_dec. | 534 Extraction In_dec. |
535 (* end thide *) | 535 (* end thide *) |
536 | 536 |
537 (** %\begin{verbatim} | 537 (** %\begin{verbatim} |
594 (** %\vspace{-.15in}% [[ | 594 (** %\vspace{-.15in}% [[ |
595 = ?? | 595 = ?? |
596 : {{m | 0 = S m}} | 596 : {{m | 0 = S m}} |
597 ]] | 597 ]] |
598 | 598 |
599 %\smallskip{}%Because we used [maybe], one valid implementation of the type we gave [pred_strong7] would return [??] in every case. We can strengthen the type to rule out such vacuous implementations, and the type family %\index{Gallina terms!sumor}%[sumor] from the standard library provides the easiest starting point. For type [A] and proposition [B], [A + {B}] desugars to [sumor A B], whose values are either values of [A] or proofs of [B]. *) | 599 Because we used [maybe], one valid implementation of the type we gave [pred_strong7] would return [??] in every case. We can strengthen the type to rule out such vacuous implementations, and the type family %\index{Gallina terms!sumor}%[sumor] from the standard library provides the easiest starting point. For type [A] and proposition [B], [A + {B}] desugars to [sumor A B], whose values are either values of [A] or proofs of [B]. *) |
600 | 600 |
601 Print sumor. | 601 Print sumor. |
602 (** %\vspace{-.15in}% [[ | 602 (** %\vspace{-.15in}% [[ |
603 Inductive sumor (A : Type) (B : Prop) : Type := | 603 Inductive sumor (A : Type) (B : Prop) : Type := |
604 inleft : A -> A + {B} | inright : B -> A + {B} | 604 inleft : A -> A + {B} | inright : B -> A + {B} |
605 ]] | 605 ]] |
606 | 606 |
607 %\smallskip{}%We add notations for easy use of the [sumor] constructors. The second notation is specialized to [sumor]s whose [A] parameters are instantiated with regular subset types, since this is how we will use [sumor] below. *) | 607 We add notations for easy use of the [sumor] constructors. The second notation is specialized to [sumor]s whose [A] parameters are instantiated with regular subset types, since this is how we will use [sumor] below. *) |
608 | 608 |
609 Notation "!!" := (inright _ _). | 609 Notation "!!" := (inright _ _). |
610 Notation "[|| x ||]" := (inleft _ [x]). | 610 Notation "[|| x ||]" := (inleft _ [x]). |
611 | 611 |
612 (** Now we are ready to give the final version of possibly failing predecessor. The [sumor]-based type that we use is maximally expressive; any implementation of the type has the same input-output behavior. *) | 612 (** Now we are ready to give the final version of possibly failing predecessor. The [sumor]-based type that we use is maximally expressive; any implementation of the type has the same input-output behavior. *) |
774 (** %\vspace{-.15in}% [[ | 774 (** %\vspace{-.15in}% [[ |
775 = ?? | 775 = ?? |
776 : {{t | hasType (Plus (Nat 1) (Bool false)) t}} | 776 : {{t | hasType (Plus (Nat 1) (Bool false)) t}} |
777 ]] | 777 ]] |
778 | 778 |
779 %\smallskip{}%The type checker also extracts to some reasonable OCaml code. *) | 779 The type checker also extracts to some reasonable OCaml code. *) |
780 | 780 |
781 Extraction typeCheck. | 781 Extraction typeCheck. |
782 | 782 |
783 (** %\begin{verbatim} | 783 (** %\begin{verbatim} |
784 (** val typeCheck : exp -> type0 maybe **) | 784 (** val typeCheck : exp -> type0 maybe **) |
927 = !! | 927 = !! |
928 : {t : type | hasType (Plus (Nat 1) (Bool false)) t} + | 928 : {t : type | hasType (Plus (Nat 1) (Bool false)) t} + |
929 {(forall t : type, ~ hasType (Plus (Nat 1) (Bool false)) t)} | 929 {(forall t : type, ~ hasType (Plus (Nat 1) (Bool false)) t)} |
930 ]] | 930 ]] |
931 | 931 |
932 %\smallskip{}%The results of simplifying calls to [typeCheck'] look deceptively similar to the results for [typeCheck], but now the types of the results provide more information. *) | 932 The results of simplifying calls to [typeCheck'] look deceptively similar to the results for [typeCheck], but now the types of the results provide more information. *) |