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