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. *)