comparison src/MoreDep.v @ 443:97c60ffdb998

Vertical spacing pass for MoreDep and DataStruct
author Adam Chlipala <adam@chlipala.net>
date Wed, 01 Aug 2012 16:32:04 -0400
parents 8077352044b2
children 2740b8a23cce
comparison
equal deleted inserted replaced
442:89c67796754e 443:97c60ffdb998
85 (* end thide *) 85 (* end thide *)
86 86
87 (* EX: Implement statically checked "car"/"hd" *) 87 (* EX: Implement statically checked "car"/"hd" *)
88 88
89 (** Now let us attempt a function that is surprisingly tricky to write. In ML, the list head function raises an exception when passed an empty list. With length-indexed lists, we can rule out such invalid calls statically, and here is a first attempt at doing so. We write [???] as a placeholder for a term that we do not know how to write, not for any real Coq notation like those introduced two chapters ago. 89 (** Now let us attempt a function that is surprisingly tricky to write. In ML, the list head function raises an exception when passed an empty list. With length-indexed lists, we can rule out such invalid calls statically, and here is a first attempt at doing so. We write [???] as a placeholder for a term that we do not know how to write, not for any real Coq notation like those introduced two chapters ago.
90
91 [[ 90 [[
92 Definition hd n (ls : ilist (S n)) : A := 91 Definition hd n (ls : ilist (S n)) : A :=
93 match ls with 92 match ls with
94 | Nil => ??? 93 | Nil => ???
95 | Cons _ h _ => h 94 | Cons _ h _ => h
96 end. 95 end.
97
98 ]] 96 ]]
99
100 It is not clear what to write for the [Nil] case, so we are stuck before we even turn our function over to the type checker. We could try omitting the [Nil] case: 97 It is not clear what to write for the [Nil] case, so we are stuck before we even turn our function over to the type checker. We could try omitting the [Nil] case:
101
102 [[ 98 [[
103 Definition hd n (ls : ilist (S n)) : A := 99 Definition hd n (ls : ilist (S n)) : A :=
104 match ls with 100 match ls with
105 | Cons _ h _ => h 101 | Cons _ h _ => h
106 end. 102 end.
139 hd' 135 hd'
140 : forall n : nat, ilist n -> match n with 136 : forall n : nat, ilist n -> match n with
141 | 0 => unit 137 | 0 => unit
142 | S _ => A 138 | S _ => A
143 end 139 end
144
145 ]] 140 ]]
146 *) 141 *)
147 142
148 Definition hd n (ls : ilist (S n)) : A := hd' ls. 143 Definition hd n (ls : ilist (S n)) : A := hd' ls.
149 (* end thide *) 144 (* end thide *)
241 (* end hide *) 236 (* end hide *)
242 237
243 (** Despite the fancy type, the function definition is routine. In fact, it is less complicated than what we would write in ML or Haskell 98, since we do not need to worry about pushing final values in and out of an algebraic datatype. The only unusual thing is the use of an expression of the form [if E then true else false] in the [Eq] case. Remember that [eq_nat_dec] has a rich dependent type, rather than a simple boolean type. Coq's native [if] is overloaded to work on a test of any two-constructor type, so we can use [if] to build a simple boolean from the [sumbool] that [eq_nat_dec] returns. 238 (** Despite the fancy type, the function definition is routine. In fact, it is less complicated than what we would write in ML or Haskell 98, since we do not need to worry about pushing final values in and out of an algebraic datatype. The only unusual thing is the use of an expression of the form [if E then true else false] in the [Eq] case. Remember that [eq_nat_dec] has a rich dependent type, rather than a simple boolean type. Coq's native [if] is overloaded to work on a test of any two-constructor type, so we can use [if] to build a simple boolean from the [sumbool] that [eq_nat_dec] returns.
244 239
245 We can implement our old favorite, a constant folding function, and prove it correct. It will be useful to write a function [pairOut] that checks if an [exp] of [Prod] type is a pair, returning its two components if so. Unsurprisingly, a first attempt leads to a type error. 240 We can implement our old favorite, a constant folding function, and prove it correct. It will be useful to write a function [pairOut] that checks if an [exp] of [Prod] type is a pair, returning its two components if so. Unsurprisingly, a first attempt leads to a type error.
246
247 [[ 241 [[
248 Definition pairOut t1 t2 (e : exp (Prod t1 t2)) : option (exp t1 * exp t2) := 242 Definition pairOut t1 t2 (e : exp (Prod t1 t2)) : option (exp t1 * exp t2) :=
249 match e in (exp (Prod t1 t2)) return option (exp t1 * exp t2) with 243 match e in (exp (Prod t1 t2)) return option (exp t1 * exp t2) with
250 | Pair _ _ e1 e2 => Some (e1, e2) 244 | Pair _ _ e1 e2 => Some (e1, e2)
251 | _ => None 245 | _ => None
372 end 366 end
373 367
374 ]] 368 ]]
375 369
376 We would like to do a case analysis on [cfold e1], and we attempt that in the way that has worked so far. 370 We would like to do a case analysis on [cfold e1], and we attempt that in the way that has worked so far.
377
378 [[ 371 [[
379 destruct (cfold e1). 372 destruct (cfold e1).
380 ]] 373 ]]
381 374
382 << 375 <<
535 End present. 528 End present.
536 529
537 (** Insertion relies on two balancing operations. It will be useful to give types to these operations using a relative of the subset types from last chapter. While subset types let us pair a value with a proof about that value, here we want to pair a value with another non-proof dependently typed value. The %\index{Gallina terms!sigT}%[sigT] type fills this role. *) 530 (** Insertion relies on two balancing operations. It will be useful to give types to these operations using a relative of the subset types from last chapter. While subset types let us pair a value with a proof about that value, here we want to pair a value with another non-proof dependently typed value. The %\index{Gallina terms!sigT}%[sigT] type fills this role. *)
538 531
539 Locate "{ _ : _ & _ }". 532 Locate "{ _ : _ & _ }".
540 (** [[ 533 (** %\vspace{-.15in}%[[
541 Notation Scope 534 Notation Scope
542 "{ x : A & P }" := sigT (fun x : A => P) 535 "{ x : A & P }" := sigT (fun x : A => P)
543 ]] 536 ]]
544 *) 537 *)
545 538
546 Print sigT. 539 Print sigT.
547 (** [[ 540 (** %\vspace{-.15in}%[[
548 Inductive sigT (A : Type) (P : A -> Type) : Type := 541 Inductive sigT (A : Type) (P : A -> Type) : Type :=
549 existT : forall x : A, P x -> sigT P 542 existT : forall x : A, P x -> sigT P
550 ]] 543 ]]
551 *) 544 *)
552 545