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.