Mercurial > cpdt > repo
comparison src/Equality.v @ 426:5f25705a10ea
Pass through DataStruct, to incorporate new coqdoc features; globally replace [refl_equal] with [eq_refl]
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Wed, 25 Jul 2012 18:10:26 -0400 |
parents | ff0aef0f33a5 |
children | 5e6b76ca14de |
comparison
equal
deleted
inserted
replaced
425:6ed5ee4845e4 | 426:5f25705a10ea |
---|---|
198 match ls return fhlist ls -> fmember ls -> B elm with | 198 match ls return fhlist ls -> fmember ls -> B elm with |
199 | nil => fun _ idx => match idx with end | 199 | nil => fun _ idx => match idx with end |
200 | _ :: ls' => fun mls idx => | 200 | _ :: ls' => fun mls idx => |
201 match idx with | 201 match idx with |
202 | inl pf => match pf with | 202 | inl pf => match pf with |
203 | refl_equal => fst mls | 203 | eq_refl => fst mls |
204 end | 204 end |
205 | inr idx' => fhget ls' (snd mls) idx' | 205 | inr idx' => fhget ls' (snd mls) idx' |
206 end | 206 end |
207 end. | 207 end. |
208 End fhlist. | 208 End fhlist. |
242 Part of our single remaining subgoal is: | 242 Part of our single remaining subgoal is: |
243 [[ | 243 [[ |
244 a0 : a = elm | 244 a0 : a = elm |
245 ============================ | 245 ============================ |
246 match a0 in (_ = a2) return (C a2) with | 246 match a0 in (_ = a2) return (C a2) with |
247 | refl_equal => f a1 | 247 | eq_refl => f a1 |
248 end = f match a0 in (_ = a2) return (B a2) with | 248 end = f match a0 in (_ = a2) return (B a2) with |
249 | refl_equal => a1 | 249 | eq_refl => a1 |
250 end | 250 end |
251 ]] | 251 ]] |
252 | 252 |
253 This seems like a trivial enough obligation. The equality proof [a0] must be [refl_equal], since that is the only constructor of [eq]. Therefore, both the [match]es reduce to the point where the conclusion follows by reflexivity. | 253 This seems like a trivial enough obligation. The equality proof [a0] must be [eq_refl], since that is the only constructor of [eq]. Therefore, both the [match]es reduce to the point where the conclusion follows by reflexivity. |
254 [[ | 254 [[ |
255 destruct a0. | 255 destruct a0. |
256 ]] | 256 ]] |
257 | 257 |
258 << | 258 << |
259 User error: Cannot solve a second-order unification problem | 259 User error: Cannot solve a second-order unification problem |
260 >> | 260 >> |
261 | 261 |
262 This is one of Coq's standard error messages for informing us that its heuristics for attempting an instance of an undecidable problem about dependent typing have failed. We might try to nudge things in the right direction by stating the lemma that we believe makes the conclusion trivial. | 262 This is one of Coq's standard error messages for informing us that its heuristics for attempting an instance of an undecidable problem about dependent typing have failed. We might try to nudge things in the right direction by stating the lemma that we believe makes the conclusion trivial. |
263 [[ | 263 [[ |
264 assert (a0 = refl_equal _). | 264 assert (a0 = eq_refl _). |
265 ]] | 265 ]] |
266 | 266 |
267 << | 267 << |
268 The term "refl_equal ?98" has type "?98 = ?98" | 268 The term "eq_refl ?98" has type "?98 = ?98" |
269 while it is expected to have type "a = elm" | 269 while it is expected to have type "a = elm" |
270 >> | 270 >> |
271 | 271 |
272 In retrospect, the problem is not so hard to see. Reflexivity proofs only show [x = x] for particular values of [x], whereas here we are thinking in terms of a proof of [a = elm], where the two sides of the equality are not equal syntactically. Thus, the essential lemma we need does not even type-check! | 272 In retrospect, the problem is not so hard to see. Reflexivity proofs only show [x = x] for particular values of [x], whereas here we are thinking in terms of a proof of [a = elm], where the two sides of the equality are not equal syntactically. Thus, the essential lemma we need does not even type-check! |
273 | 273 |
289 Qed. | 289 Qed. |
290 (* end thide *) | 290 (* end thide *) |
291 | 291 |
292 (** It will be helpful to examine the proof terms generated by this sort of strategy. A simpler example illustrates what is going on. *) | 292 (** It will be helpful to examine the proof terms generated by this sort of strategy. A simpler example illustrates what is going on. *) |
293 | 293 |
294 Lemma lemma1 : forall x (pf : x = elm), O = match pf with refl_equal => O end. | 294 Lemma lemma1 : forall x (pf : x = elm), O = match pf with eq_refl => O end. |
295 (* begin thide *) | 295 (* begin thide *) |
296 simple destruct pf; reflexivity. | 296 simple destruct pf; reflexivity. |
297 Qed. | 297 Qed. |
298 (* end thide *) | 298 (* end thide *) |
299 | 299 |
302 Print lemma1. | 302 Print lemma1. |
303 (** %\vspace{-.15in}% [[ | 303 (** %\vspace{-.15in}% [[ |
304 lemma1 = | 304 lemma1 = |
305 fun (x : A) (pf : x = elm) => | 305 fun (x : A) (pf : x = elm) => |
306 match pf as e in (_ = y) return (0 = match e with | 306 match pf as e in (_ = y) return (0 = match e with |
307 | refl_equal => 0 | 307 | eq_refl => 0 |
308 end) with | 308 end) with |
309 | refl_equal => refl_equal 0 | 309 | eq_refl => eq_refl 0 |
310 end | 310 end |
311 : forall (x : A) (pf : x = elm), 0 = match pf with | 311 : forall (x : A) (pf : x = elm), 0 = match pf with |
312 | refl_equal => 0 | 312 | eq_refl => 0 |
313 end | 313 end |
314 | 314 |
315 ]] | 315 ]] |
316 | 316 |
317 Using what we know about shorthands for [match] annotations, we can write this proof in shorter form manually. *) | 317 Using what we know about shorthands for [match] annotations, we can write this proof in shorter form manually. *) |
318 | 318 |
319 (* begin thide *) | 319 (* begin thide *) |
320 Definition lemma1' := | 320 Definition lemma1' := |
321 fun (x : A) (pf : x = elm) => | 321 fun (x : A) (pf : x = elm) => |
322 match pf return (0 = match pf with | 322 match pf return (0 = match pf with |
323 | refl_equal => 0 | 323 | eq_refl => 0 |
324 end) with | 324 end) with |
325 | refl_equal => refl_equal 0 | 325 | eq_refl => eq_refl 0 |
326 end. | 326 end. |
327 (* end thide *) | 327 (* end thide *) |
328 | 328 |
329 (** Surprisingly, what seems at first like a _simpler_ lemma is harder to prove. *) | 329 (** Surprisingly, what seems at first like a _simpler_ lemma is harder to prove. *) |
330 | 330 |
331 Lemma lemma2 : forall (x : A) (pf : x = x), O = match pf with refl_equal => O end. | 331 Lemma lemma2 : forall (x : A) (pf : x = x), O = match pf with eq_refl => O end. |
332 (* begin thide *) | 332 (* begin thide *) |
333 (** %\vspace{-.25in}%[[ | 333 (** %\vspace{-.25in}%[[ |
334 simple destruct pf. | 334 simple destruct pf. |
335 ]] | 335 ]] |
336 | 336 |
344 | 344 |
345 (* begin thide *) | 345 (* begin thide *) |
346 Definition lemma2 := | 346 Definition lemma2 := |
347 fun (x : A) (pf : x = x) => | 347 fun (x : A) (pf : x = x) => |
348 match pf return (0 = match pf with | 348 match pf return (0 = match pf with |
349 | refl_equal => 0 | 349 | eq_refl => 0 |
350 end) with | 350 end) with |
351 | refl_equal => refl_equal 0 | 351 | eq_refl => eq_refl 0 |
352 end. | 352 end. |
353 (* end thide *) | 353 (* end thide *) |
354 | 354 |
355 (** We can try to prove a lemma that would simplify proofs of many facts like [lemma2]: *) | 355 (** We can try to prove a lemma that would simplify proofs of many facts like [lemma2]: *) |
356 | 356 |
357 Lemma lemma3 : forall (x : A) (pf : x = x), pf = refl_equal x. | 357 Lemma lemma3 : forall (x : A) (pf : x = x), pf = eq_refl x. |
358 (* begin thide *) | 358 (* begin thide *) |
359 (** %\vspace{-.25in}%[[ | 359 (** %\vspace{-.25in}%[[ |
360 simple destruct pf. | 360 simple destruct pf. |
361 ]] | 361 ]] |
362 | 362 |
369 | 369 |
370 (** This time, even our manual attempt fails. | 370 (** This time, even our manual attempt fails. |
371 [[ | 371 [[ |
372 Definition lemma3' := | 372 Definition lemma3' := |
373 fun (x : A) (pf : x = x) => | 373 fun (x : A) (pf : x = x) => |
374 match pf as pf' in (_ = x') return (pf' = refl_equal x') with | 374 match pf as pf' in (_ = x') return (pf' = eq_refl x') with |
375 | refl_equal => refl_equal _ | 375 | eq_refl => eq_refl _ |
376 end. | 376 end. |
377 ]] | 377 ]] |
378 | 378 |
379 << | 379 << |
380 The term "refl_equal x'" has type "x' = x'" while it is expected to have type | 380 The term "eq_refl x'" has type "x' = x'" while it is expected to have type |
381 "x = x'" | 381 "x = x'" |
382 >> | 382 >> |
383 | 383 |
384 The type error comes from our [return] annotation. In that annotation, the [as]-bound variable [pf'] has type [x = x'], referring to the [in]-bound variable [x']. To do a dependent [match], we _must_ choose a fresh name for the second argument of [eq]. We are just as constrained to use the %``%#"#real#"#%''% value [x] for the first argument. Thus, within the [return] clause, the proof we are matching on _must_ equate two non-matching terms, which makes it impossible to equate that proof with reflexivity. | 384 The type error comes from our [return] annotation. In that annotation, the [as]-bound variable [pf'] has type [x = x'], referring to the [in]-bound variable [x']. To do a dependent [match], we _must_ choose a fresh name for the second argument of [eq]. We are just as constrained to use the %``%#"#real#"#%''% value [x] for the first argument. Thus, within the [return] clause, the proof we are matching on _must_ equate two non-matching terms, which makes it impossible to equate that proof with reflexivity. |
385 | 385 |
386 Nonetheless, it turns out that, with one catch, we _can_ prove this lemma. *) | 386 Nonetheless, it turns out that, with one catch, we _can_ prove this lemma. *) |
387 | 387 |
388 Lemma lemma3 : forall (x : A) (pf : x = x), pf = refl_equal x. | 388 Lemma lemma3 : forall (x : A) (pf : x = x), pf = eq_refl x. |
389 intros; apply UIP_refl. | 389 intros; apply UIP_refl. |
390 Qed. | 390 Qed. |
391 | 391 |
392 Check UIP_refl. | 392 Check UIP_refl. |
393 (** %\vspace{-.15in}% [[ | 393 (** %\vspace{-.15in}% [[ |
394 UIP_refl | 394 UIP_refl |
395 : forall (U : Type) (x : U) (p : x = x), p = refl_equal x | 395 : forall (U : Type) (x : U) (p : x = x), p = eq_refl x |
396 ]] | 396 ]] |
397 | 397 |
398 The theorem %\index{Gallina terms!UIP\_refl}%[UIP_refl] comes from the [Eqdep] module of the standard library. Do the Coq authors know of some clever trick for building such proofs that we have not seen yet? If they do, they did not use it for this proof. Rather, the proof is based on an _axiom_. *) | 398 The theorem %\index{Gallina terms!UIP\_refl}%[UIP_refl] comes from the [Eqdep] module of the standard library. Do the Coq authors know of some clever trick for building such proofs that we have not seen yet? If they do, they did not use it for this proof. Rather, the proof is based on an _axiom_. *) |
399 | 399 |
400 Print eq_rect_eq. | 400 Print eq_rect_eq. |
424 (* end thide *) | 424 (* end thide *) |
425 (** %\vspace{-.15in}% [[ | 425 (** %\vspace{-.15in}% [[ |
426 Streicher_K = | 426 Streicher_K = |
427 fun U : Type => UIP_refl__Streicher_K U (UIP_refl U) | 427 fun U : Type => UIP_refl__Streicher_K U (UIP_refl U) |
428 : forall (U : Type) (x : U) (P : x = x -> Prop), | 428 : forall (U : Type) (x : U) (P : x = x -> Prop), |
429 P (refl_equal x) -> forall p : x = x, P p | 429 P (eq_refl x) -> forall p : x = x, P p |
430 ]] | 430 ]] |
431 | 431 |
432 This is the unfortunately named %\index{axiom K}``%#"#Streicher's axiom K,#"#%''% which says that a predicate on properly typed equality proofs holds of all such proofs if it holds of reflexivity. *) | 432 This is the unfortunately named %\index{axiom K}``%#"#Streicher's axiom K,#"#%''% which says that a predicate on properly typed equality proofs holds of all such proofs if it holds of reflexivity. *) |
433 | 433 |
434 End fhlist_map. | 434 End fhlist_map. |
475 Theorem fhapp_ass : forall ls1 ls2 ls3 | 475 Theorem fhapp_ass : forall ls1 ls2 ls3 |
476 (pf : (ls1 ++ ls2) ++ ls3 = ls1 ++ (ls2 ++ ls3)) | 476 (pf : (ls1 ++ ls2) ++ ls3 = ls1 ++ (ls2 ++ ls3)) |
477 (hls1 : fhlist B ls1) (hls2 : fhlist B ls2) (hls3 : fhlist B ls3), | 477 (hls1 : fhlist B ls1) (hls2 : fhlist B ls2) (hls3 : fhlist B ls3), |
478 fhapp hls1 (fhapp hls2 hls3) | 478 fhapp hls1 (fhapp hls2 hls3) |
479 = match pf in (_ = ls) return fhlist _ ls with | 479 = match pf in (_ = ls) return fhlist _ ls with |
480 | refl_equal => fhapp (fhapp hls1 hls2) hls3 | 480 | eq_refl => fhapp (fhapp hls1 hls2) hls3 |
481 end. | 481 end. |
482 induction ls1; crush. | 482 induction ls1; crush. |
483 | 483 |
484 (** The first remaining subgoal looks trivial enough: | 484 (** The first remaining subgoal looks trivial enough: |
485 [[ | 485 [[ |
486 ============================ | 486 ============================ |
487 fhapp (ls1:=ls2) (ls2:=ls3) hls2 hls3 = | 487 fhapp (ls1:=ls2) (ls2:=ls3) hls2 hls3 = |
488 match pf in (_ = ls) return (fhlist B ls) with | 488 match pf in (_ = ls) return (fhlist B ls) with |
489 | refl_equal => fhapp (ls1:=ls2) (ls2:=ls3) hls2 hls3 | 489 | eq_refl => fhapp (ls1:=ls2) (ls2:=ls3) hls2 hls3 |
490 end | 490 end |
491 ]] | 491 ]] |
492 | 492 |
493 We can try what worked in previous examples. | 493 We can try what worked in previous examples. |
494 [[ | 494 [[ |
517 ============================ | 517 ============================ |
518 (a0, | 518 (a0, |
519 fhapp (ls1:=ls1) (ls2:=ls2 ++ ls3) b | 519 fhapp (ls1:=ls1) (ls2:=ls2 ++ ls3) b |
520 (fhapp (ls1:=ls2) (ls2:=ls3) hls2 hls3)) = | 520 (fhapp (ls1:=ls2) (ls2:=ls3) hls2 hls3)) = |
521 match pf in (_ = ls) return (fhlist B ls) with | 521 match pf in (_ = ls) return (fhlist B ls) with |
522 | refl_equal => | 522 | eq_refl => |
523 (a0, | 523 (a0, |
524 fhapp (ls1:=ls1 ++ ls2) (ls2:=ls3) | 524 fhapp (ls1:=ls1 ++ ls2) (ls2:=ls3) |
525 (fhapp (ls1:=ls1) (ls2:=ls2) b hls2) hls3) | 525 (fhapp (ls1:=ls1) (ls2:=ls2) b hls2) hls3) |
526 end | 526 end |
527 | 527 |
542 ============================ | 542 ============================ |
543 (a0, | 543 (a0, |
544 fhapp (ls1:=ls1) (ls2:=ls2 ++ ls3) b | 544 fhapp (ls1:=ls1) (ls2:=ls2 ++ ls3) b |
545 (fhapp (ls1:=ls2) (ls2:=ls3) hls2 hls3)) = | 545 (fhapp (ls1:=ls2) (ls2:=ls3) hls2 hls3)) = |
546 match pf in (_ = ls) return (fhlist B ls) with | 546 match pf in (_ = ls) return (fhlist B ls) with |
547 | refl_equal => | 547 | eq_refl => |
548 (a0, | 548 (a0, |
549 fhapp (ls1:=ls1 ++ ls2) (ls2:=ls3) | 549 fhapp (ls1:=ls1 ++ ls2) (ls2:=ls3) |
550 (fhapp (ls1:=ls1) (ls2:=ls2) b hls2) hls3) | 550 (fhapp (ls1:=ls1) (ls2:=ls2) b hls2) hls3) |
551 end | 551 end |
552 ]] | 552 ]] |
556 rewrite (IHls1 _ _ pf'). | 556 rewrite (IHls1 _ _ pf'). |
557 (** [[ | 557 (** [[ |
558 ============================ | 558 ============================ |
559 (a0, | 559 (a0, |
560 match pf' in (_ = ls) return (fhlist B ls) with | 560 match pf' in (_ = ls) return (fhlist B ls) with |
561 | refl_equal => | 561 | eq_refl => |
562 fhapp (ls1:=ls1 ++ ls2) (ls2:=ls3) | 562 fhapp (ls1:=ls1 ++ ls2) (ls2:=ls3) |
563 (fhapp (ls1:=ls1) (ls2:=ls2) b hls2) hls3 | 563 (fhapp (ls1:=ls1) (ls2:=ls2) b hls2) hls3 |
564 end) = | 564 end) = |
565 match pf in (_ = ls) return (fhlist B ls) with | 565 match pf in (_ = ls) return (fhlist B ls) with |
566 | refl_equal => | 566 | eq_refl => |
567 (a0, | 567 (a0, |
568 fhapp (ls1:=ls1 ++ ls2) (ls2:=ls3) | 568 fhapp (ls1:=ls1 ++ ls2) (ls2:=ls3) |
569 (fhapp (ls1:=ls1) (ls2:=ls2) b hls2) hls3) | 569 (fhapp (ls1:=ls1) (ls2:=ls2) b hls2) hls3) |
570 end | 570 end |
571 ]] | 571 ]] |
575 generalize (fhapp (fhapp b hls2) hls3). | 575 generalize (fhapp (fhapp b hls2) hls3). |
576 (** [[ | 576 (** [[ |
577 forall f : fhlist B ((ls1 ++ ls2) ++ ls3), | 577 forall f : fhlist B ((ls1 ++ ls2) ++ ls3), |
578 (a0, | 578 (a0, |
579 match pf' in (_ = ls) return (fhlist B ls) with | 579 match pf' in (_ = ls) return (fhlist B ls) with |
580 | refl_equal => f | 580 | eq_refl => f |
581 end) = | 581 end) = |
582 match pf in (_ = ls) return (fhlist B ls) with | 582 match pf in (_ = ls) return (fhlist B ls) with |
583 | refl_equal => (a0, f) | 583 | eq_refl => (a0, f) |
584 end | 584 end |
585 ]] | 585 ]] |
586 | 586 |
587 The conclusion has gotten markedly simpler. It seems counterintuitive that we can have an easier time of proving a more general theorem, but that is exactly the case here and for many other proofs that use dependent types heavily. Speaking informally, the reason why this kind of activity helps is that [match] annotations only support variables in certain positions. By reducing more elements of a goal to variables, built-in tactics can have more success building [match] terms under the hood. | 587 The conclusion has gotten markedly simpler. It seems counterintuitive that we can have an easier time of proving a more general theorem, but that is exactly the case here and for many other proofs that use dependent types heavily. Speaking informally, the reason why this kind of activity helps is that [match] annotations only support variables in certain positions. By reducing more elements of a goal to variables, built-in tactics can have more success building [match] terms under the hood. |
588 | 588 |
593 forall (pf0 : a :: (ls1 ++ ls2) ++ ls3 = a :: ls1 ++ ls2 ++ ls3) | 593 forall (pf0 : a :: (ls1 ++ ls2) ++ ls3 = a :: ls1 ++ ls2 ++ ls3) |
594 (pf'0 : (ls1 ++ ls2) ++ ls3 = ls1 ++ ls2 ++ ls3) | 594 (pf'0 : (ls1 ++ ls2) ++ ls3 = ls1 ++ ls2 ++ ls3) |
595 (f : fhlist B ((ls1 ++ ls2) ++ ls3)), | 595 (f : fhlist B ((ls1 ++ ls2) ++ ls3)), |
596 (a0, | 596 (a0, |
597 match pf'0 in (_ = ls) return (fhlist B ls) with | 597 match pf'0 in (_ = ls) return (fhlist B ls) with |
598 | refl_equal => f | 598 | eq_refl => f |
599 end) = | 599 end) = |
600 match pf0 in (_ = ls) return (fhlist B ls) with | 600 match pf0 in (_ = ls) return (fhlist B ls) with |
601 | refl_equal => (a0, f) | 601 | eq_refl => (a0, f) |
602 end | 602 end |
603 ]] | 603 ]] |
604 | 604 |
605 To an experienced dependent types hacker, the appearance of this goal term calls for a celebration. The formula has a critical property that indicates that our problems are over. To get our proofs into the right form to apply [UIP_refl], we need to use associativity of list append to rewrite their types. We could not do that before because other parts of the goal require the proofs to retain their original types. In particular, the call to [fhapp] that we generalized must have type [(ls1 ++ ls2) ++ ls3], for some values of the list variables. If we rewrite the type of the proof used to type-cast this value to something like [ls1 ++ ls2 ++ ls3 = ls1 ++ ls2 ++ ls3], then the lefthand side of the equality would no longer match the type of the term we are trying to cast. | 605 To an experienced dependent types hacker, the appearance of this goal term calls for a celebration. The formula has a critical property that indicates that our problems are over. To get our proofs into the right form to apply [UIP_refl], we need to use associativity of list append to rewrite their types. We could not do that before because other parts of the goal require the proofs to retain their original types. In particular, the call to [fhapp] that we generalized must have type [(ls1 ++ ls2) ++ ls3], for some values of the list variables. If we rewrite the type of the proof used to type-cast this value to something like [ls1 ++ ls2 ++ ls3 = ls1 ++ ls2 ++ ls3], then the lefthand side of the equality would no longer match the type of the term we are trying to cast. |
606 | 606 |
612 forall (pf0 : a :: ls1 ++ ls2 ++ ls3 = a :: ls1 ++ ls2 ++ ls3) | 612 forall (pf0 : a :: ls1 ++ ls2 ++ ls3 = a :: ls1 ++ ls2 ++ ls3) |
613 (pf'0 : ls1 ++ ls2 ++ ls3 = ls1 ++ ls2 ++ ls3) | 613 (pf'0 : ls1 ++ ls2 ++ ls3 = ls1 ++ ls2 ++ ls3) |
614 (f : fhlist B (ls1 ++ ls2 ++ ls3)), | 614 (f : fhlist B (ls1 ++ ls2 ++ ls3)), |
615 (a0, | 615 (a0, |
616 match pf'0 in (_ = ls) return (fhlist B ls) with | 616 match pf'0 in (_ = ls) return (fhlist B ls) with |
617 | refl_equal => f | 617 | eq_refl => f |
618 end) = | 618 end) = |
619 match pf0 in (_ = ls) return (fhlist B ls) with | 619 match pf0 in (_ = ls) return (fhlist B ls) with |
620 | refl_equal => (a0, f) | 620 | eq_refl => (a0, f) |
621 end | 621 end |
622 ]] | 622 ]] |
623 | 623 |
624 We can see that we have achieved the crucial property: the type of each generalized equality proof has syntactically equal operands. This makes it easy to finish the proof with [UIP_refl]. *) | 624 We can see that we have achieved the crucial property: the type of each generalized equality proof has syntactically equal operands. This makes it easy to finish the proof with [UIP_refl]. *) |
625 | 625 |
648 | 648 |
649 The identity [JMeq] stands for %\index{John Major equality}``%#"#John Major equality,#"#%''% a name coined by Conor McBride%~\cite{JMeq}% as a sort of pun about British politics. The definition [JMeq] starts out looking a lot like the definition of [eq]. The crucial difference is that we may use [JMeq] _on arguments of different types_. For instance, a lemma that we failed to establish before is trivial with [JMeq]. It makes for prettier theorem statements to define some syntactic shorthand first. *) | 649 The identity [JMeq] stands for %\index{John Major equality}``%#"#John Major equality,#"#%''% a name coined by Conor McBride%~\cite{JMeq}% as a sort of pun about British politics. The definition [JMeq] starts out looking a lot like the definition of [eq]. The crucial difference is that we may use [JMeq] _on arguments of different types_. For instance, a lemma that we failed to establish before is trivial with [JMeq]. It makes for prettier theorem statements to define some syntactic shorthand first. *) |
650 | 650 |
651 Infix "==" := JMeq (at level 70, no associativity). | 651 Infix "==" := JMeq (at level 70, no associativity). |
652 | 652 |
653 (* EX: Prove UIP_refl' : forall (A : Type) (x : A) (pf : x = x), pf == refl_equal x *) | 653 (* EX: Prove UIP_refl' : forall (A : Type) (x : A) (pf : x = x), pf == eq_refl x *) |
654 (* begin thide *) | 654 (* begin thide *) |
655 Definition UIP_refl' (A : Type) (x : A) (pf : x = x) : pf == refl_equal x := | 655 Definition UIP_refl' (A : Type) (x : A) (pf : x = x) : pf == eq_refl x := |
656 match pf return (pf == refl_equal _) with | 656 match pf return (pf == eq_refl _) with |
657 | refl_equal => JMeq_refl _ | 657 | eq_refl => JMeq_refl _ |
658 end. | 658 end. |
659 (* end thide *) | 659 (* end thide *) |
660 | 660 |
661 (** There is no quick way to write such a proof by tactics, but the underlying proof term that we want is trivial. | 661 (** There is no quick way to write such a proof by tactics, but the underlying proof term that we want is trivial. |
662 | 662 |
663 Suppose that we want to use [UIP_refl'] to establish another lemma of the kind we have run into several times so far. *) | 663 Suppose that we want to use [UIP_refl'] to establish another lemma of the kind we have run into several times so far. *) |
664 | 664 |
665 Lemma lemma4 : forall (A : Type) (x : A) (pf : x = x), | 665 Lemma lemma4 : forall (A : Type) (x : A) (pf : x = x), |
666 O = match pf with refl_equal => O end. | 666 O = match pf with eq_refl => O end. |
667 (* begin thide *) | 667 (* begin thide *) |
668 intros; rewrite (UIP_refl' pf); reflexivity. | 668 intros; rewrite (UIP_refl' pf); reflexivity. |
669 Qed. | 669 Qed. |
670 (* end thide *) | 670 (* end thide *) |
671 | 671 |
860 (* begin thide *) | 860 (* begin thide *) |
861 (** Assuming axioms (like axiom K and [JMeq_eq]) is a hazardous business. The due diligence associated with it is necessarily global in scope, since two axioms may be consistent alone but inconsistent together. It turns out that all of the major axioms proposed for reasoning about equality in Coq are logically equivalent, so that we only need to pick one to assert without proof. In this section, we demonstrate this by showing how each of the previous two sections' approaches reduces to the other logically. | 861 (** Assuming axioms (like axiom K and [JMeq_eq]) is a hazardous business. The due diligence associated with it is necessarily global in scope, since two axioms may be consistent alone but inconsistent together. It turns out that all of the major axioms proposed for reasoning about equality in Coq are logically equivalent, so that we only need to pick one to assert without proof. In this section, we demonstrate this by showing how each of the previous two sections' approaches reduces to the other logically. |
862 | 862 |
863 To show that [JMeq] and its axiom let us prove [UIP_refl], we start from the lemma [UIP_refl'] from the previous section. The rest of the proof is trivial. *) | 863 To show that [JMeq] and its axiom let us prove [UIP_refl], we start from the lemma [UIP_refl'] from the previous section. The rest of the proof is trivial. *) |
864 | 864 |
865 Lemma UIP_refl'' : forall (A : Type) (x : A) (pf : x = x), pf = refl_equal x. | 865 Lemma UIP_refl'' : forall (A : Type) (x : A) (pf : x = x), pf = eq_refl x. |
866 intros; rewrite (UIP_refl' pf); reflexivity. | 866 intros; rewrite (UIP_refl' pf); reflexivity. |
867 Qed. | 867 Qed. |
868 | 868 |
869 (** The other direction is perhaps more interesting. Assume that we only have the axiom of the [Eqdep] module available. We can define [JMeq] in a way that satisfies the same interface as the combination of the [JMeq] module's inductive definition and axiom. *) | 869 (** The other direction is perhaps more interesting. Assume that we only have the axiom of the [Eqdep] module available. We can define [JMeq] in a way that satisfies the same interface as the combination of the [JMeq] module's inductive definition and axiom. *) |
870 | 870 |
871 Definition JMeq' (A : Type) (x : A) (B : Type) (y : B) : Prop := | 871 Definition JMeq' (A : Type) (x : A) (B : Type) (y : B) : Prop := |
872 exists pf : B = A, x = match pf with refl_equal => y end. | 872 exists pf : B = A, x = match pf with eq_refl => y end. |
873 | 873 |
874 Infix "===" := JMeq' (at level 70, no associativity). | 874 Infix "===" := JMeq' (at level 70, no associativity). |
875 | 875 |
876 (** We say that, by definition, [x] and [y] are equal if and only if there exists a proof [pf] that their types are equal, such that [x] equals the result of casting [y] with [pf]. This statement can look strange from the standpoint of classical math, where we almost never mention proofs explicitly with quantifiers in formulas, but it is perfectly legal Coq code. | 876 (** We say that, by definition, [x] and [y] are equal if and only if there exists a proof [pf] that their types are equal, such that [x] equals the result of casting [y] with [pf]. This statement can look strange from the standpoint of classical math, where we almost never mention proofs explicitly with quantifiers in formulas, but it is perfectly legal Coq code. |
877 | 877 |
878 We can easily prove a theorem with the same type as that of the [JMeq_refl] constructor of [JMeq]. *) | 878 We can easily prove a theorem with the same type as that of the [JMeq_refl] constructor of [JMeq]. *) |
879 | 879 |
880 (** remove printing exists *) | 880 (** remove printing exists *) |
881 Theorem JMeq_refl' : forall (A : Type) (x : A), x === x. | 881 Theorem JMeq_refl' : forall (A : Type) (x : A), x === x. |
882 intros; unfold JMeq'; exists (refl_equal A); reflexivity. | 882 intros; unfold JMeq'; exists (eq_refl A); reflexivity. |
883 Qed. | 883 Qed. |
884 | 884 |
885 (** printing exists $\exists$ *) | 885 (** printing exists $\exists$ *) |
886 | 886 |
887 (** The proof of an analogue to [JMeq_eq] is a little more interesting, but most of the action is in appealing to [UIP_refl]. *) | 887 (** The proof of an analogue to [JMeq_eq] is a little more interesting, but most of the action is in appealing to [UIP_refl]. *) |
890 x === y -> x = y. | 890 x === y -> x = y. |
891 unfold JMeq'; intros. | 891 unfold JMeq'; intros. |
892 (** [[ | 892 (** [[ |
893 H : exists pf : A = A, | 893 H : exists pf : A = A, |
894 x = match pf in (_ = T) return T with | 894 x = match pf in (_ = T) return T with |
895 | refl_equal => y | 895 | eq_refl => y |
896 end | 896 end |
897 ============================ | 897 ============================ |
898 x = y | 898 x = y |
899 ]] | 899 ]] |
900 *) | 900 *) |
901 | 901 |
902 destruct H. | 902 destruct H. |
903 (** [[ | 903 (** [[ |
904 x0 : A = A | 904 x0 : A = A |
905 H : x = match x0 in (_ = T) return T with | 905 H : x = match x0 in (_ = T) return T with |
906 | refl_equal => y | 906 | eq_refl => y |
907 end | 907 end |
908 ============================ | 908 ============================ |
909 x = y | 909 x = y |
910 ]] | 910 ]] |
911 *) | 911 *) |
913 rewrite H. | 913 rewrite H. |
914 (** [[ | 914 (** [[ |
915 x0 : A = A | 915 x0 : A = A |
916 ============================ | 916 ============================ |
917 match x0 in (_ = T) return T with | 917 match x0 in (_ = T) return T with |
918 | refl_equal => y | 918 | eq_refl => y |
919 end = y | 919 end = y |
920 ]] | 920 ]] |
921 *) | 921 *) |
922 | 922 |
923 rewrite (UIP_refl _ _ x0); reflexivity. | 923 rewrite (UIP_refl _ _ x0); reflexivity. |