Mercurial > cpdt > repo
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'. |