comparison src/MoreDep.v @ 417:539ed97750bb

Update for Coq trunk version intended for final 8.4 release
author Adam Chlipala <adam@chlipala.net>
date Tue, 17 Jul 2012 16:37:58 -0400
parents ded318830bb0
children 6ed5ee4845e4
comparison
equal deleted inserted replaced
416:ded318830bb0 417:539ed97750bb
278 end. 278 end.
279 (* end thide *) 279 (* end thide *)
280 280
281 (** There is one important subtlety in this definition. Coq allows us to use convenient ML-style pattern matching notation, but, internally and in proofs, we see that patterns are expanded out completely, matching one level of inductive structure at a time. Thus, the default case in the [match] above expands out to one case for each constructor of [exp] besides [Pair], and the underscore in [pairOutDefault _] is resolved differently in each case. From an ML or Haskell programmer's perspective, what we have here is type inference determining which code is run (returning either [None] or [tt]), which goes beyond what is possible with type inference guiding parametric polymorphism in Hindley-Milner languages%\index{Hindley-Milner}%, but is similar to what goes on with Haskell type classes%\index{type classes}%. 281 (** There is one important subtlety in this definition. Coq allows us to use convenient ML-style pattern matching notation, but, internally and in proofs, we see that patterns are expanded out completely, matching one level of inductive structure at a time. Thus, the default case in the [match] above expands out to one case for each constructor of [exp] besides [Pair], and the underscore in [pairOutDefault _] is resolved differently in each case. From an ML or Haskell programmer's perspective, what we have here is type inference determining which code is run (returning either [None] or [tt]), which goes beyond what is possible with type inference guiding parametric polymorphism in Hindley-Milner languages%\index{Hindley-Milner}%, but is similar to what goes on with Haskell type classes%\index{type classes}%.
282 282
283 With [pairOut] available, we can write [cfold] in a straightforward way. There are really no surprises beyond that Coq verifies that this code has such an expressive type, given the small annotation burden. In some places, we see that Coq's [match] annotation inference is too smart for its own good, and we have to turn that inference off by writing [return _]. *) 283 With [pairOut] available, we can write [cfold] in a straightforward way. There are really no surprises beyond that Coq verifies that this code has such an expressive type, given the small annotation burden. In some places, we see that Coq's [match] annotation inference is too smart for its own good, and we have to turn that inference with explicit [return] clauses. *)
284 284
285 Fixpoint cfold t (e : exp t) : exp t := 285 Fixpoint cfold t (e : exp t) : exp t :=
286 match e with 286 match e with
287 | NConst n => NConst n 287 | NConst n => NConst n
288 | Plus e1 e2 => 288 | Plus e1 e2 =>
289 let e1' := cfold e1 in 289 let e1' := cfold e1 in
290 let e2' := cfold e2 in 290 let e2' := cfold e2 in
291 match e1', e2' return _ with 291 match e1', e2' return exp Nat with
292 | NConst n1, NConst n2 => NConst (n1 + n2) 292 | NConst n1, NConst n2 => NConst (n1 + n2)
293 | _, _ => Plus e1' e2' 293 | _, _ => Plus e1' e2'
294 end 294 end
295 | Eq e1 e2 => 295 | Eq e1 e2 =>
296 let e1' := cfold e1 in 296 let e1' := cfold e1 in
297 let e2' := cfold e2 in 297 let e2' := cfold e2 in
298 match e1', e2' return _ with 298 match e1', e2' return exp Bool with
299 | NConst n1, NConst n2 => BConst (if eq_nat_dec n1 n2 then true else false) 299 | NConst n1, NConst n2 => BConst (if eq_nat_dec n1 n2 then true else false)
300 | _, _ => Eq e1' e2' 300 | _, _ => Eq e1' e2'
301 end 301 end
302 302
303 | BConst b => BConst b 303 | BConst b => BConst b
304 | And e1 e2 => 304 | And e1 e2 =>
305 let e1' := cfold e1 in 305 let e1' := cfold e1 in
306 let e2' := cfold e2 in 306 let e2' := cfold e2 in
307 match e1', e2' return _ with 307 match e1', e2' return exp Bool with
308 | BConst b1, BConst b2 => BConst (b1 && b2) 308 | BConst b1, BConst b2 => BConst (b1 && b2)
309 | _, _ => And e1' e2' 309 | _, _ => And e1' e2'
310 end 310 end
311 | If _ e e1 e2 => 311 | If _ e e1 e2 =>
312 let e' := cfold e in 312 let e' := cfold e in