comparison src/Subset.v @ 440:f923024bd284

Vertical spacing pass, through end of Subset
author Adam Chlipala <adam@chlipala.net>
date Mon, 30 Jul 2012 16:50:02 -0400
parents 393b8ed99c2f
children 89c67796754e
comparison
equal deleted inserted replaced
439:393b8ed99c2f 440:f923024bd284
81 81
82 Eval compute in pred_strong1 two_gt0. 82 Eval compute in pred_strong1 two_gt0.
83 (** %\vspace{-.15in}% [[ 83 (** %\vspace{-.15in}% [[
84 = 1 84 = 1
85 : nat 85 : nat
86
87 ]] 86 ]]
88 87
89 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 %\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.
90 89
91 [[ 90 %\vspace{-.15in}%[[
92 Definition pred_strong1' (n : nat) (pf : n > 0) : nat := 91 Definition pred_strong1' (n : nat) (pf : n > 0) : nat :=
93 match n with 92 match n with
94 | O => match zgtz pf with end 93 | O => match zgtz pf with end
95 | S n' => n' 94 | S n' => n'
96 end. 95 end.
150 149
151 Print sig. 150 Print sig.
152 (** %\vspace{-.15in}% [[ 151 (** %\vspace{-.15in}% [[
153 Inductive sig (A : Type) (P : A -> Prop) : Type := 152 Inductive sig (A : Type) (P : A -> Prop) : Type :=
154 exist : forall x : A, P x -> sig P 153 exist : forall x : A, P x -> sig P
155
156 ]] 154 ]]
157 155
158 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 %\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.
159 157
160 We rewrite [pred_strong1], using some syntactic sugar for subset types. *) 158 We rewrite [pred_strong1], using some syntactic sugar for subset types. *)
161 159
162 Locate "{ _ : _ | _ }". 160 Locate "{ _ : _ | _ }".
163 (** %\vspace{-.15in}% [[ 161 (** %\vspace{-.15in}% [[
299 | S n' => 297 | S n' =>
300 fun _ : S n' > 0 => 298 fun _ : S n' > 0 =>
301 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'))
302 end 300 end
303 : forall n : nat, n > 0 -> {m : nat | n = S m} 301 : forall n : nat, n > 0 -> {m : nat | n = S m}
304
305 ]] 302 ]]
306 303
307 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 %\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. *)
308 305
309 Eval compute in pred_strong4 two_gt0. 306 Eval compute in pred_strong4 two_gt0.
310 (** %\vspace{-.15in}% [[ 307 (** %\vspace{-.15in}% [[
311 = exist (fun m : nat => 2 = S m) 1 (eq_refl 2) 308 = exist (fun m : nat => 2 = S m) 1 (eq_refl 2)
312 : {m : nat | 2 = S m} 309 : {m : nat | 2 = S m}
313 ]] 310 ]]
314 311
315 A tactic modifier called %\index{tactics!abstract}%[abstract] can be helpful for producing shorter terms, by automatically abstracting subgoals into named lemmas. *) 312 %\smallskip{}%A tactic modifier called %\index{tactics!abstract}%[abstract] can be helpful for producing shorter terms, by automatically abstracting subgoals into named lemmas. *)
316 313
317 (* begin thide *) 314 (* begin thide *)
318 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}.
319 refine (fun n => 316 refine (fun n =>
320 match n with 317 match n with
359 (** %\vspace{-.15in}% [[ 356 (** %\vspace{-.15in}% [[
360 = [1] 357 = [1]
361 : {m : nat | 2 = S m} 358 : {m : nat | 2 = S m}
362 ]] 359 ]]
363 360
364 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 %\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}% *)
365 362
366 Obligation Tactic := crush. 363 Obligation Tactic := crush.
367 364
368 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} :=
369 match n with 366 match n with
377 (** %\vspace{-.15in}% [[ 374 (** %\vspace{-.15in}% [[
378 = [1] 375 = [1]
379 : {m : nat | 2 = S m} 376 : {m : nat | 2 = S m}
380 ]] 377 ]]
381 378
382 In this case, we see that the new definition yields the same computational behavior as before. *) 379 %\smallskip{}%In this case, we see that the new definition yields the same computational behavior as before. *)
383 380
384 381
385 (** * Decidable Proposition Types *) 382 (** * Decidable Proposition Types *)
386 383
387 (** 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}% *)
421 Eval compute in eq_nat_dec 2 3. 418 Eval compute in eq_nat_dec 2 3.
422 (** %\vspace{-.15in}% [[ 419 (** %\vspace{-.15in}% [[
423 = No 420 = No
424 : {2 = 3} + {2 <> 3} 421 : {2 = 3} + {2 <> 3}
425 ]] 422 ]]
426 *) 423
427 424 %\smallskip{}%Note that the %\coqdocnotation{%#<tt>#Yes#</tt>#%}% and %\coqdocnotation{%#<tt>#No#</tt>#%}% notations are hiding proofs establishing the correctness of the outputs.
428 (** Note that the %\coqdocnotation{%#<tt>#Yes#</tt>#%}% and %\coqdocnotation{%#<tt>#No#</tt>#%}% notations are hiding proofs establishing the correctness of the outputs.
429 425
430 Our definition extracts to reasonable OCaml code. *) 426 Our definition extracts to reasonable OCaml code. *)
431 427
432 Extraction eq_nat_dec. 428 Extraction eq_nat_dec.
433 429
530 Eval compute in In_dec eq_nat_dec 3 (1 :: 2 :: nil). 526 Eval compute in In_dec eq_nat_dec 3 (1 :: 2 :: nil).
531 (** %\vspace{-.15in}% [[ 527 (** %\vspace{-.15in}% [[
532 = No 528 = No
533 : {In 3 (1 :: 2 :: nil)} + {~ In 3 (1 :: 2 :: nil)} 529 : {In 3 (1 :: 2 :: nil)} + {~ In 3 (1 :: 2 :: nil)}
534 ]] 530 ]]
535 *) 531
536 532 %\smallskip{}%[In_dec] has a reasonable extraction to OCaml. *)
537 (** [In_dec] has a reasonable extraction to OCaml. *)
538 533
539 Extraction In_dec. 534 Extraction In_dec.
540 (* end thide *) 535 (* end thide *)
541 536
542 (** %\begin{verbatim} 537 (** %\begin{verbatim}
599 (** %\vspace{-.15in}% [[ 594 (** %\vspace{-.15in}% [[
600 = ?? 595 = ??
601 : {{m | 0 = S m}} 596 : {{m | 0 = S m}}
602 ]] 597 ]]
603 598
604 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 %\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]. *)
605 600
606 Print sumor. 601 Print sumor.
607 (** %\vspace{-.15in}% [[ 602 (** %\vspace{-.15in}% [[
608 Inductive sumor (A : Type) (B : Prop) : Type := 603 Inductive sumor (A : Type) (B : Prop) : Type :=
609 inleft : A -> A + {B} | inright : B -> A + {B} 604 inleft : A -> A + {B} | inright : B -> A + {B}
610 ]] 605 ]]
611 *) 606
612 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. *)
613 (** 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. *)
614 608
615 Notation "!!" := (inright _ _). 609 Notation "!!" := (inright _ _).
616 Notation "[|| x ||]" := (inleft _ [x]). 610 Notation "[|| x ||]" := (inleft _ [x]).
617 611
618 (** 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. *)
779 Eval simpl in typeCheck (Plus (Nat 1) (Bool false)). 773 Eval simpl in typeCheck (Plus (Nat 1) (Bool false)).
780 (** %\vspace{-.15in}% [[ 774 (** %\vspace{-.15in}% [[
781 = ?? 775 = ??
782 : {{t | hasType (Plus (Nat 1) (Bool false)) t}} 776 : {{t | hasType (Plus (Nat 1) (Bool false)) t}}
783 ]] 777 ]]
784 *) 778
785 779 %\smallskip{}%The type checker also extracts to some reasonable OCaml code. *)
786 (** The type checker also extracts to some reasonable OCaml code. *)
787 780
788 Extraction typeCheck. 781 Extraction typeCheck.
789 782
790 (** %\begin{verbatim} 783 (** %\begin{verbatim}
791 (** val typeCheck : exp -> type0 maybe **) 784 (** val typeCheck : exp -> type0 maybe **)
934 = !! 927 = !!
935 : {t : type | hasType (Plus (Nat 1) (Bool false)) t} + 928 : {t : type | hasType (Plus (Nat 1) (Bool false)) t} +
936 {(forall t : type, ~ hasType (Plus (Nat 1) (Bool false)) t)} 929 {(forall t : type, ~ hasType (Plus (Nat 1) (Bool false)) t)}
937 ]] 930 ]]
938 931
939 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 %\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. *)