comparison src/Equality.v @ 120:39c7894b3f7f

JMeq
author Adam Chlipala <adamc@hcoop.net>
date Sat, 18 Oct 2008 14:24:11 -0400
parents 8df59f0b3dc0
children 61e5622b1195
comparison
equal deleted inserted replaced
119:8df59f0b3dc0 120:39c7894b3f7f
6 * The license text is available at: 6 * The license text is available at:
7 * http://creativecommons.org/licenses/by-nc-nd/3.0/ 7 * http://creativecommons.org/licenses/by-nc-nd/3.0/
8 *) 8 *)
9 9
10 (* begin hide *) 10 (* begin hide *)
11 Require Import Eqdep List. 11 Require Import Eqdep JMeq List.
12 12
13 Require Import Tactics. 13 Require Import Tactics.
14 14
15 Set Implicit Arguments. 15 Set Implicit Arguments.
16 (* end hide *) 16 (* end hide *)
468 rewrite (UIP_refl _ _ pf0). 468 rewrite (UIP_refl _ _ pf0).
469 rewrite (UIP_refl _ _ pf'0). 469 rewrite (UIP_refl _ _ pf'0).
470 reflexivity. 470 reflexivity.
471 Qed. 471 Qed.
472 End fhapp. 472 End fhapp.
473
474 Implicit Arguments fhapp [A B ls1 ls2].
475
476
477 (** * Heterogeneous Equality *)
478
479 (** There is another equality predicate, defined in the [JMeq] module of the standard library, implementing %\textit{%#<i>#heterogeneous equality#</i>#%}%. *)
480
481 Print JMeq.
482 (** [[
483
484 Inductive JMeq (A : Type) (x : A) : forall B : Type, B -> Prop :=
485 JMeq_refl : JMeq x x
486 ]]
487
488 [JMeq] stands for "John Major equality," a name coined by Conor McBride as a sort of pun about British politics. [JMeq] starts out looking a lot like [eq]. The crucial difference is that we may use [JMeq] %\textit{%#<i>#on arguments of different types#</i>#%}%. 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. *)
489
490 Infix "==" := JMeq (at level 70, no associativity).
491
492 Definition lemma3' (A : Type) (x : A) (pf : x = x) : pf == refl_equal x :=
493 match pf return (pf == refl_equal _) with
494 | refl_equal => JMeq_refl _
495 end.
496
497 (** There is no quick way to write such a proof by tactics, but the underlying proof term that we want is trivial.
498
499 Suppose that we want to use [lemma3'] to establish another lemma of the kind of we have run into several times so far. *)
500
501 Lemma lemma4 : forall (A : Type) (x : A) (pf : x = x),
502 O = match pf with refl_equal => O end.
503 intros; rewrite (lemma3' pf); reflexivity.
504 Qed.
505
506 (** All in all, refreshingly straightforward, but there really is no such thing as a free lunch. The use of [rewrite] is implemented in terms of an axiom: *)
507
508 Check JMeq_eq.
509 (** [[
510
511 JMeq_eq
512 : forall (A : Type) (x y : A), x == y -> x = y
513 ]] *)
514
515 (** It may be surprising that we cannot prove that heterogeneous equality implies normal equality. The difficulties are the same kind we have seen so far, based on limitations of [match] annotations.
516
517 We can redo our [fhapp] associativity proof based around [JMeq]. *)
518
519 Section fhapp'.
520 Variable A : Type.
521 Variable B : A -> Type.
522
523 (** This time, the naive theorem statement type-checks. *)
524
525 Theorem fhapp_ass' : forall ls1 ls2 ls3
526 (hls1 : fhlist B ls1) (hls2 : fhlist B ls2) (hls3 : fhlist B ls3),
527 fhapp hls1 (fhapp hls2 hls3) == fhapp (fhapp hls1 hls2) hls3.
528 induction ls1; crush.
529
530 (** Even better, [crush] discharges the first subgoal automatically. The second subgoal is:
531
532 [[
533
534 ============================
535 (a0,
536 fhapp (B:=B) (ls1:=ls1) (ls2:=ls2 ++ ls3) b
537 (fhapp (B:=B) (ls1:=ls2) (ls2:=ls3) hls2 hls3)) ==
538 (a0,
539 fhapp (B:=B) (ls1:=ls1 ++ ls2) (ls2:=ls3)
540 (fhapp (B:=B) (ls1:=ls1) (ls2:=ls2) b hls2) hls3)
541 ]]
542
543 It looks like one rewrite with the inductive hypothesis should be enough to make the goal trivial.
544
545 [[
546
547 rewrite IHls1.
548
549 [[
550
551 Error: Impossible to unify "fhlist B ((ls1 ++ ?1572) ++ ?1573)" with
552 "fhlist B (ls1 ++ ?1572 ++ ?1573)"
553 ]]
554
555 We see that [JMeq] is not a silver bullet. We can use it to simplify the statements of equality facts, but the Coq type-checker uses non-trivial heterogeneous equality facts no more readily than it uses standard equality facts. Here, the problem is that the form [(e1, e2)] is syntactic sugar for an explicit application of a constructor of an inductive type. That application mentions the type of each tuple element explicitly, and our [rewrite] tries to change one of those elements without updating the corresponding type argument.
556
557 We can get around this problem by another multiple use of [generalize]. We want to bring into the goal the proper instance of the inductive hypothesis, and we also want to generalize the two relevant uses of [fhapp]. *)
558
559 generalize (fhapp b (fhapp hls2 hls3))
560 (fhapp (fhapp b hls2) hls3)
561 (IHls1 _ _ b hls2 hls3).
562 (** [[
563
564 ============================
565 forall (f : fhlist B (ls1 ++ ls2 ++ ls3))
566 (f0 : fhlist B ((ls1 ++ ls2) ++ ls3)), f == f0 -> (a0, f) == (a0, f0)
567 ]]
568
569 Now we can rewrite with append associativity, as before. *)
570
571 rewrite app_ass.
572 (** [[
573
574 ============================
575 forall f f0 : fhlist B (ls1 ++ ls2 ++ ls3), f == f0 -> (a0, f) == (a0, f0)
576 ]]
577
578 From this point, the goal is trivial. *)
579
580 intros f f0 H; rewrite H; reflexivity.
581 Qed.
582 End fhapp'.