Mercurial > cpdt > repo
comparison src/Subset.v @ 471:51a8472aca68
Batch of changes based on proofreader feedback
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Mon, 08 Oct 2012 16:04:49 -0400 |
parents | b36876d4611e |
children | d9e1fb184672 |
comparison
equal
deleted
inserted
replaced
470:0df6dde807ab | 471:51a8472aca68 |
---|---|
105 | 105 |
106 The term [zgtz pf] fails to type-check. Somehow the type checker has failed to take into account information that follows from which [match] branch that term appears in. The problem is that, by default, [match] does not let us use such implied information. To get refined typing, we must always rely on [match] annotations, either written explicitly or inferred. | 106 The term [zgtz pf] fails to type-check. Somehow the type checker has failed to take into account information that follows from which [match] branch that term appears in. The problem is that, by default, [match] does not let us use such implied information. To get refined typing, we must always rely on [match] annotations, either written explicitly or inferred. |
107 | 107 |
108 In this case, we must use a [return] annotation to declare the relationship between the _value_ of the [match] discriminee and the _type_ of the result. There is no annotation that lets us declare a relationship between the discriminee and the type of a variable that is already in scope; hence, we delay the binding of [pf], so that we can use the [return] annotation to express the needed relationship. | 108 In this case, we must use a [return] annotation to declare the relationship between the _value_ of the [match] discriminee and the _type_ of the result. There is no annotation that lets us declare a relationship between the discriminee and the type of a variable that is already in scope; hence, we delay the binding of [pf], so that we can use the [return] annotation to express the needed relationship. |
109 | 109 |
110 We are lucky that Coq's heuristics infer the [return] clause (specifically, [return n > 0 -> nat]) for us in this case. *) | 110 We are lucky that Coq's heuristics infer the [return] clause (specifically, [return n > 0 -> nat]) for us in the definition of [pred_strong1], leading to the following elaborated code: *) |
111 | 111 |
112 Definition pred_strong1' (n : nat) : n > 0 -> nat := | 112 Definition pred_strong1' (n : nat) : n > 0 -> nat := |
113 match n return n > 0 -> nat with | 113 match n return n > 0 -> nat with |
114 | O => fun pf : 0 > 0 => match zgtz pf with end | 114 | O => fun pf : 0 > 0 => match zgtz pf with end |
115 | S n' => fun _ => n' | 115 | S n' => fun _ => n' |
136 | O -> assert false (* absurd case *) | 136 | O -> assert false (* absurd case *) |
137 | S n' -> n' | 137 | S n' -> n' |
138 </pre># *) | 138 </pre># *) |
139 | 139 |
140 (** The proof argument has disappeared! We get exactly the OCaml code we would have written manually. This is our first demonstration of the main technically interesting feature of Coq program extraction: proofs are erased systematically. | 140 (** The proof argument has disappeared! We get exactly the OCaml code we would have written manually. This is our first demonstration of the main technically interesting feature of Coq program extraction: proofs are erased systematically. |
141 | |
142 %\medskip% | |
141 | 143 |
142 We can reimplement our dependently typed [pred] based on%\index{subset types}% _subset types_, defined in the standard library with the type family %\index{Gallina terms!sig}%[sig]. *) | 144 We can reimplement our dependently typed [pred] based on%\index{subset types}% _subset types_, defined in the standard library with the type family %\index{Gallina terms!sig}%[sig]. *) |
143 | 145 |
144 (* begin hide *) | 146 (* begin hide *) |
145 (* begin thide *) | 147 (* begin thide *) |
387 (** %\vspace{-.15in}% [[ | 389 (** %\vspace{-.15in}% [[ |
388 Inductive sumbool (A : Prop) (B : Prop) : Set := | 390 Inductive sumbool (A : Prop) (B : Prop) : Set := |
389 left : A -> {A} + {B} | right : B -> {A} + {B} | 391 left : A -> {A} + {B} | right : B -> {A} + {B} |
390 ]] | 392 ]] |
391 | 393 |
392 We can define some notations to make working with [sumbool] more convenient. *) | 394 Here, the constructors of [sumbool] have types written in terms of a registered notation for [sumbool], such that the result type of each constructor desugars to [sumbool A B]. We can define some notations of our own to make working with [sumbool] more convenient. *) |
393 | 395 |
394 Notation "'Yes'" := (left _ _). | 396 Notation "'Yes'" := (left _ _). |
395 Notation "'No'" := (right _ _). | 397 Notation "'No'" := (right _ _). |
396 Notation "'Reduce' x" := (if x then Yes else No) (at level 50). | 398 Notation "'Reduce' x" := (if x then Yes else No) (at level 50). |
397 | 399 |
636 (** As with our other maximally expressive [pred] function, we arrive at quite simple output values, thanks to notations. *) | 638 (** As with our other maximally expressive [pred] function, we arrive at quite simple output values, thanks to notations. *) |
637 | 639 |
638 | 640 |
639 (** * Monadic Notations *) | 641 (** * Monadic Notations *) |
640 | 642 |
641 (** We can treat [maybe] like a monad%~\cite{Monads}\index{monad}\index{failure monad}%, in the same way that the Haskell <<Maybe>> type is interpreted as a failure monad. Our [maybe] has the wrong type to be a literal monad, but a "bind"-like notation will still be helpful. *) | 643 (** We can treat [maybe] like a monad%~\cite{Monads}\index{monad}\index{failure monad}%, in the same way that the Haskell <<Maybe>> type is interpreted as a failure monad. Our [maybe] has the wrong type to be a literal monad, but a "bind"-like notation will still be helpful. %Note that the notation definition uses an ASCII \texttt{<-}, while later code uses (in this rendering) a nicer left arrow $\leftarrow$.% *) |
642 | 644 |
643 Notation "x <- e1 ; e2" := (match e1 with | 645 Notation "x <- e1 ; e2" := (match e1 with |
644 | Unknown => ?? | 646 | Unknown => ?? |
645 | Found x _ => e2 | 647 | Found x _ => e2 |
646 end) | 648 end) |
659 m2 <- pred_strong7 n2; | 661 m2 <- pred_strong7 n2; |
660 [|(m1, m2)|]); tauto. | 662 [|(m1, m2)|]); tauto. |
661 Defined. | 663 Defined. |
662 (* end thide *) | 664 (* end thide *) |
663 | 665 |
664 (** We can build a [sumor] version of the "bind" notation and use it to write a similarly straightforward version of this function. %The operator rendered here as $\longleftarrow$ is noted in the source as a less-than character followed by two hyphens.% *) | 666 (** We can build a [sumor] version of the "bind" notation and use it to write a similarly straightforward version of this function. %Again, the notation definition exposes the ASCII syntax with an operator \texttt{<-{}-}, while the later code uses a nicer long left arrow $\longleftarrow$.% *) |
665 | 667 |
666 Notation "x <-- e1 ; e2" := (match e1 with | 668 Notation "x <-- e1 ; e2" := (match e1 with |
667 | inright _ => !! | 669 | inright _ => !! |
668 | inleft (exist x _) => e2 | 670 | inleft (exist x _) => e2 |
669 end) | 671 end) |
894 eq_type_dec t1 TBool;;; | 896 eq_type_dec t1 TBool;;; |
895 eq_type_dec t2 TBool;;; | 897 eq_type_dec t2 TBool;;; |
896 [||TBool||] | 898 [||TBool||] |
897 end); clear F; crush' tt hasType; eauto. | 899 end); clear F; crush' tt hasType; eauto. |
898 | 900 |
899 (** We clear [F], the local name for the recursive function, to avoid strange proofs that refer to recursive calls that we never make. The [crush] variant %\index{tactics!crush'}%[crush'] helps us by performing automatic inversion on instances of the predicates specified in its second argument. Once we throw in [eauto] to apply [hasType_det] for us, we have discharged all the subgoals. *) | 901 (** We clear [F], the local name for the recursive function, to avoid strange proofs that refer to recursive calls that we never make. Such a step is usually warranted when defining a recursive function with [refine]. The [crush] variant %\index{tactics!crush'}%[crush'] helps us by performing automatic inversion on instances of the predicates specified in its second argument. Once we throw in [eauto] to apply [hasType_det] for us, we have discharged all the subgoals. *) |
900 (* end thide *) | 902 (* end thide *) |
901 | 903 |
902 | 904 |
903 Defined. | 905 Defined. |
904 | 906 |