comparison src/Match.v @ 220:15501145d696

Ported Match
author Adam Chlipala <adamc@hcoop.net>
date Mon, 16 Nov 2009 10:32:04 -0500
parents f05514cc6c0d
children 82eae7bc91ea
comparison
equal deleted inserted replaced
219:dbac52f5bce1 220:15501145d696
1 (* Copyright (c) 2008, Adam Chlipala 1 (* Copyright (c) 2008-2009, Adam Chlipala
2 * 2 *
3 * This work is licensed under a 3 * This work is licensed under a
4 * Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 4 * Creative Commons Attribution-Noncommercial-No Derivative Works 3.0
5 * Unported License. 5 * Unported License.
6 * The license text is available at: 6 * The license text is available at:
33 33
34 (** * Hint Databases *) 34 (** * Hint Databases *)
35 35
36 (** Another class of built-in tactics includes [auto], [eauto], and [autorewrite]. These are based on %\textit{%#<i>#hint databases#</i>#%}%, which we have seen extended in many examples so far. These tactics are important, because, in Ltac programming, we cannot create "global variables" whose values can be extended seamlessly by different modules in different source files. We have seen the advantages of hints so far, where [crush] can be defined once and for all, while still automatically applying the hints we add throughout developments. 36 (** Another class of built-in tactics includes [auto], [eauto], and [autorewrite]. These are based on %\textit{%#<i>#hint databases#</i>#%}%, which we have seen extended in many examples so far. These tactics are important, because, in Ltac programming, we cannot create "global variables" whose values can be extended seamlessly by different modules in different source files. We have seen the advantages of hints so far, where [crush] can be defined once and for all, while still automatically applying the hints we add throughout developments.
37 37
38 The basic hints for [auto] and [eauto] are [Hint Immediate lemma], asking to try solving a goal immediately by applying the premise-free lemma; [Resolve lemma], which does the same but may add new premises that are themselves to be subjects of proof search; [Constructor type], which acts like [Resolve] applied to every constructor of an inductive type; and [Unfold ident], which tries unfolding [ident] when it appears at the head of a proof goal. Each of these [Hint] commands may be used with a suffix, as in [Hint Resolve lemma : my_db]. This adds the hint only to the specified database, so that it would only be used by, for instance, [auto with my_db]. An additional argument to [auto] specifies the maximum depth of proof trees to search in depth-first order, as in [auto 8] or [auto 8 with my_db]. The default depth is 5. 38 The basic hints for [auto] and [eauto] are [Hint Immediate lemma], asking to try solving a goal immediately by applying a lemma and discharging any hypotheses with a single proof step each; [Resolve lemma], which does the same but may add new premises that are themselves to be subjects of nested proof search; [Constructor type], which acts like [Resolve] applied to every constructor of an inductive type; and [Unfold ident], which tries unfolding [ident] when it appears at the head of a proof goal. Each of these [Hint] commands may be used with a suffix, as in [Hint Resolve lemma : my_db]. This adds the hint only to the specified database, so that it would only be used by, for instance, [auto with my_db]. An additional argument to [auto] specifies the maximum depth of proof trees to search in depth-first order, as in [auto 8] or [auto 8 with my_db]. The default depth is 5.
39 39
40 All of these [Hint] commands can be issued alternatively with a more primitive hint kind, [Extern]. A few examples should do best to explain how [Hint Extern] works. *) 40 All of these [Hint] commands can be issued alternatively with a more primitive hint kind, [Extern]. A few examples should do best to explain how [Hint Extern] works. *)
41 41
42 Theorem bool_neq : true <> false. 42 Theorem bool_neq : true <> false.
43 (* begin thide *) 43 (* begin thide *)
44 auto. 44 auto.
45
45 (** [crush] would have discharged this goal, but the default hint database for [auto] contains no hint that applies. *) 46 (** [crush] would have discharged this goal, but the default hint database for [auto] contains no hint that applies. *)
47
46 Abort. 48 Abort.
47 49
48 (** It is hard to come up with a [bool]-specific hint that is not just a restatement of the theorem we mean to prove. Luckily, a simpler form suffices. *) 50 (** It is hard to come up with a [bool]-specific hint that is not just a restatement of the theorem we mean to prove. Luckily, a simpler form suffices. *)
49 51
50 Hint Extern 1 (_ <> _) => congruence. 52 Hint Extern 1 (_ <> _) => congruence.
65 Hypothesis both : forall x, P x /\ Q x. 67 Hypothesis both : forall x, P x /\ Q x.
66 68
67 Theorem forall_and : forall z, P z. 69 Theorem forall_and : forall z, P z.
68 (* begin thide *) 70 (* begin thide *)
69 crush. 71 crush.
72
70 (** [crush] makes no progress beyond what [intros] would have accomplished. [auto] will not apply the hypothesis [both] to prove the goal, because the conclusion of [both] does not unify with the conclusion of the goal. However, we can teach [auto] to handle this kind of goal. *) 73 (** [crush] makes no progress beyond what [intros] would have accomplished. [auto] will not apply the hypothesis [both] to prove the goal, because the conclusion of [both] does not unify with the conclusion of the goal. However, we can teach [auto] to handle this kind of goal. *)
71 74
72 Hint Extern 1 (P ?X) => 75 Hint Extern 1 (P ?X) =>
73 match goal with 76 match goal with
74 | [ H : forall x, P x /\ _ |- _ ] => apply (proj1 (H X)) 77 | [ H : forall x, P x /\ _ |- _ ] => apply (proj1 (H X))
77 auto. 80 auto.
78 Qed. 81 Qed.
79 (* end thide *) 82 (* end thide *)
80 83
81 (** We see that an [Extern] pattern may bind unification variables that we use in the associated tactic. [proj1] is a function from the standard library for extracting a proof of [R] from a proof of [R /\ S]. *) 84 (** We see that an [Extern] pattern may bind unification variables that we use in the associated tactic. [proj1] is a function from the standard library for extracting a proof of [R] from a proof of [R /\ S]. *)
85
82 End forall_and. 86 End forall_and.
83 87
84 (** After our success on this example, we might get more ambitious and seek to generalize the hint to all possible predicates [P]. 88 (** After our success on this example, we might get more ambitious and seek to generalize the hint to all possible predicates [P].
85 89
86 [[ 90 [[
87 Hint Extern 1 (?P ?X) => 91 Hint Extern 1 (?P ?X) =>
88 match goal with 92 match goal with
89 | [ H : forall x, ?P x /\ _ |- _ ] => apply (proj1 (H X)) 93 | [ H : forall x, P x /\ _ |- _ ] => apply (proj1 (H X))
90 end. 94 end.
91 95
92 ]]
93
94 [[
95 User error: Bound head variable 96 User error: Bound head variable
97
96 ]] 98 ]]
97 99
98 Coq's [auto] hint databases work as tables mapping %\textit{%#<i>#head symbols#</i>#%}% to lists of tactics to try. Because of this, the constant head of an [Extern] pattern must be determinable statically. In our first [Extern] hint, the head symbol was [not], since [x <> y] desugars to [not (eq x y)]; and, in the second example, the head symbol was [P]. 100 Coq's [auto] hint databases work as tables mapping %\textit{%#<i>#head symbols#</i>#%}% to lists of tactics to try. Because of this, the constant head of an [Extern] pattern must be determinable statically. In our first [Extern] hint, the head symbol was [not], since [x <> y] desugars to [not (eq x y)]; and, in the second example, the head symbol was [P].
99 101
100 This restriction on [Extern] hints is the main limitation of the [auto] mechanism, preventing us from using it for general context simplifications that are not keyed off of the form of the conclusion. This is perhaps just as well, since we can often code more efficient tactics with specialized Ltac programs, and we will see how in later sections of the chapter. 102 This restriction on [Extern] hints is the main limitation of the [auto] mechanism, preventing us from using it for general context simplifications that are not keyed off of the form of the conclusion. This is perhaps just as well, since we can often code more efficient tactics with specialized Ltac programs, and we will see how in later sections of the chapter.
123 Hint Rewrite f_g : my_db. 125 Hint Rewrite f_g : my_db.
124 126
125 Lemma f_f_f' : forall x, f (f (f x)) = f x. 127 Lemma f_f_f' : forall x, f (f (f x)) = f x.
126 intros; autorewrite with my_db. 128 intros; autorewrite with my_db.
127 (** [[ 129 (** [[
128
129 ============================ 130 ============================
130 g (g (g x)) = g x 131 g (g (g x)) = g x
131 ]] *) 132 ]] *)
133
132 Abort. 134 Abort.
133 135
134 (** Our new hint was used to rewrite the goal into a form where the old hint could no longer be applied. This "non-monotonicity" of rewrite hints contrasts with the situation for [auto], where new hints may slow down proof search but can never "break" old proofs. *) 136 (** Our new hint was used to rewrite the goal into a form where the old hint could no longer be applied. This "non-monotonicity" of rewrite hints contrasts with the situation for [auto], where new hints may slow down proof search but can never "break" old proofs. *)
135 137
136 Reset garden_path. 138 Reset garden_path.
155 subgoal 3 is: 157 subgoal 3 is:
156 P (f x) 158 P (f x)
157 subgoal 4 is: 159 subgoal 4 is:
158 P (f x) 160 P (f x)
159 ]] *) 161 ]] *)
162
160 Abort. 163 Abort.
161 164
162 (** The inappropriate rule fired the same three times as before, even though we know we will not be able to prove the premises. *) 165 (** The inappropriate rule fired the same three times as before, even though we know we will not be able to prove the premises. *)
163 166
164 Reset garden_path. 167 Reset garden_path.
186 intros; autorewrite with my_db; reflexivity. 189 intros; autorewrite with my_db; reflexivity.
187 (* end thide *) 190 (* end thide *)
188 Qed. 191 Qed.
189 End garden_path. 192 End garden_path.
190 193
194 (** remove printing * *)
195
191 (** It can also be useful to use the [autorewrite with db in *] form, which does rewriting in hypotheses, as well as in the conclusion. *) 196 (** It can also be useful to use the [autorewrite with db in *] form, which does rewriting in hypotheses, as well as in the conclusion. *)
197
198 (** printing * $*$ *)
192 199
193 Lemma in_star : forall x y, f (f (f (f x))) = f (f y) 200 Lemma in_star : forall x y, f (f (f (f x))) = f (f y)
194 -> f x = f (f (f y)). 201 -> f x = f (f (f y)).
195 (* begin thide *) 202 (* begin thide *)
196 intros; autorewrite with my_db in *; assumption. 203 intros; autorewrite with my_db in *; assumption.
284 end. 291 end.
285 (* end thide *) 292 (* end thide *)
286 293
287 (** Since [match] patterns can share unification variables between hypothesis and conclusion patterns, it is easy to figure out when the conclusion matches a hypothesis. The [exact] tactic solves a goal completely when given a proof term of the proper type. 294 (** Since [match] patterns can share unification variables between hypothesis and conclusion patterns, it is easy to figure out when the conclusion matches a hypothesis. The [exact] tactic solves a goal completely when given a proof term of the proper type.
288 295
289 It is also trivial to implement the "introduction rules" for a few of the connectives. Implementing elimination rules is only a little more work, since we must bind a name for a hypothesis to [destruct]. 296 It is also trivial to implement the "introduction rules" for a few of the connectives. Implementing elimination rules is only a little more work, since we must give a name for a hypothesis to [destruct].
290 297
291 The last rule implements modus ponens. The most interesting part is the use of the Ltac-level [let] with a [fresh] expression. [fresh] takes in a name base and returns a fresh hypothesis variable based on that name. We use the new name variable [H] as the name we assign to the result of modus ponens. The use of [generalize] changes our conclusion to be an implication from [Q]. We clear the original hypothesis and move [Q] into the context with name [H]. *) 298 The last rule implements modus ponens. The most interesting part is the use of the Ltac-level [let] with a [fresh] expression. [fresh] takes in a name base and returns a fresh hypothesis variable based on that name. We use the new name variable [H] as the name we assign to the result of modus ponens. The use of [generalize] changes our conclusion to be an implication from [Q]. We clear the original hypothesis and move [Q] into the context with name [H]. *)
292 299
293 Section propositional. 300 Section propositional.
294 Variables P Q R : Prop. 301 Variables P Q R : Prop.
321 328
322 The example shows how failure can move to a different pattern within a [match]. Failure can also trigger an attempt to find %\textit{%#<i>#a different way of matching a single pattern#</i>#%}%. Consider another example: *) 329 The example shows how failure can move to a different pattern within a [match]. Failure can also trigger an attempt to find %\textit{%#<i>#a different way of matching a single pattern#</i>#%}%. Consider another example: *)
323 330
324 Theorem m2 : forall P Q R : Prop, P -> Q -> R -> Q. 331 Theorem m2 : forall P Q R : Prop, P -> Q -> R -> Q.
325 intros; match goal with 332 intros; match goal with
326 | [ H : _ |- _ ] => pose H 333 | [ H : _ |- _ ] => idtac H
327 end. 334 end.
328 (** [[ 335
329 336 (** Coq prints "[H1]". By applying [idtac] with an argument, a convenient debugging tool for "leaking information out of [match]es," we see that this [match] first tries binding [H] to [H1], which cannot be used to prove [Q]. Nonetheless, the following variation on the tactic succeeds at proving the goal: *)
330 r := H1 : R
331 ============================
332 Q
333 ]]
334
335 By applying [pose], a convenient debugging tool for "leaking information out of [match]es," we see that this [match] first tries binding [H] to [H1], which cannot be used to prove [Q]. Nonetheless, the following variation on the tactic succeeds at proving the goal: *)
336 337
337 (* begin thide *) 338 (* begin thide *)
338 match goal with 339 match goal with
339 | [ H : _ |- _ ] => exact H 340 | [ H : _ |- _ ] => exact H
340 end. 341 end.
404 405
405 Theorem fo : forall x, P x -> S x. 406 Theorem fo : forall x, P x -> S x.
406 (* begin thide *) 407 (* begin thide *)
407 completer. 408 completer.
408 (** [[ 409 (** [[
409
410 x : A 410 x : A
411 H : P x 411 H : P x
412 H0 : Q x 412 H0 : Q x
413 H3 : R x 413 H3 : R x
414 H4 : S x 414 H4 : S x
447 Hypothesis H2 : forall x, R x -> S x. 447 Hypothesis H2 : forall x, R x -> S x.
448 448
449 Theorem fo' : forall x, P x -> S x. 449 Theorem fo' : forall x, P x -> S x.
450 (* begin thide *) 450 (* begin thide *)
451 (** [[ 451 (** [[
452
453 completer'. 452 completer'.
454 453
455 ]] 454 ]]
456 455
457 Coq loops forever at this point. What went wrong? *) 456 Coq loops forever at this point. What went wrong? *)
457
458 Abort. 458 Abort.
459 (* end thide *) 459 (* end thide *)
460 End firstorder'. 460 End firstorder'.
461 461
462 (** A few examples should illustrate the issue. Here we see a [match]-based proof that works fine: *) 462 (** A few examples should illustrate the issue. Here we see a [match]-based proof that works fine: *)
472 (** This one fails. *) 472 (** This one fails. *)
473 473
474 (* begin thide *) 474 (* begin thide *)
475 Theorem t1' : forall x : nat, x = x. 475 Theorem t1' : forall x : nat, x = x.
476 (** [[ 476 (** [[
477
478 match goal with 477 match goal with
479 | [ |- forall x, ?P ] => trivial 478 | [ |- forall x, ?P ] => trivial
480 end. 479 end.
481 480
482 ]]
483
484 [[
485 User error: No matching clauses for match goal 481 User error: No matching clauses for match goal
486 ]] *) 482 ]] *)
483
487 Abort. 484 Abort.
488 (* end thide *) 485 (* end thide *)
489 486
490 (** The problem is that unification variables may not contain locally-bound variables. In this case, [?P] would need to be bound to [x = x], which contains the local quantified variable [x]. By using a wildcard in the earlier version, we avoided this restriction. 487 (** The problem is that unification variables may not contain locally-bound variables. In this case, [?P] would need to be bound to [x = x], which contains the local quantified variable [x]. By using a wildcard in the earlier version, we avoided this restriction.
491 488
507 match ls with 504 match ls with
508 | nil => O 505 | nil => O
509 | _ :: ls' => S (length ls') 506 | _ :: ls' => S (length ls')
510 end. 507 end.
511 508
512 ]]
513
514 [[
515 Error: The reference ls' was not found in the current environment 509 Error: The reference ls' was not found in the current environment
510
516 ]] 511 ]]
517 512
518 At this point, we hopefully remember that pattern variable names must be prefixed by question marks in Ltac. 513 At this point, we hopefully remember that pattern variable names must be prefixed by question marks in Ltac.
519 514
520 [[ 515 [[
522 match ls with 517 match ls with
523 | nil => O 518 | nil => O
524 | _ :: ?ls' => S (length ls') 519 | _ :: ?ls' => S (length ls')
525 end. 520 end.
526 521
527 ]]
528
529 [[
530 Error: The reference S was not found in the current environment 522 Error: The reference S was not found in the current environment
523
531 ]] 524 ]]
532 525
533 The problem is that Ltac treats the expression [S (length ls')] as an invocation of a tactic [S] with argument [length ls']. We need to use a special annotation to "escape into" the Gallina parsing nonterminal. *) 526 The problem is that Ltac treats the expression [S (length ls')] as an invocation of a tactic [S] with argument [length ls']. We need to use a special annotation to "escape into" the Gallina parsing nonterminal. *)
534 527
535 (* begin thide *) 528 (* begin thide *)
543 536
544 Goal False. 537 Goal False.
545 let n := length (1 :: 2 :: 3 :: nil) in 538 let n := length (1 :: 2 :: 3 :: nil) in
546 pose n. 539 pose n.
547 (** [[ 540 (** [[
548
549 n := S (length (2 :: 3 :: nil)) : nat 541 n := S (length (2 :: 3 :: nil)) : nat
550 ============================ 542 ============================
551 False 543 False
544
552 ]] 545 ]]
553 546
554 [n] only has the length calculation unrolled one step. What has happened here is that, by escaping into the [constr] nonterminal, we referred to the [length] function of Gallina, rather than the [length] Ltac function that we are defining. *)Abort. 547 We use the [pose] tactic, which extends the proof context with a new variable that is set equal to particular a term. We could also have used [idtac n] in place of [pose n], which would have printed the result without changing the context.
548
549 [n] only has the length calculation unrolled one step. What has happened here is that, by escaping into the [constr] nonterminal, we referred to the [length] function of Gallina, rather than the [length] Ltac function that we are defining. *)
550
551 Abort.
555 552
556 Reset length. 553 Reset length.
557 554
558 (** The thing to remember is that Gallina terms built by tactics must be bound explicitly via [let] or a similar technique, rather than inserting Ltac calls directly in other Gallina terms. *) 555 (** The thing to remember is that Gallina terms built by tactics must be bound explicitly via [let] or a similar technique, rather than inserting Ltac calls directly in other Gallina terms. *)
559 556
567 564
568 Goal False. 565 Goal False.
569 let n := length (1 :: 2 :: 3 :: nil) in 566 let n := length (1 :: 2 :: 3 :: nil) in
570 pose n. 567 pose n.
571 (** [[ 568 (** [[
572
573 n := 3 : nat 569 n := 3 : nat
574 ============================ 570 ============================
575 False 571 False
576 ]] *) 572 ]] *)
573
577 Abort. 574 Abort.
578 (* end thide *) 575 (* end thide *)
579 576
580 (* EX: Write a list map function in Ltac. *) 577 (* EX: Write a list map function in Ltac. *)
581 578
599 596
600 Goal False. 597 Goal False.
601 let ls := map (nat * nat)%type ltac:(fun x => constr:(x, x)) (1 :: 2 :: 3 :: nil) in 598 let ls := map (nat * nat)%type ltac:(fun x => constr:(x, x)) (1 :: 2 :: 3 :: nil) in
602 pose ls. 599 pose ls.
603 (** [[ 600 (** [[
604
605 l := (1, 1) :: (2, 2) :: (3, 3) :: nil : list (nat * nat) 601 l := (1, 1) :: (2, 2) :: (3, 3) :: nil : list (nat * nat)
606 ============================ 602 ============================
607 False 603 False
608 ]] *) 604 ]] *)
605
609 Abort. 606 Abort.
610 (* end thide *) 607 (* end thide *)
611 608
612 609
613 (** * Recursive Proof Search *) 610 (** * Recursive Proof Search *)
638 Variable g : A -> A -> A. 635 Variable g : A -> A -> A.
639 636
640 Hypothesis H1 : forall x y, P (g x y) -> Q (f x). 637 Hypothesis H1 : forall x y, P (g x y) -> Q (f x).
641 638
642 Theorem test_inster : forall x y, P (g x y) -> Q (f x). 639 Theorem test_inster : forall x y, P (g x y) -> Q (f x).
643 intros; inster 2. 640 inster 2.
644 Qed. 641 Qed.
645 642
646 Hypothesis H3 : forall u v, P u /\ P v /\ u <> v -> P (g u v). 643 Hypothesis H3 : forall u v, P u /\ P v /\ u <> v -> P (g u v).
647 Hypothesis H4 : forall u, Q (f u) -> P u /\ P (f u). 644 Hypothesis H4 : forall u, Q (f u) -> P u /\ P (f u).
648 645
649 Theorem test_inster2 : forall x y, x <> y -> P x -> Q (f y) -> Q (f x). 646 Theorem test_inster2 : forall x y, x <> y -> P x -> Q (f y) -> Q (f x).
650 intros; inster 3. 647 inster 3.
651 Qed. 648 Qed.
652 End test_inster. 649 End test_inster.
653 650
654 (** The style employed in the definition of [inster] can seem very counterintuitive to functional programmers. Usually, functional programs accumulate state changes in explicit arguments to recursive functions. In Ltac, the state of the current subgoal is always implicit. Nonetheless, in contrast to general imperative programming, it is easy to undo any changes to this state, and indeed such "undoing" happens automatically at failures within [match]es. In this way, Ltac programming is similar to programming in Haskell with a stateful failure monad that supports a composition operator along the lines of the [first] tactical. 651 (** The style employed in the definition of [inster] can seem very counterintuitive to functional programmers. Usually, functional programs accumulate state changes in explicit arguments to recursive functions. In Ltac, the state of the current subgoal is always implicit. Nonetheless, in contrast to general imperative programming, it is easy to undo any changes to this state, and indeed such "undoing" happens automatically at failures within [match]es. In this way, Ltac programming is similar to programming in Haskell with a stateful failure monad that supports a composition operator along the lines of the [first] tactical.
655 652
788 Theorem imp_True : forall P, 785 Theorem imp_True : forall P,
789 P --> True. 786 P --> True.
790 imp. 787 imp.
791 Qed. 788 Qed.
792 789
793 (** Our final [matcher] tactic is now straightforward. First, we [intros] all variables into scope. Then we attempt simple premise simplifications, finishing the proof upon finding [False] and eliminating any existential quantifiers that we find. After that, we search through the conclusion. We remove [True] conjuncts, remove existential quantifiers by introducing unification variables for their bound variables, and search for matching premises to cancel. Finally, when no more progress is made, we see if the goal has become trivial and can be solved by [imp_True]. *) 790 (** Our final [matcher] tactic is now straightforward. First, we [intros] all variables into scope. Then we attempt simple premise simplifications, finishing the proof upon finding [False] and eliminating any existential quantifiers that we find. After that, we search through the conclusion. We remove [True] conjuncts, remove existential quantifiers by introducing unification variables for their bound variables, and search for matching premises to cancel. Finally, when no more progress is made, we see if the goal has become trivial and can be solved by [imp_True]. In each case, we use the tactic [simple apply] in place of [apply] to use a simpler, less expensive unification algorithm. *)
794 791
795 Ltac matcher := 792 Ltac matcher :=
796 intros; 793 intros;
797 repeat search_prem ltac:(simple apply False_prem || (simple apply ex_prem; intro)); 794 repeat search_prem ltac:(simple apply False_prem || (simple apply ex_prem; intro));
798 repeat search_conc ltac:(simple apply True_conc || simple eapply ex_conc 795 repeat search_conc ltac:(simple apply True_conc || simple eapply ex_conc
808 Qed. 805 Qed.
809 806
810 (** In the generated proof, we find a trace of the workings of the search tactics. *) 807 (** In the generated proof, we find a trace of the workings of the search tactics. *)
811 808
812 Print t2. 809 Print t2.
813 (** [[ 810 (** %\vspace{-.15in}% [[
814
815 t2 = 811 t2 =
816 fun P Q : Prop => 812 fun P Q : Prop =>
817 comm_prem (assoc_prem1 (assoc_prem2 (False_prem (P:=P /\ P /\ Q) (P /\ Q)))) 813 comm_prem (assoc_prem1 (assoc_prem2 (False_prem (P:=P /\ P /\ Q) (P /\ Q))))
818 : forall P Q : Prop, Q /\ (P /\ False) /\ P --> P /\ Q 814 : forall P Q : Prop, Q /\ (P /\ False) /\ P --> P /\ Q
819 ]] *) 815
820 816 ]]
821 (** We can also see that [matcher] is well-suited for cases where some human intervention is needed after the automation finishes. *) 817
818 We can also see that [matcher] is well-suited for cases where some human intervention is needed after the automation finishes. *)
822 819
823 Theorem t3 : forall P Q R : Prop, 820 Theorem t3 : forall P Q R : Prop,
824 P /\ Q --> Q /\ R /\ P. 821 P /\ Q --> Q /\ R /\ P.
825 matcher. 822 matcher.
826 (** [[ 823 (** [[
827
828 ============================ 824 ============================
829 True --> R 825 True --> R
826
830 ]] 827 ]]
831 828
832 [matcher] canceled those conjuncts that it was able to cancel, leaving a simplified subgoal for us, much as [intuition] does. *) 829 [matcher] canceled those conjuncts that it was able to cancel, leaving a simplified subgoal for us, much as [intuition] does. *)
830
833 Abort. 831 Abort.
834 832
835 (** [matcher] even succeeds at guessing quantifier instantiations. It is the unification that occurs in uses of the [Match] lemma that does the real work here. *) 833 (** [matcher] even succeeds at guessing quantifier instantiations. It is the unification that occurs in uses of the [Match] lemma that does the real work here. *)
836 834
837 Theorem t4 : forall (P : nat -> Prop) Q, (exists x, P x /\ Q) --> Q /\ (exists x, P x). 835 Theorem t4 : forall (P : nat -> Prop) Q, (exists x, P x /\ Q) --> Q /\ (exists x, P x).
838 matcher. 836 matcher.
839 Qed. 837 Qed.
840 838
841 Print t4. 839 Print t4.
842 840 (** %\vspace{-.15in}% [[
843 (** [[
844
845 t4 = 841 t4 =
846 fun (P : nat -> Prop) (Q : Prop) => 842 fun (P : nat -> Prop) (Q : Prop) =>
847 and_True_prem 843 and_True_prem
848 (ex_prem (P:=fun x : nat => P x /\ Q) 844 (ex_prem (P:=fun x : nat => P x /\ Q)
849 (fun x : nat => 845 (fun x : nat =>